opends/src/messages/messages/tools.properties
@@ -1901,7 +1901,8 @@ trying to decode the response from the server: %s SEVERE_ERR_TASK_CLIENT_INVALID_RESPONSE_TYPE_1318=ERROR: Expected an add \ response message but got a %s message instead INFO_TASK_TOOL_TASK_SCHEDULED_1319=Scheduled task %s INFO_TASK_TOOL_TASK_SCHEDULED_NOW_1319=%s task %s scheduled to start \ immediately SEVERE_ERR_LDAP_CONN_INCOMPATIBLE_ARGS_1320=ERROR: argument %s is \ incompatible with use of this tool to interact with the directory as a client SEVERE_ERR_CREATERC_ONLY_RUNS_ON_UNIX_1321=This tool may only be used on \ @@ -2138,4 +2139,9 @@ cannot be canceled SEVERE_ERR_TASK_CLIENT_TASK_STATE_UNKNOWN_1455=State for task '%s' cannot be \ determined INFO_DESCRIPTION_START_DATETIME_1456=Indicates the date/time at which the this \ task will start when scheduled expressed in format 'YYYYMMDDhhmmss'. \ Omission of this option will cause the task to be for immediate execution SEVERE_ERR_START_DATETIME_FORMAT_1457=The start date/time must in format \ 'YYYYMMDDhhmmss' INFO_TASK_TOOL_TASK_SCHEDULED_FUTURE_1458=%s task %s scheduled to start %s opends/src/server/org/opends/server/backends/task/Task.java
@@ -61,6 +61,7 @@ import org.opends.server.types.Operation; import org.opends.server.util.EMailMessage; import org.opends.server.util.TimeThread; import org.opends.server.util.StaticUtils; import static org.opends.server.config.ConfigConstants.*; import static org.opends.server.loggers.debug.DebugLogger.*; @@ -726,10 +727,9 @@ ATTR_TASK_ACTUAL_START_TIME); } SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_GMT_TIME); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); Date d = new Date(actualStartTime); ASN1OctetString s = new ASN1OctetString(dateFormat.format(d)); String startTimeStr = StaticUtils.formatDateTimeString(d); ASN1OctetString s = new ASN1OctetString(startTimeStr); LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(); opends/src/server/org/opends/server/tools/BackUpDB.java
@@ -177,11 +177,10 @@ } // Create the command-line argument parser for use with this program. Message toolDescription = INFO_BACKUPDB_TOOL_DESCRIPTION.get(); LDAPConnectionArgumentParser argParser = new LDAPConnectionArgumentParser("org.opends.server.tools.BackUpDB", toolDescription, false); createArgParser("org.opends.server.tools.BackUpDB", INFO_BACKUPDB_TOOL_DESCRIPTION.get()); // Initialize all the command-line argument types and register them with the // parser. @@ -298,6 +297,7 @@ try { argParser.parseArguments(args); validateTaskArgs(); } catch (ArgumentException ae) { opends/src/server/org/opends/server/tools/ExportLDIF.java
@@ -178,10 +178,9 @@ } // Create the command-line argument parser for use with this program. Message toolDescription = INFO_LDIFEXPORT_TOOL_DESCRIPTION.get(); LDAPConnectionArgumentParser argParser = new LDAPConnectionArgumentParser("org.opends.server.tools.ExportLDIF", toolDescription, false); createArgParser("org.opends.server.tools.ExportLDIF", INFO_LDIFEXPORT_TOOL_DESCRIPTION.get()); // Initialize all the command-line argument types and register them with the @@ -323,6 +322,7 @@ try { argParser.parseArguments(args); validateTaskArgs(); } catch (ArgumentException ae) { opends/src/server/org/opends/server/tools/ImportLDIF.java
@@ -199,11 +199,9 @@ // Create the command-line argument parser for use with this program. Message toolDescription = INFO_LDIFIMPORT_TOOL_DESCRIPTION.get(); LDAPConnectionArgumentParser argParser = new LDAPConnectionArgumentParser("org.opends.server.tools.ImportLDIF", toolDescription, false); createArgParser("org.opends.server.tools.ImportLDIF", INFO_LDIFIMPORT_TOOL_DESCRIPTION.get()); // Initialize all the command-line argument types and register them with the // parser. @@ -236,7 +234,7 @@ templateFile = new StringArgument("templatefile", 't', "templateFile", false, false, new StringArgument("templatefile", 'A', "templateFile", false, false, true, "{templateFile}", null, null, INFO_LDIFIMPORT_DESCRIPTION_TEMPLATE_FILE.get()); argParser.addArgument(templateFile); @@ -390,6 +388,7 @@ try { argParser.parseArguments(args); validateTaskArgs(); } catch (ArgumentException ae) { opends/src/server/org/opends/server/tools/ManageTasks.java
@@ -180,7 +180,7 @@ try { task = new StringArgument( "task", 't', "task", "info", 'i', "info", false, true, "{taskID}", INFO_TASKINFO_TASK_ARG_DESCRIPTION.get()); argParser.addArgument(task); opends/src/server/org/opends/server/tools/RestoreDB.java
@@ -172,10 +172,9 @@ } // Create the command-line argument parser for use with this program. Message toolDescription = INFO_RESTOREDB_TOOL_DESCRIPTION.get(); LDAPConnectionArgumentParser argParser = new LDAPConnectionArgumentParser("org.opends.server.tools.RestoreDB", toolDescription, false); createArgParser("org.opends.server.tools.RestoreDB", INFO_RESTOREDB_TOOL_DESCRIPTION.get()); // Initialize all the command-line argument types and register them with the @@ -246,6 +245,7 @@ try { argParser.parseArguments(args); validateTaskArgs(); } catch (ArgumentException ae) { opends/src/server/org/opends/server/tools/StopDS.java
@@ -480,40 +480,15 @@ if (stopTimeStr.isPresent()) { String timeStr = stopTimeStr.getValue(); if (timeStr.endsWith("Z")) try { SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_GENERALIZED_TIME); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); dateFormat.setLenient(true); try { stopTime = dateFormat.parse(timeStr); } catch (Exception e) { Message message = ERR_STOPDS_CANNOT_DECODE_STOP_TIME.get(); err.println(wrapText(message, MAX_LINE_WIDTH)); return LDAPResultCode.CLIENT_SIDE_PARAM_ERROR; } stopTime = parseDateTimeString(timeStr); } else catch (Exception e) { SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_COMPACT_LOCAL_TIME); dateFormat.setLenient(true); try { stopTime = dateFormat.parse(timeStr); } catch (Exception e) { Message message = ERR_STOPDS_CANNOT_DECODE_STOP_TIME.get(); err.println(wrapText(message, MAX_LINE_WIDTH)); return LDAPResultCode.CLIENT_SIDE_PARAM_ERROR; } Message message = ERR_STOPDS_CANNOT_DECODE_STOP_TIME.get(); err.println(wrapText(message, MAX_LINE_WIDTH)); return LDAPResultCode.CLIENT_SIDE_PARAM_ERROR; } } opends/src/server/org/opends/server/tools/ToolConstants.java
@@ -706,5 +706,21 @@ * Value for verbose option long form. */ public static final String OPTION_LONG_VERBOSE = "verbose"; /** * Scheduled start date/time option long form. */ public static final String OPTION_LONG_START_DATETIME = "start"; /** * Scheduled start date/time option short form. */ public static final Character OPTION_SHORT_START_DATETIME = 't'; /** * Placeholder string for the usage statement. */ public static final String OPTION_VALUE_START_DATETIME = "{startTime}"; } opends/src/server/org/opends/server/tools/tasks/TaskClient.java
@@ -59,6 +59,8 @@ import org.opends.server.types.SearchScope; import static org.opends.server.types.ResultCode.*; import org.opends.server.backends.task.TaskState; import static org.opends.server.util.ServerConstants.*; import org.opends.server.util.StaticUtils; import java.io.IOException; import java.text.SimpleDateFormat; @@ -102,9 +104,10 @@ * @throws LDAPException if there is a problem getting information * out to the directory * @throws ASN1Exception if there is a problem with the encoding * @throws TaskClientException if there is a problem with the task entry */ public synchronized String schedule(TaskScheduleInformation information) throws LDAPException, IOException, ASN1Exception public synchronized TaskEntry schedule(TaskScheduleInformation information) throws LDAPException, IOException, ASN1Exception, TaskClientException { LDAPReader reader = connection.getLDAPReader(); LDAPWriter writer = connection.getLDAPWriter(); @@ -135,6 +138,17 @@ classValues.add(new ASN1OctetString(information.getTaskClass().getName())); attributes.add(new LDAPAttribute(ATTR_TASK_CLASS, classValues)); // add the start time if necessary Date startDate = information.getStartDateTime(); if (startDate != null) { String startTimeString = StaticUtils.formatDateTimeString(startDate); ArrayList<ASN1OctetString> startDateValues = new ArrayList<ASN1OctetString>(1); startDateValues.add(new ASN1OctetString(startTimeString)); attributes.add(new LDAPAttribute(ATTR_TASK_SCHEDULED_START_TIME, startDateValues)); } information.addTaskAttributes(attributes); AddRequestProtocolOp addRequest = new AddRequestProtocolOp(entryDN, @@ -171,7 +185,7 @@ LDAPResultCode.CLIENT_SIDE_LOCAL_ERROR, errorMessage); } return taskID; return getTaskEntry(taskID); } /** opends/src/server/org/opends/server/tools/tasks/TaskEntry.java
@@ -454,9 +454,10 @@ } Date date = dateFormat.parse(timeString); DateFormat df = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL); ret = Message.raw(df.format(date)); DateFormat.MEDIUM, DateFormat.LONG); String dateString = df.format(date); ret = Message.raw(dateString); } catch (ParseException pe){ ret = Message.raw(timeString); } opends/src/server/org/opends/server/tools/tasks/TaskScheduleInformation.java
@@ -30,6 +30,7 @@ import org.opends.server.types.RawAttribute; import java.util.List; import java.util.Date; /** * Interface for tools that are capable of scheduling a task remotely @@ -62,4 +63,10 @@ */ Class getTaskClass(); /** * Gets the date at which this task should be scheduled to start. * * @return date/time at which the task should be scheduled */ Date getStartDateTime(); } opends/src/server/org/opends/server/tools/tasks/TaskTool.java
@@ -29,16 +29,24 @@ import org.opends.server.util.args.LDAPConnectionArgumentParser; import org.opends.server.util.args.ArgumentException; import org.opends.server.util.args.StringArgument; import static org.opends.server.util.StaticUtils.wrapText; import static org.opends.server.util.StaticUtils.getExceptionMessage; import static org.opends.server.util.ServerConstants.MAX_LINE_WIDTH; import org.opends.server.util.StaticUtils; import org.opends.server.protocols.asn1.ASN1Exception; import org.opends.server.tools.LDAPConnection; import org.opends.server.tools.LDAPConnectionException; import static org.opends.server.tools.ToolConstants.*; import org.opends.server.types.LDAPException; import org.opends.server.types.OpenDsException; import org.opends.server.core.DirectoryServer; import org.opends.messages.Message; import static org.opends.messages.ToolMessages.*; import java.io.PrintStream; import java.text.ParseException; import java.util.Date; import java.io.IOException; /** @@ -48,6 +56,87 @@ */ public abstract class TaskTool implements TaskScheduleInformation { LDAPConnectionArgumentParser argParser; StringArgument startArg; /** * Called when this utility should perform its actions locally in this * JVM. * * @param initializeServer indicates whether or not to initialize the * directory server in the case of a local action * @param out stream to write messages; may be null * @param err stream to write messages; may be null * @return int indicating the result of this action */ abstract protected int processLocal(boolean initializeServer, PrintStream out, PrintStream err); /** * Creates an argument parser prepopulated with arguments for processing * input for scheduling tasks with the task backend. * * @param className of this tool * @param toolDescription of this tool * @return LDAPConnectionArgumentParser for processing CLI input */ protected LDAPConnectionArgumentParser createArgParser(String className, Message toolDescription) { LDAPConnectionArgumentParser argParser = new LDAPConnectionArgumentParser( className, toolDescription, false); try { startArg = new StringArgument( OPTION_LONG_START_DATETIME, OPTION_SHORT_START_DATETIME, OPTION_LONG_START_DATETIME, false, false, true, OPTION_VALUE_START_DATETIME, null, null, INFO_DESCRIPTION_START_DATETIME.get()); argParser.addArgument(startArg); } catch (ArgumentException e) { // should never happen } return argParser; } /** * Validates arguments related to task scheduling. This should be * called after the <code>ArgumentParser.parseArguments</code> has * been called. * * @throws ArgumentException if there is a problem with the arguments */ protected void validateTaskArgs() throws ArgumentException { if (startArg.isPresent()) { try { StaticUtils.parseDateTimeString(startArg.getValue()); } catch (ParseException pe) { throw new ArgumentException(ERR_START_DATETIME_FORMAT.get()); } } } /** * {@inheritDoc} */ public Date getStartDateTime() { Date start = null; if (startArg != null && startArg.isPresent()) { try { start = StaticUtils.parseDateTimeString(startArg.getValue()); } catch (ParseException pe) { // ignore; valiidated in validateTaskArgs() } } return start; } /** * Either invokes initiates this tool's local action or schedule this * tool using the tasks interface based on user input. @@ -63,24 +152,50 @@ boolean initializeServer, PrintStream out, PrintStream err) { int ret; String taskId; if (argParser.isLdapOperation()) { if (initializeServer) { try { DirectoryServer.bootstrapClient(); DirectoryServer.initializeJMX(); } catch (Exception e) { Message message = ERR_SERVER_BOOTSTRAP_ERROR.get( getExceptionMessage(e)); err.println(wrapText(message, MAX_LINE_WIDTH)); return 1; } } try { LDAPConnection conn = argParser.connect(out, err); TaskClient tc = new TaskClient(conn); taskId = tc.schedule(this); out.println(wrapText(INFO_TASK_TOOL_TASK_SCHEDULED.get(taskId), MAX_LINE_WIDTH)); TaskEntry taskEntry = tc.schedule(this); Message startTime = taskEntry.getScheduledStartTime(); if (startTime == null || startTime.length() == 0) { out.println( wrapText(INFO_TASK_TOOL_TASK_SCHEDULED_NOW.get( taskEntry.getType(), taskEntry.getId()), MAX_LINE_WIDTH)); } else { out.println( wrapText(INFO_TASK_TOOL_TASK_SCHEDULED_FUTURE.get( taskEntry.getType(), taskEntry.getId(), taskEntry.getScheduledStartTime()), MAX_LINE_WIDTH)); } ret = 0; } catch (LDAPConnectionException e) { Message message = ERR_LDAP_CONN_CANNOT_CONNECT.get(e.getMessage()); if (err != null) err.println(wrapText(message, MAX_LINE_WIDTH)); ret = 1; } catch (ArgumentException e) { Message message = e.getMessageObject(); if (err != null) err.println(wrapText(message, MAX_LINE_WIDTH)); ret = 1; } catch (IOException ioe) { Message message = ERR_TASK_TOOL_IO_ERROR.get(String.valueOf(ioe)); if (err != null) err.println(wrapText(message, MAX_LINE_WIDTH)); @@ -93,6 +208,10 @@ Message message = ERR_TASK_TOOL_DECODE_ERROR.get(le.getMessage()); if (err != null) err.println(wrapText(message, MAX_LINE_WIDTH)); ret = 1; } catch (OpenDsException e) { Message message = e.getMessageObject(); if (err != null) err.println(wrapText(message, MAX_LINE_WIDTH)); ret = 1; } } else { ret = processLocal(initializeServer, out, err); @@ -100,18 +219,4 @@ return ret; } /** * Called when this utility should perform its actions locally in this * JVM. * * @param initializeServer indicates whether or not to initialize the * directory server in the case of a local action * @param out stream to write messages; may be null * @param err stream to write messages; may be null * @return int indicating the result of this action */ abstract protected int processLocal(boolean initializeServer, PrintStream out, PrintStream err); } opends/src/server/org/opends/server/util/StaticUtils.java
@@ -41,6 +41,7 @@ import java.lang.reflect.InvocationTargetException; import java.nio.ByteBuffer; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -48,6 +49,8 @@ import java.util.Map; import java.util.RandomAccess; import java.util.StringTokenizer; import java.util.Date; import java.util.TimeZone; import org.opends.messages.Message; import org.opends.messages.MessageBuilder; @@ -66,7 +69,6 @@ import org.opends.server.types.RDN; /** * This class defines a number of static utility methods that may be used * throughout the server. Note that because of the frequency with which these @@ -3952,5 +3954,56 @@ } } /** * Converts a string representing a time in "yyyyMMddHHmmss.SSS'Z'" or * "yyyyMMddHHmmss" to a <code>Date</code>. * * @param timeStr string formatted appropriately * @return Date object; null if <code>timeStr</code> is null * @throws ParseException if there was a problem converting the string to * a <code>Date</code>. */ static public Date parseDateTimeString(String timeStr) throws ParseException { Date dateTime = null; if (timeStr != null) { if (timeStr.endsWith("Z")) { SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_GENERALIZED_TIME); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); dateFormat.setLenient(true); dateTime = dateFormat.parse(timeStr); } else { SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_COMPACT_LOCAL_TIME); dateFormat.setLenient(true); dateTime = dateFormat.parse(timeStr); } } return dateTime; } /** * Formats a Date to String representation in "yyyyMMddHHmmss'Z'". * * @param date to format; null if <code>date</code> is null * @return string representation of the date */ static public String formatDateTimeString(Date date) { String timeStr = null; if (date != null) { SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_GMT_TIME); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); timeStr = dateFormat.format(date); } return timeStr; } }