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