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