001/* 002 * Copyright 2008-2020 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2008-2020 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2015-2020 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk.unboundidds.tasks; 037 038 039 040import java.util.Arrays; 041import java.util.ArrayList; 042import java.util.Collections; 043import java.util.Date; 044import java.util.LinkedHashMap; 045import java.util.List; 046import java.util.Map; 047 048import com.unboundid.ldap.sdk.Attribute; 049import com.unboundid.ldap.sdk.Entry; 050import com.unboundid.util.NotMutable; 051import com.unboundid.util.StaticUtils; 052import com.unboundid.util.ThreadSafety; 053import com.unboundid.util.ThreadSafetyLevel; 054 055import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*; 056 057 058 059/** 060 * This class defines a Directory Server task that can be used to shut down or 061 * restart the server. 062 * <BR> 063 * <BLOCKQUOTE> 064 * <B>NOTE:</B> This class, and other classes within the 065 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 066 * supported for use against Ping Identity, UnboundID, and 067 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 068 * for proprietary functionality or for external specifications that are not 069 * considered stable or mature enough to be guaranteed to work in an 070 * interoperable way with other types of LDAP servers. 071 * </BLOCKQUOTE> 072 * <BR> 073 * The properties that are available for use with this type of task include: 074 * <UL> 075 * <LI>A flag that indicates whether to shut down the server or to perform 076 * an in-core restart (in which the server shuts down and restarts itself 077 * within the same JVM).</LI> 078 * <LI>An optional message that can be used to provide a reason for the 079 * shutdown or restart.</LI> 080 * </UL> 081 */ 082@NotMutable() 083@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 084public final class ShutdownTask 085 extends Task 086{ 087 /** 088 * The fully-qualified name of the Java class that is used for the shutdown 089 * task. 090 */ 091 static final String SHUTDOWN_TASK_CLASS = 092 "com.unboundid.directory.server.tasks.ShutdownTask"; 093 094 095 096 /** 097 * The name of the attribute used to define a shutdown message. 098 */ 099 private static final String ATTR_SHUTDOWN_MESSAGE = 100 "ds-task-shutdown-message"; 101 102 103 104 /** 105 * The name of the attribute used to indicate whether to restart rather than 106 * shut down the server. 107 */ 108 private static final String ATTR_RESTART_SERVER = 109 "ds-task-restart-server"; 110 111 112 113 /** 114 * The name of the object class used in shutdown task entries. 115 */ 116 private static final String OC_SHUTDOWN_TASK = "ds-task-shutdown"; 117 118 119 120 /** 121 * The task property for the shutdown message. 122 */ 123 private static final TaskProperty PROPERTY_SHUTDOWN_MESSAGE = 124 new TaskProperty(ATTR_SHUTDOWN_MESSAGE, 125 INFO_DISPLAY_NAME_SHUTDOWN_MESSAGE.get(), 126 INFO_DESCRIPTION_SHUTDOWN_MESSAGE.get(), String.class, 127 false, false, false); 128 129 130 131 /** 132 * The task property for the restart server flag. 133 */ 134 private static final TaskProperty PROPERTY_RESTART_SERVER = 135 new TaskProperty(ATTR_RESTART_SERVER, 136 INFO_DISPLAY_NAME_RESTART_SERVER.get(), 137 INFO_DESCRIPTION_RESTART_SERVER.get(), Boolean.class, 138 false, false, false); 139 140 141 142 /** 143 * The serial version UID for this serializable class. 144 */ 145 private static final long serialVersionUID = -5332685779844073667L; 146 147 148 149 // Indicates whether to restart the server rather than shut it down. 150 private final boolean restartServer; 151 152 // A message that describes the reason for the shutdown. 153 private final String shutdownMessage; 154 155 156 157 /** 158 * Creates a new uninitialized shutdown task instance which should only be 159 * used for obtaining general information about this task, including the task 160 * name, description, and supported properties. Attempts to use a task 161 * created with this constructor for any other reason will likely fail. 162 */ 163 public ShutdownTask() 164 { 165 shutdownMessage = null; 166 restartServer = false; 167 } 168 169 170 171 /** 172 * Creates a new shutdown task with the provided information. 173 * 174 * @param taskID The task ID to use for this task. If it is 175 * {@code null} then a UUID will be generated for use 176 * as the task ID. 177 * @param shutdownMessage A message that describes the reason for the 178 * shutdown. It may be {@code null}. 179 * @param restartServer Indicates whether to restart the server rather 180 * than shut it down. 181 */ 182 public ShutdownTask(final String taskID, final String shutdownMessage, 183 final boolean restartServer) 184 { 185 this(taskID, shutdownMessage, restartServer, null, null, null, null, null); 186 } 187 188 189 190 /** 191 * Creates a new shutdown task with the provided information. 192 * 193 * @param taskID The task ID to use for this task. If it is 194 * {@code null} then a UUID will be generated 195 * for use as the task ID. 196 * @param shutdownMessage A message that describes the reason for the 197 * shutdown. It may be {@code null}. 198 * @param restartServer Indicates whether to restart the server 199 * rather than shut it down. 200 * @param scheduledStartTime The time that this task should start 201 * running. 202 * @param dependencyIDs The list of task IDs that will be required 203 * to complete before this task will be 204 * eligible to start. 205 * @param failedDependencyAction Indicates what action should be taken if 206 * any of the dependencies for this task do 207 * not complete successfully. 208 * @param notifyOnCompletion The list of e-mail addresses of individuals 209 * that should be notified when this task 210 * completes. 211 * @param notifyOnError The list of e-mail addresses of individuals 212 * that should be notified if this task does 213 * not complete successfully. 214 */ 215 public ShutdownTask(final String taskID, final String shutdownMessage, 216 final boolean restartServer, 217 final Date scheduledStartTime, 218 final List<String> dependencyIDs, 219 final FailedDependencyAction failedDependencyAction, 220 final List<String> notifyOnCompletion, 221 final List<String> notifyOnError) 222 { 223 this(taskID, shutdownMessage, restartServer, scheduledStartTime, 224 dependencyIDs, failedDependencyAction, null, notifyOnCompletion, 225 null, notifyOnError, null, null, null); 226 } 227 228 229 230 /** 231 * Creates a new shutdown task with the provided information. 232 * 233 * @param taskID The task ID to use for this task. If it is 234 * {@code null} then a UUID will be generated 235 * for use as the task ID. 236 * @param shutdownMessage A message that describes the reason for the 237 * shutdown. It may be {@code null}. 238 * @param restartServer Indicates whether to restart the server 239 * rather than shut it down. 240 * @param scheduledStartTime The time that this task should start 241 * running. 242 * @param dependencyIDs The list of task IDs that will be required 243 * to complete before this task will be 244 * eligible to start. 245 * @param failedDependencyAction Indicates what action should be taken if 246 * any of the dependencies for this task do 247 * not complete successfully. 248 * @param notifyOnStart The list of e-mail addresses of individuals 249 * that should be notified when this task 250 * starts running. 251 * @param notifyOnCompletion The list of e-mail addresses of individuals 252 * that should be notified when this task 253 * completes. 254 * @param notifyOnSuccess The list of e-mail addresses of individuals 255 * that should be notified if this task 256 * completes successfully. 257 * @param notifyOnError The list of e-mail addresses of individuals 258 * that should be notified if this task does 259 * not complete successfully. 260 * @param alertOnStart Indicates whether the server should send an 261 * alert notification when this task starts. 262 * @param alertOnSuccess Indicates whether the server should send an 263 * alert notification if this task completes 264 * successfully. 265 * @param alertOnError Indicates whether the server should send an 266 * alert notification if this task fails to 267 * complete successfully. 268 */ 269 public ShutdownTask(final String taskID, final String shutdownMessage, 270 final boolean restartServer, 271 final Date scheduledStartTime, 272 final List<String> dependencyIDs, 273 final FailedDependencyAction failedDependencyAction, 274 final List<String> notifyOnStart, 275 final List<String> notifyOnCompletion, 276 final List<String> notifyOnSuccess, 277 final List<String> notifyOnError, 278 final Boolean alertOnStart, final Boolean alertOnSuccess, 279 final Boolean alertOnError) 280 { 281 super(taskID, SHUTDOWN_TASK_CLASS, scheduledStartTime, dependencyIDs, 282 failedDependencyAction, notifyOnStart, notifyOnCompletion, 283 notifyOnSuccess, notifyOnError, alertOnStart, alertOnSuccess, 284 alertOnError); 285 286 this.shutdownMessage = shutdownMessage; 287 this.restartServer = restartServer; 288 } 289 290 291 292 /** 293 * Creates a new shutdown task from the provided entry. 294 * 295 * @param entry The entry to use to create this shutdown task. 296 * 297 * @throws TaskException If the provided entry cannot be parsed as a 298 * shutdown task entry. 299 */ 300 public ShutdownTask(final Entry entry) 301 throws TaskException 302 { 303 super(entry); 304 305 // Get the shutdown message. It may be absent. 306 shutdownMessage = entry.getAttributeValue(ATTR_SHUTDOWN_MESSAGE); 307 308 309 // Get the restart server flag. It may be absent. 310 restartServer = parseBooleanValue(entry, ATTR_RESTART_SERVER, false); 311 } 312 313 314 315 /** 316 * Creates a new shutdown task from the provided set of task properties. 317 * 318 * @param properties The set of task properties and their corresponding 319 * values to use for the task. It must not be 320 * {@code null}. 321 * 322 * @throws TaskException If the provided set of properties cannot be used to 323 * create a valid shutdown task. 324 */ 325 public ShutdownTask(final Map<TaskProperty,List<Object>> properties) 326 throws TaskException 327 { 328 super(SHUTDOWN_TASK_CLASS, properties); 329 330 boolean r = false; 331 String m = null; 332 333 for (final Map.Entry<TaskProperty,List<Object>> entry : 334 properties.entrySet()) 335 { 336 final TaskProperty p = entry.getKey(); 337 final String attrName = p.getAttributeName(); 338 final List<Object> values = entry.getValue(); 339 340 if (attrName.equalsIgnoreCase(ATTR_SHUTDOWN_MESSAGE)) 341 { 342 m = parseString(p, values, m); 343 } 344 else if (attrName.equalsIgnoreCase(ATTR_RESTART_SERVER)) 345 { 346 r = parseBoolean(p, values, r); 347 } 348 } 349 350 shutdownMessage = m; 351 restartServer = r; 352 } 353 354 355 356 /** 357 * {@inheritDoc} 358 */ 359 @Override() 360 public String getTaskName() 361 { 362 return INFO_TASK_NAME_SHUTDOWN.get(); 363 } 364 365 366 367 /** 368 * {@inheritDoc} 369 */ 370 @Override() 371 public String getTaskDescription() 372 { 373 return INFO_TASK_DESCRIPTION_SHUTDOWN.get(); 374 } 375 376 377 378 /** 379 * Retrieves the shutdown message that may provide a reason for or additional 380 * information about the shutdown or restart. 381 * 382 * @return The shutdown message, or {@code null} if there is none. 383 */ 384 public String getShutdownMessage() 385 { 386 return shutdownMessage; 387 } 388 389 390 391 /** 392 * Indicates whether to attempt to restart the server rather than shut it 393 * down. 394 * 395 * @return {@code true} if the task should attempt to restart the server, or 396 * {@code false} if it should shut it down. 397 */ 398 public boolean restartServer() 399 { 400 return restartServer; 401 } 402 403 404 405 /** 406 * {@inheritDoc} 407 */ 408 @Override() 409 protected List<String> getAdditionalObjectClasses() 410 { 411 return Collections.singletonList(OC_SHUTDOWN_TASK); 412 } 413 414 415 416 /** 417 * {@inheritDoc} 418 */ 419 @Override() 420 protected List<Attribute> getAdditionalAttributes() 421 { 422 final ArrayList<Attribute> attrs = new ArrayList<>(2); 423 424 if (shutdownMessage != null) 425 { 426 attrs.add(new Attribute(ATTR_SHUTDOWN_MESSAGE, shutdownMessage)); 427 } 428 429 attrs.add(new Attribute(ATTR_RESTART_SERVER, 430 String.valueOf(restartServer))); 431 432 return attrs; 433 } 434 435 436 437 /** 438 * {@inheritDoc} 439 */ 440 @Override() 441 public List<TaskProperty> getTaskSpecificProperties() 442 { 443 final List<TaskProperty> propList = Arrays.asList( 444 PROPERTY_SHUTDOWN_MESSAGE, 445 PROPERTY_RESTART_SERVER); 446 447 return Collections.unmodifiableList(propList); 448 } 449 450 451 452 /** 453 * {@inheritDoc} 454 */ 455 @Override() 456 public Map<TaskProperty,List<Object>> getTaskPropertyValues() 457 { 458 final LinkedHashMap<TaskProperty,List<Object>> props = 459 new LinkedHashMap<>(StaticUtils.computeMapCapacity(10)); 460 461 if (shutdownMessage == null) 462 { 463 props.put(PROPERTY_SHUTDOWN_MESSAGE, Collections.emptyList()); 464 } 465 else 466 { 467 props.put(PROPERTY_SHUTDOWN_MESSAGE, 468 Collections.<Object>singletonList(shutdownMessage)); 469 } 470 471 props.put(PROPERTY_RESTART_SERVER, 472 Collections.<Object>singletonList(restartServer)); 473 474 props.putAll(super.getTaskPropertyValues()); 475 return Collections.unmodifiableMap(props); 476 } 477}