From 2d93a199604f010b176eac1e690272ea8fd61bf0 Mon Sep 17 00:00:00 2001
From: kenneth_suter <kenneth_suter@localhost>
Date: Wed, 22 Aug 2007 16:48:31 +0000
Subject: [PATCH] Expands the interface of both the export-ldif and import-ldif tools to include arguments that allow the task to be scheduled to run in the directory server's JVM through the task interface as well as through the existing method or operating within the running JVM.
---
opends/src/server/org/opends/server/tools/tasks/TaskScheduleInformation.java | 65 ++
opends/src/server/org/opends/server/tools/ExportLDIF.java | 220 +++++++-
opends/src/messages/messages/tools.properties | 44 +
opends/src/server/org/opends/server/tools/tasks/TaskTool.java | 101 ++++
opends/src/server/org/opends/server/tools/tasks/package-info.java | 37 +
opends/src/server/org/opends/server/util/args/LDAPConnectionArgumentParser.java | 450 ++++++++++++++++++
opends/src/server/org/opends/server/tools/tasks/TaskSchedulingClient.java | 208 ++++++++
opends/src/server/org/opends/server/tools/ImportLDIF.java | 266 +++++++++-
8 files changed, 1,322 insertions(+), 69 deletions(-)
diff --git a/opends/src/messages/messages/tools.properties b/opends/src/messages/messages/tools.properties
index 84f22e3..e28f002 100644
--- a/opends/src/messages/messages/tools.properties
+++ b/opends/src/messages/messages/tools.properties
@@ -2158,3 +2158,47 @@
weight
FATAL_ERR_INITIALIZE_SERVER_ROOT_1293=An unexpected error occured \
attempting to set the server's root directory to %s: %s
+SEVERE_ERR_LDAP_CONN_MUTUALLY_EXCLUSIVE_ARGUMENTS_1294=ERROR: You may not \
+ provide both the %s and the %s arguments
+SEVERE_ERR_LDAP_CONN_CANNOT_INITIALIZE_SSL_1295=ERROR: Unable to perform SSL \
+ initialization: %s
+SEVERE_ERR_LDAP_CONN_CANNOT_PARSE_SASL_OPTION_1296=ERROR: The provided SASL \
+ option string "%s" could not be parsed in the form "name=value"
+SEVERE_ERR_LDAP_CONN_NO_SASL_MECHANISM_1297=ERROR: One or more SASL options were \
+ provided, but none of them were the "mech" option to specify which SASL \
+ mechanism should be used
+SEVERE_ERR_LDAP_CONN_CANNOT_DETERMINE_PORT_1298=ERROR: Cannot parse the value of \
+ the %s argument as an integer value between 1 and 65535: %s
+SEVERE_ERR_LDAP_CONN_CANNOT_CONNECT_1299=ERROR: Cannot establish a connection to \
+ the Directory Server: %s
+INFO_LDAP_CONN_DESCRIPTION_HOST_1300=Directory server hostname or IP address
+INFO_LDAP_CONN_DESCRIPTION_PORT_1301=Directory server port number
+INFO_LDAP_CONN_DESCRIPTION_USESSL_1302=Use SSL for secure communication with the \
+ server
+INFO_LDAP_CONN_DESCRIPTION_USESTARTTLS_1303=Use StartTLS for secure communication \
+ with the server
+INFO_LDAP_CONN_DESCRIPTION_BINDDN_1304=Specifies the DN to use to bind to the \
+ server
+INFO_LDAP_CONN_DESCRIPTION_BINDPW_1305=Specifies the password to use to bind to \
+ the server
+INFO_LDAP_CONN_DESCRIPTION_BINDPWFILE_1306=Bind password file
+INFO_LDAP_CONN_DESCRIPTION_SASLOPTIONS_1307=SASL bind options
+INFO_LDAP_CONN_DESCRIPTION_TRUST_ALL_1308=Trust all server SSL certificates
+INFO_LDAP_CONN_DESCRIPTION_KSFILE_1309=Certificate keystore path
+INFO_LDAP_CONN_DESCRIPTION_KSPW_1310=Certificate keystore PIN
+INFO_LDAP_CONN_DESCRIPTION_KSPWFILE_1311=Certificate keystore PIN file
+INFO_LDAP_CONN_DESCRIPTION_TSFILE_1312=Certificate trust store path
+INFO_LDAP_CONN_DESCRIPTION_TSPW_1313=Certificate trust store PIN
+INFO_LDAP_CONN_DESCRIPTION_TSPWFILE_1314=Certificate trust store PIN file
+SEVERE_ERR_TASK_CLIENT_UNEXPECTED_CONNECTION_CLOSURE_1315=NOTICE: The connection \
+ to the Directory Server was closed while waiting for a response to the \
+ shutdown request. This likely means that the server has started the shutdown \
+ process
+SEVERE_ERR_TASK_CLIENT_IO_ERROR_1316=ERROR: An I/O error occurred while attempting \
+ to communicate with the Directory Server: %s
+SEVERE_ERR_TASK_CLIENT_DECODE_ERROR_1317=ERROR: An error occurred while 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_CLIENT_TASK_SCHEDULED_1319=Scheduled task %s
+
diff --git a/opends/src/server/org/opends/server/tools/ExportLDIF.java b/opends/src/server/org/opends/server/tools/ExportLDIF.java
index a79da18..f4c7575 100644
--- a/opends/src/server/org/opends/server/tools/ExportLDIF.java
+++ b/opends/src/server/org/opends/server/tools/ExportLDIF.java
@@ -25,9 +25,6 @@
* Portions Copyright 2006-2007 Sun Microsystems, Inc.
*/
package org.opends.server.tools;
-import org.opends.messages.Message;
-
-
import java.io.OutputStream;
import java.io.PrintStream;
@@ -39,6 +36,7 @@
import org.opends.server.api.ErrorLogPublisher;
import org.opends.server.api.plugin.PluginType;
import org.opends.server.config.ConfigException;
+import static org.opends.server.config.ConfigConstants.*;
import org.opends.server.core.CoreConfigManager;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.LockFileManager;
@@ -53,35 +51,42 @@
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.NullOutputStream;
import org.opends.server.types.SearchFilter;
+import org.opends.server.types.RawAttribute;
import org.opends.server.util.args.ArgumentException;
-import org.opends.server.util.args.ArgumentParser;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.IntegerArgument;
import org.opends.server.util.args.StringArgument;
+import org.opends.server.util.args.LDAPConnectionArgumentParser;
+import org.opends.messages.Message;
import static org.opends.messages.ToolMessages.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.tools.ToolConstants.*;
+import org.opends.server.tools.tasks.TaskTool;
import org.opends.server.admin.std.server.BackendCfg;
+import org.opends.server.protocols.ldap.LDAPAttribute;
+import org.opends.server.protocols.asn1.ASN1OctetString;
+import org.opends.server.tasks.ExportTask;
/**
* This program provides a utility that may be used to export the contents of a
- * Directory Server backend to an LDIF file. This will be a process that is
- * intended to run separate from Directory Server and not internally within the
- * server process (e.g., via the tasks interface).
+ * Directory Server backend to an LDIF file. Depending on the arguments given,
+ * this program will either perform the export directly as a process that
+ * runs separate from Directory Server; or by scheduling a task to perform the
+ * action within the Directory Server via the tasks interface.
*/
-public class ExportLDIF
-{
+public class ExportLDIF extends TaskTool {
+
private static ErrorLogPublisher errorLogPublisher = null;
+
/**
* The main method for ExportLDIF tool.
*
* @param args The command-line arguments provided to this program.
*/
-
public static void main(String[] args)
{
int retCode = mainExportLDIF(args, true, System.out, System.err);
@@ -126,6 +131,32 @@
OutputStream outStream,
OutputStream errStream)
{
+ ExportLDIF tool = new ExportLDIF();
+ return tool.process(args, initializeServer, outStream, errStream);
+ }
+
+ // Define the command-line arguments that may be used with this program.
+ private BooleanArgument appendToLDIF = null;
+ private BooleanArgument compressLDIF = null;
+ private BooleanArgument displayUsage = null;
+ private BooleanArgument encryptLDIF = null;
+ private BooleanArgument excludeOperationalAttrs = null;
+ private BooleanArgument signHash = null;
+ private IntegerArgument wrapColumn = null;
+ private StringArgument backendID = null;
+ private StringArgument configClass = null;
+ private StringArgument configFile = null;
+ private StringArgument excludeAttributeStrings = null;
+ private StringArgument excludeBranchStrings = null;
+ private StringArgument excludeFilterStrings = null;
+ private StringArgument includeAttributeStrings = null;
+ private StringArgument includeBranchStrings = null;
+ private StringArgument includeFilterStrings = null;
+ private StringArgument ldifFile = null;
+
+ private int process(String[] args, boolean initializeServer,
+ OutputStream outStream, OutputStream errStream) {
+
PrintStream out;
if (outStream == null)
{
@@ -146,31 +177,11 @@
err = new PrintStream(errStream);
}
- // Define the command-line arguments that may be used with this program.
- BooleanArgument appendToLDIF = null;
- BooleanArgument compressLDIF = null;
- BooleanArgument displayUsage = null;
- BooleanArgument encryptLDIF = null;
- BooleanArgument excludeOperationalAttrs = null;
- BooleanArgument signHash = null;
- IntegerArgument wrapColumn = null;
- StringArgument backendID = null;
- StringArgument configClass = null;
- StringArgument configFile = null;
- StringArgument excludeAttributeStrings = null;
- StringArgument excludeBranchStrings = null;
- StringArgument excludeFilterStrings = null;
- StringArgument includeAttributeStrings = null;
- StringArgument includeBranchStrings = null;
- StringArgument includeFilterStrings = null;
- StringArgument ldifFile = null;
-
-
// Create the command-line argument parser for use with this program.
Message toolDescription = INFO_LDIFEXPORT_TOOL_DESCRIPTION.get();
- ArgumentParser argParser =
- new ArgumentParser("org.opends.server.tools.ExportLDIF",
- toolDescription, false);
+ LDAPConnectionArgumentParser argParser =
+ new LDAPConnectionArgumentParser("org.opends.server.tools.ExportLDIF",
+ toolDescription, false);
// Initialize all the command-line argument types and register them with the
@@ -267,7 +278,7 @@
wrapColumn =
- new IntegerArgument("wrapcolumn", 'w', "wrapColumn", false, false,
+ new IntegerArgument("wrapcolumn", null, "wrapColumn", false, false,
true, "{wrapColumn}", 0, null, true, 0, false, 0,
INFO_LDIFEXPORT_DESCRIPTION_WRAP_COLUMN.get());
argParser.addArgument(wrapColumn);
@@ -330,6 +341,147 @@
return 0;
}
+ return process(argParser, initializeServer, out, err);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addTaskAttributes(List<RawAttribute> attributes)
+ {
+ //
+ // Required attributes
+ //
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(ldifFile.getValue()));
+ attributes.add(new LDAPAttribute(ATTR_TASK_EXPORT_LDIF_FILE, values));
+
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(backendID.getValue()));
+ attributes.add(new LDAPAttribute(ATTR_TASK_EXPORT_BACKEND_ID, values));
+
+ //
+ // Optional attributes
+ //
+ if (appendToLDIF.getValue() != null &&
+ !appendToLDIF.getValue().equals(appendToLDIF.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(appendToLDIF.getValue()));
+ attributes.add(
+ new LDAPAttribute(ATTR_TASK_EXPORT_APPEND_TO_LDIF, values));
+ }
+
+ if (compressLDIF.getValue() != null &&
+ !compressLDIF.getValue().equals(compressLDIF.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(compressLDIF.getValue()));
+ attributes.add(new LDAPAttribute(ATTR_TASK_EXPORT_COMPRESS_LDIF, values));
+ }
+
+ if (encryptLDIF.getValue() != null &&
+ !encryptLDIF.getValue().equals(encryptLDIF.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(encryptLDIF.getValue()));
+ attributes.add(new LDAPAttribute(ATTR_TASK_EXPORT_ENCRYPT_LDIF, values));
+ }
+
+ if (signHash.getValue() != null &&
+ !signHash.getValue().equals(signHash.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(signHash.getValue()));
+ attributes.add(
+ new LDAPAttribute(ATTR_TASK_EXPORT_SIGN_HASH, values));
+ }
+
+ List<String> includeAttributes = includeAttributeStrings.getValues();
+ if (includeAttributes != null && includeAttributes.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(includeAttributes.size());
+ for (String includeAttribute : includeAttributes) {
+ values.add(new ASN1OctetString(includeAttribute));
+ }
+ attributes.add(
+ new LDAPAttribute(ATTR_TASK_EXPORT_INCLUDE_ATTRIBUTE, values));
+ }
+
+ List<String> excludeAttributes = excludeAttributeStrings.getValues();
+ if (excludeAttributes != null && excludeAttributes.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(excludeAttributes.size());
+ for (String excludeAttribute : excludeAttributes) {
+ values.add(new ASN1OctetString(excludeAttribute));
+ }
+ attributes.add(
+ new LDAPAttribute(ATTR_TASK_EXPORT_EXCLUDE_ATTRIBUTE, values));
+ }
+
+ List<String> includeFilters = includeFilterStrings.getValues();
+ if (includeFilters != null && includeFilters.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(includeFilters.size());
+ for (String includeFilter : includeFilters) {
+ values.add(new ASN1OctetString(includeFilter));
+ }
+ attributes.add(
+ new LDAPAttribute(ATTR_TASK_EXPORT_INCLUDE_FILTER, values));
+ }
+
+ List<String> excludeFilters = excludeFilterStrings.getValues();
+ if (excludeFilters != null && excludeFilters.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(excludeFilters.size());
+ for (String excludeFilter : excludeFilters) {
+ values.add(new ASN1OctetString(excludeFilter));
+ }
+ attributes.add(
+ new LDAPAttribute(ATTR_TASK_EXPORT_EXCLUDE_FILTER, values));
+ }
+
+ List<String> includeBranches = includeBranchStrings.getValues();
+ if (includeBranches != null && includeBranches.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(includeBranches.size());
+ for (String includeBranche : includeBranches) {
+ values.add(new ASN1OctetString(includeBranche));
+ }
+ attributes.add(
+ new LDAPAttribute(ATTR_TASK_EXPORT_INCLUDE_BRANCH, values));
+ }
+
+ List<String> excludeBranches = excludeBranchStrings.getValues();
+ if (excludeBranches != null && excludeBranches.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(excludeBranches.size());
+ for (String excludeBranche : excludeBranches) {
+ values.add(new ASN1OctetString(excludeBranche));
+ }
+ attributes.add(
+ new LDAPAttribute(ATTR_TASK_EXPORT_EXCLUDE_BRANCH, values));
+ }
+
+ if (wrapColumn.getValue() != null &&
+ !wrapColumn.getValue().equals(wrapColumn.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(wrapColumn.getValue()));
+ attributes.add(
+ new LDAPAttribute(ATTR_TASK_EXPORT_WRAP_COLUMN, values));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getTaskObjectclass() {
+ return "ds-task-export";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Class getTaskClass() {
+ return ExportTask.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected int processLocal(boolean initializeServer,
+ PrintStream out,
+ PrintStream err) {
// Perform the initial bootstrap of the Directory Server and process the
// configuration.
diff --git a/opends/src/server/org/opends/server/tools/ImportLDIF.java b/opends/src/server/org/opends/server/tools/ImportLDIF.java
index 9d52fcd..3ca389e 100644
--- a/opends/src/server/org/opends/server/tools/ImportLDIF.java
+++ b/opends/src/server/org/opends/server/tools/ImportLDIF.java
@@ -41,6 +41,7 @@
import org.opends.server.api.ErrorLogPublisher;
import org.opends.server.api.plugin.PluginType;
import org.opends.server.config.ConfigException;
+import static org.opends.server.config.ConfigConstants.*;
import org.opends.server.core.CoreConfigManager;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.LockFileManager;
@@ -58,19 +59,23 @@
import org.opends.server.types.LDIFImportResult;
import org.opends.server.types.NullOutputStream;
import org.opends.server.types.SearchFilter;
+import org.opends.server.types.RawAttribute;
import org.opends.server.util.args.ArgumentException;
-import org.opends.server.util.args.ArgumentParser;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.IntegerArgument;
import org.opends.server.util.args.StringArgument;
+import org.opends.server.util.args.LDAPConnectionArgumentParser;
-import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.messages.ToolMessages.*;
import org.opends.messages.Message;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.tools.ToolConstants.*;
+import org.opends.server.tools.tasks.TaskTool;
+import org.opends.server.tasks.ImportTask;
+import org.opends.server.protocols.asn1.ASN1OctetString;
+import org.opends.server.protocols.ldap.LDAPAttribute;
/**
@@ -79,8 +84,7 @@
* intended to run separate from Directory Server and not internally within the
* server process (e.g., via the tasks interface).
*/
-public class ImportLDIF
-{
+public class ImportLDIF extends TaskTool {
/**
* The buffer size that should be used when reading data from LDIF.
*/
@@ -138,6 +142,39 @@
OutputStream outStream,
OutputStream errStream)
{
+ ImportLDIF tool = new ImportLDIF();
+ return tool.process(args, initializeServer, outStream, errStream);
+ }
+
+ // Define the command-line arguments that may be used with this program.
+ private BooleanArgument append = null;
+ private BooleanArgument countRejects = null;
+ private BooleanArgument displayUsage = null;
+ private BooleanArgument isCompressed = null;
+ private BooleanArgument isEncrypted = null;
+ private BooleanArgument overwrite = null;
+ private BooleanArgument quietMode = null;
+ private BooleanArgument replaceExisting = null;
+ private BooleanArgument skipSchemaValidation = null;
+ private BooleanArgument clearBackend = null;
+ private IntegerArgument randomSeed = null;
+ private StringArgument backendID = null;
+ private StringArgument configClass = null;
+ private StringArgument configFile = null;
+ private StringArgument excludeAttributeStrings = null;
+ private StringArgument excludeBranchStrings = null;
+ private StringArgument excludeFilterStrings = null;
+ private StringArgument includeAttributeStrings = null;
+ private StringArgument includeBranchStrings = null;
+ private StringArgument includeFilterStrings = null;
+ private StringArgument ldifFiles = null;
+ private StringArgument rejectFile = null;
+ private StringArgument skipFile = null;
+ private StringArgument templateFile = null;
+
+ private int process(String[] args, boolean initializeServer,
+ OutputStream outStream, OutputStream errStream) {
+
PrintStream out;
if (outStream == null)
{
@@ -160,38 +197,12 @@
// FIXME -- Need to add a mechanism for verifying the file signature.
- // Define the command-line arguments that may be used with this program.
- BooleanArgument append = null;
- BooleanArgument countRejects = null;
- BooleanArgument displayUsage = null;
- BooleanArgument isCompressed = null;
- BooleanArgument isEncrypted = null;
- BooleanArgument overwrite = null;
- BooleanArgument quietMode = null;
- BooleanArgument replaceExisting = null;
- BooleanArgument skipSchemaValidation = null;
- BooleanArgument clearBackend = null;
- IntegerArgument randomSeed = null;
- StringArgument backendID = null;
- StringArgument configClass = null;
- StringArgument configFile = null;
- StringArgument excludeAttributeStrings = null;
- StringArgument excludeBranchStrings = null;
- StringArgument excludeFilterStrings = null;
- StringArgument includeAttributeStrings = null;
- StringArgument includeBranchStrings = null;
- StringArgument includeFilterStrings = null;
- StringArgument ldifFiles = null;
- StringArgument rejectFile = null;
- StringArgument skipFile = null;
- StringArgument templateFile = null;
-
// Create the command-line argument parser for use with this program.
Message toolDescription = INFO_LDIFIMPORT_TOOL_DESCRIPTION.get();
- ArgumentParser argParser =
- new ArgumentParser("org.opends.server.tools.ImportLDIF",
- toolDescription, false);
+ LDAPConnectionArgumentParser argParser =
+ new LDAPConnectionArgumentParser("org.opends.server.tools.ImportLDIF",
+ toolDescription, false);
// Initialize all the command-line argument types and register them with the
@@ -309,7 +320,7 @@
skipFile =
- new StringArgument("skipfile", 'K', "skipFile", false, false,
+ new StringArgument("skipfile", null, "skipFile", false, false,
true, "{skipFile}", null, null,
INFO_LDIFIMPORT_DESCRIPTION_SKIP_FILE.get());
argParser.addArgument(skipFile);
@@ -354,7 +365,7 @@
argParser.addArgument(isEncrypted);
- quietMode = new BooleanArgument("quietmode", 'q', "quiet",
+ quietMode = new BooleanArgument("quietmode", null, "quiet",
INFO_LDIFIMPORT_DESCRIPTION_QUIET.get());
argParser.addArgument(quietMode);
@@ -430,6 +441,191 @@
return 1;
}
+ return process(argParser, initializeServer, out, err);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addTaskAttributes(List<RawAttribute> attributes)
+ {
+ //
+ // Required attributes
+ //
+ ArrayList<ASN1OctetString> values;
+ List<String> fileList = ldifFiles.getValues();
+ if (fileList != null && fileList.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(fileList.size());
+ for (String file : fileList) {
+ values.add(new ASN1OctetString(file));
+ }
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_LDIF_FILE, values));
+ }
+
+ //
+ // Optional attributes
+ //
+ if (append.getValue() != null &&
+ !append.getValue().equals(append.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(append.getValue()));
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_APPEND, values));
+ }
+
+ if (replaceExisting.getValue() != null &&
+ !replaceExisting.getValue().equals(
+ replaceExisting.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(replaceExisting.getValue()));
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_REPLACE_EXISTING, values));
+ }
+
+ if (backendID.getValue() != null &&
+ !backendID.getValue().equals(
+ backendID.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(backendID.getValue()));
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_BACKEND_ID, values));
+ }
+
+ List<String> includeAttributes = includeAttributeStrings.getValues();
+ if (includeAttributes != null && includeAttributes.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(includeAttributes.size());
+ for (String includeAttribute : includeAttributes) {
+ values.add(new ASN1OctetString(includeAttribute));
+ }
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_INCLUDE_ATTRIBUTE, values));
+ }
+
+ List<String> excludeAttributes = excludeAttributeStrings.getValues();
+ if (excludeAttributes != null && excludeAttributes.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(excludeAttributes.size());
+ for (String excludeAttribute : excludeAttributes) {
+ values.add(new ASN1OctetString(excludeAttribute));
+ }
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_EXCLUDE_ATTRIBUTE, values));
+ }
+
+ List<String> includeFilters = includeFilterStrings.getValues();
+ if (includeFilters != null && includeFilters.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(includeFilters.size());
+ for (String includeFilter : includeFilters) {
+ values.add(new ASN1OctetString(includeFilter));
+ }
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_INCLUDE_FILTER, values));
+ }
+
+ List<String> excludeFilters = excludeFilterStrings.getValues();
+ if (excludeFilters != null && excludeFilters.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(excludeFilters.size());
+ for (String excludeFilter : excludeFilters) {
+ values.add(new ASN1OctetString(excludeFilter));
+ }
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_EXCLUDE_FILTER, values));
+ }
+
+ List<String> includeBranches = includeBranchStrings.getValues();
+ if (includeBranches != null && includeBranches.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(includeBranches.size());
+ for (String includeBranche : includeBranches) {
+ values.add(new ASN1OctetString(includeBranche));
+ }
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_INCLUDE_BRANCH, values));
+ }
+
+ List<String> excludeBranches = excludeBranchStrings.getValues();
+ if (excludeBranches != null && excludeBranches.size() > 0) {
+ values = new ArrayList<ASN1OctetString>(excludeBranches.size());
+ for (String excludeBranch : excludeBranches) {
+ values.add(new ASN1OctetString(excludeBranch));
+ }
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_EXCLUDE_BRANCH, values));
+ }
+
+ if (rejectFile.getValue() != null &&
+ !rejectFile.getValue().equals(
+ rejectFile.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(rejectFile.getValue()));
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_REJECT_FILE, values));
+ }
+
+ if (skipFile.getValue() != null &&
+ !skipFile.getValue().equals(
+ skipFile.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(skipFile.getValue()));
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_SKIP_FILE, values));
+ }
+
+ if (overwrite.getValue() != null &&
+ !overwrite.getValue().equals(
+ overwrite.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(overwrite.getValue()));
+ attributes.add(new LDAPAttribute(ATTR_IMPORT_OVERWRITE, values));
+ }
+
+ if (skipSchemaValidation.getValue() != null &&
+ !skipSchemaValidation.getValue().equals(
+ skipSchemaValidation.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(skipSchemaValidation.getValue()));
+ attributes.add(
+ new LDAPAttribute(ATTR_IMPORT_SKIP_SCHEMA_VALIDATION, values));
+ }
+
+ if (isCompressed.getValue() != null &&
+ !isCompressed.getValue().equals(
+ isCompressed.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(isCompressed.getValue()));
+ attributes.add(
+ new LDAPAttribute(ATTR_IMPORT_IS_COMPRESSED, values));
+ }
+
+ if (isEncrypted.getValue() != null &&
+ !isEncrypted.getValue().equals(
+ isEncrypted.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(isEncrypted.getValue()));
+ attributes.add(
+ new LDAPAttribute(ATTR_IMPORT_IS_ENCRYPTED, values));
+ }
+
+ if (clearBackend.getValue() != null &&
+ !clearBackend.getValue().equals(
+ clearBackend.getDefaultValue())) {
+ values = new ArrayList<ASN1OctetString>(1);
+ values.add(new ASN1OctetString(clearBackend.getValue()));
+ attributes.add(
+ new LDAPAttribute(ATTR_IMPORT_CLEAR_BACKEND, values));
+ }
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getTaskObjectclass() {
+ return "ds-task-import";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Class getTaskClass() {
+ return ImportTask.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected int processLocal(boolean initializeServer,
+ PrintStream out,
+ PrintStream err) {
+
+
// Perform the initial bootstrap of the Directory Server and process the
// configuration.
DirectoryServer directoryServer = DirectoryServer.getInstance();
diff --git a/opends/src/server/org/opends/server/tools/tasks/TaskScheduleInformation.java b/opends/src/server/org/opends/server/tools/tasks/TaskScheduleInformation.java
new file mode 100644
index 0000000..2318bf5
--- /dev/null
+++ b/opends/src/server/org/opends/server/tools/tasks/TaskScheduleInformation.java
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.tools.tasks;
+
+import org.opends.server.types.RawAttribute;
+
+import java.util.List;
+
+/**
+ * Interface for tools that are capable of scheduling a task remotely
+ * through the task backend.
+ *
+ * @see TaskSchedulingClient
+ */
+public interface TaskScheduleInformation {
+
+ /**
+ * Adds utility specific attributes to <code>attributes</code> for
+ * population of the entry that is added to the task backend.
+ *
+ * @param attributes that will be added to the task backend
+ */
+ void addTaskAttributes(List<RawAttribute> attributes);
+
+ /**
+ * Gets the objectclass used to represent scheduled instances of this
+ * utility in the task backend.
+ *
+ * @return String representation of this utilities objectclass
+ */
+ String getTaskObjectclass();
+
+ /**
+ * Gets the Class that implements the utility to execute.
+ *
+ * @return class of the tasks implementation
+ */
+ Class getTaskClass();
+
+}
diff --git a/opends/src/server/org/opends/server/tools/tasks/TaskSchedulingClient.java b/opends/src/server/org/opends/server/tools/tasks/TaskSchedulingClient.java
new file mode 100644
index 0000000..7ea3541
--- /dev/null
+++ b/opends/src/server/org/opends/server/tools/tasks/TaskSchedulingClient.java
@@ -0,0 +1,208 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.tools.tasks;
+
+import org.opends.server.types.LDAPException;
+import org.opends.server.types.RawAttribute;
+import org.opends.server.protocols.asn1.ASN1OctetString;
+import org.opends.server.protocols.asn1.ASN1Exception;
+import org.opends.server.protocols.ldap.LDAPControl;
+import org.opends.server.protocols.ldap.AddRequestProtocolOp;
+import org.opends.server.protocols.ldap.LDAPMessage;
+import org.opends.server.protocols.ldap.LDAPResultCode;
+import org.opends.server.protocols.ldap.LDAPConstants;
+import org.opends.server.protocols.ldap.ExtendedResponseProtocolOp;
+import org.opends.server.protocols.ldap.AddResponseProtocolOp;
+import org.opends.server.protocols.ldap.LDAPAttribute;
+import static org.opends.server.config.ConfigConstants.ATTR_TASK_ID;
+import static org.opends.server.config.ConfigConstants.SCHEDULED_TASK_BASE_RDN;
+import static org.opends.server.config.ConfigConstants.DN_TASK_ROOT;
+import static org.opends.server.config.ConfigConstants.ATTR_OBJECTCLASS;
+import static org.opends.server.config.ConfigConstants.ATTR_TASK_CLASS;
+import org.opends.server.config.ConfigConstants;
+import static org.opends.server.util.ServerConstants.MAX_LINE_WIDTH;
+import static org.opends.server.util.StaticUtils.wrapText;
+import org.opends.server.tools.LDAPConnection;
+import org.opends.server.tools.LDAPReader;
+import org.opends.server.tools.LDAPWriter;
+import org.opends.messages.Message;
+import static org.opends.messages.ToolMessages.*;
+
+import java.util.UUID;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.io.IOException;
+import java.io.PrintStream;
+
+/**
+ * Helper class for interacting with the task backend on behalf of utilities
+ * that are capable of being scheduled.
+ */
+public class TaskSchedulingClient {
+
+ /**
+ * Connection through which task scheduling will take place.
+ */
+ protected LDAPConnection connection;
+
+ /**
+ * Creates a new TaskClient for interacting with the task backend remotely.
+ * @param conn for accessing the task backend
+ */
+ public TaskSchedulingClient(LDAPConnection conn) {
+ this.connection = conn;
+ }
+
+ /**
+ * Schedule a task for execution by writing an entry to the task backend.
+ *
+ * @param information to be scheduled
+ * @param out stream for writing error messages
+ * @param err stream for writing error messages
+ * @return int representing an LDAP return code
+ */
+ public synchronized int schedule(TaskScheduleInformation information,
+ PrintStream out, PrintStream err) {
+
+ // Attempt to connect and authenticate to the Directory Server.
+ AtomicInteger nextMessageID = new AtomicInteger(1);
+
+ LDAPReader reader = connection.getLDAPReader();
+ LDAPWriter writer = connection.getLDAPWriter();
+
+ // Construct the add request to send to the server.
+ String taskID = UUID.randomUUID().toString();
+ ASN1OctetString entryDN =
+ new ASN1OctetString(ATTR_TASK_ID + "=" + taskID + "," +
+ SCHEDULED_TASK_BASE_RDN + "," + DN_TASK_ROOT);
+
+ ArrayList<LDAPControl> controls = new ArrayList<LDAPControl>();
+
+ ArrayList<RawAttribute> attributes = new ArrayList<RawAttribute>();
+
+ ArrayList<ASN1OctetString> ocValues = new ArrayList<ASN1OctetString>(3);
+ ocValues.add(new ASN1OctetString("top"));
+ ocValues.add(new ASN1OctetString(ConfigConstants.OC_TASK));
+ ocValues.add(new ASN1OctetString(information.getTaskObjectclass()));
+ attributes.add(new LDAPAttribute(ATTR_OBJECTCLASS, ocValues));
+
+ ArrayList<ASN1OctetString> taskIDValues = new ArrayList<ASN1OctetString>(1);
+ taskIDValues.add(new ASN1OctetString(taskID));
+ attributes.add(new LDAPAttribute(ATTR_TASK_ID, taskIDValues));
+
+ ArrayList<ASN1OctetString> classValues = new ArrayList<ASN1OctetString>(1);
+ classValues.add(new ASN1OctetString(information.getTaskClass().getName()));
+ attributes.add(new LDAPAttribute(ATTR_TASK_CLASS, classValues));
+
+ information.addTaskAttributes(attributes);
+
+ AddRequestProtocolOp addRequest = new AddRequestProtocolOp(entryDN,
+ attributes);
+ LDAPMessage requestMessage =
+ new LDAPMessage(nextMessageID.getAndIncrement(), addRequest, controls);
+
+ // Send the request to the server and read the response.
+ LDAPMessage responseMessage;
+ try
+ {
+ writer.writeMessage(requestMessage);
+
+ responseMessage = reader.readMessage();
+ if (responseMessage == null)
+ {
+ Message message = ERR_TASK_CLIENT_UNEXPECTED_CONNECTION_CLOSURE.get();
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ return LDAPResultCode.CLIENT_SIDE_SERVER_DOWN;
+ }
+ }
+ catch (IOException ioe)
+ {
+ Message message = ERR_TASK_CLIENT_IO_ERROR.get(String.valueOf(ioe));
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ return LDAPResultCode.CLIENT_SIDE_SERVER_DOWN;
+ }
+ catch (ASN1Exception ae)
+ {
+ Message message = ERR_TASK_CLIENT_DECODE_ERROR.get(ae.getMessage());
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ return LDAPResultCode.CLIENT_SIDE_DECODING_ERROR;
+ }
+ catch (LDAPException le)
+ {
+ Message message = ERR_TASK_CLIENT_DECODE_ERROR.get(le.getMessage());
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ return LDAPResultCode.CLIENT_SIDE_DECODING_ERROR;
+ }
+
+ if (responseMessage.getProtocolOpType() !=
+ LDAPConstants.OP_TYPE_ADD_RESPONSE)
+ {
+ if (responseMessage.getProtocolOpType() ==
+ LDAPConstants.OP_TYPE_EXTENDED_RESPONSE)
+ {
+ // It's possible that this is a notice of disconnection, which we can
+ // probably interpret as a "success" in this case.
+ ExtendedResponseProtocolOp extendedResponse =
+ responseMessage.getExtendedResponseProtocolOp();
+ String responseOID = extendedResponse.getOID();
+ if ((responseOID != null) &&
+ (responseOID.equals(LDAPConstants.OID_NOTICE_OF_DISCONNECTION)))
+ {
+ Message message = extendedResponse.getErrorMessage();
+ if (message != null)
+ {
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ }
+
+ return extendedResponse.getResultCode();
+ }
+ }
+
+ Message message = ERR_TASK_CLIENT_INVALID_RESPONSE_TYPE.get(
+ responseMessage.getProtocolOpName());
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ return LDAPResultCode.CLIENT_SIDE_LOCAL_ERROR;
+ }
+
+ AddResponseProtocolOp addResponse =
+ responseMessage.getAddResponseProtocolOp();
+ Message errorMessage = addResponse.getErrorMessage();
+ if (errorMessage != null)
+ {
+ err.println(wrapText(errorMessage, MAX_LINE_WIDTH));
+ }
+ else
+ {
+ out.println(wrapText(INFO_TASK_CLIENT_TASK_SCHEDULED.get(taskID),
+ MAX_LINE_WIDTH));
+ }
+
+ return addResponse.getResultCode();
+ }
+
+}
diff --git a/opends/src/server/org/opends/server/tools/tasks/TaskTool.java b/opends/src/server/org/opends/server/tools/tasks/TaskTool.java
new file mode 100644
index 0000000..2156b5a
--- /dev/null
+++ b/opends/src/server/org/opends/server/tools/tasks/TaskTool.java
@@ -0,0 +1,101 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.tools.tasks;
+
+import org.opends.server.util.args.LDAPConnectionArgumentParser;
+import org.opends.server.util.args.ArgumentException;
+import static org.opends.server.util.StaticUtils.wrapText;
+import static org.opends.server.util.ServerConstants.MAX_LINE_WIDTH;
+import org.opends.server.protocols.ldap.LDAPResultCode;
+import org.opends.server.tools.LDAPConnection;
+import org.opends.server.tools.LDAPConnectionException;
+import org.opends.messages.Message;
+import static org.opends.messages.ToolMessages.ERR_LDAP_CONN_CANNOT_CONNECT;
+
+import java.io.PrintStream;
+
+/**
+ * Base class for tools that are capable of operating either by running
+ * local within this JVM or by scheduling a task to perform the same
+ * action running within the directory server through the tasks interface.
+ */
+public abstract class TaskTool implements TaskScheduleInformation {
+
+ /**
+ * Either invokes initiates this tool's local action or schedule this
+ * tool using the tasks interface based on user input.
+ *
+ * @param argParser used to parse user arguments
+ * @param initializeServer indicates whether or not to initialize the
+ * directory server in the case of a local action
+ * @param out stream to write messages
+ * @param err stream to write messages
+ * @return int indicating the result of this action
+ */
+ protected int process(LDAPConnectionArgumentParser argParser,
+ boolean initializeServer,
+ PrintStream out, PrintStream err) {
+ int ret;
+ if (argParser.isLdapOperation())
+ {
+ try {
+ LDAPConnection conn = argParser.connect(out, err);
+ TaskSchedulingClient tc = new TaskSchedulingClient(conn);
+ ret = tc.schedule(this, out, err);
+ } catch (LDAPConnectionException e) {
+ Message message = ERR_LDAP_CONN_CANNOT_CONNECT.get(e.getMessage());
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ ret = LDAPResultCode.CLIENT_SIDE_CONNECT_ERROR;
+ } catch (ArgumentException e) {
+ Message message = e.getMessageObject();
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ ret = LDAPResultCode.CLIENT_SIDE_PARAM_ERROR;
+ }
+ }
+ else
+ {
+ ret = processLocal(initializeServer, out, err);
+ }
+ 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
+ * @param err stream to write messages
+ * @return int indicating the result of this action
+ */
+ abstract protected int processLocal(boolean initializeServer,
+ PrintStream out,
+ PrintStream err);
+
+}
diff --git a/opends/src/server/org/opends/server/tools/tasks/package-info.java b/opends/src/server/org/opends/server/tools/tasks/package-info.java
new file mode 100644
index 0000000..291bd2c
--- /dev/null
+++ b/opends/src/server/org/opends/server/tools/tasks/package-info.java
@@ -0,0 +1,37 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ */
+
+
+
+/**
+ * This package contains classes that support client tool interaction with the
+ * tasks backend.
+ */
+@org.opends.server.types.PublicAPI(
+ stability=org.opends.server.types.StabilityLevel.PRIVATE)
+package org.opends.server.tools.tasks;
+
diff --git a/opends/src/server/org/opends/server/util/args/LDAPConnectionArgumentParser.java b/opends/src/server/org/opends/server/util/args/LDAPConnectionArgumentParser.java
new file mode 100644
index 0000000..f04a6d9
--- /dev/null
+++ b/opends/src/server/org/opends/server/util/args/LDAPConnectionArgumentParser.java
@@ -0,0 +1,450 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.util.args;
+
+import org.opends.messages.Message;
+import static org.opends.messages.ToolMessages.*;
+import org.opends.server.tools.LDAPConnection;
+import org.opends.server.tools.LDAPConnectionOptions;
+import org.opends.server.tools.SSLConnectionFactory;
+import org.opends.server.tools.SSLConnectionException;
+import org.opends.server.tools.LDAPConnectionException;
+import static org.opends.server.tools.ToolConstants.*;
+import static org.opends.server.util.ServerConstants.MAX_LINE_WIDTH;
+import static org.opends.server.util.StaticUtils.wrapText;
+
+import java.util.LinkedList;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.io.PrintStream;
+
+/**
+ * Creates an argument parser pre-populated with arguments for specifying
+ * information for openning and LDAPConnection an LDAP connection.
+ */
+public class LDAPConnectionArgumentParser extends ArgumentParser {
+
+ /** Argument indicating whether all SSL certs will be trusted. */
+ protected BooleanArgument trustAll;
+
+ /** Argument indicating whether or not to use SSL. */
+ protected BooleanArgument useSSL;
+
+ /** Argument indicating whether or not to use StartTLS. */
+ protected BooleanArgument useStartTLS;
+
+ /** Argument indicating location of a bind password file. */
+ protected FileBasedArgument bindPWFile;
+
+ /** Argument indicating the location of the keystore password file. */
+ protected FileBasedArgument keyStorePWFile;
+
+ /** Argument indicating the location of the trust store password file. */
+ protected FileBasedArgument trustStorePWFile;
+
+ /** Argument indicating the port of the directory server. */
+ protected IntegerArgument port;
+
+ /** Argument indicating the DN of the user with which to bind. */
+ protected StringArgument bindDN;
+
+ /** Argument indicating the password of the user with which to bind. */
+ protected StringArgument bindPW;
+
+ /** Argument indicating the nickname of the certificate to use. */
+ protected StringArgument certNickname;
+
+ /** Argument indicating the hostname of the directory server. */
+ protected StringArgument host;
+
+ /** Argument indicating the location of the keystore file. */
+ protected StringArgument keyStoreFile;
+
+ /** Argument indicating the password fo the keystore. */
+ protected StringArgument keyStorePW;
+
+ /** Argument indicating a SASL option. */
+ protected StringArgument saslOption;
+
+ /** Argument indicating the location of the trust store file. */
+ protected StringArgument trustStoreFile;
+
+ /** Argument indicating the password of the trust store. */
+ protected StringArgument trustStorePW;
+
+ /**
+ * {@inheritDoc}
+ */
+ public LDAPConnectionArgumentParser(String mainClassName,
+ Message toolDescription,
+ boolean longArgumentsCaseSensitive) {
+ super(mainClassName, toolDescription, longArgumentsCaseSensitive);
+ addLdapConnectionArguments();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public LDAPConnectionArgumentParser(String mainClassName,
+ Message toolDescription,
+ boolean longArgumentsCaseSensitive,
+ boolean allowsTrailingArguments,
+ int minTrailingArguments,
+ int maxTrailingArguments,
+ String trailingArgsDisplayName) {
+ super(mainClassName, toolDescription, longArgumentsCaseSensitive,
+ allowsTrailingArguments, minTrailingArguments, maxTrailingArguments,
+ trailingArgsDisplayName);
+ addLdapConnectionArguments();
+ }
+
+ /**
+ * Indicates whether or not the user has indicated that they would like
+ * to perform a remote operation based on the arguments.
+ *
+ * @return true if the user wants to perform a remote operation;
+ * false otherwise
+ */
+ public boolean isLdapOperation() {
+ // This may not be ideal in all cases. We might want to assume no
+ // host means 'localhost'. However we would still need some way to
+ // tell whether the user intends this invocation to be remote.
+ return host.isPresent();
+ }
+
+ /**
+ * Creates a new LDAPConnection and invokes a connect operation using
+ * information provided in the parsed set of arguments that were provided
+ * by the user.
+ *
+ * @param out stream to write messages
+ * @param err stream to write messages
+ * @return LDAPConnection created by this class from parsed arguments
+ * @throws LDAPConnectionException if there was a problem connecting
+ * to the server indicated by the input arguments
+ * @throws ArgumentException if there was a problem processing the input
+ * arguments
+ */
+ public LDAPConnection connect(PrintStream out, PrintStream err)
+ throws LDAPConnectionException, ArgumentException
+ {
+ // If both a bind password and bind password file were provided, then return
+ // an error.
+ if (bindPW.isPresent() && bindPWFile.isPresent())
+ {
+ Message message = ERR_LDAP_CONN_MUTUALLY_EXCLUSIVE_ARGUMENTS.get(
+ bindPW.getLongIdentifier(),
+ bindPWFile.getLongIdentifier());
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ throw new ArgumentException(message);
+ }
+
+
+ // If both a key store password and key store password file were provided,
+ // then return an error.
+ if (keyStorePW.isPresent() && keyStorePWFile.isPresent())
+ {
+ Message message = ERR_LDAP_CONN_MUTUALLY_EXCLUSIVE_ARGUMENTS.get(
+ keyStorePW.getLongIdentifier(),
+ keyStorePWFile.getLongIdentifier());
+ throw new ArgumentException(message);
+ }
+
+
+ // If both a trust store password and trust store password file were
+ // provided, then return an error.
+ if (trustStorePW.isPresent() && trustStorePWFile.isPresent())
+ {
+ Message message = ERR_LDAP_CONN_MUTUALLY_EXCLUSIVE_ARGUMENTS.get(
+ trustStorePW.getLongIdentifier(),
+ trustStorePWFile.getLongIdentifier());
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ throw new ArgumentException(message);
+ }
+
+ // Create the LDAP connection options object, which will be used to
+ // customize the way that we connect to the server and specify a set of
+ // basic defaults.
+ LDAPConnectionOptions connectionOptions = new LDAPConnectionOptions();
+ connectionOptions.setVersionNumber(3);
+
+
+ // See if we should use SSL or StartTLS when establishing the connection.
+ // If so, then make sure only one of them was specified.
+ if (useSSL.isPresent())
+ {
+ if (useStartTLS.isPresent())
+ {
+ Message message = ERR_LDAP_CONN_MUTUALLY_EXCLUSIVE_ARGUMENTS.get(
+ useSSL.getLongIdentifier(),
+ useStartTLS.getLongIdentifier());
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ throw new ArgumentException(message);
+ }
+ else
+ {
+ connectionOptions.setUseSSL(true);
+ }
+ }
+ else if (useStartTLS.isPresent())
+ {
+ connectionOptions.setStartTLS(true);
+ }
+
+
+ // If we should blindly trust any certificate, then install the appropriate
+ // SSL connection factory.
+ if (useSSL.isPresent() || useStartTLS.isPresent())
+ {
+ try
+ {
+ String clientAlias;
+ if (certNickname.isPresent())
+ {
+ clientAlias = certNickname.getValue();
+ }
+ else
+ {
+ clientAlias = null;
+ }
+
+ SSLConnectionFactory sslConnectionFactory = new SSLConnectionFactory();
+ sslConnectionFactory.init(trustAll.isPresent(), keyStoreFile.getValue(),
+ keyStorePW.getValue(), clientAlias,
+ trustStoreFile.getValue(),
+ trustStorePW.getValue());
+
+ connectionOptions.setSSLConnectionFactory(sslConnectionFactory);
+ }
+ catch (SSLConnectionException sce)
+ {
+ Message message =
+ ERR_LDAP_CONN_CANNOT_INITIALIZE_SSL.get(sce.getMessage());
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ }
+ }
+
+
+ // If one or more SASL options were provided, then make sure that one of
+ // them was "mech" and specified a valid SASL mechanism.
+ if (saslOption.isPresent())
+ {
+ String mechanism = null;
+ LinkedList<String> options = new LinkedList<String>();
+
+ for (String s : saslOption.getValues())
+ {
+ int equalPos = s.indexOf('=');
+ if (equalPos <= 0)
+ {
+ Message message = ERR_LDAP_CONN_CANNOT_PARSE_SASL_OPTION.get(s);
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ throw new ArgumentException(message);
+ }
+ else
+ {
+ String name = s.substring(0, equalPos);
+
+ if (name.equalsIgnoreCase("mech"))
+ {
+ mechanism = s;
+ }
+ else
+ {
+ options.add(s);
+ }
+ }
+ }
+
+ if (mechanism == null)
+ {
+ Message message = ERR_LDAP_CONN_NO_SASL_MECHANISM.get();
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ throw new ArgumentException(message);
+ }
+
+ connectionOptions.setSASLMechanism(mechanism);
+
+ for (String option : options)
+ {
+ connectionOptions.addSASLProperty(option);
+ }
+ }
+
+
+ // Attempt to connect and authenticate to the Directory Server.
+ AtomicInteger nextMessageID = new AtomicInteger(1);
+
+ LDAPConnection connection = new LDAPConnection(
+ host.getValue(), port.getIntValue(),
+ connectionOptions, out, err);
+
+ connection.connectToHost(bindDN.getValue(), bindPW.getValue(),
+ nextMessageID);
+
+ return connection;
+ }
+
+ private void addLdapConnectionArguments() {
+
+ try
+ {
+ host = new StringArgument(
+ "host", OPTION_SHORT_HOST,
+ OPTION_LONG_HOST, false, false, true,
+ OPTION_VALUE_HOST, "127.0.0.1", null,
+ INFO_LDAP_CONN_DESCRIPTION_HOST.get());
+ addArgument(host);
+
+ port = new IntegerArgument(
+ "port", OPTION_SHORT_PORT,
+ OPTION_LONG_PORT, false, false, true,
+ OPTION_VALUE_PORT, 389, null, true, 1,
+ true, 65535, INFO_LDAP_CONN_DESCRIPTION_PORT.get());
+ addArgument(port);
+
+ useSSL = new BooleanArgument(
+ "usessl", OPTION_SHORT_USE_SSL,
+ OPTION_LONG_USE_SSL,
+ INFO_LDAP_CONN_DESCRIPTION_USESSL.get());
+ addArgument(useSSL);
+
+ useStartTLS = new BooleanArgument(
+ "usestarttls", OPTION_SHORT_START_TLS,
+ OPTION_LONG_START_TLS,
+ INFO_LDAP_CONN_DESCRIPTION_USESTARTTLS.get());
+ addArgument(useStartTLS);
+
+ bindDN = new StringArgument(
+ "binddn", OPTION_SHORT_BINDDN,
+ OPTION_LONG_BINDDN, false, false, true,
+ OPTION_VALUE_BINDDN, null, null,
+ INFO_LDAP_CONN_DESCRIPTION_BINDDN.get());
+ addArgument(bindDN);
+
+ bindPW = new StringArgument(
+ "bindpw", OPTION_SHORT_BINDPWD,
+ OPTION_LONG_BINDPWD, false, false,
+ true,
+ OPTION_VALUE_BINDPWD, null, null,
+ INFO_LDAP_CONN_DESCRIPTION_BINDPW.get());
+ addArgument(bindPW);
+
+ bindPWFile = new FileBasedArgument(
+ "bindpwfile",
+ OPTION_SHORT_BINDPWD_FILE,
+ OPTION_LONG_BINDPWD_FILE,
+ false, false,
+ OPTION_VALUE_BINDPWD_FILE,
+ null, null,
+ INFO_LDAP_CONN_DESCRIPTION_BINDPWFILE.get());
+ addArgument(bindPWFile);
+
+ saslOption = new StringArgument(
+ "sasloption", OPTION_SHORT_SASLOPTION,
+ OPTION_LONG_SASLOPTION, false,
+ true, true,
+ OPTION_VALUE_SASLOPTION, null, null,
+ INFO_LDAP_CONN_DESCRIPTION_SASLOPTIONS.get());
+ addArgument(saslOption);
+
+ trustAll = new BooleanArgument(
+ "trustall", 'X', "trustAll",
+ INFO_LDAP_CONN_DESCRIPTION_TRUST_ALL.get());
+ addArgument(trustAll);
+
+ keyStoreFile = new StringArgument(
+ "keystorefile",
+ OPTION_SHORT_KEYSTOREPATH,
+ OPTION_LONG_KEYSTOREPATH,
+ false, false, true,
+ OPTION_VALUE_KEYSTOREPATH,
+ null, null,
+ INFO_LDAP_CONN_DESCRIPTION_KSFILE.get());
+ addArgument(keyStoreFile);
+
+ keyStorePW = new StringArgument(
+ "keystorepw", OPTION_SHORT_KEYSTORE_PWD,
+ OPTION_LONG_KEYSTORE_PWD,
+ false, false, true,
+ OPTION_VALUE_KEYSTORE_PWD,
+ null, null,
+ INFO_LDAP_CONN_DESCRIPTION_KSPW.get());
+ addArgument(keyStorePW);
+
+ keyStorePWFile = new FileBasedArgument(
+ "keystorepwfile",
+ OPTION_SHORT_KEYSTORE_PWD_FILE,
+ OPTION_LONG_KEYSTORE_PWD_FILE,
+ false, false,
+ OPTION_VALUE_KEYSTORE_PWD_FILE,
+ null, null,
+ INFO_LDAP_CONN_DESCRIPTION_KSPWFILE.get());
+ addArgument(keyStorePWFile);
+
+ certNickname = new StringArgument(
+ "certnickname", 'N', "certNickname",
+ false, false, true, "{nickname}", null,
+ null, INFO_DESCRIPTION_CERT_NICKNAME.get());
+ addArgument(certNickname);
+
+ trustStoreFile = new StringArgument(
+ "truststorefile",
+ OPTION_SHORT_TRUSTSTOREPATH,
+ OPTION_LONG_TRUSTSTOREPATH,
+ false, false, true,
+ OPTION_VALUE_TRUSTSTOREPATH,
+ null, null,
+ INFO_LDAP_CONN_DESCRIPTION_TSFILE.get());
+ addArgument(trustStoreFile);
+
+ trustStorePW = new StringArgument(
+ "truststorepw", 'T',
+ OPTION_LONG_TRUSTSTORE_PWD,
+ false, false,
+ true, OPTION_VALUE_TRUSTSTORE_PWD, null,
+ null, INFO_LDAP_CONN_DESCRIPTION_TSPW.get());
+ addArgument(trustStorePW);
+
+ trustStorePWFile = new FileBasedArgument(
+ "truststorepwfile",
+ OPTION_SHORT_TRUSTSTORE_PWD_FILE,
+ OPTION_LONG_TRUSTSTORE_PWD_FILE,
+ false, false,
+ OPTION_VALUE_TRUSTSTORE_PWD_FILE, null, null,
+ INFO_LDAP_CONN_DESCRIPTION_TSPWFILE.get());
+ addArgument(trustStorePWFile);
+
+ }
+ catch (ArgumentException ae)
+ {
+ // Should never happen
+ }
+
+ }
+
+}
--
Gitblit v1.10.0