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