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