From eb93a7bf09123d5fe7a8509e4a1421101163b670 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Fri, 08 Jun 2007 14:43:45 +0000
Subject: [PATCH] The following commit adds all the code necessary to be able to configure replication using the setup.
---
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java | 442 ++++
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java | 2157 +++++++++++++++++++----
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java | 18
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupLog.java | 3
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/DataReplicationOptions.java | 13
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java | 110 +
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/ServerSettingsPanel.java | 14
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java | 8
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java | 422 ++-
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SuffixesToReplicatePanel.java | 66
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java | 13
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java | 91
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java | 71
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Step.java | 5
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java | 131 +
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetup.java | 108 +
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties | 183 +
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Application.java | 18
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserDataCertificateException.java | 134 +
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/images/wait.gif | 0
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserDataConfirmationException.java | 2
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ReviewPanel.java | 12
opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java | 12
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java | 33
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java | 105
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java | 4
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallProgressStep.java | 20
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FramePanel.java | 26
opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties | 1
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataReplicationPanel.java | 76
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/RemoteReplicationPortsPanel.java | 310 +++
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java | 655 +++++++
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java | 44
33 files changed, 4,476 insertions(+), 831 deletions(-)
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Application.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Application.java
index eda03c8..4fa82af 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Application.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Application.java
@@ -27,6 +27,7 @@
package org.opends.quicksetup;
+import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.quicksetup.event.ProgressNotifier;
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.event.ProgressUpdateEvent;
@@ -64,6 +65,8 @@
private ServerController serverController;
+ private ApplicationTrustManager trustManager;
+
/** Formats progress messages. */
protected ProgressMessageFormatter formatter;
@@ -526,6 +529,21 @@
abstract public boolean isFinished();
/**
+ * Returns the trust manager that can be used to establish secure connections.
+ * @return the trust manager that can be used to establish secure connections.
+ */
+ protected ApplicationTrustManager getTrustManager()
+ {
+ if (trustManager == null)
+ {
+ trustManager = new ApplicationTrustManager();
+ }
+ return trustManager;
+ }
+
+
+
+ /**
* Indicates whether or not this application is capable of cancelling
* the operation performed in the run method. A cancellable operation
* should leave its environment in the same state as it was prior to
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupLog.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupLog.java
index 43e6ed2..36619dc 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupLog.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupLog.java
@@ -58,6 +58,9 @@
logger.setUseParentHandlers(false); // disable logging to console
logger.addHandler(fileHandler);
logger.log(Level.INFO, getInitialLogRecord());
+ logger = Logger.getLogger("org.opends.admin.ads");
+ logger.setUseParentHandlers(false); // disable logging to console
+ logger.addHandler(fileHandler);
}
}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java
index 178a5a1..58cfab1 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java
@@ -65,8 +65,6 @@
}
private CertificateType certificateType;
-
- private String selfSignedCertificateName;
private String keyStorePath;
private String keyStorePassword;
private String aliasToUse;
@@ -93,19 +91,17 @@
/**
* Creates a new instance of a SecurityOptions using a self-signed
* certificate.
- * @param name the name of the certificate (the CN value).
* @param enableSSL whether SSL is enabled or not.
* @param enableStartTLS whether Start TLS is enabled or not.
* @param sslPort the value of the LDAPS port.
* @return a new instance of a SecurityOptions using a self-signed
* certificate.
*/
- public static SecurityOptions createSelfSignedCertificateOptions(String name,
+ public static SecurityOptions createSelfSignedCertificateOptions(
boolean enableSSL, boolean enableStartTLS, int sslPort)
{
SecurityOptions ops = new SecurityOptions();
ops.setCertificateType(CertificateType.SELF_SIGNED_CERTIFICATE);
- ops.setSelfSignedCertificateName(name);
updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort, null);
return ops;
}
@@ -270,24 +266,6 @@
}
/**
- * Returns the self-signed certificate name.
- * @return the self-signed certificate name.
- */
- public String getSelfSignedCertificateName()
- {
- return selfSignedCertificateName;
- }
-
- /**
- * Sets the self-signed certificate name.
- * @param selfSignedCertificateName the new self-signed certificate name.
- */
- private void setSelfSignedCertificateName(String selfSignedCertificateName)
- {
- this.selfSignedCertificateName = selfSignedCertificateName;
- }
-
- /**
* Updates the provided certificate options object with some parameters.
* @param ops the SecurityOptions object to be updated.
* @param enableSSL whether to enable SSL or not.
@@ -328,15 +306,6 @@
}
/**
- * Sets the Self-Signed certificate name (the CN).
- * @param selfSignedCertificateName the new Self-Signed certificate name.
- */
- void setCertificateUserName(String selfSignedCertificateName)
- {
- this.selfSignedCertificateName = selfSignedCertificateName;
- }
-
- /**
* Returns the alias of the certificate in the keystore to be used.
* @return the alias of the certificate in the keystore to be used.
*/
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Step.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Step.java
index bf532dc..be3d2ec 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Step.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Step.java
@@ -63,6 +63,11 @@
*/
SUFFIXES_OPTIONS("suffixes-step"),
/**
+ * Panel when the user specifies the replication ports of the remote servers
+ * that have not defined it.
+ */
+ REMOTE_REPLICATION_PORTS("remote-replication-ports-step"),
+ /**
* Data Options panel (suffix dn, LDIF path, etc.).
*/
NEW_SUFFIX_OPTIONS("data-options-step"),
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
index 38051d7..7aa2a7b 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
@@ -27,8 +27,11 @@
package org.opends.quicksetup;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
+import org.opends.admin.ads.ServerDescriptor;
import org.opends.admin.ads.SuffixDescriptor;
import org.opends.quicksetup.installer.AuthenticationData;
import org.opends.quicksetup.installer.DataReplicationOptions;
@@ -47,6 +50,8 @@
{
private String serverLocation;
+ private String hostName;
+
private int serverPort;
private String directoryManagerDn;
@@ -72,6 +77,8 @@
private SuffixesToReplicateOptions suffixesToReplicateOptions;
+ private Map<ServerDescriptor, Integer> remoteWithNoReplicationPort;
+
private boolean silent;
private boolean noninteractive;
@@ -93,6 +100,8 @@
setServerPort(defaultPort);
}
+ setHostName(getDefaultHostName());
+
setDirectoryManagerDn(Constants.DIRECTORY_MANAGER_DN);
setNewSuffixOptions(defaultNewSuffixOptions);
@@ -100,7 +109,8 @@
data.setDn(Constants.DIRECTORY_MANAGER_DN);
data.setPort(389);
DataReplicationOptions repl = new DataReplicationOptions(
- DataReplicationOptions.Type.STANDALONE, data);
+ DataReplicationOptions.Type.STANDALONE, data,
+ getDefaultReplicationPort());
setReplicationOptions(repl);
setGlobalAdministratorUID("admin");
@@ -112,8 +122,9 @@
setSuffixesToReplicateOptions(suffixes);
SecurityOptions sec = SecurityOptions.createNoCertificateOptions();
sec.setSslPort(getDefaultSslPort());
- sec.setCertificateUserName(getDefaultSelfSignedName());
setSecurityOptions(sec);
+
+ remoteWithNoReplicationPort = new HashMap<ServerDescriptor, Integer>();
}
/**
@@ -135,6 +146,24 @@
}
/**
+ * Sets the host name.
+ * @param hostName the server host name.
+ */
+ public void setHostName(String hostName)
+ {
+ this.hostName = hostName;
+ }
+
+ /**
+ * Returns the server host name.
+ * @return the server host name.
+ */
+ public String getHostName()
+ {
+ return hostName;
+ }
+
+ /**
* Sets the server LDAP port.
* @param serverPort the new server LDAP port.
*/
@@ -498,11 +527,34 @@
}
return defaultJMXPort;
}
+
/**
- * Provides the default name for the self signed certificate that will be
- * created.
+ * Provides the port that will be proposed to the user in the replication
+ * options panel of the installation wizard. It will check whether we can use
+ * ports of type X989 and if not it will return -1.
+ *
+ * @return the free port of type X989 if it is available and we can use and -1
+ * if not.
*/
- private String getDefaultSelfSignedName()
+ static int getDefaultReplicationPort()
+ {
+ int defaultPort = -1;
+
+ for (int i=0;i<10000 && (defaultPort == -1);i+=1000)
+ {
+ int port = i + 8989;
+ if (Utils.canUseAsPort(port))
+ {
+ defaultPort = port;
+ }
+ }
+ return defaultPort;
+ }
+
+ /**
+ * Provides the default host name that will be displayed.
+ */
+ private String getDefaultHostName()
{
String name = "";
try
@@ -514,4 +566,33 @@
}
return name;
}
+
+ /**
+ * Returns a Map containing as key a ServerDescriptor and as value an Integer
+ * corresponding to the Replication Port chosen by the user.
+ *
+ * Only the servers that have no replication port appear on this map.
+ * @return a Map containing as key a ServerDescriptor and as value an Integer
+ * corresponding to the Replication Port chosen by the user.
+ */
+ public Map<ServerDescriptor, Integer> getRemoteWithNoReplicationPort()
+ {
+ HashMap<ServerDescriptor, Integer> copy =
+ new HashMap<ServerDescriptor, Integer>();
+ copy.putAll(remoteWithNoReplicationPort);
+ return copy;
+ }
+
+ /**
+ * Sets a the Replication Ports chosen by the user in the remote servers.
+ * @param remoteWithNoReplicationPort the Map containing as key a
+ * ServerDescriptor and as value an Integer corresponding to the Replication
+ * Port chosen by the user.
+ */
+ public void setRemoteWithNoReplicationPort(
+ Map<ServerDescriptor, Integer> remoteWithNoReplicationPort)
+ {
+ this.remoteWithNoReplicationPort.clear();
+ this.remoteWithNoReplicationPort.putAll(remoteWithNoReplicationPort);
+ }
}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserDataCertificateException.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserDataCertificateException.java
new file mode 100644
index 0000000..3d3727d4
--- /dev/null
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserDataCertificateException.java
@@ -0,0 +1,134 @@
+/*
+ * 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.quicksetup;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * This exception is used when there is a certificate issue and the user must
+ * be asked to accept it or not.
+ * It will be thrown by the class that is in charge of validating the user data
+ * (the Application class).
+ *
+ */
+public class UserDataCertificateException extends UserDataException
+{
+ private String host;
+ private int port;
+ private X509Certificate[] chain;
+ private String authType;
+ private Type type;
+ /**
+ * The enumeration for the different types of the exception.
+ */
+ public enum Type
+ {
+ /**
+ * The certificate was not trusted.
+ */
+ NOT_TRUSTED,
+ /**
+ * The certificate's subject DN's value and the host name we tried to
+ * connect to do not match.
+ */
+ HOST_NAME_MISMATCH
+ }
+
+ private static final long serialVersionUID = 6404258710409027956L;
+
+ /**
+ * Constructor for UserDataCertificateException.
+ * @param step the step in the wizard where the exception occurred.
+ * @param localizedMessage the localized message describing the error.
+ * @param t the root cause for this exception.
+ * @param host the host we tried to connect to.
+ * @param port the port we tried to connect to.
+ * @param chain the certificate chain.
+ * @param authType the authentication type.
+ * @param type the type of the exception.
+ */
+ public UserDataCertificateException(WizardStep step, String localizedMessage,
+ Throwable t, String host, int port, X509Certificate[] chain,
+ String authType, Type type)
+ {
+ super(step, localizedMessage);
+ initCause(t);
+ this.host = host;
+ this.port = port;
+ this.chain = chain;
+ this.authType = authType;
+ this.type = type;
+ }
+
+ /**
+ * Returns the host we tried to connect to when this exception was generated.
+ * @return the host we tried to connect to when this exception was generated.
+ */
+ public String getHost()
+ {
+ return host;
+ }
+
+ /**
+ * Returns the port we tried to connect to when this exception was generated.
+ * @return the port we tried to connect to when this exception was generated.
+ */
+ public int getPort()
+ {
+ return port;
+ }
+
+ /**
+ * Returns the auth type used when this certificate exception occurred.
+ * @return the auth type used when this certificate exception occurred.
+ */
+ public String getAuthType()
+ {
+ return authType;
+ }
+
+ /**
+ * Returns the type of exception.
+ * @return the type of exception.
+ */
+ public Type getType()
+ {
+ return type;
+ }
+
+ /**
+ * Returns the certificate chain received when this exception was generated.
+ * @return the certificate chain received when this exception was generated.
+ */
+ public X509Certificate[] getChain()
+ {
+ return chain;
+ }
+}
+
+
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserDataConfirmationException.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserDataConfirmationException.java
index c36e47f..951b493 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserDataConfirmationException.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserDataConfirmationException.java
@@ -38,7 +38,7 @@
private static final long serialVersionUID = -2662491859817280513L;
/**
- * Constructor for UserDataException.
+ * Constructor for UserDataConfirmationException.
* @param step the step in the wizard where the exception occurred.
* @param localizedMessage the localized message describing the error.
*/
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/images/wait.gif b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/images/wait.gif
new file mode 100644
index 0000000..286e1bc
--- /dev/null
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/images/wait.gif
Binary files differ
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/DataReplicationOptions.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/DataReplicationOptions.java
index 32d4596..8a78b43 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/DataReplicationOptions.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/DataReplicationOptions.java
@@ -57,6 +57,7 @@
}
private Type type;
+ private int replicationPort;
private AuthenticationData authenticationData;
/**
@@ -80,6 +81,7 @@
{
case IN_EXISTING_TOPOLOGY:
authenticationData = (AuthenticationData)args[0];
+ replicationPort = (Integer)args[1];
break;
default:
@@ -87,6 +89,7 @@
if ((args != null) && (args.length > 0))
{
authenticationData = (AuthenticationData)args[0];
+ replicationPort = (Integer)args[1];
}
}
}
@@ -112,5 +115,15 @@
{
return authenticationData;
}
+
+ /**
+ * Returns the port that is going to be used for replication.
+ *
+ * @return the replication that must be used to configure replication.
+ */
+ public int getReplicationPort()
+ {
+ return replicationPort;
+ }
}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallProgressStep.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallProgressStep.java
index e9637d0..e4771ed 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallProgressStep.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallProgressStep.java
@@ -72,11 +72,31 @@
IMPORTING_AUTOMATICALLY_GENERATED,
/**
+ * Configuring replication.
+ */
+ CONFIGURING_REPLICATION,
+
+ /**
* Starting Open DS server.
*/
STARTING_SERVER,
/**
+ * Stopping Open DS server.
+ */
+ STOPPING_SERVER,
+
+ /**
+ * Initialize Replicated Suffixes.
+ */
+ INITIALIZE_REPLICATED_SUFFIXES,
+
+ /**
+ * Configuring ADS.
+ */
+ CONFIGURING_ADS,
+
+ /**
* Enabling Windows service.
*/
ENABLING_WINDOWS_SERVICE,
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
index 0ec86d3..96e376a 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -31,23 +31,40 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.net.URI;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.util.*;
+import java.util.logging.Level;
import java.util.logging.Logger;
import java.awt.event.WindowEvent;
+import javax.naming.AuthenticationException;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NoPermissionException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import org.opends.admin.ads.ADSContext;
import org.opends.admin.ads.ADSContextException;
+import org.opends.admin.ads.ReplicaDescriptor;
+import org.opends.admin.ads.ServerDescriptor;
import org.opends.admin.ads.SuffixDescriptor;
+import org.opends.admin.ads.TopologyCache;
+import org.opends.admin.ads.TopologyCacheException;
+import org.opends.admin.ads.util.ApplicationTrustManager;
+import org.opends.admin.ads.util.ServerLoader;
import org.opends.quicksetup.ui.*;
import org.opends.quicksetup.util.Utils;
-import org.opends.quicksetup.util.InProcessServerController;
import org.opends.quicksetup.*;
import org.opends.server.util.CertificateManager;
import org.opends.quicksetup.installer.ui.DataOptionsPanel;
@@ -55,6 +72,7 @@
import org.opends.quicksetup.installer.ui.GlobalAdministratorPanel;
import org.opends.quicksetup.installer.ui.InstallReviewPanel;
import org.opends.quicksetup.installer.ui.InstallWelcomePanel;
+import org.opends.quicksetup.installer.ui.RemoteReplicationPortsPanel;
import org.opends.quicksetup.installer.ui.ServerSettingsPanel;
import org.opends.quicksetup.installer.ui.SuffixesToReplicatePanel;
import org.opends.server.util.SetupUtils;
@@ -80,6 +98,7 @@
*
*/
public abstract class Installer extends GuiApplication {
+ private TopologyCache lastLoadedCache;
/* Indicates that we've detected that there is something installed */
boolean forceToDisplaySetup = false;
@@ -108,9 +127,11 @@
private final HashSet<WizardStep> SUBSTEPS = new HashSet<WizardStep>();
{
SUBSTEPS.add(Step.CREATE_GLOBAL_ADMINISTRATOR);
-// TODO: remove this comment once the replication code is in place.
SUBSTEPS.add(Step.SUFFIXES_OPTIONS);
+ // TODO: remove this comment once we want to display the replication options
+ // in setup.
//SUBSTEPS.add(Step.NEW_SUFFIX_OPTIONS);
+ SUBSTEPS.add(Step.REMOTE_REPLICATION_PORTS);
}
private HashMap<WizardStep, WizardStep> hmPreviousSteps =
@@ -128,10 +149,13 @@
public Installer() {
lstSteps.add(WELCOME);
lstSteps.add(SERVER_SETTINGS);
+ // TODO: remove this comment once we want to display the replication options
+ // in setup.
/*
lstSteps.add(REPLICATION_OPTIONS);
lstSteps.add(CREATE_GLOBAL_ADMINISTRATOR);
lstSteps.add(SUFFIXES_OPTIONS);
+ lstSteps.add(REMOTE_REPLICATION_PORTS);
*/
lstSteps.add(NEW_SUFFIX_OPTIONS);
lstSteps.add(REVIEW);
@@ -247,11 +271,19 @@
isVisible = false;
}
}
+ else if (step == REMOTE_REPLICATION_PORTS)
+ {
+ isVisible = isVisible(SUFFIXES_OPTIONS) &&
+ (getUserData().getRemoteWithNoReplicationPort().size() > 0) &&
+ (getUserData().getSuffixesToReplicateOptions().getType() ==
+ SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES);
+ }
else
{
isVisible = true;
}
- // TODO: to delete the following line once the replication code works.
+ // TODO: remove this line once we want to display the replication options
+ // in setup.
isVisible = true;
return isVisible;
}
@@ -388,6 +420,8 @@
p = new GlobalAdministratorPanel(this);
} else if (step == SUFFIXES_OPTIONS) {
p = new SuffixesToReplicatePanel(this);
+ } else if (step == REMOTE_REPLICATION_PORTS) {
+ p = new RemoteReplicationPortsPanel(this);
} else if (step == NEW_SUFFIX_OPTIONS) {
p = new DataOptionsPanel(this);
} else if (step == REVIEW) {
@@ -538,12 +572,24 @@
getType())
{
case REPLICATE_WITH_EXISTING_SUFFIXES:
- next = Step.REVIEW;
+
+ if (getUserData().getRemoteWithNoReplicationPort().size() > 0)
+ {
+ next = Step.REMOTE_REPLICATION_PORTS;
+ }
+ else
+ {
+ next = Step.REVIEW;
+ }
break;
default:
next = Step.NEW_SUFFIX_OPTIONS;
}
}
+ else if (step == Step.REMOTE_REPLICATION_PORTS)
+ {
+ next = Step.REVIEW;
+ }
else
{
int i = lstSteps.indexOf(step);
@@ -566,11 +612,13 @@
LinkedHashSet<WizardStep> orderedSteps = new LinkedHashSet<WizardStep>();
orderedSteps.add(WELCOME);
orderedSteps.add(SERVER_SETTINGS);
- // TODO: remove this comment once the replication code is in place.
+ // TODO: remove this comment once we want to display the replication options
+ // in setup.
/*
orderedSteps.add(REPLICATION_OPTIONS);
orderedSteps.add(CREATE_GLOBAL_ADMINISTRATOR);
orderedSteps.add(SUFFIXES_OPTIONS);
+ orderedSteps.add(REMOTE_REPLICATION_PORTS);
*/
orderedSteps.add(NEW_SUFFIX_OPTIONS);
orderedSteps.add(REVIEW);
@@ -637,6 +685,8 @@
argList.add(String.valueOf(getUserData().getServerPort()));
SecurityOptions sec = getUserData().getSecurityOptions();
+ // TODO: even if the user does not configure SSL maybe we should choose
+ // a secure port that is not being used and that we can actually use.
if (sec.getEnableSSL())
{
argList.add("-P");
@@ -710,6 +760,17 @@
argList.add("-b");
argList.add(getUserData().getNewSuffixOptions().getBaseDn());
}
+ else
+ {
+ Set<SuffixDescriptor> suffixesToReplicate =
+ getUserData().getSuffixesToReplicateOptions().getSuffixes();
+
+ for (SuffixDescriptor suffix: suffixesToReplicate)
+ {
+ argList.add("-b");
+ argList.add(suffix.getDN());
+ }
+ }
String[] args = new String[argList.size()];
argList.toArray(args);
@@ -755,7 +816,7 @@
CertificateManager.KEY_STORE_TYPE_JKS,
pwd);
certManager.generateSelfSignedCertificate("server-cert",
- getSelfSignedCertificateSubjectDN(sec),
+ getSelfSignedCertificateSubjectDN(),
getSelfSignedCertificateValidity());
exportCertificate(certManager, "server-cert",
getTemporaryCertificatePath());
@@ -844,7 +905,7 @@
* the UserData object provided in the constructor.
* @throws ApplicationException if something goes wrong.
*/
- protected void createBaseEntry() throws ApplicationException {
+ private void createBaseEntry() throws ApplicationException {
String[] arg =
{ getUserData().getNewSuffixOptions().getBaseDn() };
notifyListeners(getFormattedWithPoints(
@@ -897,7 +958,7 @@
* the UserData object provided in the constructor.
* @throws ApplicationException if something goes wrong.
*/
- protected void importLDIF() throws ApplicationException {
+ private void importLDIF() throws ApplicationException {
String[] arg =
{ getUserData().getNewSuffixOptions().getLDIFPath() };
notifyListeners(getFormattedProgress(getMsg("progress-importing-ldif", arg))
@@ -941,7 +1002,7 @@
* of the UserData object provided in the constructor.
* @throws ApplicationException if something goes wrong.
*/
- protected void importAutomaticallyGenerated() throws ApplicationException {
+ private void importAutomaticallyGenerated() throws ApplicationException {
File templatePath = createTemplateFile();
int nEntries = getUserData().getNewSuffixOptions().getNumberEntries();
String[] arg =
@@ -987,6 +1048,190 @@
}
/**
+ * This method creates the replication configuration for the suffixes on the
+ * the local server (and eventually in the remote servers) to synchronize
+ * things.
+ * NOTE: this method assumes that the server is running.
+ * @throws ApplicationException if something goes wrong.
+ */
+ protected void configureReplication() throws ApplicationException
+ {
+ notifyListeners(getFormattedWithPoints(
+ getMsg("progress-configuring-replication")));
+
+ InstallerHelper helper = new InstallerHelper();
+ Set<Integer> knownServerIds = new HashSet<Integer>();
+ Set<Integer> knownReplicationServerIds = new HashSet<Integer>();
+ if (lastLoadedCache != null)
+ {
+ for (SuffixDescriptor suffix : lastLoadedCache.getSuffixes())
+ {
+ for (ReplicaDescriptor replica : suffix.getReplicas())
+ {
+ knownServerIds.add(replica.getReplicationId());
+ }
+ }
+ for (ServerDescriptor server : lastLoadedCache.getServers())
+ {
+ Object v = server.getServerProperties().get
+ (ServerDescriptor.ServerProperty.REPLICATION_SERVER_ID);
+ if (v != null)
+ {
+ knownReplicationServerIds.add((Integer)v);
+ }
+ }
+ }
+ else
+ {
+ /* There is no ADS anywhere. Just use the SuffixDescriptors we found */
+ for (SuffixDescriptor suffix :
+ getUserData().getSuffixesToReplicateOptions().getAvailableSuffixes())
+ {
+ for (ReplicaDescriptor replica : suffix.getReplicas())
+ {
+ knownServerIds.add(replica.getReplicationId());
+ Object v = replica.getServer().getServerProperties().get
+ (ServerDescriptor.ServerProperty.REPLICATION_SERVER_ID);
+ if (v != null)
+ {
+ knownReplicationServerIds.add((Integer)v);
+ }
+ }
+ }
+ }
+ Set<String> dns = new HashSet<String>();
+ DataReplicationOptions rep = getUserData().getReplicationOptions();
+ String newReplicationServer = getLocalReplicationServer();
+
+ Map<String, Set<String>> replicationServers =
+ new HashMap<String, Set<String>>();
+
+ if (rep.getType() == DataReplicationOptions.Type.FIRST_IN_TOPOLOGY)
+ {
+ String dn = getUserData().getNewSuffixOptions().getBaseDn();
+ dns.add(dn);
+ HashSet<String> h = new HashSet<String>();
+ h.add(newReplicationServer);
+ replicationServers.put(dn, h);
+ }
+ else
+ {
+ Set<SuffixDescriptor> suffixes =
+ getUserData().getSuffixesToReplicateOptions().getSuffixes();
+ for (SuffixDescriptor suffix : suffixes)
+ {
+ dns.add(suffix.getDN());
+ HashSet<String> h = new HashSet<String>();
+ h.addAll(suffix.getReplicationServers());
+ h.add(newReplicationServer);
+ for (ReplicaDescriptor replica : suffix.getReplicas())
+ {
+ ServerDescriptor server = replica.getServer();
+ Integer replicationPort = getUserData().
+ getRemoteWithNoReplicationPort().get(server);
+ if (replicationPort != null)
+ {
+ h.add(server.getHostName()+":"+replicationPort);
+ }
+ }
+ replicationServers.put(suffix.getDN(), h);
+ }
+ }
+
+ InitialLdapContext ctx = null;
+ try
+ {
+ ctx = createLocalContext();
+ helper.configureReplication(ctx, dns, replicationServers,
+ getUserData().getReplicationOptions().getReplicationPort(),
+ getLocalHostPort(),
+ knownReplicationServerIds, knownServerIds);
+ }
+ catch (ApplicationException ae)
+ {
+ throw ae;
+ }
+ catch (NamingException ne)
+ {
+ String failedMsg = getThrowableMsg("error-connecting-to-local", null, ne);
+ throw new ApplicationException(
+ ApplicationException.Type.CONFIGURATION_ERROR, failedMsg, ne);
+ }
+ finally
+ {
+ try
+ {
+ if (ctx != null)
+ {
+ ctx.close();
+ }
+ }
+ catch (Throwable t)
+ {
+ }
+ }
+ notifyListeners(getFormattedDone());
+
+ if (rep.getType() == DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY)
+ {
+ Map<ServerDescriptor, Set<ReplicaDescriptor>> hm =
+ new HashMap<ServerDescriptor, Set<ReplicaDescriptor>>();
+ for (SuffixDescriptor suffix :
+ getUserData().getSuffixesToReplicateOptions().getSuffixes())
+ {
+ for (ReplicaDescriptor replica : suffix.getReplicas())
+ {
+ Set<ReplicaDescriptor> replicas = hm.get(replica.getServer());
+ if (replicas == null)
+ {
+ replicas = new HashSet<ReplicaDescriptor>();
+ hm.put(replica.getServer(), replicas);
+ }
+ replicas.add(replica);
+ }
+ }
+ for (ServerDescriptor server : hm.keySet())
+ {
+ notifyListeners(getLineBreak());
+ notifyListeners(getFormattedWithPoints(
+ getMsg("progress-configuring-replication-remote",
+ server.getHostPort(true))));
+ Integer v = (Integer)server.getServerProperties().get(
+ ServerDescriptor.ServerProperty.REPLICATION_SERVER_PORT);
+ int replicationPort;
+ if (v != null)
+ {
+ replicationPort = v;
+ }
+ else
+ {
+ replicationPort =
+ getUserData().getRemoteWithNoReplicationPort().get(server);
+ }
+ dns = new HashSet<String>();
+ for (ReplicaDescriptor replica : hm.get(server))
+ {
+ dns.add(replica.getSuffix().getDN());
+ }
+
+ ctx = getRemoteConnection(server, getTrustManager());
+ helper.configureReplication(ctx, dns, replicationServers,
+ replicationPort, server.getHostPort(true),
+ knownReplicationServerIds, knownServerIds);
+
+ try
+ {
+ ctx.close();
+ }
+ catch (Throwable t)
+ {
+ }
+ notifyListeners(getFormattedDone());
+ }
+ }
+ }
+
+ /**
* This methods enables this server as a Windows service.
* @throws ApplicationException if something goes wrong.
*/
@@ -1021,8 +1266,16 @@
InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED,
getFormattedSummary(
getMsg("summary-importing-automatically-generated")));
+ hmSummary.put(InstallProgressStep.CONFIGURING_REPLICATION,
+ getFormattedSummary(getMsg("summary-configuring-replication")));
hmSummary.put(InstallProgressStep.STARTING_SERVER,
getFormattedSummary(getMsg("summary-starting")));
+ hmSummary.put(InstallProgressStep.STOPPING_SERVER,
+ getFormattedSummary(getMsg("summary-stopping")));
+ hmSummary.put(InstallProgressStep.CONFIGURING_ADS,
+ getFormattedSummary(getMsg("summary-configuring-ads")));
+ hmSummary.put(InstallProgressStep.INITIALIZE_REPLICATED_SUFFIXES,
+ getFormattedSummary(getMsg("summary-initialize-replicated-suffixes")));
hmSummary.put(InstallProgressStep.ENABLING_WINDOWS_SERVICE,
getFormattedSummary(getMsg("summary-enabling-windows-service")));
@@ -1083,6 +1336,10 @@
{
updateUserDataForSuffixesOptionsPanel(qs);
}
+ else if (cStep == REMOTE_REPLICATION_PORTS)
+ {
+ updateUserDataForRemoteReplicationPorts(qs);
+ }
else if (cStep == NEW_SUFFIX_OPTIONS)
{
updateUserDataForNewSuffixOptionsPanel(qs);
@@ -1139,80 +1396,157 @@
break;
}
}
- else
+ }
+
+ /**
+ * This method initialize the contents of the synchronized servers with the
+ * contents of the first server we find.
+ * @throws ApplicationException if something goes wrong.
+ */
+ protected void initializeSuffixes() throws ApplicationException
+ {
+ InitialLdapContext ctx = null;
+ try
{
- /* We must replicate some suffixes: for the moment just create them. */
- /* TODO: replicate them. */
- Set<SuffixDescriptor> suffixesToReplicate =
- getUserData().getSuffixesToReplicateOptions().getAvailableSuffixes();
- boolean startedServer = false;
- if (suffixesToReplicate.size() > 0)
+ ctx = createLocalContext();
+ }
+ catch (Throwable t)
+ {
+ String failedMsg = getThrowableMsg("error-connecting-to-local", null, t);
+ try
{
- startServerWithoutConnectionHandlers();
- startedServer = true;
- }
- for (SuffixDescriptor suffix: suffixesToReplicate)
- {
- // TODO: localize
- notifyListeners(getFormattedWithPoints("Creating Suffix"));
-
- ArrayList<String> argList = new ArrayList<String>();
- argList.add("-C");
- argList.add(CONFIG_CLASS_NAME);
-
- argList.add("-c");
- argList.add(getInstallation().getCurrentConfigurationFile().toString());
-
- argList.add("-b");
- argList.add(suffix.getDN());
-
- String[] args = new String[argList.size()];
- argList.toArray(args);
- try
+ if (ctx != null)
{
- InstallerHelper helper = new InstallerHelper();
- int result = helper.invokeConfigureServer(args);
+ ctx.close();
+ }
+ }
+ catch (Throwable t1)
+ {
+ }
+ throw new ApplicationException(
+ ApplicationException.Type.CONFIGURATION_ERROR, failedMsg, t);
+ }
- if (result != 0)
+ Set<SuffixDescriptor> suffixes =
+ getUserData().getSuffixesToReplicateOptions().getSuffixes();
+ int i = 0;
+ for (SuffixDescriptor suffix : suffixes)
+ {
+ String dn = suffix.getDN();
+
+ ReplicaDescriptor replica = suffix.getReplicas().iterator().next();
+ ServerDescriptor server = replica.getServer();
+ String hostPort = server.getHostPort(true);
+
+ notifyListeners(getFormattedProgress(
+ getMsg("progress-initializing-suffix", dn, hostPort)));
+ notifyListeners(getLineBreak());
+ try
+ {
+ int replicationId = replica.getReplicationId();
+ if (replicationId == -1)
+ {
+ /**
+ * This occurs if the remote server had not replication configured.
+ */
+ InitialLdapContext rCtx = null;
+ try
{
+ rCtx = getRemoteConnection(server, getTrustManager());
+ ServerDescriptor s = ServerDescriptor.createStandalone(rCtx);
+ for (ReplicaDescriptor r : s.getReplicas())
+ {
+ if (Utils.areDnsEqual(r.getSuffix().getDN(), dn))
+ {
+ replicationId = r.getReplicationId();
+ }
+ }
+ }
+ catch (NamingException ne)
+ {
+ String[] arg = {server.getHostPort(true)};
throw new ApplicationException(
ApplicationException.Type.CONFIGURATION_ERROR,
- getMsg("error-configuring"), null);
+ getMsg("cannot-connect-to-remote-generic", arg), ne);
}
- } catch (Throwable t)
- {
- throw new ApplicationException(
- ApplicationException.Type.CONFIGURATION_ERROR,
- getThrowableMsg("error-configuring", null, t), t);
+ finally
+ {
+ try
+ {
+ rCtx.close();
+ }
+ catch (Throwable t)
+ {
+ }
+ }
}
- notifyListeners(getFormattedDone());
-
- // TODO: localize
- notifyListeners(
- getFormattedProgress("One day we will replicate the suffixes!"));
+ int nTries = 4;
+ boolean initDone = false;
+ while (!initDone)
+ {
+ try
+ {
+ initializeSuffix(ctx, replicationId, dn, true, hostPort);
+ initDone = true;
+ }
+ catch (PeerNotFoundException pnfe)
+ {
+ LOG.log(Level.INFO, "Peer could not be found");
+ if (nTries == 1)
+ {
+ throw new ApplicationException(
+ ApplicationException.Type.APPLICATION,
+ pnfe.getLocalizedMessage(), null);
+ }
+ try
+ {
+ Thread.sleep((5 - nTries) * 3000);
+ }
+ catch (Throwable t)
+ {
+ }
+ }
+ nTries--;
+ }
}
- if (startedServer)
+ catch (ApplicationException ae)
{
- new InProcessServerController(getInstallation()).stopServer();
+ try
+ {
+ if (ctx != null)
+ {
+ ctx.close();
+ }
+ }
+ catch (Throwable t1)
+ {
+ }
+ throw ae;
}
+ if (i > 0)
+ {
+ notifyListeners(getLineBreak());
+ }
+ i++;
}
}
/**
- * This methods updates the ADS contents (and creates the according suffixes).
+ * This method updates the ADS contents (and creates the according suffixes).
+ * NOTE: this method assumes that the server is running.
* @throws ApplicationException if something goes wrong.
*/
protected void updateADS() throws ApplicationException
{
- if (true) return;
- /* First check if the remote server contains an ADS: if it is the case the
+ /*
+ * First check if the remote server contains an ADS: if it is the case the
* best is to update its contents with the new data and then configure the
* local server to be replicated with the remote server.
*/
- DataReplicationOptions repl =
- getUserData().getReplicationOptions();
+ DataReplicationOptions repl = getUserData().getReplicationOptions();
boolean remoteServer =
repl.getType() == DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY;
+ InitialLdapContext localCtx = null;
if (remoteServer)
{
// Try to connect
@@ -1223,11 +1557,22 @@
InitialLdapContext ctx = null;
try
{
- ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
- Utils.getDefaultLDAPTimeout(), null);
+ if (auth.useSecureConnection())
+ {
+ ApplicationTrustManager trustManager = getTrustManager();
+ trustManager.setHost(auth.getHostName());
+ ctx = Utils.createLdapsContext(ldapUrl, dn, pwd,
+ Utils.getDefaultLDAPTimeout(), null, trustManager);
+ }
+ else
+ {
+ ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
+ Utils.getDefaultLDAPTimeout(), null);
+ }
ADSContext adsContext = new ADSContext(ctx);
- if (adsContext.hasAdminData())
+ boolean hasAdminData = adsContext.hasAdminData();
+ if (hasAdminData)
{
/* Add global administrator if the user specified one. */
if (getUserData().mustCreateAdministrator())
@@ -1236,9 +1581,10 @@
{
String[] arg = {getHostDisplay(auth)};
notifyListeners(getFormattedWithPoints(
- getMsg("creating-administrator", arg)));
+ getMsg("progress-creating-administrator", arg)));
adsContext.createAdministrator(getAdministratorProperties());
notifyListeners(getFormattedDone());
+ notifyListeners(getLineBreak());
}
catch (ADSContextException ade)
{
@@ -1254,37 +1600,215 @@
}
}
}
-
- Map<ADSContext.ServerProperty, Object> serverProperties =
- getNewServerProperties();
-
- /* Register new server data. */
- adsContext.registerServer(serverProperties);
-
- /* Configure local server to have an ADS and replicate it */
- // TODO
- notifyListeners(getFormattedProgress(
- "Here we create the new server ADS and we replicate it.\n"));
}
else
{
- /* TODO: We need to integrate in remote framework to make this work.
- */
- /*
+ notifyListeners(getFormattedWithPoints(
+ getMsg("progress-creating-ads-on-remote", getHostDisplay(auth))));
+
adsContext.createAdminData();
adsContext.createAdministrator(getAdministratorProperties());
adsContext.registerServer(
- getRemoteServerProperties(adsContext.getDirContext()));
- adsContext.registerServer(getNewServerProperties());
- */
- notifyListeners(getFormattedProgress(
- "Here we update the server in "+getHostDisplay(auth)+"\n"));
+ getRemoteServerProperties(auth.getHostName(),
+ adsContext.getDirContext()));
- /* Configure local server to have an ADS and replicate it */
- // TODO
- notifyListeners(getFormattedProgress(
- "Here we create the new server ADS and we replicate it.\n"));
+ notifyListeners(getFormattedDone());
+ notifyListeners(getLineBreak());
+ }
+ /* Configure local server to have an ADS */
+ notifyListeners(getFormattedWithPoints(
+ getMsg("progress-creating-ads")));
+ try
+ {
+ localCtx = createLocalContext();
+ }
+ catch (Throwable t)
+ {
+ String failedMsg = getThrowableMsg("error-connecting-to-local", null,
+ t);
+ throw new ApplicationException(
+ ApplicationException.Type.CONFIGURATION_ERROR, failedMsg, t);
+ }
+ createLocalAds(localCtx);
+ notifyListeners(getFormattedDone());
+ notifyListeners(getLineBreak());
+ lastLoadedCache = new TopologyCache(adsContext, getTrustManager());
+ lastLoadedCache.reloadTopology();
+ Set<Integer> knownServerIds = new HashSet<Integer>();
+ Set<Integer> knownReplicationServerIds = new HashSet<Integer>();
+ Set<String> replicationServers = new HashSet<String>();
+ replicationServers.add(getLocalReplicationServer());
+ Set<ServerDescriptor> remoteWithAds = new HashSet<ServerDescriptor>();
+
+ for (SuffixDescriptor suffix : lastLoadedCache.getSuffixes())
+ {
+ for (ReplicaDescriptor replica : suffix.getReplicas())
+ {
+ knownServerIds.add(replica.getReplicationId());
+ }
+ if (Utils.areDnsEqual(suffix.getDN(),
+ ADSContext.getAdministrationSuffixDN()))
+ {
+ replicationServers.addAll(suffix.getReplicationServers());
+ for (ReplicaDescriptor replica : suffix.getReplicas())
+ {
+ ServerDescriptor server = replica.getServer();
+ Object e = server.getServerProperties().get
+ (ServerDescriptor.ServerProperty.IS_REPLICATION_SERVER);
+ if (Boolean.TRUE.equals(e))
+ {
+ replicationServers.add(server.getHostName()+":"+
+ server.getServerProperties().get
+ (ServerDescriptor.ServerProperty.REPLICATION_SERVER_PORT));
+ }
+ remoteWithAds.add(server);
+ }
+ }
+ }
+ for (ServerDescriptor server : lastLoadedCache.getServers())
+ {
+ Object v = server.getServerProperties().get
+ (ServerDescriptor.ServerProperty.REPLICATION_SERVER_ID);
+ if (v != null)
+ {
+ knownReplicationServerIds.add((Integer)v);
+ }
+ }
+ InstallerHelper helper = new InstallerHelper();
+ Set<String> dns = new HashSet<String>();
+ dns.add(ADSContext.getAdministrationSuffixDN());
+ Map <String, Set<String>>hmRepServers =
+ new HashMap<String, Set<String>>();
+ hmRepServers.put(ADSContext.getAdministrationSuffixDN(),
+ replicationServers);
+ for (ServerDescriptor server : remoteWithAds)
+ {
+ Integer replicationPort = (Integer)server.getServerProperties().get
+ (ServerDescriptor.ServerProperty.REPLICATION_SERVER_PORT);
+ if (replicationPort != null)
+ {
+ InitialLdapContext rCtx = getRemoteConnection(server,
+ getTrustManager());
+ helper.configureReplication(rCtx, dns, hmRepServers,
+ replicationPort, server.getHostPort(true),
+ knownReplicationServerIds, knownServerIds);
+ try
+ {
+ rCtx.close();
+ }
+ catch (Throwable t)
+ {
+ }
+ }
+ }
+ /* Register new server data. */
+ try
+ {
+ adsContext.registerServer(getNewServerAdsProperties());
+ }
+ catch (ADSContextException adse)
+ {
+ if (adse.getError() ==
+ ADSContextException.ErrorType.ALREADY_REGISTERED)
+ {
+ /* This might occur after registering and unregistering a server */
+ adsContext.unregisterServer(getNewServerAdsProperties());
+ adsContext.registerServer(getNewServerAdsProperties());
+ }
+ else
+ {
+ throw adse;
+ }
+ }
+
+ /* Configure replication on local server */
+ helper.configureReplication(localCtx, dns, hmRepServers,
+ getUserData().getReplicationOptions().getReplicationPort(),
+ getLocalHostPort(), knownReplicationServerIds, knownServerIds);
+
+ /* Initialize local ADS contents. */
+ ServerDescriptor server = ServerDescriptor.createStandalone(ctx);
+ for (ReplicaDescriptor replica : server.getReplicas())
+ {
+ if (Utils.areDnsEqual(replica.getSuffix().getDN(),
+ ADSContext.getAdministrationSuffixDN()))
+ {
+ notifyListeners(getFormattedWithPoints(
+ getMsg("progress-initializing-ads")));
+
+ int replicationId = replica.getReplicationId();
+ if (replicationId == -1)
+ {
+ /**
+ * This occurs if the remote server had not replication
+ * configured.
+ */
+ InitialLdapContext rCtx = null;
+ try
+ {
+ rCtx = getRemoteConnection(server, getTrustManager());
+ ServerDescriptor s = ServerDescriptor.createStandalone(rCtx);
+ for (ReplicaDescriptor r : s.getReplicas())
+ {
+ if (Utils.areDnsEqual(r.getSuffix().getDN(), dn))
+ {
+ replicationId = r.getReplicationId();
+ }
+ }
+ }
+ catch (NamingException ne)
+ {
+ String[] arg = {server.getHostPort(true)};
+ throw new ApplicationException(
+ ApplicationException.Type.CONFIGURATION_ERROR,
+ getMsg("cannot-connect-to-remote-generic", arg), ne);
+ }
+ finally
+ {
+ try
+ {
+ rCtx.close();
+ }
+ catch (Throwable t)
+ {
+ }
+ }
+ }
+ int nTries = 4;
+ boolean initDone = false;
+ while (!initDone)
+ {
+ try
+ {
+ initializeSuffix(localCtx, replica.getReplicationId(),
+ ADSContext.getAdministrationSuffixDN(),
+ true, server.getHostPort(true));
+ initDone = true;
+ }
+ catch (PeerNotFoundException pnfe)
+ {
+ LOG.log(Level.INFO, "Peer could not be found");
+ if (nTries == 1)
+ {
+ throw new ApplicationException(
+ ApplicationException.Type.APPLICATION,
+ pnfe.getLocalizedMessage(), null);
+ }
+ try
+ {
+ Thread.sleep((5 - nTries) * 3000);
+ }
+ catch (Throwable t)
+ {
+ }
+ }
+ nTries--;
+ }
+ notifyListeners(getFormattedDone());
+ notifyListeners(getLineBreak());
+ break;
+ }
}
}
catch (NoPermissionException x)
@@ -1301,6 +1825,14 @@
ApplicationException.Type.CONFIGURATION_ERROR,
getMsg("cannot-connect-to-remote-generic", arg), ne);
}
+ catch (TopologyCacheException tpe)
+ {
+ LOG.log(Level.WARNING, "Error reloading topology cache to "+
+ "configure ADS replication.", tpe);
+ throw new ApplicationException(
+ ApplicationException.Type.CONFIGURATION_ERROR,
+ getMsg("bug-msg"), tpe);
+ }
catch (ADSContextException ace)
{
String[] args = {getHostDisplay(auth), ace.toString()};
@@ -1320,27 +1852,75 @@
{
}
}
+ if (localCtx != null)
+ {
+ try
+ {
+ localCtx.close();
+ }
+ catch (Throwable t)
+ {
+ }
+ }
}
}
else
{
- notifyListeners(getFormattedWithPoints(getMsg("creating-ads")));
- Map<ADSContext.ServerProperty, Object> serverProperties =
- getNewServerProperties();
- /*
try
{
- ADSContext.createOfflineAdminData(serverProperties,
- getUserData().getServerLocation(), getBackendName());
+ /* Configure local server to have an ADS */
+ notifyListeners(getFormattedWithPoints(
+ getMsg("progress-creating-ads")));
+ try
+ {
+ localCtx = createLocalContext();
+ }
+ catch (Throwable t)
+ {
+ String failedMsg = getThrowableMsg("error-connecting-to-local", null,
+ t);
+ throw new ApplicationException(
+ ApplicationException.Type.CONFIGURATION_ERROR, failedMsg, t);
+ }
+ createLocalAds(localCtx);
+ int replicationPort =
+ getUserData().getReplicationOptions().getReplicationPort();
+ Set<String> dns = new HashSet<String>();
+ dns.add(ADSContext.getAdministrationSuffixDN());
+ Map<String, Set<String>> hmReplicationServers =
+ new HashMap<String, Set<String>>();
+ HashSet<String> replicationServers = new HashSet<String>();
+ String newReplicationServer = getLocalReplicationServer();
+ replicationServers.add(newReplicationServer);
+ hmReplicationServers.put(ADSContext.getAdministrationSuffixDN(),
+ replicationServers);
+ InstallerHelper helper = new InstallerHelper();
+
+ helper.configureReplication(localCtx, dns, hmReplicationServers,
+ replicationPort, getLocalHostPort(),
+ new HashSet<Integer>(), new HashSet<Integer>());
+ notifyListeners(getFormattedDone());
+ notifyListeners(getLineBreak());
}
catch (ADSContextException ace)
{
throw new ApplicationException(
ApplicationException.Type.CONFIGURATION_ERROR,
- getMsg("local-ads-exception"), ace);
+ getMsg("ads-exception", ace.toString()), ace);
}
- */
- notifyListeners(getFormattedDone());
+ finally
+ {
+ if (localCtx != null)
+ {
+ try
+ {
+ localCtx.close();
+ }
+ catch (Throwable t)
+ {
+ }
+ }
+ }
}
}
@@ -1350,7 +1930,7 @@
* @return <CODE>true</CODE> if we must create a new suffix and
* <CODE>false</CODE> otherwise.
*/
- private boolean createNotReplicatedSuffix()
+ protected boolean createNotReplicatedSuffix()
{
boolean createSuffix;
@@ -1363,15 +1943,84 @@
createSuffix =
(repl.getType() == DataReplicationOptions.Type.FIRST_IN_TOPOLOGY) ||
(repl.getType() == DataReplicationOptions.Type.STANDALONE) ||
- (suf.getType() ==
- SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY);
+ (suf.getType() == SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY);
return createSuffix;
}
+ /**
+ * Returns <CODE>true</CODE> if we must configure replication and
+ * <CODE>false</CODE> otherwise.
+ * @return <CODE>true</CODE> if we must configure replication and
+ * <CODE>false</CODE> otherwise.
+ */
+ protected boolean mustConfigureReplication()
+ {
+ return getUserData().getReplicationOptions().getType() !=
+ DataReplicationOptions.Type.STANDALONE;
+ }
+
+ /**
+ * Returns <CODE>true</CODE> if we must create the ADS and
+ * <CODE>false</CODE> otherwise.
+ * @return <CODE>true</CODE> if we must create the ADS and
+ * <CODE>false</CODE> otherwise.
+ */
+ protected boolean mustCreateAds()
+ {
+ return getUserData().getReplicationOptions().getType() !=
+ DataReplicationOptions.Type.STANDALONE;
+ }
+
+ /**
+ * Returns <CODE>true</CODE> if we must start the server and
+ * <CODE>false</CODE> otherwise.
+ * @return <CODE>true</CODE> if we must start the server and
+ * <CODE>false</CODE> otherwise.
+ */
+ protected boolean mustStart()
+ {
+ return getUserData().getStartServer() || mustCreateAds();
+ }
+
+ /**
+ * Returns <CODE>true</CODE> if we must stop the server and
+ * <CODE>false</CODE> otherwise.
+ * The server might be stopped if the user asked not to start it at the
+ * end of the installation and it was started temporarily to update its
+ * configuration.
+ * @return <CODE>true</CODE> if we must stop the server and
+ * <CODE>false</CODE> otherwise.
+ */
+ protected boolean mustStop()
+ {
+ return !getUserData().getStartServer() && mustCreateAds();
+ }
+
+ /**
+ * Returns <CODE>true</CODE> if we must initialize suffixes and
+ * <CODE>false</CODE> otherwise.
+ * @return <CODE>true</CODE> if we must initialize suffixes and
+ * <CODE>false</CODE> otherwise.
+ */
+ protected boolean mustInitializeSuffixes()
+ {
+ return getUserData().getReplicationOptions().getType() ==
+ DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY;
+ }
+
private String getLdapUrl(AuthenticationData auth)
{
- return "ldap://"+auth.getHostName()+":"+auth.getPort();
+ String ldapUrl;
+ if (auth.useSecureConnection())
+ {
+ ldapUrl = "ldaps://"+auth.getHostName()+":"+auth.getPort();
+ }
+ else
+ {
+ ldapUrl = "ldap://"+auth.getHostName()+":"+auth.getPort();
+ }
+ return ldapUrl;
}
private String getHostDisplay(AuthenticationData auth)
@@ -1379,42 +2028,50 @@
return auth.getHostName()+":"+auth.getPort();
}
- private Map<ADSContext.ServerProperty, Object> getNewServerProperties()
+ private Map<ADSContext.ServerProperty, Object> getNewServerAdsProperties()
{
Map<ADSContext.ServerProperty, Object> serverProperties =
new HashMap<ADSContext.ServerProperty, Object>();
- // TODO: this might not work
- /*
- try
- {
- serverProperties.put(ADSContext.ServerProperty.HOSTNAME,
- java.net.InetAddress.getLocalHost().getHostName());
- }
- catch (Throwable t)
- {
- t.printStackTrace();
- }
- serverProperties.put(ADSContext.ServerProperty.PORT,
+ serverProperties.put(ADSContext.ServerProperty.HOST_NAME,
+ getUserData().getHostName());
+ serverProperties.put(ADSContext.ServerProperty.LDAP_PORT,
String.valueOf(getUserData().getServerPort()));
serverProperties.put(ADSContext.ServerProperty.LDAP_ENABLED, "true");
// TODO: even if the user does not configure SSL maybe we should choose
// a secure port that is not being used and that we can actually use.
- serverProperties.put(ADSContext.ServerProperty.SECURE_PORT, "636");
- serverProperties.put(ADSContext.ServerProperty.LDAPS_ENABLED, "false");
+ SecurityOptions sec = getUserData().getSecurityOptions();
+ if (sec.getEnableSSL())
+ {
+ serverProperties.put(ADSContext.ServerProperty.LDAPS_PORT,
+ String.valueOf(sec.getSslPort()));
+ serverProperties.put(ADSContext.ServerProperty.LDAPS_ENABLED, "true");
+ }
+ else
+ {
+ serverProperties.put(ADSContext.ServerProperty.LDAPS_PORT, "636");
+ serverProperties.put(ADSContext.ServerProperty.LDAPS_ENABLED, "false");
+ }
- serverProperties.put(ADSContext.ServerProperty.JMX_PORT,
- String.valueOf(getUserData().getServerJMXPort()));
- serverProperties.put(ADSContext.ServerProperty.JMX_ENABLED, "true");
+ serverProperties.put(ADSContext.ServerProperty.JMX_PORT, "1689");
+ serverProperties.put(ADSContext.ServerProperty.JMX_ENABLED, "false");
- serverProperties.put(ADSContext.ServerProperty.INSTANCE_PATH,
- getUserData().getServerLocation());
+ String path;
+ if (Utils.isWebStart())
+ {
+ path = getUserData().getServerLocation();
+ }
+ else
+ {
+ path = Utils.getInstallPathFromClasspath();
+ }
+ serverProperties.put(ADSContext.ServerProperty.INSTANCE_PATH, path);
- String serverID = serverProperties.get(ADSContext.ServerProperty.HOSTNAME)+
+ String serverID = serverProperties.get(ADSContext.ServerProperty.HOST_NAME)+
":"+getUserData().getServerPort();
- */
+
/* TODO: do we want to ask this specifically to the user? */
- //serverProperties.put(ADSContext.ServerProperty.ID, serverID);
+ serverProperties.put(ADSContext.ServerProperty.ID, serverID);
serverProperties.put(ADSContext.ServerProperty.HOST_OS,
Utils.getOSString());
@@ -1428,7 +2085,7 @@
new HashMap<ADSContext.AdministratorProperty, Object>();
adminProperties.put(ADSContext.AdministratorProperty.UID,
getUserData().getGlobalAdministratorUID());
- adminProperties.put(ADSContext.AdministratorProperty.UID,
+ adminProperties.put(ADSContext.AdministratorProperty.PASSWORD,
getUserData().getGlobalAdministratorPassword());
adminProperties.put(ADSContext.AdministratorProperty.DESCRIPTION,
getMsg("global-administrator-description"));
@@ -1548,6 +2205,20 @@
}
}
+ // Check the host is not empty.
+ // TODO: check that the host name is valid...
+ String hostName = qs.getFieldStringValue(FieldName.HOST_NAME);
+ if ((hostName == null) || hostName.trim().isEmpty())
+ {
+ errorMsgs.add(getMsg("empty-host-name"));
+ qs.displayFieldInvalid(FieldName.HOST_NAME, true);
+ }
+ else
+ {
+ qs.displayFieldInvalid(FieldName.HOST_NAME, false);
+ getUserData().setHostName(hostName);
+ }
+
// Check the port
String sPort = qs.getFieldStringValue(FieldName.SERVER_PORT);
int port = -1;
@@ -1722,10 +2393,13 @@
private void updateUserDataForReplicationOptionsPanel(QuickSetup qs)
throws UserDataException {
boolean hasGlobalAdministrators = false;
+ Integer replicationPort = -1;
String host = null;
Integer port = null;
String dn = null;
String pwd = null;
+ boolean isSecure = Boolean.TRUE.equals(qs.getFieldValue(
+ FieldName.REMOTE_SERVER_IS_SECURE_PORT));
ArrayList<String> errorMsgs = new ArrayList<String>();
DataReplicationOptions.Type type = (DataReplicationOptions.Type)
@@ -1734,195 +2408,56 @@
dn = qs.getFieldStringValue(FieldName.REMOTE_SERVER_DN);
pwd = qs.getFieldStringValue(FieldName.REMOTE_SERVER_PWD);
+ if (type != DataReplicationOptions.Type.STANDALONE)
+ {
+ // Check replication port
+ replicationPort = checkReplicationPort(qs, errorMsgs);
+ }
+
+ UserDataConfirmationException confirmEx = null;
switch (type)
{
case IN_EXISTING_TOPOLOGY:
{
- // Check host name
- if ((host == null) || (host.length() == 0))
- {
- errorMsgs.add(getMsg("empty-remote-host"));
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, true);
- }
- else
- {
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, false);
- }
-
- // Check port
String sPort = qs.getFieldStringValue(FieldName.REMOTE_SERVER_PORT);
- try
- {
- port = Integer.parseInt(sPort);
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, false);
- }
- catch (Throwable t)
- {
- errorMsgs.add(getMsg("invalid-remote-port"));
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, true);
- }
-
- // Check dn
- if ((dn == null) || (dn.length() == 0))
- {
- errorMsgs.add(getMsg("empty-remote-dn"));
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
- }
- else
- {
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, false);
- }
-
- // Check password
- if ((pwd == null) || (pwd.length() == 0))
- {
- errorMsgs.add(getMsg("empty-remote-pwd"));
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
- }
- else
- {
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, false);
- }
+ checkRemoteHostPortDnAndPwd(host, sPort, dn, pwd, qs, errorMsgs);
if (errorMsgs.size() == 0)
{
+ port = Integer.parseInt(sPort);
// Try to connect
- String ldapUrl = "ldap://"+host+":"+port;
- InitialLdapContext ctx = null;
+ boolean[] globalAdmin = {hasGlobalAdministrators};
+ String[] effectiveDn = {dn};
try
{
- try
- {
- ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
- Utils.getDefaultLDAPTimeout(), null);
- }
- catch (Throwable t)
- {
- // Try using a global administrator
- dn = ADSContext.getAdministratorDN(dn);
- ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
- Utils.getDefaultLDAPTimeout(), null);
- }
-
- ADSContext adsContext = new ADSContext(ctx);
- if (adsContext.hasAdminData())
- {
- /* Check if there are already global administrators */
- Set administrators = adsContext.readAdministratorRegistry();
- if (administrators.size() > 0)
- {
- hasGlobalAdministrators = true;
- }
- updateUserDataWithSuffixesInADS(adsContext);
- }
- else
- {
- getUserData().setSuffixesToReplicateOptions(
- new SuffixesToReplicateOptions(
- SuffixesToReplicateOptions.Type.
- REPLICATE_WITH_EXISTING_SUFFIXES,
- staticSuffixes(),
- staticSuffixes()));
- }
+ updateUserDataWithADS(host, port, dn, pwd, qs, errorMsgs,
+ globalAdmin, effectiveDn);
}
- catch (NoPermissionException x)
+ catch (UserDataConfirmationException e)
{
- String[] arg = {host+":"+port};
- errorMsgs.add(getMsg("cannot-connect-to-remote-permissions", arg));
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
+ confirmEx = e;
}
- catch (NamingException ne)
- {
- String[] arg = {host+":"+port};
- errorMsgs.add(getMsg("cannot-connect-to-remote-generic", arg));
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, true);
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, true);
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
- qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
- }
- catch (ADSContextException ace)
- {
- String[] args = {host+":"+port, ace.toString()};
- errorMsgs.add(getMsg("remote-ads-exception", args));
- }
- finally
- {
- if (ctx != null)
- {
- try
- {
- ctx.close();
- }
- catch (Throwable t)
- {
- }
- }
- }
+ hasGlobalAdministrators = globalAdmin[0];
+ dn = effectiveDn[0];
}
break;
}
case STANDALONE:
{
- Set<SuffixDescriptor> available;
- SuffixesToReplicateOptions repl =
- getUserData().getSuffixesToReplicateOptions();
-
- if (repl != null)
- {
- available = repl.getAvailableSuffixes();
- }
- else
- {
- available = new HashSet<SuffixDescriptor>();
- }
-
- Set<SuffixDescriptor> chosen;
- if (repl != null)
- {
- chosen = repl.getSuffixes();
- }
- else
- {
- chosen = new HashSet<SuffixDescriptor>();
- }
-
getUserData().setSuffixesToReplicateOptions(
new SuffixesToReplicateOptions(
SuffixesToReplicateOptions.Type.NO_SUFFIX_TO_REPLICATE,
- available,
- chosen));
+ new HashSet<SuffixDescriptor>(),
+ new HashSet<SuffixDescriptor>()));
break;
}
case FIRST_IN_TOPOLOGY:
{
- Set<SuffixDescriptor> available;
- SuffixesToReplicateOptions repl =
- getUserData().getSuffixesToReplicateOptions();
-
- if (repl != null)
- {
- available = repl.getAvailableSuffixes();
- }
- else
- {
- available = new HashSet<SuffixDescriptor>();
- }
-
- Set<SuffixDescriptor> chosen;
- if (repl != null)
- {
- chosen = repl.getSuffixes();
- }
- else
- {
- chosen = new HashSet<SuffixDescriptor>();
- }
getUserData().setSuffixesToReplicateOptions(
new SuffixesToReplicateOptions(
SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY,
- available,
- chosen));
+ new HashSet<SuffixDescriptor>(),
+ new HashSet<SuffixDescriptor>()));
break;
}
default:
@@ -1940,20 +2475,367 @@
}
auth.setDn(dn);
auth.setPwd(pwd);
+ auth.setUseSecureConnection(isSecure);
DataReplicationOptions repl = new DataReplicationOptions(type,
- auth);
+ auth, replicationPort);
getUserData().setReplicationOptions(repl);
getUserData().createAdministrator(!hasGlobalAdministrators &&
type == DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY);
-
}
if (errorMsgs.size() > 0)
{
throw new UserDataException(Step.REPLICATION_OPTIONS,
Utils.getStringFromCollection(errorMsgs, "\n"));
}
+ if (confirmEx != null)
+ {
+ throw confirmEx;
+ }
+ }
+
+ private int checkReplicationPort(QuickSetup qs, ArrayList<String> errorMsgs)
+ {
+ int replicationPort = -1;
+ String sPort = qs.getFieldStringValue(FieldName.REPLICATION_PORT);
+ try
+ {
+ replicationPort = Integer.parseInt(sPort);
+ if ((replicationPort < MIN_PORT_VALUE) ||
+ (replicationPort > MAX_PORT_VALUE))
+ {
+ String[] args =
+ { String.valueOf(MIN_PORT_VALUE), String.valueOf(MAX_PORT_VALUE) };
+ errorMsgs.add(getMsg("invalid-replication-port-value-range", args));
+ qs.displayFieldInvalid(FieldName.SERVER_PORT, true);
+ } else if (!Utils.canUseAsPort(replicationPort))
+ {
+ if (Utils.isPriviledgedPort(replicationPort))
+ {
+ errorMsgs.add(getMsg("cannot-bind-priviledged-port",
+ new String[] { String.valueOf(replicationPort) }));
+ } else
+ {
+ errorMsgs.add(getMsg("cannot-bind-port",
+ new String[] { String.valueOf(replicationPort) }));
+ }
+ qs.displayFieldInvalid(FieldName.REPLICATION_PORT, true);
+
+ } else
+ {
+ /* Check that we did not chose this port for another protocol */
+ SecurityOptions sec = getUserData().getSecurityOptions();
+ if ((replicationPort == getUserData().getServerPort()) ||
+ (replicationPort == getUserData().getServerJMXPort()) ||
+ ((replicationPort == sec.getSslPort()) && sec.getEnableSSL()))
+ {
+ errorMsgs.add(
+ getMsg("replication-port-already-chosen-for-other-protocol"));
+ qs.displayFieldInvalid(FieldName.REPLICATION_PORT, true);
+ }
+ else
+ {
+ qs.displayFieldInvalid(FieldName.REPLICATION_PORT, false);
+ }
+ }
+
+ } catch (NumberFormatException nfe)
+ {
+ String[] args =
+ { String.valueOf(MIN_PORT_VALUE), String.valueOf(MAX_PORT_VALUE) };
+ errorMsgs.add(getMsg("invalid-replication-port-value-range", args));
+ qs.displayFieldInvalid(FieldName.REPLICATION_PORT, true);
+ }
+ return replicationPort;
+ }
+
+ private void checkRemoteHostPortDnAndPwd(String host, String sPort, String dn,
+ String pwd, QuickSetup qs, ArrayList<String> errorMsgs)
+ {
+ // Check host
+ if ((host == null) || (host.length() == 0))
+ {
+ errorMsgs.add(getMsg("empty-remote-host"));
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, true);
+ }
+ else
+ {
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, false);
+ }
+
+ // Check port
+ try
+ {
+ Integer.parseInt(sPort);
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, false);
+ }
+ catch (Throwable t)
+ {
+ errorMsgs.add(getMsg("invalid-remote-port"));
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, true);
+ }
+
+ // Check dn
+ if ((dn == null) || (dn.length() == 0))
+ {
+ errorMsgs.add(getMsg("empty-remote-dn"));
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
+ }
+ else
+ {
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, false);
+ }
+
+ // Check password
+ if ((pwd == null) || (pwd.length() == 0))
+ {
+ errorMsgs.add(getMsg("empty-remote-pwd"));
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
+ }
+ else
+ {
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, false);
+ }
+ }
+
+ private void updateUserDataWithADS(String host, int port, String dn,
+ String pwd, QuickSetup qs, ArrayList<String> errorMsgs,
+ boolean[] hasGlobalAdministrators,
+ String[] effectiveDn) throws UserDataException
+ {
+ String ldapUrl;
+ host = Utils.getHostNameForLdapUrl(host);
+ boolean isSecure = Boolean.TRUE.equals(qs.getFieldValue(
+ FieldName.REMOTE_SERVER_IS_SECURE_PORT));
+ if (isSecure)
+ {
+ ldapUrl = "ldaps://"+host+":"+port;
+ }
+ else
+ {
+ ldapUrl = "ldap://"+host+":"+port;
+ }
+ InitialLdapContext ctx = null;
+
+ ApplicationTrustManager trustManager = getTrustManager();
+ trustManager.setHost(host);
+ trustManager.resetLastRefusedItems();
+ try
+ {
+ try
+ {
+ if (isSecure)
+ {
+ ctx = Utils.createLdapsContext(ldapUrl, dn, pwd,
+ Utils.getDefaultLDAPTimeout(), null, trustManager);
+ }
+ else
+ {
+ ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
+ Utils.getDefaultLDAPTimeout(), null);
+ }
+ }
+ catch (Throwable t)
+ {
+ if (!isCertificateException(t))
+ {
+ // Try using a global administrator
+ dn = ADSContext.getAdministratorDN(dn);
+ if (isSecure)
+ {
+ ctx = Utils.createLdapsContext(ldapUrl, dn, pwd,
+ Utils.getDefaultLDAPTimeout(), null, trustManager);
+ }
+ else
+ {
+ ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
+ Utils.getDefaultLDAPTimeout(), null);
+ }
+ }
+ else
+ {
+ throw t;
+ }
+ }
+
+ ADSContext adsContext = new ADSContext(ctx);
+ if (adsContext.hasAdminData())
+ {
+ /* Check if there are already global administrators */
+ Set administrators = adsContext.readAdministratorRegistry();
+ if (administrators.size() > 0)
+ {
+ hasGlobalAdministrators[0] = true;
+ }
+ else
+ {
+ hasGlobalAdministrators[0] = false;
+ }
+ Set<TopologyCacheException> exceptions =
+ updateUserDataWithSuffixesInADS(adsContext, trustManager);
+ Set<String> exceptionMsgs = new LinkedHashSet<String>();
+ /* Check the exceptions and see if we throw them or not. */
+ for (TopologyCacheException e : exceptions)
+ {
+ switch (e.getType())
+ {
+ case NOT_GLOBAL_ADMINISTRATOR:
+ String errorMsg = getMsg("not-global-administrator-provided");
+ throw new UserDataException(Step.REPLICATION_OPTIONS, errorMsg);
+ case GENERIC_CREATING_CONNECTION:
+ if ((e.getCause() != null) &&
+ isCertificateException(e.getCause()))
+ {
+ UserDataCertificateException.Type excType;
+ ApplicationTrustManager.Cause cause =
+ trustManager.getLastRefusedCause();
+ LOG.log(Level.INFO, "Certificate exception cause: "+cause);
+ if (cause == ApplicationTrustManager.Cause.NOT_TRUSTED)
+ {
+ excType = UserDataCertificateException.Type.NOT_TRUSTED;
+ }
+ else if (cause ==
+ ApplicationTrustManager.Cause.HOST_NAME_MISMATCH)
+ {
+ excType = UserDataCertificateException.Type.HOST_NAME_MISMATCH;
+ }
+ else
+ {
+ excType = null;
+ }
+ if (excType != null)
+ {
+ String h;
+ int p;
+ try
+ {
+ URI uri = new URI(e.getLdapUrl());
+ h = uri.getHost();
+ p = uri.getPort();
+ }
+ catch (Throwable t)
+ {
+ LOG.log(Level.WARNING,
+ "Error parsing ldap url of TopologyCacheException.", t);
+ h = getMsg("not-available-label");
+ p = -1;
+ }
+ throw new UserDataCertificateException(Step.REPLICATION_OPTIONS,
+ getMsg("certificate-exception", h, String.valueOf(p)),
+ e.getCause(), h, p,
+ e.getTrustManager().getLastRefusedChain(),
+ trustManager.getLastRefusedAuthType(), excType);
+ }
+ }
+ }
+ exceptionMsgs.add(getStringRepresentation(e));
+ }
+ if (exceptionMsgs.size() > 0)
+ {
+ String confirmationMsg =
+ getMsg("error-reading-registered-servers-confirm",
+ Utils.getStringFromCollection(exceptionMsgs, "\n"));
+ throw new UserDataConfirmationException(Step.REPLICATION_OPTIONS,
+ confirmationMsg);
+ }
+ }
+ else
+ {
+ updateUserDataWithSuffixesInServer(ctx);
+ }
+ }
+ catch (UserDataException ude)
+ {
+ throw ude;
+ }
+ catch (Throwable t)
+ {
+ LOG.log(Level.INFO, "Error connecting to remote server.", t);
+ if (isCertificateException(t))
+ {
+ UserDataCertificateException.Type excType;
+ ApplicationTrustManager.Cause cause =
+ trustManager.getLastRefusedCause();
+ LOG.log(Level.INFO, "Certificate exception cause: "+cause);
+ if (cause == ApplicationTrustManager.Cause.NOT_TRUSTED)
+ {
+ excType = UserDataCertificateException.Type.NOT_TRUSTED;
+ }
+ else if (cause == ApplicationTrustManager.Cause.HOST_NAME_MISMATCH)
+ {
+ excType = UserDataCertificateException.Type.HOST_NAME_MISMATCH;
+ }
+ else
+ {
+ excType = null;
+ }
+
+ if (excType != null)
+ {
+ throw new UserDataCertificateException(Step.REPLICATION_OPTIONS,
+ getMsg("certificate-exception", host, String.valueOf(port)), t,
+ host, port, trustManager.getLastRefusedChain(),
+ trustManager.getLastRefusedAuthType(), excType);
+ }
+ else
+ {
+ String[] arg = {host+":"+port, t.toString()};
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, true);
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, true);
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
+ errorMsgs.add(getMsg("cannot-connect-to-remote-generic", arg));
+ }
+ }
+ else if (t instanceof AuthenticationException)
+ {
+ String[] arg = {host+":"+port};
+ errorMsgs.add(getMsg("cannot-connect-to-remote-authentication", arg));
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
+ }
+ else if (t instanceof NoPermissionException)
+ {
+ String[] arg = {host+":"+port};
+ errorMsgs.add(getMsg("cannot-connect-to-remote-permissions", arg));
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
+ }
+ else if (t instanceof NamingException)
+ {
+ String[] arg = {host+":"+port, t.toString()};
+ errorMsgs.add(getMsg("cannot-connect-to-remote-generic", arg));
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, true);
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, true);
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
+ qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
+ }
+ else if (t instanceof ADSContextException)
+ {
+ String[] args = {host+":"+port, t.toString()};
+ errorMsgs.add(getMsg("remote-ads-exception", args));
+ }
+ else
+ {
+ throw new UserDataException(Step.REPLICATION_OPTIONS,
+ getThrowableMsg("bug-msg", null, t));
+ }
+ }
+ finally
+ {
+ if (ctx != null)
+ {
+ try
+ {
+ ctx.close();
+ }
+ catch (Throwable t)
+ {
+ }
+ }
+ }
+ effectiveDn[0] = dn;
}
/**
@@ -2016,7 +2898,7 @@
if (pwdValid)
{
- getUserData().setDirectoryManagerPwd(pwd1);
+ getUserData().setGlobalAdministratorPassword(pwd1);
qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_PWD, false);
qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM, false);
}
@@ -2068,6 +2950,8 @@
chosen);
getUserData().setSuffixesToReplicateOptions(options);
}
+ getUserData().setRemoteWithNoReplicationPort(
+ getRemoteWithNoReplicationPort(getUserData()));
}
else
{
@@ -2091,6 +2975,77 @@
}
/**
+ * Validate the data provided by the user in the remote server replication
+ * port panel and update the userData object according to that content.
+ *
+ * @throws UserDataException if the data provided by the user is not
+ * valid.
+ */
+ private void updateUserDataForRemoteReplicationPorts(QuickSetup qs)
+ throws UserDataException
+ {
+ ArrayList<String> errorMsgs = new ArrayList<String>();
+ Map<ServerDescriptor, Integer> servers =
+ getUserData().getRemoteWithNoReplicationPort();
+ Map hm = (Map) qs.getFieldValue(FieldName.REMOTE_REPLICATION_PORT);
+ for (ServerDescriptor server : servers.keySet())
+ {
+ String hostName = server.getHostName();
+ int replicationPort = -1;
+ String sPort = (String)hm.get(server.getId());
+ try
+ {
+ replicationPort = Integer.parseInt(sPort);
+ if ((replicationPort < MIN_PORT_VALUE) ||
+ (replicationPort > MAX_PORT_VALUE))
+ {
+ String[] args = { server.getHostPort(true),
+ String.valueOf(MIN_PORT_VALUE), String.valueOf(MAX_PORT_VALUE)};
+ errorMsgs.add(getMsg("invalid-remote-replication-port-value-range",
+ args));
+ }
+ if (hostName.equalsIgnoreCase(getUserData().getHostName()))
+ {
+ int securePort = -1;
+ if (getUserData().getSecurityOptions().getEnableSSL())
+ {
+ securePort = getUserData().getSecurityOptions().getSslPort();
+ }
+ if ((replicationPort == getUserData().getServerPort()) ||
+ (replicationPort == getUserData().getServerJMXPort()) ||
+ (replicationPort ==
+ getUserData().getReplicationOptions().getReplicationPort()) ||
+ (replicationPort == securePort))
+ {
+ errorMsgs.add(getMsg(
+ "remote-replication-port-already-chosen-for-other-protocol",
+ server.getHostPort(true)));
+ }
+ }
+ servers.put(server, replicationPort);
+ } catch (NumberFormatException nfe)
+ {
+ String[] args = { hostName, String.valueOf(MIN_PORT_VALUE),
+ String.valueOf(MAX_PORT_VALUE)};
+ errorMsgs.add(getMsg("invalid-remote-replication-port-value-range",
+ args));
+ }
+ }
+
+ if (errorMsgs.size() > 0)
+ {
+ qs.displayFieldInvalid(FieldName.REMOTE_REPLICATION_PORT, true);
+ throw new UserDataException(Step.REMOTE_REPLICATION_PORTS,
+ Utils.getStringFromCollection(errorMsgs, "\n"));
+ }
+ else
+ {
+ qs.displayFieldInvalid(FieldName.REMOTE_REPLICATION_PORT, false);
+ getUserData().setRemoteWithNoReplicationPort(servers);
+ }
+ }
+
+ /**
* Validate the data provided by the user in the new suffix data options panel
* and update the UserInstallData object according to that content.
*
@@ -2239,22 +3194,125 @@
}
private Map<ADSContext.ServerProperty, Object> getRemoteServerProperties(
- InitialLdapContext ctx) throws NamingException
+ String hostName, InitialLdapContext ctx) throws NamingException
{
- // TODO: use administration framework.
- return new HashMap<ADSContext.ServerProperty, Object>();
+ ServerDescriptor server = ServerDescriptor.createStandalone(ctx);
+ Map<ADSContext.ServerProperty, Object> serverProperties =
+ new HashMap<ADSContext.ServerProperty, Object>();
+ serverProperties.put(ADSContext.ServerProperty.HOST_NAME, hostName);
+ ADSContext.ServerProperty[][] adsProperties =
+ {
+ {ADSContext.ServerProperty.LDAP_PORT,
+ ADSContext.ServerProperty.LDAP_ENABLED},
+ {ADSContext.ServerProperty.LDAPS_PORT,
+ ADSContext.ServerProperty.LDAPS_ENABLED},
+ {ADSContext.ServerProperty.JMX_PORT,
+ ADSContext.ServerProperty.JMX_ENABLED},
+ {ADSContext.ServerProperty.JMXS_PORT,
+ ADSContext.ServerProperty.JMXS_ENABLED}
+
+ };
+ ServerDescriptor.ServerProperty[][] properties =
+ {
+ {ServerDescriptor.ServerProperty.LDAP_PORT,
+ ServerDescriptor.ServerProperty.LDAP_ENABLED},
+ {ServerDescriptor.ServerProperty.LDAPS_PORT,
+ ServerDescriptor.ServerProperty.LDAPS_ENABLED},
+ {ServerDescriptor.ServerProperty.JMX_PORT,
+ ServerDescriptor.ServerProperty.JMX_ENABLED},
+ {ServerDescriptor.ServerProperty.JMXS_PORT,
+ ServerDescriptor.ServerProperty.JMXS_ENABLED}
+ };
+ for (int i=0; i<properties.length; i++)
+ {
+ ArrayList portNumbers =
+ (ArrayList)server.getServerProperties().get(properties[i][0]);
+ if (portNumbers != null)
+ {
+ ArrayList enabled =
+ (ArrayList)server.getServerProperties().get(properties[i][1]);
+ boolean enabledFound = false;
+ for (int j=0; j<enabled.size() && !enabledFound; j++)
+ {
+ if (Boolean.TRUE.equals(enabled.get(j)))
+ {
+ enabledFound = true;
+ serverProperties.put(adsProperties[i][0],
+ String.valueOf(portNumbers.get(j)));
+ }
+ }
+ if (!enabledFound && (portNumbers.size() > 0))
+ {
+ serverProperties.put(adsProperties[i][0],
+ String.valueOf(portNumbers.get(0)));
+ }
+ serverProperties.put(adsProperties[i][1], enabledFound?"true":"false");
+ }
+ }
+
+ serverProperties.put(ADSContext.ServerProperty.ID,
+ server.getHostPort(true));
+
+ return serverProperties;
}
/**
- * Update the UserInstallData object according to the content of the review
- * panel.
+ * Update the UserInstallData with the contents we discover in the ADS.
*/
- private void updateUserDataWithSuffixesInADS(ADSContext adsContext)
+ private Set<TopologyCacheException> updateUserDataWithSuffixesInADS(
+ ADSContext adsContext, ApplicationTrustManager trustManager)
+ throws TopologyCacheException
+ {
+ Set<TopologyCacheException> exceptions =
+ new HashSet<TopologyCacheException>();
+ SuffixesToReplicateOptions suf =
+ getUserData().getSuffixesToReplicateOptions();
+ SuffixesToReplicateOptions.Type type;
+
+ if ((suf == null) || (suf.getType() ==
+ SuffixesToReplicateOptions.Type.NO_SUFFIX_TO_REPLICATE))
+ {
+ type = suf.getType();
+ }
+ else
+ {
+ type = SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY;
+ }
+ lastLoadedCache = new TopologyCache(adsContext, trustManager);
+ lastLoadedCache.reloadTopology();
+ Set<SuffixDescriptor> suffixes = lastLoadedCache.getSuffixes();
+
+ getUserData().setSuffixesToReplicateOptions(
+ new SuffixesToReplicateOptions(type, suffixes, suf.getSuffixes()));
+
+ /* Analyze if we had any exception while loading servers. For the moment
+ * only throw the exception found if the user did not provide the
+ * Administrator DN and this caused a problem authenticating in one server
+ * or if there is a certificate problem.
+ */
+ Set<ServerDescriptor> servers = lastLoadedCache.getServers();
+ for (ServerDescriptor server : servers)
+ {
+ TopologyCacheException e = server.getLastException();
+ if (e != null)
+ {
+ exceptions.add(e);
+ }
+ }
+ return exceptions;
+ }
+
+ /**
+ * Update the UserInstallData object with the contents of the server to which
+ * we are connected with the provided InitialLdapContext.
+ */
+ private void updateUserDataWithSuffixesInServer(InitialLdapContext ctx)
+ throws NamingException
{
SuffixesToReplicateOptions suf =
getUserData().getSuffixesToReplicateOptions();
SuffixesToReplicateOptions.Type type;
- Set<SuffixDescriptor> suffixes = null;
+ Set<SuffixDescriptor> suffixes = new HashSet<SuffixDescriptor>();
if (suf == null)
{
type = SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY;
@@ -2263,117 +3321,14 @@
{
type = suf.getType();
}
- // TODO: get the suffixes using the adsContext.
- if (suffixes == null)
+ ServerDescriptor s = ServerDescriptor.createStandalone(ctx);
+ Set<ReplicaDescriptor> replicas = s.getReplicas();
+ for (ReplicaDescriptor replica : replicas)
{
- suffixes = new HashSet<SuffixDescriptor>();
+ suffixes.add(replica.getSuffix());
}
- suffixes = staticSuffixes();
getUserData().setSuffixesToReplicateOptions(
- new SuffixesToReplicateOptions(type, suffixes, suffixes));
- }
-
- private Set<SuffixDescriptor> staticSuffixes()
- {
- /*
- ServerDescriptor server1 = new ServerDescriptor();
- Map<ADSContext.ServerProperty, Object> serverProp1 =
- new HashMap<ADSContext.ServerProperty, Object>();
- serverProp1.put(ADSContext.ServerProperty.HOSTNAME, "potato.france");
- serverProp1.put(ADSContext.ServerProperty.PORT, "389");
- serverProp1.put(ADSContext.ServerProperty.SECURE_PORT, "689");
- serverProp1.put(ADSContext.ServerProperty.LDAP_ENABLED, "true");
- serverProp1.put(ADSContext.ServerProperty.LDAPS_ENABLED, "false");
- serverProp1.put(ADSContext.ServerProperty.INSTANCE_PATH, "/tmp/jvl1");
- server1.setAdsProperties(serverProp1);
-
- ServerDescriptor server2 = new ServerDescriptor();
- Map<ADSContext.ServerProperty, Object> serverProp2 =
- new HashMap<ADSContext.ServerProperty, Object>();
- serverProp2.put(ADSContext.ServerProperty.HOSTNAME, "skalariak.france");
- serverProp2.put(ADSContext.ServerProperty.PORT, "389");
- serverProp2.put(ADSContext.ServerProperty.SECURE_PORT, "689");
- serverProp2.put(ADSContext.ServerProperty.LDAP_ENABLED, "false");
- serverProp2.put(ADSContext.ServerProperty.LDAPS_ENABLED, "true");
- serverProp2.put(ADSContext.ServerProperty.INSTANCE_PATH, "/tmp/jvl2");
- server2.setAdsProperties(serverProp2);
-
- SuffixDescriptor suffix1 = new SuffixDescriptor();
- suffix1.setDN("dc=example,dc=com");
- Set<ReplicaDescriptor> replicas1 = new HashSet<ReplicaDescriptor>();
-
- SuffixDescriptor suffix2 = new SuffixDescriptor();
- suffix2.setDN("dc=for real,dc=com");
- Set<ReplicaDescriptor> replicas2 = new HashSet<ReplicaDescriptor>();
-
- SuffixDescriptor suffix3 = new SuffixDescriptor();
- suffix3.setDN("dc=s3,dc=com");
- Set<ReplicaDescriptor> replicas3 = new HashSet<ReplicaDescriptor>();
-
- SuffixDescriptor suffix4 = new SuffixDescriptor();
- suffix4.setDN("dc=s4,dc=com");
- Set<ReplicaDescriptor> replicas4 = new HashSet<ReplicaDescriptor>();
-
-
- ReplicaDescriptor replica1 = new ReplicaDescriptor();
- replica1.setSuffix(suffix1);
- replica1.setServer(server1);
- replica1.setEntries(1002);
- replicas1.add(replica1);
-
- ReplicaDescriptor replica2 = new ReplicaDescriptor();
- replica2.setSuffix(suffix1);
- replica2.setServer(server2);
- replica2.setEntries(1003);
- replicas1.add(replica2);
-
- suffix1.setReplicas(replicas1);
-
- ReplicaDescriptor replica3 = new ReplicaDescriptor();
- replica3.setSuffix(suffix2);
- replica3.setServer(server2);
- replicas2.add(replica3);
-
- suffix2.setReplicas(replicas2);
-
- ReplicaDescriptor replica5 = new ReplicaDescriptor();
- replica5.setSuffix(suffix3);
- replica5.setServer(server1);
- replica5.setEntries(1003);
- replicas3.add(replica5);
-
- ReplicaDescriptor replica6 = new ReplicaDescriptor();
- replica6.setSuffix(suffix3);
- replica6.setServer(server2);
- replica6.setEntries(1003);
- replicas3.add(replica6);
-
- suffix3.setReplicas(replicas3);
-
- ReplicaDescriptor replica7 = new ReplicaDescriptor();
- replica7.setSuffix(suffix4);
- replica7.setServer(server1);
- replica7.setEntries(1003);
- replicas4.add(replica7);
-
- ReplicaDescriptor replica8 = new ReplicaDescriptor();
- replica8.setSuffix(suffix3);
- replica8.setServer(server2);
- replica8.setEntries(1003);
- replicas4.add(replica8);
-
- suffix4.setReplicas(replicas4);
- */
- Set<SuffixDescriptor> suffixes = new HashSet<SuffixDescriptor>();
- /*
- suffixes.add(suffix1);
- suffixes.add(suffix2);
- suffixes.add(suffix3);
- suffixes.add(suffix4);
-*/
- //suffixes.clear();
-
- return suffixes;
+ new SuffixesToReplicateOptions(type, suffixes, suf.getSuffixes()));
}
/**
@@ -2441,9 +3396,9 @@
* Returns the Subject DN to be used to generate the self-signed certificate.
* @return the Subject DN to be used to generate the self-signed certificate.
*/
- private String getSelfSignedCertificateSubjectDN(SecurityOptions sec)
+ private String getSelfSignedCertificateSubjectDN()
{
- return "cn="+Rdn.escapeValue(sec.getSelfSignedCertificateName())+
+ return "cn="+Rdn.escapeValue(getUserData().getHostName())+
",O=OpenDS Self-Signed Certificate";
}
@@ -2522,6 +3477,385 @@
return generatedChar;
}
+ private boolean isCertificateException(Throwable t)
+ {
+ return Utils.isCertificateException(t);
+ }
+
+ private String getStringRepresentation(TopologyCacheException e)
+ {
+ StringBuilder buf = new StringBuilder();
+
+ String ldapUrl = e.getLdapUrl();
+ if (ldapUrl != null)
+ {
+ String hostName = ldapUrl.substring(ldapUrl.indexOf("://") + 3);
+ buf.append(getMsg("server-error", hostName) + " ");
+ }
+ if (e.getCause() instanceof NamingException)
+ {
+ buf.append(getThrowableMsg("bug-msg", null, e.getCause()));
+ }
+ else
+ {
+ // This is unexpected.
+ buf.append(getThrowableMsg("bug-msg", null, e.getCause()));
+ }
+ return buf.toString();
+ }
+
+ private Map<ServerDescriptor, Integer> getRemoteWithNoReplicationPort(
+ UserData userData)
+ {
+ Map<ServerDescriptor, Integer> servers =
+ new HashMap<ServerDescriptor, Integer>();
+ Set<SuffixDescriptor> suffixes =
+ userData.getSuffixesToReplicateOptions().getSuffixes();
+ for (SuffixDescriptor suffix : suffixes)
+ {
+ for (ReplicaDescriptor replica : suffix.getReplicas())
+ {
+ ServerDescriptor server = replica.getServer();
+ Object v = server.getServerProperties().get(
+ ServerDescriptor.ServerProperty.IS_REPLICATION_SERVER);
+ if (!Boolean.TRUE.equals(v))
+ {
+ servers.put(server, 8989);
+ }
+ }
+ }
+ return servers;
+ }
+
+ private InitialLdapContext createLocalContext() throws NamingException
+ {
+ String ldapUrl = "ldap://"+getUserData().getHostName()+":"+
+ getUserData().getServerPort();
+ String dn = getUserData().getDirectoryManagerDn();
+ String pwd = getUserData().getDirectoryManagerPwd();
+ return Utils.createLdapContext(ldapUrl, dn, pwd,
+ Utils.getDefaultLDAPTimeout(), null);
+ }
+ private void createLocalAds(InitialLdapContext ctx)
+ throws ApplicationException, ADSContextException
+ {
+ try
+ {
+ ADSContext adsContext = new ADSContext(ctx);
+ adsContext.createAdminData();
+ adsContext.registerServer(getNewServerAdsProperties());
+ if (getUserData().mustCreateAdministrator())
+ {
+ adsContext.createAdministrator(getAdministratorProperties());
+ }
+ }
+ catch (ADSContextException ace)
+ {
+ throw ace;
+ }
+ catch (Throwable t)
+ {
+ String failedMsg = getThrowableMsg("bug-msg", null, t);
+ throw new ApplicationException(
+ ApplicationException.Type.CONFIGURATION_ERROR, failedMsg, t);
+ }
+ }
+
+ private InitialLdapContext getRemoteConnection(ServerDescriptor server,
+ ApplicationTrustManager trustManager) throws ApplicationException
+ {
+ Map<ADSContext.ServerProperty, Object> adsProperties;
+ AuthenticationData auth =
+ getUserData().getReplicationOptions().getAuthenticationData();
+ if (!server.isRegistered())
+ {
+ /* Create adsProperties to be able to use the class ServerLoader to
+ * get the connection. Just update the connection parameters with what
+ * the user chose in the Topology Options panel (i.e. even if SSL
+ * is enabled on the remote server, use standard LDAP to connect to the
+ * server if the user specified the LDAP port: this avoids having an
+ * issue with the certificate if it has not been accepted previously
+ * by the user).
+ */
+ adsProperties = new HashMap<ADSContext.ServerProperty, Object>();
+ adsProperties.put(ADSContext.ServerProperty.HOST_NAME,
+ server.getHostName());
+ if (auth.useSecureConnection())
+ {
+ adsProperties.put(ADSContext.ServerProperty.LDAPS_PORT,
+ String.valueOf(auth.getPort()));
+ adsProperties.put(ADSContext.ServerProperty.LDAPS_ENABLED, "true");
+ }
+ else
+ {
+ adsProperties.put(ADSContext.ServerProperty.LDAP_PORT,
+ String.valueOf(auth.getPort()));
+ adsProperties.put(ADSContext.ServerProperty.LDAP_ENABLED, "true");
+ }
+ }
+ else
+ {
+ adsProperties = server.getAdsProperties();
+ }
+
+ ServerLoader loader = new ServerLoader(adsProperties, auth.getDn(),
+ auth.getPwd(), trustManager);
+
+ InitialLdapContext ctx = null;
+ try
+ {
+ ctx = loader.createContext();
+ }
+ catch (NamingException ne)
+ {
+ System.out.println("dn: "+auth.getDn());
+ System.out.println("dn: "+auth.getDn());
+
+ String errorMessage = getMsg("cannot-connect-to-remote-generic",
+ server.getHostPort(true), ne.toString(true));
+ throw new ApplicationException(
+ ApplicationException.Type.CONFIGURATION_ERROR, errorMessage, ne);
+ }
+ return ctx;
+ }
+
+ private void initializeSuffix(InitialLdapContext ctx, int replicaId,
+ String suffixDn, boolean displayProgress, String sourceServerDisplay)
+ throws ApplicationException, PeerNotFoundException
+ {
+ boolean taskCreated = false;
+ int i = 1;
+ boolean isOver = false;
+ String dn = null;
+ BasicAttributes attrs = new BasicAttributes();
+ Attribute oc = new BasicAttribute("objectclass");
+ oc.add("top");
+ oc.add("ds-task");
+ oc.add("ds-task-initialize-from-remote-replica");
+ attrs.put(oc);
+ attrs.put("ds-task-class-name", "org.opends.server.tasks.InitializeTask");
+ attrs.put("ds-task-initialize-domain-dn", suffixDn);
+ attrs.put("ds-task-initialize-replica-server-id",
+ String.valueOf(replicaId));
+ while (!taskCreated)
+ {
+ String id = "quicksetup-initialize"+i;
+ dn = "ds-task-id="+id+",cn=Scheduled Tasks,cn=Tasks";
+ attrs.put("ds-task-id", id);
+ try
+ {
+ DirContext dirCtx = ctx.createSubcontext(dn, attrs);
+ taskCreated = true;
+ LOG.log(Level.INFO, "created task entry: "+attrs);
+ dirCtx.close();
+ }
+ catch (NameAlreadyBoundException x)
+ {
+ }
+ catch (NamingException ne)
+ {
+ LOG.log(Level.SEVERE, "Error creating task "+attrs, ne);
+ String[] arg = {sourceServerDisplay};
+ throw new ApplicationException(ApplicationException.Type.APPLICATION,
+ getThrowableMsg("error-launching-initialization", arg, ne), ne);
+ }
+ i++;
+ }
+ // Wait until it is over
+ SearchControls searchControls = new SearchControls();
+ searchControls.setCountLimit(1);
+ searchControls.setSearchScope(
+ SearchControls. OBJECT_SCOPE);
+ String filter = "objectclass=*";
+ searchControls.setReturningAttributes(
+ new String[] {
+ "ds-task-unprocessed-entry-count",
+ "ds-task-processed-entry-count",
+ "ds-task-log-message",
+ "ds-task-state"
+ });
+ String lastDisplayedMsg = null;
+ String lastLogMsg = null;
+ long lastTimeMsgDisplayed = -1;
+ int totalEntries = 0;
+ while (!isOver)
+ {
+ try
+ {
+ Thread.sleep(500);
+ }
+ catch (Throwable t)
+ {
+ }
+ try
+ {
+ NamingEnumeration res = ctx.search(dn, filter, searchControls);
+ SearchResult sr = (SearchResult)res.next();
+ if (displayProgress)
+ {
+ // Display the number of entries that have been handled and
+ // a percentage...
+ String msg;
+ String sProcessed = getFirstValue(sr,
+ "ds-task-processed-entry-count");
+ String sUnprocessed = getFirstValue(sr,
+ "ds-task-unprocessed-entry-count");
+ int processed = -1;
+ int unprocessed = -1;
+ if (sProcessed != null)
+ {
+ processed = Integer.parseInt(sProcessed);
+ }
+ if (sUnprocessed != null)
+ {
+ unprocessed = Integer.parseInt(sUnprocessed);
+ }
+ totalEntries = Math.max(totalEntries, processed+unprocessed);
+
+ if ((processed != -1) && (unprocessed != -1))
+ {
+ if (processed + unprocessed > 0)
+ {
+ int perc = (100 * processed) / (processed + unprocessed);
+ msg = getMsg("initialize-progress-with-percentage", sProcessed,
+ String.valueOf(perc));
+ }
+ else
+ {
+ //msg = getMsg("no-entries-to-initialize");
+ msg = null;
+ }
+ }
+ else if (processed != -1)
+ {
+ msg = getMsg("initialize-progress-with-processed", sProcessed);
+ }
+ else if (unprocessed != -1)
+ {
+ msg = getMsg("initialize-progress-with-unprocessed",
+ sUnprocessed);
+ }
+ else
+ {
+ msg = lastDisplayedMsg;
+ }
+
+ if (msg != null)
+ {
+ long currentTime = System.currentTimeMillis();
+ /* Refresh period: to avoid having too many lines in the log */
+ long minRefreshPeriod;
+ if (totalEntries < 100)
+ {
+ minRefreshPeriod = 0;
+ }
+ else if (totalEntries < 1000)
+ {
+ minRefreshPeriod = 1000;
+ }
+ else if (totalEntries < 10000)
+ {
+ minRefreshPeriod = 5000;
+ }
+ else
+ {
+ minRefreshPeriod = 10000;
+ }
+ if (!msg.equals(lastDisplayedMsg) &&
+ ((currentTime - minRefreshPeriod) > lastTimeMsgDisplayed))
+ {
+ notifyListeners(getFormattedProgress(msg));
+ lastDisplayedMsg = msg;
+ notifyListeners(getLineBreak());
+ lastTimeMsgDisplayed = currentTime;
+ }
+ }
+ }
+ String logMsg = getFirstValue(sr, "ds-task-log-message");
+ if (logMsg != null)
+ {
+ if (!logMsg.equals(lastLogMsg))
+ {
+ LOG.log(Level.INFO, logMsg);
+ lastLogMsg = logMsg;
+ }
+ }
+ InstallerHelper helper = new InstallerHelper();
+ String state = getFirstValue(sr, "ds-task-state");
+
+ if (helper.isDone(state) || helper.isStoppedByError(state))
+ {
+ isOver = true;
+ String errorMsg;
+ if (lastLogMsg == null)
+ {
+ errorMsg = getMsg("error-during-initialization-no-log",
+ sourceServerDisplay);
+ }
+ else
+ {
+ errorMsg = getMsg("error-during-initialization-log",
+ sourceServerDisplay, lastLogMsg);
+ }
+
+ if (helper.isCompletedWithErrors(state))
+ {
+ notifyListeners(getFormattedWarning(errorMsg));
+ }
+ else if (!helper.isSuccessful(state) ||
+ helper.isStoppedByError(state))
+ {
+ ApplicationException ae = new ApplicationException(
+ ApplicationException.Type.APPLICATION, errorMsg, null);
+ if ((lastLogMsg != null) &&
+ helper.isPeersNotFoundError(lastLogMsg))
+ {
+ throw new PeerNotFoundException(errorMsg);
+ }
+ else
+ {
+ throw ae;
+ }
+ }
+ else if (displayProgress)
+ {
+ notifyListeners(getFormattedProgress(
+ getMsg("suffix-initialized-successfully")));
+ }
+ }
+ }
+ catch (NameNotFoundException x)
+ {
+ isOver = true;
+ notifyListeners(getFormattedProgress(
+ getMsg("suffix-initialized-successfully")));
+ }
+ catch (NamingException ne)
+ {
+ String[] arg = {sourceServerDisplay};
+ throw new ApplicationException(ApplicationException.Type.APPLICATION,
+ getThrowableMsg("error-pooling-initialization", arg, ne), ne);
+ }
+ }
+ }
+
+ private String getFirstValue(SearchResult entry, String attrName)
+ throws NamingException
+ {
+ return Utils.getFirstValue(entry, attrName);
+ }
+
+ private String getLocalReplicationServer()
+ {
+ return getUserData().getHostName()+":"+
+ getUserData().getReplicationOptions().getReplicationPort();
+ }
+
+ private String getLocalHostPort()
+ {
+ return getUserData().getHostName()+":"+getUserData().getServerPort();
+ }
+
private static int getRandomInt(Random random,int modulo)
{
int value = 0;
@@ -2529,3 +3863,22 @@
return value;
}
}
+
+/**
+ * The exception that is thrown during initialization if the peer specified
+ * could not be found.
+ *
+ */
+class PeerNotFoundException extends Exception
+{
+ private static final long serialVersionUID = -362726764261560341L;
+
+ /**
+ * The constructor for the exception.
+ * @param localizedMsg the localized message.
+ */
+ PeerNotFoundException(String localizedMsg)
+ {
+ super(localizedMsg);
+ }
+}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java
index 15ab091..7ee27c9 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java
@@ -29,26 +29,67 @@
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.naming.ldap.InitialLdapContext;
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.webstart.JnlpProperties;
import org.opends.quicksetup.util.Utils;
+import org.opends.server.admin.DefaultBehaviorException;
+import org.opends.server.admin.ManagedObjectNotFoundException;
+import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.client.ldap.LDAPManagementContext;
+import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
+import org.opends.server.admin.std.client.*;
+import org.opends.server.admin.std.meta.*;
+import org.opends.server.backends.task.TaskState;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.extensions.ConfigFileHandler;
+import org.opends.server.messages.CoreMessages;
+import org.opends.server.messages.ReplicationMessages;
+import org.opends.server.tools.ConfigureDS;
+import org.opends.server.tools.ConfigureWindowsService;
+import org.opends.server.tools.ImportLDIF;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.AttributeValue;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.Entry;
+import org.opends.server.types.ExistingFileBehavior;
+import org.opends.server.types.LDIFExportConfig;
+import org.opends.server.types.ObjectClass;
+import org.opends.server.util.LDIFException;
+import org.opends.server.util.LDIFWriter;
+import org.opends.server.util.StaticUtils;
/**
* This is the only class that uses classes in org.opends.server (excluding the
- * case of org.opends.server.util.DynamicConstants and
- * org.opends.server.util.SetupUtils which are already included in
- * quicksetup.jar).
+ * case of DynamicConstants, SetupUtils, OperatingSystem and CertificateManager
+ * which are already included in quicksetup.jar).
*
- * Important note: do not include references to the classes in package
- * org.opends.server in the import. These classes must be loaded during
- * Runtime.
+ * Important note: do not include references to this class until OpenDS.jar has
+ * been loaded. These classes must be loaded during Runtime.
* The code is written in a way that when we execute the code that uses these
* classes the required jar files are already loaded. However these jar files
* are not necessarily loaded when we create this class.
*/
public class InstallerHelper implements JnlpProperties {
+ private static final Logger LOG = Logger.getLogger(
+ InstallerHelper.class.getName());
+
+ private static final int MAX_ID_VALUE = Short.MAX_VALUE;
+ private static final String DOMAIN_BASE_NAME = "domain ";
/**
* Invokes the method ConfigureDS.configMain with the provided parameters.
@@ -58,7 +99,7 @@
* @see org.opends.server.tools.ConfigureDS#configMain(String[]).
*/
public int invokeConfigureServer(String[] args) throws ApplicationException {
- return org.opends.server.tools.ConfigureDS.configMain(args);
+ return ConfigureDS.configMain(args);
}
/**
@@ -69,7 +110,7 @@
* @see org.opends.server.tools.ImportLDIF#mainImportLDIF(String[]).
*/
public int invokeImportLDIF(String[] args) throws ApplicationException {
- return org.opends.server.tools.ImportLDIF.mainImportLDIF(args);
+ return ImportLDIF.mainImportLDIF(args);
}
/**
@@ -78,8 +119,7 @@
*/
public String getStartedId()
{
- return String.valueOf(org.opends.server.messages.CoreMessages.
- MSGID_DIRECTORY_SERVER_STARTED);
+ return String.valueOf(CoreMessages.MSGID_DIRECTORY_SERVER_STARTED);
}
/**
@@ -87,18 +127,16 @@
* @throws ApplicationException if something goes wrong.
*/
public void enableWindowsService() throws ApplicationException {
- int code = org.opends.server.tools.ConfigureWindowsService.enableService(
- System.out, System.err);
+ int code = ConfigureWindowsService.enableService(System.out, System.err);
- String errorMessage = ResourceProvider.getInstance().getMsg(
- "error-enabling-windows-service");
+ String errorMessage = getMsg("error-enabling-windows-service");
switch (code) {
case
- org.opends.server.tools.ConfigureWindowsService.SERVICE_ENABLE_SUCCESS:
+ ConfigureWindowsService.SERVICE_ENABLE_SUCCESS:
break;
case
- org.opends.server.tools.ConfigureWindowsService.SERVICE_ALREADY_ENABLED:
+ ConfigureWindowsService.SERVICE_ALREADY_ENABLED:
break;
default:
throw new ApplicationException(
@@ -141,26 +179,21 @@
try
{
- org.opends.server.types.LDIFExportConfig exportConfig =
- new org.opends.server.types.LDIFExportConfig(ldifFile
- .getAbsolutePath(),
- org.opends.server.types.ExistingFileBehavior.OVERWRITE);
+ LDIFExportConfig exportConfig = new LDIFExportConfig(
+ ldifFile.getAbsolutePath(), ExistingFileBehavior.OVERWRITE);
- org.opends.server.util.LDIFWriter writer =
- new org.opends.server.util.LDIFWriter(exportConfig);
+ LDIFWriter writer = new LDIFWriter(exportConfig);
- org.opends.server.types.DN dn =
- org.opends.server.types.DN.decode(baseDn);
- org.opends.server.types.Entry entry =
- org.opends.server.util.StaticUtils.createEntry(dn);
+ DN dn = DN.decode(baseDn);
+ Entry entry = StaticUtils.createEntry(dn);
writer.writeEntry(entry);
writer.close();
- } catch (org.opends.server.types.DirectoryException de) {
+ } catch (DirectoryException de) {
throw new ApplicationException(
ApplicationException.Type.CONFIGURATION_ERROR,
getThrowableMsg("error-importing-ldif", null, de), de);
- } catch (org.opends.server.util.LDIFException le) {
+ } catch (LDIFException le) {
throw new ApplicationException(
ApplicationException.Type.CONFIGURATION_ERROR,
getThrowableMsg("error-importing-ldif", null, le), le);
@@ -175,4 +208,357 @@
}
return ldifFile;
}
+
+ /**
+ * Configures the replication on a given server.
+ * @param remoteCtx the conection to the server where we want to configure
+ * the replication.
+ * @param dns the suffix base dns for which we want to configure the
+ * replication.
+ * @param replicationServers a Map where the key value is the base dn and
+ * the value is the list of replication servers for that base dn (or domain).
+ * @param replicationPort the replicationPort of the server that is being
+ * configured (it might not exist and the user specified it in the setup).
+ * @param serverDisplay the server display.
+ * @param usedReplicationServerIds the list of replication server ids that
+ * are already used.
+ * @param usedServerIds the list of server ids (domain ids) that
+ * are already used.
+ * @throws ApplicationException if something goes wrong.
+ */
+ public void configureReplication(InitialLdapContext remoteCtx,
+ Set<String> dns, Map<String,Set<String>> replicationServers,
+ int replicationPort, String serverDisplay,
+ Set<Integer> usedReplicationServerIds, Set<Integer> usedServerIds)
+ throws ApplicationException
+ {
+ try
+ {
+ ManagementContext mCtx = LDAPManagementContext.createFromContext(
+ JNDIDirContextAdaptor.adapt(remoteCtx));
+ RootCfgClient root = mCtx.getRootConfiguration();
+
+ /*
+ * Configure Synchronization plugin.
+ */
+ MultimasterSynchronizationProviderCfgClient sync = null;
+ try
+ {
+ sync = (MultimasterSynchronizationProviderCfgClient)
+ root.getSynchronizationProvider("Multimaster Synchronization");
+ }
+ catch (ManagedObjectNotFoundException monfe)
+ {
+ // It does not exist.
+ }
+ if (sync == null)
+ {
+ MultimasterSynchronizationProviderCfgDefn provider =
+ MultimasterSynchronizationProviderCfgDefn.getInstance();
+ sync = root.createSynchronizationProvider(provider,
+ "Multimaster Synchronization",
+ new ArrayList<DefaultBehaviorException>());
+ sync.setJavaImplementationClass(
+ "org.opends.server.replication.plugin.MultimasterReplication");
+ }
+ sync.setEnabled(Boolean.TRUE);
+ sync.commit();
+
+ /*
+ * Configure the replication server.
+ */
+ ReplicationServerCfgClient replicationServer = null;
+
+ if (!sync.hasReplicationServer())
+ {
+ int id = getReplicationId(usedReplicationServerIds);
+ usedReplicationServerIds.add(id);
+ replicationServer = sync.createReplicationServer(
+ ReplicationServerCfgDefn.getInstance(),
+ new ArrayList<DefaultBehaviorException>());
+ replicationServer.setReplicationServerId(id);
+ replicationServer.setReplicationPort(replicationPort);
+ }
+ else
+ {
+ replicationServer = sync.getReplicationServer();
+ usedReplicationServerIds.add(
+ replicationServer.getReplicationServerId());
+ }
+
+ Set<String> servers = replicationServer.getReplicationServer();
+ if (servers == null)
+ {
+ servers = new HashSet<String>();
+ }
+ for (Set<String> rs : replicationServers.values())
+ {
+ servers.addAll(rs);
+ }
+
+ replicationServer.setReplicationServer(servers);
+
+ replicationServer.commit();
+
+ /*
+ * Create the domains
+ */
+ String[] domainNames = sync.listMultimasterDomains();
+ if (domainNames == null)
+ {
+ domainNames = new String[]{};
+ }
+ MultimasterDomainCfgClient[] domains =
+ new MultimasterDomainCfgClient[domainNames.length];
+ for (int i=0; i<domains.length; i++)
+ {
+ domains[i] = sync.getMultimasterDomain(domainNames[i]);
+ }
+ for (String dn : dns)
+ {
+ MultimasterDomainCfgClient domain = null;
+ for (int i=0; i<domains.length && (domain == null); i++)
+ {
+ if (Utils.areDnsEqual(dn,
+ domains[i].getReplicationDN().toString()))
+ {
+ domain = domains[i];
+ }
+ }
+ if (domain == null)
+ {
+ int domainId = getReplicationId(usedServerIds);
+ usedServerIds.add(domainId);
+ String domainName = getDomainName(domainNames, domainId);
+ domain = sync.createMultimasterDomain(
+ MultimasterDomainCfgDefn.getInstance(), domainName,
+ new ArrayList<DefaultBehaviorException>());
+ domain.setServerId(domainId);
+ domain.setReplicationDN(DN.decode(dn));
+ }
+ domain.setReplicationServer(replicationServers.get(dn));
+ usedServerIds.add(domain.getServerId());
+
+ domain.commit();
+ }
+ }
+ catch (Throwable t)
+ {
+ String errorMessage = getMsg("error-configuring-remote-generic",
+ serverDisplay, t.toString());
+ throw new ApplicationException(
+ ApplicationException.Type.CONFIGURATION_ERROR, errorMessage, t);
+ }
+ }
+
+ /**
+ * For the given state provided by a Task tells if the task is done or not.
+ * @param sState the String representing the task state.
+ * @return <CODE>true</CODE> if the task is done and <CODE>false</CODE>
+ * otherwise.
+ */
+ public boolean isDone(String sState)
+ {
+ TaskState state = TaskState.fromString(sState);
+ return TaskState.isDone(state);
+ }
+
+ /**
+ * For the given state provided by a Task tells if the task is successful or
+ * not.
+ * @param sState the String representing the task state.
+ * @return <CODE>true</CODE> if the task is successful and <CODE>false</CODE>
+ * otherwise.
+ */
+ public boolean isSuccessful(String sState)
+ {
+ TaskState state = TaskState.fromString(sState);
+ return TaskState.isSuccessful(state);
+ }
+
+ /**
+ * For the given state provided by a Task tells if the task is complete with
+ * errors or not.
+ * @param sState the String representing the task state.
+ * @return <CODE>true</CODE> if the task is complete with errors and
+ * <CODE>false</CODE> otherwise.
+ */
+ public boolean isCompletedWithErrors(String sState)
+ {
+ TaskState state = TaskState.fromString(sState);
+ return state == TaskState.COMPLETED_WITH_ERRORS;
+ }
+
+ /**
+ * For the given state provided by a Task tells if the task is stopped by
+ * error or not.
+ * @param sState the String representing the task state.
+ * @return <CODE>true</CODE> if the task is stopped by error and
+ * <CODE>false</CODE> otherwise.
+ */
+ public boolean isStoppedByError(String sState)
+ {
+ TaskState state = TaskState.fromString(sState);
+ return state == TaskState.STOPPED_BY_ERROR;
+ }
+
+ /**
+ * Tells whether the provided log message corresponds to a peers not found
+ * error during the initialization of a replica or not.
+ * @param logMsg the log message.
+ * @return <CODE>true</CODE> if the log message corresponds to a peers not
+ * found error during initialization and <CODE>false</CODE> otherwise.
+ */
+ public boolean isPeersNotFoundError(String logMsg)
+ {
+ return logMsg.indexOf(
+ "="+ReplicationMessages.MSGID_NO_REACHABLE_PEER_IN_THE_DOMAIN) != -1;
+ }
+ private void addConfigEntry(ConfigFileHandler configFileHandler, DN dn,
+ String[] ocs, String[] attributeNames, String[][] attributeValues)
+ throws DirectoryException
+ {
+ HashMap<ObjectClass,String> objectClasses =
+ new HashMap<ObjectClass,String>();
+ HashMap<AttributeType,List<Attribute>> userAttributes =
+ new HashMap<AttributeType,List<Attribute>>();
+ HashMap<AttributeType,List<Attribute>> operationalAttributes =
+ new HashMap<AttributeType,List<Attribute>>();
+
+ for (int j=0; j<ocs.length; j++)
+ {
+ String ocName = ocs[j];
+ ObjectClass objectClass = DirectoryServer.getObjectClass(ocName);
+ if (objectClass == null)
+ {
+ objectClass = DirectoryServer.getDefaultObjectClass(ocName);
+ }
+ objectClasses.put(objectClass, ocName);
+ }
+ for (int j=0; j<attributeNames.length; j++)
+ {
+ String attrName = attributeNames[j];
+ AttributeType attrType = DirectoryServer.getAttributeType(attrName);
+ if (attrType == null)
+ {
+ attrType = DirectoryServer.getDefaultAttributeType(attrName);
+ }
+ String[] attrValues = attributeValues[j];
+ LinkedHashSet<AttributeValue> valueSet =
+ new LinkedHashSet<AttributeValue>();
+ for (int k=0; k<attrValues.length; k++)
+ {
+ AttributeValue attributeValue = new AttributeValue(attrType,
+ attrValues[k]);
+ valueSet.add(attributeValue);
+ }
+ ArrayList<Attribute> attrList = new ArrayList<Attribute>();
+ attrList.add(new Attribute(attrType, attrName, null, valueSet));
+ userAttributes.put(attrType, attrList);
+ }
+ Entry entry = new Entry(dn, objectClasses, userAttributes,
+ operationalAttributes);
+ configFileHandler.addEntry(entry, null);
+ }
+
+ private int getReplicationId(Set<Integer> usedIds)
+ {
+ Random r = new Random();
+ int id = 0;
+ while ((id == 0) || usedIds.contains(id))
+ {
+ id = r.nextInt(MAX_ID_VALUE);
+ }
+ return id;
+ }
+
+ private String getMsg(String key, String ... args)
+ {
+ return ResourceProvider.getInstance().getMsg(key, args);
+ }
+
+ private String getDomainName(String[] existingDomains, int newDomainId)
+ {
+ String domainName = DOMAIN_BASE_NAME+newDomainId;
+ boolean nameExists = true;
+ int j = 0;
+ while (nameExists)
+ {
+ boolean found = false;
+ for (int i=0; i<existingDomains.length && !found; i++)
+ {
+ found = existingDomains[i].equalsIgnoreCase(domainName);
+ }
+ if (found)
+ {
+ domainName = DOMAIN_BASE_NAME+newDomainId+"-"+j;
+ }
+ else
+ {
+ nameExists = false;
+ }
+ j++;
+ }
+ return domainName;
+ }
}
+
+/**
+ * A class describing a replication domain.
+ *
+ */
+class DomainEntry
+{
+ private String name;
+ private int replicationId;
+ private String baseDn;
+ private Set<String> replicationServers;
+ /**
+ * The constructor of the domain entry.
+ * @param name the name of the domain.
+ * @param replicationId the replicationId of the domain.
+ * @param baseDn the base dn of the domain.
+ * @param replicationServers the list of replication servers for the domain.
+ */
+ public DomainEntry(String name, int replicationId, String baseDn,
+ Set<String> replicationServers)
+ {
+ this.name = name;
+ this.replicationId = replicationId;
+ this.baseDn = baseDn;
+ this.replicationServers = replicationServers;
+ }
+ /**
+ * Returns the base dn of the domain.
+ * @return the base dn of the domain.
+ */
+ public String getBaseDn()
+ {
+ return baseDn;
+ }
+ /**
+ * Returns the name of the domain.
+ * @return the name of the domain.
+ */
+ public String getName()
+ {
+ return name;
+ }
+ /**
+ * Returns the replication Id of the domain.
+ * @return the replication Id of the domain.
+ */
+ public int getReplicationId()
+ {
+ return replicationId;
+ }
+ /**
+ * Returns the list of replication servers of the domain.
+ * @return the list of replication servers of the domain.
+ */
+ public Set<String> getReplicationServers()
+ {
+ return replicationServers;
+ }
+}
+
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
index bcee79c..cf2dc2f 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
@@ -30,6 +30,8 @@
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.ProgressStep;
@@ -62,6 +64,8 @@
private HashMap<InstallProgressStep, String> hmSummary =
new HashMap<InstallProgressStep, String>();
+ private static final Logger LOG =
+ Logger.getLogger(OfflineInstaller.class.getName());
/**
* Actually performs the install in this thread. The thread is blocked.
*
@@ -84,8 +88,6 @@
createData();
- updateADS();
-
writeJavaHome();
if (Utils.isWindows())
@@ -95,29 +97,64 @@
enableWindowsService();
}
- if (getUserData().getStartServer())
+ if (mustStart())
{
notifyListeners(getTaskSeparator());
setStatus(InstallProgressStep.STARTING_SERVER);
new ServerController(this).startServer();
}
+ if (mustConfigureReplication())
+ {
+ setStatus(InstallProgressStep.CONFIGURING_REPLICATION);
+ notifyListeners(getTaskSeparator());
+
+ configureReplication();
+ }
+
+ if (mustInitializeSuffixes())
+ {
+ notifyListeners(getTaskSeparator());
+ setStatus(InstallProgressStep.INITIALIZE_REPLICATED_SUFFIXES);
+ initializeSuffixes();
+ }
+
+ if (mustCreateAds())
+ {
+ notifyListeners(getTaskSeparator());
+ setStatus(InstallProgressStep.CONFIGURING_ADS);
+ updateADS();
+ }
+
+ if (mustStop())
+ {
+ notifyListeners(getTaskSeparator());
+ setStatus(InstallProgressStep.STOPPING_SERVER);
+ new ServerController(this).stopServer();
+ }
+
setStatus(InstallProgressStep.FINISHED_SUCCESSFULLY);
notifyListeners(null);
} catch (ApplicationException ex)
{
+ notifyListeners(getLineBreak());
+ notifyListenersOfLog();
setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
String html = getFormattedError(ex, true);
notifyListeners(html);
+ LOG.log(Level.SEVERE, "Error installing.", ex);
}
catch (Throwable t)
{
+ notifyListeners(getLineBreak());
+ notifyListenersOfLog();
setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
ApplicationException ex = new ApplicationException(
ApplicationException.Type.BUG, getThrowableMsg("bug-msg", t), t);
String msg = getFormattedError(ex, true);
notifyListeners(msg);
+ LOG.log(Level.SEVERE, "Error installing.", t);
}
System.setErr(origErr);
System.setOut(origOut);
@@ -158,43 +195,76 @@
hmTime.put(InstallProgressStep.CONFIGURING_SERVER, 5);
hmTime.put(InstallProgressStep.CREATING_BASE_ENTRY, 10);
hmTime.put(InstallProgressStep.IMPORTING_LDIF, 20);
- hmTime.put(InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED,
- 20);
+ hmTime.put(InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED, 20);
+ hmTime.put(InstallProgressStep.CONFIGURING_REPLICATION, 10);
hmTime.put(InstallProgressStep.ENABLING_WINDOWS_SERVICE, 5);
hmTime.put(InstallProgressStep.STARTING_SERVER, 10);
+ hmTime.put(InstallProgressStep.STOPPING_SERVER, 5);
+ hmTime.put(InstallProgressStep.CONFIGURING_ADS, 5);
+ hmTime.put(InstallProgressStep.INITIALIZE_REPLICATED_SUFFIXES, 25);
int totalTime = 0;
ArrayList<InstallProgressStep> steps =
new ArrayList<InstallProgressStep>();
totalTime += hmTime.get(InstallProgressStep.CONFIGURING_SERVER);
steps.add(InstallProgressStep.CONFIGURING_SERVER);
- switch (getUserData().getNewSuffixOptions().getType())
+ if (createNotReplicatedSuffix())
{
- case CREATE_BASE_ENTRY:
- steps.add(InstallProgressStep.CREATING_BASE_ENTRY);
- totalTime += hmTime.get(InstallProgressStep.CREATING_BASE_ENTRY);
- break;
- case IMPORT_FROM_LDIF_FILE:
- steps.add(InstallProgressStep.IMPORTING_LDIF);
- totalTime += hmTime.get(InstallProgressStep.IMPORTING_LDIF);
- break;
- case IMPORT_AUTOMATICALLY_GENERATED_DATA:
- steps.add(InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED);
- totalTime += hmTime.get(
- InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED);
- break;
+ switch (getUserData().getNewSuffixOptions().getType())
+ {
+ case CREATE_BASE_ENTRY:
+ steps.add(InstallProgressStep.CREATING_BASE_ENTRY);
+ totalTime += hmTime.get(InstallProgressStep.CREATING_BASE_ENTRY);
+ break;
+ case IMPORT_FROM_LDIF_FILE:
+ steps.add(InstallProgressStep.IMPORTING_LDIF);
+ totalTime += hmTime.get(InstallProgressStep.IMPORTING_LDIF);
+ break;
+ case IMPORT_AUTOMATICALLY_GENERATED_DATA:
+ steps.add(InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED);
+ totalTime += hmTime.get(
+ InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED);
+ break;
+ }
}
+
if (Utils.isWindows())
{
totalTime += hmTime.get(InstallProgressStep.ENABLING_WINDOWS_SERVICE);
steps.add(InstallProgressStep.ENABLING_WINDOWS_SERVICE);
}
- if (getUserData().getStartServer())
+
+ if (mustStart())
{
totalTime += hmTime.get(InstallProgressStep.STARTING_SERVER);
steps.add(InstallProgressStep.STARTING_SERVER);
}
+ if (mustConfigureReplication())
+ {
+ steps.add(InstallProgressStep.CONFIGURING_REPLICATION);
+ totalTime += hmTime.get(InstallProgressStep.CONFIGURING_REPLICATION);
+ }
+
+ if (mustInitializeSuffixes())
+ {
+ totalTime += hmTime.get(
+ InstallProgressStep.INITIALIZE_REPLICATED_SUFFIXES);
+ steps.add(InstallProgressStep.INITIALIZE_REPLICATED_SUFFIXES);
+ }
+
+ if (mustCreateAds())
+ {
+ totalTime += hmTime.get(InstallProgressStep.CONFIGURING_ADS);
+ steps.add(InstallProgressStep.CONFIGURING_ADS);
+ }
+
+ if (mustStop())
+ {
+ totalTime += hmTime.get(InstallProgressStep.STOPPING_SERVER);
+ steps.add(InstallProgressStep.STOPPING_SERVER);
+ }
+
int cumulatedTime = 0;
for (InstallProgressStep s : steps)
{
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataReplicationPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataReplicationPanel.java
index be58712..c441344 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataReplicationPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataReplicationPanel.java
@@ -68,6 +68,7 @@
private JRadioButton rbStandalone;
private JRadioButton rbReplicated;
private JCheckBox cbTopologyExists;
+ private JCheckBox cbRemoteServerPortSecure;
private HashMap<FieldName, JLabel> hmLabels =
new HashMap<FieldName, JLabel>();
private HashMap<FieldName, JTextComponent> hmFields =
@@ -111,6 +112,17 @@
value = DataReplicationOptions.Type.FIRST_IN_TOPOLOGY;
}
}
+ else if (fieldName == FieldName.REMOTE_SERVER_IS_SECURE_PORT)
+ {
+ if (cbRemoteServerPortSecure.isSelected())
+ {
+ value = Boolean.TRUE;
+ }
+ else
+ {
+ value = Boolean.FALSE;
+ }
+ }
else
{
JTextComponent field = getField(fieldName);
@@ -165,10 +177,31 @@
gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
gbc.insets.left = UIFactory.LEFT_INSET_RADIO_SUBORDINATE;
- panel.add(cbTopologyExists, gbc);
-
JPanel auxPanel = new JPanel(new GridBagLayout());
auxPanel.setOpaque(false);
+ panel.add(auxPanel, gbc);
+ panel.add(cbTopologyExists, gbc);
+ gbc.insets = UIFactory.getEmptyInsets();
+ gbc.gridwidth = 3;
+ gbc.weightx = 0.0;
+ gbc.insets.left = 0;
+ gbc.anchor = GridBagConstraints.WEST;
+ auxPanel.add(getLabel(FieldName.REPLICATION_PORT), gbc);
+
+ gbc.gridwidth = GridBagConstraints.RELATIVE;
+ gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ gbc.weightx = 0.0;
+ auxPanel.add(getField(FieldName.REPLICATION_PORT), gbc);
+
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.insets.left = 0;
+ gbc.weightx = 1.0;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ auxPanel.add(Box.createHorizontalGlue(), gbc);
+
+ auxPanel = new JPanel(new GridBagLayout());
+ auxPanel.setOpaque(false);
gbc.insets.left = 2 * UIFactory.LEFT_INSET_RADIO_SUBORDINATE;
panel.add(auxPanel, gbc);
@@ -200,12 +233,26 @@
JPanel aux2Panel = new JPanel(new GridBagLayout());
aux2Panel.setOpaque(false);
- gbc.gridwidth = GridBagConstraints.RELATIVE;
+
+ if (fields[i] == FieldName.REMOTE_SERVER_PORT)
+ {
+ gbc.gridwidth = 3;
+ }
+ else
+ {
+ gbc.gridwidth = GridBagConstraints.RELATIVE;
+ }
gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 0.0;
aux2Panel.add(getField(fields[i]), gbc);
+ if (fields[i] == FieldName.REMOTE_SERVER_PORT)
+ {
+ gbc.gridwidth = GridBagConstraints.RELATIVE;
+ aux2Panel.add(cbRemoteServerPortSecure, gbc);
+ }
+
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.insets.left = 0;
gbc.weightx = 1.0;
@@ -264,6 +311,10 @@
defaultUserData.getReplicationOptions().getAuthenticationData();
switch (fieldName)
{
+ case REPLICATION_PORT:
+ value = defaultUserData.getReplicationOptions().getReplicationPort();
+ break;
+
case REMOTE_SERVER_DN:
value = auth.getDn();
break;
@@ -324,6 +375,13 @@
HashMap<FieldName, LabelFieldDescriptor> hm =
new HashMap<FieldName, LabelFieldDescriptor>();
+ hm.put(FieldName.REPLICATION_PORT, new LabelFieldDescriptor(
+ getMsg("replication-port-label"),
+ getMsg("replication-port-tooltip"),
+ LabelFieldDescriptor.FieldType.TEXTFIELD,
+ LabelFieldDescriptor.LabelType.SECONDARY,
+ UIFactory.PORT_FIELD_SIZE));
+
hm.put(FieldName.REMOTE_SERVER_DN, new LabelFieldDescriptor(
getMsg("remote-server-dn-label"), getMsg("remote-server-dn-tooltip"),
LabelFieldDescriptor.FieldType.TEXTFIELD,
@@ -392,6 +450,10 @@
DataReplicationOptions.Type.STANDALONE);
cbTopologyExists.setSelected(type ==
DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY);
+ cbRemoteServerPortSecure = UIFactory.makeJCheckBox(
+ getMsg("remote-server-port-is-secure-label"),
+ getMsg("remote-server-port-is-secure-tooltip"),
+ UIFactory.TextStyle.SECONDARY_FIELD_VALID);
checkEnablingState();
}
@@ -449,7 +511,10 @@
if (lastFocusComponent instanceof JTextComponent)
{
rbReplicated.setSelected(true);
- cbTopologyExists.setSelected(true);
+ if (lastFocusComponent != getField(FieldName.REPLICATION_PORT))
+ {
+ cbTopologyExists.setSelected(true);
+ }
}
}
@@ -515,6 +580,9 @@
}
cbTopologyExists.setEnabled(rbReplicated.isSelected());
+ getLabel(FieldName.REPLICATION_PORT).setEnabled(rbReplicated.isSelected());
+ getField(FieldName.REPLICATION_PORT).setEnabled(rbReplicated.isSelected());
+ cbRemoteServerPortSecure.setEnabled(enableFields);
}
/**
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
index 07296a3..10f7b90 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
@@ -27,6 +27,7 @@
package org.opends.quicksetup.installer.ui;
+import org.opends.admin.ads.ServerDescriptor;
import org.opends.admin.ads.SuffixDescriptor;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.installer.DataReplicationOptions;
@@ -37,8 +38,12 @@
import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
+import java.util.TreeSet;
/**
* This is the panel that contains the Review Panel.
@@ -55,7 +60,9 @@
private HashMap<FieldName, JTextComponent> hmFields =
new HashMap<FieldName, JTextComponent>();
+ private JPanel bottomComponent;
private JCheckBox checkBox;
+ private JLabel warningLabel;
/**
* Constructor of the panel.
@@ -97,6 +104,21 @@
getField(FieldName.GLOBAL_ADMINISTRATOR_UID).setVisible(false);
getLabel(FieldName.GLOBAL_ADMINISTRATOR_UID).setVisible(false);
}
+
+ if (userData.getReplicationOptions().getType() ==
+ DataReplicationOptions.Type.STANDALONE)
+ {
+ getField(FieldName.REPLICATION_PORT).setVisible(false);
+ getLabel(FieldName.REPLICATION_PORT).setVisible(false);
+ }
+ else
+ {
+ setFieldValue(FieldName.REPLICATION_PORT,
+ getReplicationPortString(userData));
+ getField(FieldName.REPLICATION_PORT).setVisible(true);
+ getLabel(FieldName.REPLICATION_PORT).setVisible(true);
+ }
+ checkStartWarningLabel();
}
/**
@@ -169,6 +191,12 @@
getMsg("directory-data-label"), null,
LabelFieldDescriptor.FieldType.READ_ONLY,
LabelFieldDescriptor.LabelType.PRIMARY, 0));
+
+ hm.put(FieldName.REPLICATION_PORT, new LabelFieldDescriptor(
+ getMsg("replication-port-label"), null,
+ LabelFieldDescriptor.FieldType.READ_ONLY,
+ LabelFieldDescriptor.LabelType.PRIMARY, 0));
+
for (FieldName fieldName : hm.keySet())
{
LabelFieldDescriptor desc = hm.get(fieldName);
@@ -216,6 +244,7 @@
getField(fieldName).setText(value);
}
+
/**
* Returns the localized string describing the DataOptions chosen by the user.
* @param options the DataOptions of the user.
@@ -289,7 +318,49 @@
return msg;
}
+ /**
+ * Returns the String representing the replication port configuration.
+ * @param options the DataOptions of the user.
+ * @return the localized string describing the Replication Ports chosen by
+ * the user.
+ */
+ private String getReplicationPortString(UserData userInstallData)
+ {
+ StringBuilder buf = new StringBuilder();
+ DataReplicationOptions repl =
+ userInstallData.getReplicationOptions();
+
+ SuffixesToReplicateOptions suf =
+ userInstallData.getSuffixesToReplicateOptions();
+
+ Map<ServerDescriptor, Integer> remotePorts =
+ userInstallData.getRemoteWithNoReplicationPort();
+
+ if ((repl.getType() == DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY) &&
+ (suf.getType() ==
+ SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES) &&
+ remotePorts.size() > 0)
+ {
+ buf.append(userInstallData.getReplicationOptions().getReplicationPort());
+ TreeSet<String> remoteServerLines = new TreeSet<String>();
+ for (ServerDescriptor server : remotePorts.keySet())
+ {
+ String[] args = {String.valueOf(remotePorts.get(server)),
+ server.getHostPort(true)};
+ remoteServerLines.add(getMsg("remote-server-replication-port", args));
+ }
+ for (String line : remoteServerLines)
+ {
+ buf.append("\n"+line);
+ }
+ }
+ else
+ {
+ buf.append(userInstallData.getReplicationOptions().getReplicationPort());
+ }
+ return buf.toString();
+ }
/**
* Returns and creates the fields panel.
* @return the fields panel.
@@ -308,7 +379,8 @@
{
FieldName.SERVER_LOCATION, FieldName.SERVER_PORT,
FieldName.SECURITY_OPTIONS, FieldName.DIRECTORY_MANAGER_DN,
- FieldName.GLOBAL_ADMINISTRATOR_UID, FieldName.DATA_OPTIONS
+ FieldName.GLOBAL_ADMINISTRATOR_UID, FieldName.DATA_OPTIONS,
+ FieldName.REPLICATION_PORT
};
}
else
@@ -318,7 +390,7 @@
{
FieldName.SERVER_PORT, FieldName.SECURITY_OPTIONS,
FieldName.DIRECTORY_MANAGER_DN, FieldName.GLOBAL_ADMINISTRATOR_UID,
- FieldName.DATA_OPTIONS
+ FieldName.DATA_OPTIONS, FieldName.REPLICATION_PORT
};
}
@@ -359,7 +431,37 @@
/**
* {@inheritDoc}
*/
- protected JCheckBox getCheckBox()
+ protected JComponent getBottomComponent()
+ {
+ if (bottomComponent == null)
+ {
+ bottomComponent = new JPanel(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.gridwidth = 3;
+ bottomComponent.add(getCheckBox(), gbc);
+ gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
+ gbc.gridwidth = GridBagConstraints.RELATIVE;
+ bottomComponent.add(getWarningLabel(), gbc);
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.insets.left = 0;
+ gbc.weightx = 1.0;
+ bottomComponent.add(Box.createHorizontalGlue(), gbc);
+ }
+ return bottomComponent;
+ }
+
+ private JLabel getWarningLabel()
+ {
+ if (warningLabel == null)
+ {
+ warningLabel = UIFactory.makeJLabel(UIFactory.IconType.WARNING,
+ getMsg("install-server-must-be-temporarily-started"),
+ UIFactory.TextStyle.READ_ONLY);
+ }
+ return warningLabel;
+ }
+
+ private JCheckBox getCheckBox()
{
if (checkBox == null)
{
@@ -367,7 +469,30 @@
UIFactory.makeJCheckBox(getMsg("start-server-label"),
getMsg("start-server-tooltip"), UIFactory.TextStyle.CHECKBOX);
checkBox.setSelected(getApplication().getUserData().getStartServer());
+ checkBox.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent ev)
+ {
+ checkStartWarningLabel();
+ }
+ });
}
return checkBox;
}
+
+ /**
+ * Depending on whether we want to replicate or not, we do have to start
+ * the server temporarily to update its configuration and initialize data.
+ */
+ private void checkStartWarningLabel()
+ {
+ boolean visible = !getCheckBox().isSelected();
+ if (visible)
+ {
+ UserData userData = getApplication().getUserData();
+ DataReplicationOptions rep = userData.getReplicationOptions();
+ visible = rep.getType() != DataReplicationOptions.Type.STANDALONE;
+ }
+ getWarningLabel().setVisible(visible);
+ }
}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/RemoteReplicationPortsPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/RemoteReplicationPortsPanel.java
new file mode 100644
index 0000000..9a918f9
--- /dev/null
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/RemoteReplicationPortsPanel.java
@@ -0,0 +1,310 @@
+/*
+ * 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.quicksetup.installer.ui;
+
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.swing.Box;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.border.EmptyBorder;
+import javax.swing.text.JTextComponent;
+
+import org.opends.admin.ads.ServerDescriptor;
+
+import org.opends.quicksetup.UserData;
+import org.opends.quicksetup.ui.FieldName;
+import org.opends.quicksetup.ui.GuiApplication;
+import org.opends.quicksetup.ui.LabelFieldDescriptor;
+import org.opends.quicksetup.ui.QuickSetupStepPanel;
+import org.opends.quicksetup.ui.UIFactory;
+
+/**
+ * This class is used to provide a data model for the list of servers for which
+ * we must provide a replication port.
+ */
+public class RemoteReplicationPortsPanel extends QuickSetupStepPanel
+implements Comparator<ServerDescriptor>
+{
+ private static final long serialVersionUID = -3742350600617826375L;
+ private Component lastFocusComponent;
+ private HashMap<String, JLabel> hmLabels =
+ new HashMap<String, JLabel>();
+ private HashMap<String, JTextComponent> hmFields =
+ new HashMap<String, JTextComponent>();
+ private JScrollPane scroll;
+ private JPanel fieldsPanel;
+ private TreeSet<ServerDescriptor> orderedServers =
+ new TreeSet<ServerDescriptor>(this);
+ /**
+ * Constructor of the panel.
+ * @param application Application represented by this panel and used to
+ * initialize the fields of the panel.
+ */
+ public RemoteReplicationPortsPanel(GuiApplication application)
+ {
+ super(application);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object getFieldValue(FieldName fieldName)
+ {
+ Object value = null;
+
+ if (fieldName == FieldName.REMOTE_REPLICATION_PORT)
+ {
+ Map<String, String> hm = new HashMap<String, String>();
+ for (String id : hmFields.keySet())
+ {
+ hm.put(id, hmFields.get(id).getText());
+ }
+ value = hm;
+ }
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void displayFieldInvalid(FieldName fieldName, boolean invalid)
+ {
+ if (fieldName == FieldName.REMOTE_REPLICATION_PORT)
+ {
+ for (String id : hmLabels.keySet())
+ {
+ UIFactory.setTextStyle(hmLabels.get(id),
+ UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+ }
+ if (invalid)
+ {
+ for (String id : hmLabels.keySet())
+ {
+ String sPort = hmFields.get(id).getText();
+ boolean isValid = false;
+ try
+ {
+ int replicationPort = Integer.parseInt(sPort);
+ if ((replicationPort >= 1) &&
+ (replicationPort <= 65535))
+ {
+ isValid = true;
+ }
+ }
+ catch (Throwable t)
+ {
+ }
+ if (!isValid)
+ {
+ UIFactory.setTextStyle(hmLabels.get(id),
+ UIFactory.TextStyle.SECONDARY_FIELD_INVALID);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int compare(ServerDescriptor desc1, ServerDescriptor desc2)
+ {
+ return desc1.getHostPort(true).compareTo(desc2.getHostPort(true));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected Component createInputPanel()
+ {
+ JPanel panel = new JPanel(new GridBagLayout());
+ panel.setOpaque(false);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.weightx = 1.0;
+ gbc.anchor = GridBagConstraints.NORTHWEST;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.insets = UIFactory.getEmptyInsets();
+ gbc.weighty = 1.0;
+ gbc.fill = GridBagConstraints.BOTH;
+ fieldsPanel = new JPanel(new GridBagLayout());
+ fieldsPanel.setOpaque(false);
+ scroll = new JScrollPane(fieldsPanel);
+ scroll.setBorder(new EmptyBorder(0, 0, 0, 0));
+ scroll.setViewportBorder(new EmptyBorder(0, 0, 0, 0));
+ scroll.setOpaque(false);
+ scroll.getViewport().setOpaque(false);
+
+ panel.add(scroll, gbc);
+
+ return panel;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected String getInstructions()
+ {
+ return getMsg("remote-replication-port-instructions");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected String getTitle()
+ {
+ return getMsg("remote-replication-port-title");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void beginDisplay(UserData data)
+ {
+ TreeSet<ServerDescriptor> array = orderServers(
+ data.getRemoteWithNoReplicationPort().keySet());
+ if (!array.equals(orderedServers))
+ {
+ /**
+ * Adds the required focus listeners to the fields.
+ */
+ final FocusListener l = new FocusListener()
+ {
+ public void focusGained(FocusEvent e)
+ {
+ lastFocusComponent = e.getComponent();
+ }
+
+ public void focusLost(FocusEvent e)
+ {
+ }
+ };
+ lastFocusComponent = null;
+ HashMap<String, String> hmOldValues = new HashMap<String, String>();
+ for (String id : hmFields.keySet())
+ {
+ hmOldValues.put(id, hmFields.get(id).getText());
+ }
+ orderedServers.clear();
+ orderedServers.addAll(array);
+ hmFields.clear();
+ hmLabels.clear();
+ for (ServerDescriptor server : orderedServers)
+ {
+ LabelFieldDescriptor desc = new LabelFieldDescriptor(
+ server.getHostPort(true), getMsg("replication-port-tooltip"),
+ LabelFieldDescriptor.FieldType.TEXTFIELD,
+ LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.PORT_FIELD_SIZE);
+ Integer defaultValue =
+ data.getRemoteWithNoReplicationPort().get(server);
+ JTextComponent field = UIFactory.makeJTextComponent(desc,
+ String.valueOf(defaultValue));
+ String oldValue = hmOldValues.get(server.getId());
+ if (oldValue != null)
+ {
+ field.setText(oldValue);
+ }
+
+ JLabel label = UIFactory.makeJLabel(desc);
+
+ hmFields.put(server.getId(), field);
+ label.setLabelFor(field);
+ field.addFocusListener(l);
+ if (lastFocusComponent == null)
+ {
+ lastFocusComponent = field;
+ }
+
+ hmLabels.put(server.getId(), label);
+ }
+ populateFieldsPanel();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void endDisplay()
+ {
+ if (lastFocusComponent != null)
+ {
+ lastFocusComponent.requestFocusInWindow();
+ }
+ }
+
+ private void populateFieldsPanel()
+ {
+ fieldsPanel.removeAll();
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.fill = GridBagConstraints.BOTH;
+ gbc.anchor = GridBagConstraints.NORTHWEST;
+ boolean first = true;
+ for (ServerDescriptor server : orderedServers)
+ {
+ gbc.insets.left = 0;
+ gbc.weightx = 0.0;
+ if (!first)
+ {
+ gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+ }
+ gbc.gridwidth = 3;
+ fieldsPanel.add(hmLabels.get(server.getId()), gbc);
+ gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
+ gbc.gridwidth = GridBagConstraints.RELATIVE;
+ fieldsPanel.add(hmFields.get(server.getId()), gbc);
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.weightx = 1.0;
+ fieldsPanel.add(Box.createHorizontalGlue(), gbc);
+ first = false;
+ }
+ addVerticalGlue(fieldsPanel);
+ }
+
+ private TreeSet<ServerDescriptor> orderServers(
+ Set<ServerDescriptor> servers)
+ {
+ TreeSet<ServerDescriptor> ordered = new TreeSet<ServerDescriptor>(this);
+ ordered.addAll(servers);
+
+ return ordered;
+ }
+}
+
+
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java
index f9e844f..0101bc4 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java
@@ -77,8 +77,6 @@
private JTextField tfPort;
private JRadioButton rbUseSelfSignedCertificate;
private JRadioButton rbUseExistingCertificate;
- private JLabel lSelfSignedName;
- private JTextField tfSelfSignedName;
private JLabel lKeystoreType;
private JRadioButton rbPKCS11;
private JRadioButton rbJKS;
@@ -163,8 +161,6 @@
}
UIFactory.setTextStyle(cbEnableSSL,
UIFactory.TextStyle.SECONDARY_FIELD_VALID);
- UIFactory.setTextStyle(lSelfSignedName,
- UIFactory.TextStyle.SECONDARY_FIELD_VALID);
UIFactory.setTextStyle(lKeystorePath,
UIFactory.TextStyle.SECONDARY_FIELD_VALID);
UIFactory.setTextStyle(lKeystorePwd,
@@ -203,7 +199,7 @@
if (rbUseSelfSignedCertificate.isSelected())
{
ops = SecurityOptions.createSelfSignedCertificateOptions(
- tfSelfSignedName.getText(), enableSSL, enableStartTLS, sslPort);
+ enableSSL, enableStartTLS, sslPort);
}
else if (rbJKS.isSelected())
{
@@ -365,15 +361,6 @@
getMsg("use-self-signed-tooltip"),
UIFactory.TextStyle.SECONDARY_FIELD_VALID);
rbUseSelfSignedCertificate.addActionListener(l);
- lSelfSignedName = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
- getMsg("self-signed-certificate-name-label"),
- UIFactory.TextStyle.SECONDARY_FIELD_VALID);
- lSelfSignedName.setOpaque(false);
- String selfSignedName = securityOptions.getSelfSignedCertificateName();
- tfSelfSignedName = UIFactory.makeJTextField(selfSignedName,
- getMsg("self-signed-certificate-name-tooltip"),
- UIFactory.HOST_FIELD_SIZE, UIFactory.TextStyle.TEXTFIELD);
- lSelfSignedName.setLabelFor(tfSelfSignedName);
rbUseExistingCertificate = UIFactory.makeJRadioButton(
getMsg("use-existing-certificate-label"),
getMsg("use-existing-certificate-tooltip"),
@@ -517,22 +504,6 @@
aux2Panel = new JPanel(new GridBagLayout());
aux2Panel.setOpaque(false);
- gbc.weightx = 0.0;
- gbc.gridwidth = 3;
- aux2Panel.add(lSelfSignedName, gbc);
- gbc.gridwidth = GridBagConstraints.RELATIVE;
- gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
- aux2Panel.add(tfSelfSignedName, gbc);
- gbc.weightx = 1.0;
- gbc.gridwidth = GridBagConstraints.REMAINDER;
- gbc.insets.left = 0;
- aux2Panel.add(Box.createHorizontalGlue(), gbc);
- gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
- gbc.insets.left = UIFactory.LEFT_INSET_RADIO_SUBORDINATE;
- auxPanel.add(aux2Panel, gbc);
-
- aux2Panel = new JPanel(new GridBagLayout());
- aux2Panel.setOpaque(false);
gbc.gridwidth = GridBagConstraints.RELATIVE;
gbc.insets = UIFactory.getEmptyInsets();
gbc.weightx = 0.0;
@@ -679,8 +650,6 @@
errorMsgs.addAll(checkPort());
- errorMsgs.addAll(checkSelfSigned());
-
errorMsgs.addAll(checkKeystore());
return errorMsgs;
@@ -796,7 +765,6 @@
case SELF_SIGNED_CERTIFICATE:
rbUseSelfSignedCertificate.setSelected(true);
- tfSelfSignedName.setText(securityOptions.getSelfSignedCertificateName());
break;
case JKS:
@@ -851,10 +819,6 @@
tfPort.setEnabled(enableSSL);
rbUseSelfSignedCertificate.setEnabled(useSSL);
- lSelfSignedName.setEnabled(
- rbUseSelfSignedCertificate.isSelected() && useSSL);
- tfSelfSignedName.setEnabled(
- rbUseSelfSignedCertificate.isSelected() && useSSL);
rbUseExistingCertificate.setEnabled(useSSL);
lKeystoreType.setEnabled(
@@ -965,38 +929,6 @@
}
/**
- * Checks the self-signed certificate parameters.
- * @return the error messages found while checking self-signed certificate
- * parameters.
- */
- private ArrayList<String> checkSelfSigned()
- {
- ArrayList<String> errorMsgs = new ArrayList<String>();
-
- if (rbUseSelfSignedCertificate.isSelected() &&
- (cbEnableSSL.isSelected() || cbEnableStartTLS.isSelected()))
- {
- String name = tfSelfSignedName.getText();
- if ((name != null) && (name.length() > 0))
- {
- /* TODO: We might try to do something to check if the user provided a
- * valid host name, but we cannot guarantee that the check will be valid
- * AND we might want to allow the user to use a common name for the
- * certificate that is not the host name.
- */
- }
- else
- {
- errorMsgs.add(getMsg("no-self-signed-cert-name-provided"));
- }
- }
-
- setValidLater(lSelfSignedName, errorMsgs.size() == 0);
-
- return errorMsgs;
- }
-
- /**
* Checks the existing keystore parameters.
* @return the error messages found while checking existing keystore
* parameters.
@@ -1045,7 +977,6 @@
if (pathValid && pwdValid)
{
- // TODO: put the password in a temporary file to do the checks.
try
{
CertificateManager certManager;
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/ServerSettingsPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/ServerSettingsPanel.java
index e81db0a..9060834 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/ServerSettingsPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/ServerSettingsPanel.java
@@ -53,6 +53,7 @@
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.SecurityOptions;
import org.opends.quicksetup.UserData;
+import org.opends.server.util.CertificateManager;
/**
* This is the panel that contains the Server Settings: the port, the Directory
@@ -103,8 +104,7 @@
super(application);
this.defaultUserData = application.getUserData();
this.displayServerLocation = isWebStart();
- canUpdateSecurity =
- org.opends.server.util.CertificateManager.mayUseCertificateManager();
+ canUpdateSecurity = CertificateManager.mayUseCertificateManager();
securityOptions = defaultUserData.getSecurityOptions();
populateLabelAndFieldMaps();
addFocusListeners();
@@ -185,6 +185,7 @@
FieldName[] fieldNames =
{
+ FieldName.HOST_NAME,
FieldName.SERVER_PORT,
FieldName.SECURITY_OPTIONS,
FieldName.DIRECTORY_MANAGER_DN,
@@ -376,6 +377,10 @@
value = defaultUserData.getServerLocation();
break;
+ case HOST_NAME:
+ value = defaultUserData.getHostName();
+ break;
+
case SERVER_PORT:
if (defaultUserData.getServerPort() > 0)
{
@@ -420,6 +425,11 @@
HashMap<FieldName, LabelFieldDescriptor> hm =
new HashMap<FieldName, LabelFieldDescriptor>();
+ hm.put(FieldName.HOST_NAME, new LabelFieldDescriptor(
+ getMsg("host-name-label"), getMsg("host-name-tooltip"),
+ LabelFieldDescriptor.FieldType.TEXTFIELD,
+ LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.HOST_FIELD_SIZE));
+
hm.put(FieldName.SERVER_PORT, new LabelFieldDescriptor(
getMsg("server-port-label"), getMsg("server-port-tooltip"),
LabelFieldDescriptor.FieldType.TEXTFIELD,
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SuffixesToReplicatePanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SuffixesToReplicatePanel.java
index 063bc26..e0b179f 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SuffixesToReplicatePanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SuffixesToReplicatePanel.java
@@ -51,17 +51,18 @@
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
+import org.opends.admin.ads.ADSContext;
import org.opends.admin.ads.ReplicaDescriptor;
import org.opends.admin.ads.ServerDescriptor;
import org.opends.admin.ads.SuffixDescriptor;
-
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.installer.SuffixesToReplicateOptions;
import org.opends.quicksetup.ui.FieldName;
import org.opends.quicksetup.ui.GuiApplication;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.quicksetup.ui.UIFactory;
+import org.opends.quicksetup.util.Utils;
/**
* This class is used to provide a data model for the list of suffixes that
@@ -75,8 +76,8 @@
private UserData defaultUserData;
private TreeSet<SuffixDescriptor> orderedSuffixes =
new TreeSet<SuffixDescriptor>(this);
- private HashMap<SuffixDescriptor, JCheckBox> hmCheckBoxes =
- new HashMap<SuffixDescriptor, JCheckBox>();
+ private HashMap<String, JCheckBox> hmCheckBoxes =
+ new HashMap<String, JCheckBox>();
private Set<JEditorPane> suffixLabels = new HashSet<JEditorPane>();
private JRadioButton rbCreateNewSuffix;
@@ -123,7 +124,7 @@
Set<SuffixDescriptor> suffixes = new HashSet<SuffixDescriptor>();
for (SuffixDescriptor suffix:orderedSuffixes)
{
- if (hmCheckBoxes.get(suffix).isSelected())
+ if (hmCheckBoxes.get(suffix.getId()).isSelected())
{
suffixes.add(suffix);
}
@@ -244,12 +245,23 @@
{
TreeSet<SuffixDescriptor> array = orderSuffixes(
data.getSuffixesToReplicateOptions().getAvailableSuffixes());
- Set<SuffixDescriptor> chosen =
- data.getSuffixesToReplicateOptions().getSuffixes();
+
if (!array.equals(orderedSuffixes))
{
+ HashMap<String, Boolean> hmOldValues = new HashMap<String, Boolean>();
+ for (String id : hmCheckBoxes.keySet())
+ {
+ hmOldValues.put(id, hmCheckBoxes.get(id).isSelected());
+ }
orderedSuffixes.clear();
- orderedSuffixes.addAll(array);
+ for (SuffixDescriptor suffix : array)
+ {
+ if (!Utils.areDnsEqual(suffix.getDN(),
+ ADSContext.getAdministrationSuffixDN()))
+ {
+ orderedSuffixes.add(suffix);
+ }
+ }
hmCheckBoxes.clear();
for (SuffixDescriptor suffix : orderedSuffixes)
{
@@ -257,7 +269,11 @@
getMsg("suffixes-to-replicate-dn-tooltip"),
UIFactory.TextStyle.SECONDARY_FIELD_VALID);
cb.setOpaque(false);
- cb.setSelected(chosen.contains(suffix));
+ Boolean v = hmOldValues.get(suffix.getId());
+ if (v != null)
+ {
+ cb.setSelected(v);
+ }
cb.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ev)
@@ -268,15 +284,16 @@
}
}
});
- hmCheckBoxes.put(suffix, cb);
+ hmCheckBoxes.put(suffix.getId(), cb);
}
populateCheckBoxPanel();
- boolean display = orderedSuffixes.size() > 0;
-
- noSuffixLabel.setVisible(!display);
- labelGlue.setVisible(!display);
- scroll.setVisible(display);
}
+ boolean display = orderedSuffixes.size() > 0;
+
+ noSuffixLabel.setVisible(!display);
+ labelGlue.setVisible(!display);
+ scroll.setVisible(display);
+
checkEnablingState();
}
@@ -371,7 +388,7 @@
gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
}
gbc.gridwidth = GridBagConstraints.RELATIVE;
- JCheckBox cb = hmCheckBoxes.get(suffix);
+ JCheckBox cb = hmCheckBoxes.get(suffix.getId());
cb.setVerticalAlignment(SwingConstants.TOP);
checkBoxPanel.add(cb, gbc);
gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
@@ -419,7 +436,7 @@
ServerDescriptor server = replica.getServer();
- String serverDisplay = getServerDisplay(server);
+ String serverDisplay = server.getHostPort(true);
int nEntries = replica.getEntries();
@@ -428,24 +445,23 @@
String[] args = {serverDisplay, String.valueOf(nEntries)};
display = getMsg("suffix-list-replica-display-entries", args);
}
- else
+ else if (nEntries == 0)
{
String[] arg = {serverDisplay};
display = getMsg("suffix-list-replica-display-no-entries", arg);
}
+ else
+ {
+ String[] arg = {serverDisplay};
+ display = getMsg("suffix-list-replica-display-entries-not-available",
+ arg);
+ }
return display;
}
-
- //TODO: only handles server that have ADSProperties.
- private String getServerDisplay(ServerDescriptor server)
- {
- return server.getHostPort(true);
- }
-
private TreeSet<SuffixDescriptor> orderSuffixes(
- Set<SuffixDescriptor> suffixes)
+ Set<SuffixDescriptor> suffixes)
{
TreeSet<SuffixDescriptor> ordered = new TreeSet<SuffixDescriptor>(this);
ordered.addAll(suffixes);
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
index a6b6264..8dc716a 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
@@ -139,8 +139,6 @@
configureServer();
createData();
- updateADS();
-
if (Utils.isWindows())
{
notifyListeners(getTaskSeparator());
@@ -148,29 +146,64 @@
enableWindowsService();
}
- if (getUserData().getStartServer())
+ if (mustStart())
{
notifyListeners(getTaskSeparator());
setStatus(InstallProgressStep.STARTING_SERVER);
new ServerController(this).startServer();
}
+ if (mustConfigureReplication())
+ {
+ setStatus(InstallProgressStep.CONFIGURING_REPLICATION);
+ notifyListeners(getTaskSeparator());
+
+ configureReplication();
+ }
+
+ if (mustInitializeSuffixes())
+ {
+ notifyListeners(getTaskSeparator());
+ setStatus(InstallProgressStep.INITIALIZE_REPLICATED_SUFFIXES);
+ initializeSuffixes();
+ }
+
+ if (mustCreateAds())
+ {
+ notifyListeners(getTaskSeparator());
+ setStatus(InstallProgressStep.CONFIGURING_ADS);
+ updateADS();
+ }
+
+ if (mustStop())
+ {
+ notifyListeners(getTaskSeparator());
+ setStatus(InstallProgressStep.STOPPING_SERVER);
+ new ServerController(this).stopServer();
+ }
+
setStatus(InstallProgressStep.FINISHED_SUCCESSFULLY);
notifyListeners(null);
} catch (ApplicationException ex)
{
+ notifyListeners(getLineBreak());
+ notifyListenersOfLog();
setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
String html = getFormattedError(ex, true);
notifyListeners(html);
+ LOG.log(Level.SEVERE, "Error installing.", ex);
}
catch (Throwable t)
{
+ notifyListeners(getLineBreak());
+ notifyListenersOfLog();
setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
ApplicationException ex = new ApplicationException(
ApplicationException.Type.BUG, getThrowableMsg("bug-msg", t), t);
String msg = getFormattedError(ex, true);
notifyListeners(msg);
+ LOG.log(Level.SEVERE, "Error installing.", t);
}
System.setErr(origErr);
System.setOut(origOut);
@@ -219,10 +252,13 @@
hmTime.put(InstallProgressStep.CONFIGURING_SERVER, 5);
hmTime.put(InstallProgressStep.CREATING_BASE_ENTRY, 10);
hmTime.put(InstallProgressStep.IMPORTING_LDIF, 20);
- hmTime.put(InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED,
- 20);
+ hmTime.put(InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED, 20);
+ hmTime.put(InstallProgressStep.CONFIGURING_REPLICATION, 10);
hmTime.put(InstallProgressStep.ENABLING_WINDOWS_SERVICE, 5);
hmTime.put(InstallProgressStep.STARTING_SERVER, 10);
+ hmTime.put(InstallProgressStep.STOPPING_SERVER, 5);
+ hmTime.put(InstallProgressStep.CONFIGURING_ADS, 5);
+ hmTime.put(InstallProgressStep.INITIALIZE_REPLICATED_SUFFIXES, 25);
int totalTime = 0;
ArrayList<InstallProgressStep> steps =
@@ -234,33 +270,62 @@
totalTime += hmTime.get(InstallProgressStep.CONFIGURING_SERVER);
steps.add(InstallProgressStep.CONFIGURING_SERVER);
- switch (getUserData().getNewSuffixOptions().getType())
+ if (createNotReplicatedSuffix())
{
- case CREATE_BASE_ENTRY:
- steps.add(InstallProgressStep.CREATING_BASE_ENTRY);
- totalTime += hmTime.get(InstallProgressStep.CREATING_BASE_ENTRY);
- break;
- case IMPORT_FROM_LDIF_FILE:
- steps.add(InstallProgressStep.IMPORTING_LDIF);
- totalTime += hmTime.get(InstallProgressStep.IMPORTING_LDIF);
- break;
- case IMPORT_AUTOMATICALLY_GENERATED_DATA:
- steps.add(InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED);
- totalTime +=hmTime.get(
- InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED);
- break;
+ switch (getUserData().getNewSuffixOptions().getType())
+ {
+ case CREATE_BASE_ENTRY:
+ steps.add(InstallProgressStep.CREATING_BASE_ENTRY);
+ totalTime += hmTime.get(InstallProgressStep.CREATING_BASE_ENTRY);
+ break;
+ case IMPORT_FROM_LDIF_FILE:
+ steps.add(InstallProgressStep.IMPORTING_LDIF);
+ totalTime += hmTime.get(InstallProgressStep.IMPORTING_LDIF);
+ break;
+ case IMPORT_AUTOMATICALLY_GENERATED_DATA:
+ steps.add(InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED);
+ totalTime +=hmTime.get(
+ InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED);
+ break;
+ }
}
+
if (Utils.isWindows())
{
totalTime += hmTime.get(InstallProgressStep.ENABLING_WINDOWS_SERVICE);
steps.add(InstallProgressStep.ENABLING_WINDOWS_SERVICE);
}
- if (getUserData().getStartServer())
+ if (mustStart())
{
totalTime += hmTime.get(InstallProgressStep.STARTING_SERVER);
steps.add(InstallProgressStep.STARTING_SERVER);
}
+ if (mustConfigureReplication())
+ {
+ steps.add(InstallProgressStep.CONFIGURING_REPLICATION);
+ totalTime += hmTime.get(InstallProgressStep.CONFIGURING_REPLICATION);
+ }
+
+ if (mustInitializeSuffixes())
+ {
+ totalTime += hmTime.get(
+ InstallProgressStep.INITIALIZE_REPLICATED_SUFFIXES);
+ steps.add(InstallProgressStep.INITIALIZE_REPLICATED_SUFFIXES);
+ }
+
+ if (mustCreateAds())
+ {
+ totalTime += hmTime.get(InstallProgressStep.CONFIGURING_ADS);
+ steps.add(InstallProgressStep.CONFIGURING_ADS);
+ }
+
+ if (mustStop())
+ {
+ totalTime += hmTime.get(InstallProgressStep.STOPPING_SERVER);
+ steps.add(InstallProgressStep.STOPPING_SERVER);
+ }
+
int cumulatedTime = 0;
for (InstallProgressStep s : steps)
{
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
index 7091a63..38bb0fb 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -242,19 +242,19 @@
sure you want to close the Uninstall Window?
confirm-cancel-upgrade-title=Confirmation Required
confirm-cancel-upgrade-msg=OpenDS QuickUpgrade has not yet completed.\nIf you \
- click 'Yes' any changes that have been\nmade to the server being upgraded \
- will\nbe backed out.\n\nAre you sure you want to close the QuickUpgrade Window?\n
+ click 'Yes' any changes that have been made to the server being upgraded \
+ will be backed out.\n\nAre you sure you want to close the QuickUpgrade Window?\n
confirm-quit-upgrade-title=Confirmation Required
confirm-quit-upgrade-msg=Are you sure you want to quit OpenDS \
QuickUpgrade?\nIf you click 'Yes' nothing will be upgraded on your system.
confirm-uninstall-server-not-running-msg=Confirm Uninstall\n\
-All selected files will be permanently deleted, are you sure you\n\
+All selected files will be permanently deleted, are you sure you \
want to continue?
confirm-uninstall-server-not-running-title=Confirm Uninstall
confirm-uninstall-server-running-msg=Server is Running\n\
-The OpenDS server is currently running and must be stopped before\n\
-uninstallation can continue. Do you want the uninstaller to stop\n\
-the server for you and continue with the uninstall? If you click\n\
+The OpenDS server is currently running and must be stopped before \
+uninstallation can continue. Do you want the uninstaller to stop \
+the server for you and continue with the uninstall? If you click \
No, you will need to stop the server manually to continue.
confirm-uninstall-server-running-title=Server is Running
confirm-cancel-title=Confirmation Required
@@ -311,7 +311,7 @@
# Data validation errors
#
# Server Settings
-empty-server-location=Invalid Directory Selected\nYou must provide a valid \
+empty-server-location=Invalid Directory Selected You must provide a valid \
OpenDS root installation directory.
parent-directory-could-not-be-found=Could not find a parent directory for {0}.
parent-directory-does-not-exist-confirmation=The parent directory of {0} does \
@@ -322,6 +322,7 @@
You must have file right access on the Installation directory.
not-enough-disk-space=There is not enough free disk space under {0}.\nAt \
least {1} megabytes of free disk space are required to install OpenDS.
+empty-host-name=You must provide the name of the host.
invalid-port-value-range=The LDAP Listener Port must be an integer between \
{0} and {1}.
invalid-secure-port-value-range=The LDAPS Listener Port must be an \
@@ -340,17 +341,46 @@
not-equal-pwd=The passwords you have provided do not match.
pwd-too-short=The minimum length required for the Administrative User \
password is {0} characters.
+
+#
# Data Replication Panel
+#
+invalid-replication-port-value-range=The Replication Port must be an integer \
+between {0} and {1}.
+invalid-remote-replication-port-value-range=The Replication Port on {0} must \
+be an integer between {1} and {2}.
+equal-ports=You must specify different ports LDAP and LDAPS communication.
+replication-port-already-chosen-for-other-protocol=You must specify a \
+different Replication port than those you chose for LDAP and LDAPS \
+communication.
+remote-replication-port-already-chosen-for-other-protocol=You must specify a \
+different Replication port for existing server {0}. The specified port has \
+already been chosen to configure the new server.
empty-remote-host=You must provide the fully qualified name of the host.
invalid-remote-port=The provided port is not valid.
empty-remote-dn=You must provide a value for the Administrative User.
empty-remote-pwd=You must provide an Admin User password.
+not-global-administrator-provided=You must provide the Global Administrator ID \
+to be able to access the configuration of all the remote servers that have \
+been previously installed.
+server-error=Error on {0}:
+error-reading-server-configuration=Error reading configuration. Details:\n{0}
+error-reading-registered-servers-confirm=The following errors where \
+encountered reading the configuration of the existing servers:\n{0}\n\nDo you \
+want to continue?
+certificate-exception=You must accept the certificate presented by {0}:{1}.
+cannot-connect-to-remote-authentication=The provided credentials are not valid.
cannot-connect-to-remote-permissions=You do not have enough access rights \
to read the configuration in {0}. \nProvide credentials with enough rights.
-cannot-connect-to-remote-generic=Could not connect to {0}. \nCheck that the \
-server is running and that the provided credentials are valid.
-remote-ads-exception=An unexpected error occurred reading the \
-configuration in {0}.\nThe error is: {1}
+cannot-connect-to-remote-generic=Could not connect to {0}. The error message \
+received is:\n{1}\nCheck that the server is running and that the provided \
+credentials are valid.
+error-configuring-remote-generic=An unexpected error occurred configuring \
+server {0}.\nThe error is: {1}
+remote-ads-exception=An unexpected error occurred managing the \
+registration information in {0}.\nThe error is: {1}
+ads-exception=An unexpected error occurred managing the registration \
+information.\nThe error is: {0}
no-suffixes-chosen-to-replicate=You must select at least one suffix to \
replicate contents with.
# Create Global Administrator Panel
@@ -391,6 +421,7 @@
data-replication-step=Topology Options
create-global-administrator-step=Global Administrator
suffixes-step=Data Replication
+remote-replication-ports-step=Replication Port
data-options-step=Directory Data
review-step=Review
progress-step=Progress
@@ -446,6 +477,7 @@
opends-small-icon=images/opends_logo_small.png
help-small-icon=images/help_small.gif
wait-tiny=images/wait_tiny.png
+wait=images/wait.gif
#
# Colors: the meaning of colors is not universal. That is why they are included
@@ -527,6 +559,8 @@
where the server files will be stored
server-location-relative-tooltip=Enter the relative path to the location \
where the server files will be stored
+host-name-label=Host Name:
+host-name-tooltip=Enter the name of the host.
server-port-label=LDAP Listener Port:
server-port-tooltip=Enter the port number that the server will use to listen \
for LDAP requests
@@ -563,6 +597,9 @@
data-replication-options-panel-title=Topology Options
data-replication-options-panel-instructions=Choose the Data \
Replication Options.
+replication-port-label=Replication Port:
+replication-port-tooltip=The port that will be used to send and receive \
+replication updates between this server and the other servers.
remote-server-dn-label=Admin User:
remote-server-dn-tooltip=The DN or the UID of an administrator in the OpenDS \
you want to replicate data with.
@@ -575,6 +612,9 @@
remote-server-port-label=Port:
remote-server-port-tooltip=The LDAP port of the OpenDS you want to \
replicate data with.
+remote-server-port-is-secure-label=Secure Port
+remote-server-port-is-secure-tooltip=Check this is the provided port is the \
+LDAPS port.
standalone-server-label=This will be a standalone server
standalone-server-tooltip=Check this if you do not want to replicate the \
data on the server that you are creating with other servers.
@@ -586,6 +626,56 @@
topology-exists-tooltip=Check this if you already created a server that you \
want to replicate data with.
+
+#
+# The accept certificate dialog.
+#
+certificate-dialog-title=Certificate Not Trusted
+certificate-title=Certificate Not Trusted
+#
+# Double apostrophes required for this item.
+#
+certificate-not-trusted-text=The Certificate presented by the server {0}:{1} \
+could not be trusted.<br><br>Possible reasons for this error:\
+<br> -The Certificate Authority that issued the \
+certificate is not recognized.<br> -The server''s \
+certificate is incomplete due to a misconfiguration.\
+<br> -The server''s certificate has expired.<br>Before \
+accepting this certificate, you should examine the server''s certificate \
+carefully.<br><br>Are you willing to accept this certificate for the purpose \
+of identifying the server {0}:{1}?
+#
+# Double apostrophes required for this item.
+#
+certificate-name-mismatch-text=The Certificate presented by the server {0}:{1} \
+could not be trusted.<br><br>There is a name mismatch between the name of the \
+server ({0}) and the subject DN of the certificate. This could be caused \
+because you are connected to a server pretending to be {0}:{1}.<br><br>\
+Before accepting this certificate, you should examine the server''s \
+certificate carefully.<br><br>Are you willing to accept this certificate for \
+the purpose of identifying the server {0}:{1}?
+certificate-show-details-text=<br><br><a href="">Show Certificate Details</a>
+certificate-hide-details-text=<br><br><a href="">Hide Certificate Details</a>
+certificate-dialog-ok-button-tooltip=Close this dialog and accept the \
+certificate.
+certificate-dialog-cancel-button-tooltip=Close this dialog and do not accept \
+the certificate.
+certificate-chain-label=Certificate Chain:
+certificate-chain-combo-tooltip=To view the details of a given certificate \
+select it.
+certificate-not-valid-yet={0} - Not valid yet
+certificate-expired={0} - Expired
+certificate-subject-label=Subject:
+certificate-issued-by-label=Issued By:
+certificate-valid-from-label=Valid From:
+certificate-expires-on-label=Expires On:
+certificate-type-label=Type:
+certificate-serial-number-label=Serial Number:
+certificate-signature-label=Signature:
+certificate-signature-algorithm-label=Signature Algorithm:
+certificate-version-label=Version:
+certificate-public-key-label=Public Key:
+
#
# Global Administrator specific labels
#
@@ -603,6 +693,15 @@
Global Administrator.
#
+# Remote Replication Ports panel
+#
+remote-replication-port-instructions=You must provide the ports that will be \
+used to replicate data for the remote servers specified below.<br>The \
+specified ports must be free on the remote hosts and the user that is being \
+used to run the Directory Servers must have access rights to them.
+remote-replication-port-title=Replication Port of Remote Servers
+
+#
# Suffixes to Replicate Panel specific labels
#
suffixes-to-replicate-panel-instructions=Choose whether to create suffixes \
@@ -618,6 +717,8 @@
to replicate.
suffix-list-replica-display-entries={0} ({1} entries)
suffix-list-replica-display-no-entries={0} (no entries)
+suffix-list-replica-display-entries-not-available={0} (number of entries not \
+available)
suffix-list-unknown-label=<unknown>
suffix-list-empty=-No Suffixes Found-
@@ -641,9 +742,6 @@
testing only)
use-self-signed-tooltip=Create a new Self-Signed Certificate to encrypt \
communication.
-self-signed-certificate-name-label=Host Name:
-self-signed-certificate-name-tooltip=The host name will be used to name the \
-certificate.
use-existing-certificate-label=Use an Existing Certificate:
use-existing-certificate-tooltip=Select this if you have already a certificate \
you want the new server to use.
@@ -662,28 +760,26 @@
ssl-access-label=SSL Access:
starttls-access-label=StartTLS Access:
certificate-label=Certificate:
-no-self-signed-cert-name-provided=You must provide the host name for the \
-Self-Signed Certificate.
keystore-path-not-provided=You must provide the path of the key store.
keystore-path-does-not-exist=The provided key store path does not exist.
keystore-path-not-a-file=The provided key store path is not a file.
keystore-pwd-empty=You must provide the password of the key store.
error-accessing-jks-keystore=Could not access the JKS key store. Check that \
-the contents of the file\ncorrespond to a valid JKS key store, that you have \
-access rights to it and\nthat the provided password is valid.
+the contents of the file correspond to a valid JKS key store, that you have \
+access rights to it and that the provided password is valid.
error-accessing-pkcs11-keystore=Could not access the PKCS#11 key store. Check \
-that is installed and that the\nprovided password is valid.
+that is installed and that the provided password is valid.
error-accessing-pkcs12-keystore=Could not access the PKCS#12 key store. Check \
-that the contents of the file\ncorrespond to a valid PKCS#12 key store, that \
-you have access rights to it and\nthat the provided password is valid.
+that the contents of the file correspond to a valid PKCS#12 key store, that \
+you have access rights to it and that the provided password is valid.
pkcs11-keystore-does-not-exist=No certificates for the PCKS#11 key store could \
-be found. Check that is\ninstalled, that you have access rights to it and \
+be found. Check that is installed, that you have access rights to it and \
that the key store contains certificates.
pkcs12-keystore-does-not-exist=No certificates for the PCKS#12 key store could \
-be found. Check that the\nprovided path and password are valid and that the \
+be found. Check that the provided path and password are valid and that the \
key store contains certificates.
jks-keystore-does-not-exist=No certificates for the Java Key Store could be \
-found. Check that the provided\npath is valid.
+found. Check that the provided path is valid.
#
# Select Alias dialog specific labels
@@ -739,6 +835,9 @@
start-server-label=Start Server when Configuration has Completed
start-server-tooltip=Check this check box if you want to start the server once \
the installation and configuration has completed
+remote-server-replication-port={0} - To be configured on remote server {1}
+install-server-must-be-temporarily-started=The Server will be temporarily \
+started.
#
# Progress Panel specific labels
@@ -813,8 +912,12 @@
summary-importing-ldif=Importing LDIF File...
summary-importing-automatically-generated=Importing Automatically-Generated \
Data...
+summary-configuring-replication=Configuring Replication...
summary-starting=Starting Directory Server...
summary-enabling-windows-service=Enabling Windows Service...
+summary-configuring-ads=Creating Registration Configuration...
+summary-initialize-replicated-suffixes=Initializing Contents of Replicated \
+Suffixes...
summary-install-finished-successfully=<b>OpenDS QuickSetup Completed \
Successfully.</b><br>OpenDS is now installed in {0}.<br><br>Visit the \
<a href="https://www.opends.org/wiki/page/QuickReferenceGuide"> \
@@ -915,6 +1018,9 @@
upgrading-ratio=Downloading: {0}% Completed - Upgrading file: {1} % Completed.
progress-creating-base-entry=Creating Base Entry {0}
progress-importing-ldif=Importing LDIF file {0}:
+progress-configuring-replication=Configuring Replication
+
+progress-configuring-replication-remote=Configuring Replication on {0}
progress-import-automatically-generated=Importing Automatically-Generated Data \
({0} Entries):
progress-starting=Starting Directory Server:
@@ -933,6 +1039,16 @@
progress-server-waiting-to-stop=Waiting for Server to stop...
progress-server-stopped=Server stopped.
file-does-not-exist=Path {0} does not exist.
+progress-creating-administrator=Creating Global Administrator
+administrator-already-registered=Administrator already registered.
+progress-creating-ads=Creating Registration Configuration
+progress-creating-ads-on-remote=Creating Registration Configuration on {0}
+progress-initializing-ads=Initializing Registration information
+progress-initializing-suffix=Initializing suffix {0} with the contents from \
+{1}:
+suffix-initialized-successfully=Suffix initialized successfully.
+global-administrator-description=The Administrator that can manage all the \
+OpenDS instances.
#
# Progress errors
@@ -960,7 +1076,7 @@
error-creating-base-entry=Error Creating Base Entry.
error-importing-ldif=Error Importing LDIF File.
error-import-automatically-generated=Error Importing Automatically- Generated \
-Data when invoked with arguments: {0}".
+Data when invoked with arguments: {0}.
error-starting-server-with-no-connection-handlers=Error Starting Server with \
no connection handlers: {0}.
error-starting-server=Error Starting Directory Server.
@@ -982,6 +1098,21 @@
using it.
error-copying-file=Error copying file {0} to {1}.
info-ignoring-file=Ignoring {0} since {1} exists.
+error-connecting-to-local=An unexpected error occurred connecting to the server.
+error-launching-initialization=Error launching initialization with contents \
+from server {0}.
+initialize-progress-with-percentage={0} entries processed ({1} % complete).
+no-entries-to-initialize=No entries found to initialize.
+initialize-progress-with-processed= {0} entries processed.
+initialize-progress-with-unprocessed={0} remaining to be processed.
+error-during-initialization-no-log=Error during the initialization with \
+contents from server {0}. Check the error logs of {0} for more information.
+error-during-initialization-log=Error during the initialization with \
+contents from server {0}. Last log details: {1}. Check the error logs of the \
+server for more information.
+error-pooling-initialization=Error reading the progress of the initialization \
+with contents from server {0}.
+
# Upgrade errors
error-failed-to-create-stage-directory=Failed to create staging directory {0}.
@@ -1171,7 +1302,9 @@
general-loading=Loading...
general-see-for-details=See {0} for a detailed log of this operation.
+not-available-label=<not available>
general-build-id=Build ID
general-unset=Unset
general-none=None
general-unspecified=Unspecified
+
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java
new file mode 100644
index 0000000..6475f9e
--- /dev/null
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java
@@ -0,0 +1,655 @@
+/*
+ * 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.quicksetup.ui;
+
+import java.awt.CardLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.security.cert.X509Certificate;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JEditorPane;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+
+import org.opends.quicksetup.UserDataCertificateException;
+import org.opends.quicksetup.event.MinimumSizeComponentListener;
+import org.opends.quicksetup.i18n.ResourceProvider;
+import org.opends.quicksetup.util.Utils;
+
+/**
+ * This class is used to present the user a certificate to the user in order
+ * it to be accepted.
+ */
+public class CertificateDialog extends JDialog implements HyperlinkListener
+{
+ private static final long serialVersionUID = -8989965057591475064L;
+ private boolean isAccepted;
+ private UserDataCertificateException ce;
+ private JButton cancelButton;
+ private JButton okButton;
+ private JComponent certificateDetails;
+ private JEditorPane explanationPane;
+ private boolean detailsAlreadyClicked;
+ private String explanationWithHideDetails;
+ private String explanationWithShowDetails;
+
+ private static final Logger LOG = Logger.getLogger(
+ CertificateDialog.class.getName());
+
+ /**
+ * Constructor of the certificate dialog.
+ * @param parent the parent frame for this dialog.
+ * @param ce the UserDataCertificateException we use to get the informations
+ * about the certificate that was presented and the reason why it was
+ * rejected.
+ */
+ public CertificateDialog(JFrame parent, UserDataCertificateException ce)
+ {
+ super(parent);
+ this.ce = ce;
+ setTitle(getMsg("certificate-dialog-title"));
+ getContentPane().add(createPanel());
+ setModal(true);
+ pack();
+ if (getPreferredSize().width > parent.getWidth())
+ {
+ setPreferredSize(new Dimension(parent.getWidth() - 20,
+ getPreferredSize().height));
+ }
+ pack();
+ int minWidth = (int) getPreferredSize().getWidth();
+ int minHeight = (int) getPreferredSize().getHeight();
+ addComponentListener(new MinimumSizeComponentListener(this, minWidth,
+ minHeight));
+ getRootPane().setDefaultButton(cancelButton);
+
+ addWindowListener(new WindowAdapter()
+ {
+ public void windowClosing(WindowEvent e)
+ {
+ cancelClicked();
+ }
+ });
+ setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+
+ Utils.centerOnComponent(this, parent);
+ }
+
+ /**
+ * Wheter the user accepted the certificate or not.
+ * @return <CODE>true</CODE> ir the user accepted the certificate and
+ * <CODE>false</CODE> otherwise.
+ */
+ public boolean isAccepted()
+ {
+ return isAccepted;
+ }
+
+ /**
+ * Implements HyperlinkListener. When the user clicks on a link we assume
+ * that is the show details/hide details and we update the visible components
+ * accordingly.
+ *
+ * @param e the HyperlinkEvent.
+ */
+ public void hyperlinkUpdate(HyperlinkEvent e)
+ {
+ if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
+ {
+ boolean detailsVisible = !certificateDetails.isVisible();
+ explanationPane.setText(detailsVisible?
+ explanationWithHideDetails:explanationWithShowDetails);
+ certificateDetails.setVisible(detailsVisible);
+ if (detailsVisible && !detailsAlreadyClicked)
+ {
+ detailsAlreadyClicked = true;
+ pack();
+ }
+ }
+ }
+
+ /* The following three methods are just commodity methods to retrieve
+ * localized messages */
+ private String getMsg(String key)
+ {
+ return getI18n().getMsg(key);
+ }
+
+ private String getMsg(String key, String... args)
+ {
+ return getI18n().getMsg(key, args);
+ }
+
+ private ResourceProvider getI18n()
+ {
+ return ResourceProvider.getInstance();
+ }
+
+ /**
+ * Creates and returns the panel of the dialog.
+ * @return the panel of the dialog.
+ */
+ private JPanel createPanel()
+ {
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ JPanel contentPanel = new JPanel(new GridBagLayout());
+ contentPanel.setBackground(UIFactory.DEFAULT_BACKGROUND);
+ gbc.anchor = GridBagConstraints.NORTHWEST;
+ gbc.insets = UIFactory.getEmptyInsets();
+ gbc.fill = GridBagConstraints.BOTH;
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.weightx = 1.0;
+
+ JPanel topPanel = new JPanel(new GridBagLayout());
+ topPanel.setBorder(UIFactory.DIALOG_PANEL_BORDER);
+ topPanel.setBackground(UIFactory.CURRENT_STEP_PANEL_BACKGROUND);
+
+ gbc.weighty = 0.0;
+ gbc.insets = UIFactory.getCurrentStepPanelInsets();
+ topPanel.add(createTitlePanel(), gbc);
+ gbc.insets.top = UIFactory.TOP_INSET_INSTRUCTIONS_SUBPANEL;
+ topPanel.add(createTextPane(), gbc);
+ certificateDetails = createCertificateDetailsPane();
+ gbc.insets.top = 0;
+ gbc.insets.bottom = 0;
+ topPanel.add(Box.createHorizontalStrut(
+ certificateDetails.getPreferredSize().width), gbc);
+ gbc.insets.top = 0;
+ gbc.insets.bottom = UIFactory.TOP_INSET_INPUT_SUBPANEL;
+ gbc.weighty = 1.0;
+ topPanel.add(certificateDetails, gbc);
+ certificateDetails.setVisible(false);
+ gbc.weighty = 0.2;
+ gbc.insets = UIFactory.getEmptyInsets();
+ topPanel.add(Box.createVerticalGlue(), gbc);
+ contentPanel.add(topPanel, gbc);
+ gbc.weighty = 0.0;
+ gbc.insets = UIFactory.getButtonsPanelInsets();
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ contentPanel.add(createButtonsPanel(), gbc);
+
+ return contentPanel;
+ }
+
+ /**
+ * Creates and returns the title sub panel.
+ * @return the title sub panel.
+ */
+ private Component createTitlePanel()
+ {
+ JPanel titlePanel = new JPanel(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ titlePanel.setOpaque(false);
+ gbc.anchor = GridBagConstraints.NORTHWEST;
+ gbc.fill = GridBagConstraints.BOTH;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = GridBagConstraints.RELATIVE;
+
+ String title = getMsg("certificate-title");
+ JLabel l =
+ UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, title,
+ UIFactory.TextStyle.TITLE);
+ l.setOpaque(false);
+ titlePanel.add(l, gbc);
+
+ gbc.gridwidth = GridBagConstraints.RELATIVE;
+ gbc.anchor = GridBagConstraints.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.insets.left = 0;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ titlePanel.add(Box.createHorizontalGlue(), gbc);
+
+ return titlePanel;
+ }
+
+ /**
+ * Creates and returns the text sub panel.
+ * @return the text sub panel.
+ */
+ private Component createTextPane()
+ {
+ String text;
+ if (ce.getType() == UserDataCertificateException.Type.NOT_TRUSTED)
+ {
+ text = getMsg("certificate-not-trusted-text", ce.getHost(),
+ String.valueOf(ce.getPort()));
+ }
+ else
+ {
+ text = getMsg("certificate-name-mismatch-text",
+ ce.getHost(), String.valueOf(ce.getPort()));
+ }
+ JPanel p = new JPanel(new GridBagLayout());
+ p.setOpaque(false);
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.gridwidth = GridBagConstraints.RELATIVE;
+ gbc.anchor = GridBagConstraints.NORTHWEST;
+ p.add(UIFactory.makeJLabel(UIFactory.IconType.WARNING_LARGE, null,
+ UIFactory.TextStyle.NO_STYLE), gbc);
+ gbc.weightx = 1.0;
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.fill = GridBagConstraints.BOTH;
+ gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
+ gbc.insets.bottom = 0;
+ explanationPane = UIFactory.makeHtmlPane(null, UIFactory.INSTRUCTIONS_FONT);
+ explanationPane.setOpaque(false);
+ explanationPane.setEditable(false);
+ explanationPane.addHyperlinkListener(this);
+ p.add(explanationPane, gbc);
+ if ((ce.getChain() != null) && (ce.getChain().length > 0))
+ {
+ explanationWithShowDetails = UIFactory.applyFontToHtml(text +
+ getMsg("certificate-show-details-text"), UIFactory.INSTRUCTIONS_FONT);
+ explanationWithHideDetails = UIFactory.applyFontToHtml(text +
+ getMsg("certificate-hide-details-text"), UIFactory.INSTRUCTIONS_FONT);
+
+ explanationPane.setText(explanationWithShowDetails);
+ }
+ else
+ {
+ explanationPane.setText(text);
+ }
+ return p;
+ }
+
+ /**
+ * Creates and returns the buttons OK/CANCEL sub panel.
+ * @return the buttons OK/CANCEL sub panel.
+ */
+ private Component createButtonsPanel()
+ {
+ JPanel buttonsPanel = new JPanel(new GridBagLayout());
+ buttonsPanel.setOpaque(false);
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ gbc.gridwidth = 4;
+ gbc.insets = UIFactory.getEmptyInsets();
+ gbc.insets.left = UIFactory.getCurrentStepPanelInsets().left;
+ buttonsPanel.add(UIFactory.makeJLabel(UIFactory.IconType.OPENDS_SMALL,
+ null, UIFactory.TextStyle.NO_STYLE), gbc);
+ gbc.weightx = 1.0;
+ gbc.gridwidth--;
+ gbc.insets.left = 0;
+ buttonsPanel.add(Box.createHorizontalGlue(), gbc);
+ gbc.gridwidth = GridBagConstraints.RELATIVE;
+ gbc.fill = GridBagConstraints.NONE;
+ gbc.weightx = 0.0;
+ okButton =
+ UIFactory.makeJButton(getMsg("ok-button-label"),
+ getMsg("certificate-dialog-ok-button-tooltip"));
+ buttonsPanel.add(okButton, gbc);
+ okButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent ev)
+ {
+ okClicked();
+ }
+ });
+
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.insets.left = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS;
+ cancelButton =
+ UIFactory.makeJButton(getMsg("cancel-button-label"),
+ getMsg("certificate-dialog-cancel-button-tooltip"));
+ buttonsPanel.add(cancelButton, gbc);
+ cancelButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent ev)
+ {
+ cancelClicked();
+ }
+ });
+
+ return buttonsPanel;
+ }
+
+ /**
+ * Creates the panel containing a representation of the certificate chain.
+ * @return the panel containing a representation of the certificate chain.
+ */
+ private JComponent createCertificateDetailsPane()
+ {
+ JPanel p = new JPanel(new GridBagLayout());
+ p.setOpaque(false);
+ if ((ce.getChain() != null) && (ce.getChain().length > 0))
+ {
+ final JComboBox combo = new JComboBox();
+ combo.setToolTipText(getMsg("certificate-chain-combo-tooltip"));
+ final CardLayout cl = new CardLayout();
+ final JPanel cardPanel = new JPanel(cl);
+ final Map<String, JPanel> hmPanels = new HashMap<String, JPanel>();
+
+ String[] labels =
+ {
+ getMsg("certificate-subject-label"),
+ getMsg("certificate-issued-by-label"),
+ getMsg("certificate-valid-from-label"),
+ getMsg("certificate-expires-on-label"),
+ getMsg("certificate-type-label"),
+ getMsg("certificate-serial-number-label"),
+ getMsg("certificate-signature-label"),
+ getMsg("certificate-signature-algorithm-label"),
+ getMsg("certificate-version-label"),
+ getMsg("certificate-public-key-label")
+ };
+
+ for (int i=0; i<ce.getChain().length; i++)
+ {
+ X509Certificate cert = ce.getChain()[i];
+ JComponent[] components =
+ {
+ createSubjectComponent(cert),
+ createIssuedByComponent(cert),
+ createValidFromComponent(cert),
+ createExpiresOnComponent(cert),
+ createTypeComponent(cert),
+ createSerialNumberComponent(cert),
+ createSignatureComponent(cert),
+ createSignatureAlgorithmComponent(cert),
+ createVersionComponent(cert),
+ createPublicKeyComponent(cert)
+ };
+ JPanel certPanel = new JPanel(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.anchor = GridBagConstraints.NORTHWEST;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+
+ for (int j=0; j<labels.length; j++)
+ {
+ JLabel l = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
+ labels[j], UIFactory.TextStyle.PRIMARY_FIELD_VALID);
+
+ l.setLabelFor(components[j]);
+ if (j > 0)
+ {
+ gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+ }
+ gbc.gridwidth = GridBagConstraints.RELATIVE;
+ gbc.weightx = 0.0;
+ gbc.insets.left = 0;
+ certPanel.add(l, gbc);
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
+ certPanel.add(components[j], gbc);
+ }
+ String name = getName(cert);
+ hmPanels.put(name, certPanel);
+ cardPanel.add(name, certPanel);
+ combo.addItem(name);
+ }
+ GridBagConstraints gbc = new GridBagConstraints();
+ if (ce.getChain().length == 1)
+ {
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.fill = GridBagConstraints.BOTH;
+ p.add(cardPanel, gbc);
+
+ gbc.weighty = 1.0;
+ p.add(Box.createVerticalGlue(), gbc);
+ }
+ else
+ {
+ gbc.anchor = GridBagConstraints.WEST;
+ gbc.gridwidth = 3;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ JPanel auxPanel = new JPanel(new GridBagLayout());
+ JLabel l = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
+ getMsg("certificate-chain-label"),
+ UIFactory.TextStyle.PRIMARY_FIELD_VALID);
+ auxPanel.add(l, gbc);
+ gbc.gridwidth = GridBagConstraints.RELATIVE;
+ gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
+ auxPanel.add(combo, gbc);
+ l.setLabelFor(combo);
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.insets.left = 0;
+ gbc.weightx = 1.0;
+ auxPanel.add(Box.createHorizontalGlue(), gbc);
+
+ p.add(auxPanel, gbc);
+
+ gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
+ gbc.fill = GridBagConstraints.BOTH;
+ p.add(cardPanel, gbc);
+
+ gbc.weighty = 1.0;
+ p.add(Box.createVerticalGlue(), gbc);
+ }
+
+ combo.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent ev)
+ {
+ String selectedItem = (String)combo.getSelectedItem();
+ cl.show(hmPanels.get(selectedItem), selectedItem);
+ }
+ });
+ }
+ JScrollPane scroll = new JScrollPane(p);
+ scroll.setViewportBorder(new EmptyBorder(0, 0, 0, 0));
+ scroll.setOpaque(false);
+ scroll.getViewport().setOpaque(false);
+ scroll.setPreferredSize(new Dimension(scroll.getPreferredSize().width,
+ 175));
+ return scroll;
+ }
+
+ private JComponent createSubjectComponent(X509Certificate cert)
+ {
+ String dn = cert.getSubjectX500Principal().getName();
+ return makeValueLabel(dn);
+ }
+
+ private JComponent createIssuedByComponent(X509Certificate cert)
+ {
+ String dn = cert.getIssuerX500Principal().getName();
+ return makeValueLabel(dn);
+ }
+
+ private JComponent createValidFromComponent(X509Certificate cert)
+ {
+ JComponent c;
+
+ Date date = cert.getNotBefore();
+ DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT,
+ DateFormat.SHORT);
+ String value = df.format(date);
+ boolean isNotValidYet = false;
+ long t1 = System.currentTimeMillis();
+ long t2 = date.getTime();
+ isNotValidYet = t1 < t2;
+
+ if (isNotValidYet)
+ {
+ c = UIFactory.makeJLabel(UIFactory.IconType.ERROR,
+ getMsg("certificate-not-valid-yet", value),
+ UIFactory.TextStyle.SECONDARY_FIELD_INVALID);
+ }
+ else
+ {
+ c = makeValueLabel(value);
+ }
+ return c;
+ }
+
+ private JComponent createExpiresOnComponent(X509Certificate cert)
+ {
+ JComponent c;
+
+ Date date = cert.getNotAfter();
+ DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT,
+ DateFormat.SHORT);
+ String value = df.format(date);
+ boolean isExpired = false;
+ long t1 = System.currentTimeMillis();
+ long t2 = date.getTime();
+ isExpired = t1 > t2;
+
+ if (isExpired)
+ {
+ c = UIFactory.makeJLabel(UIFactory.IconType.ERROR,
+ getMsg("certificate-expired", value),
+ UIFactory.TextStyle.SECONDARY_FIELD_INVALID);
+ }
+ else
+ {
+ c = makeValueLabel(value);
+ }
+ return c;
+ }
+
+ private JComponent createTypeComponent(X509Certificate cert)
+ {
+ String type = cert.getType();
+ return makeValueLabel(type);
+ }
+
+ private JComponent createSerialNumberComponent(X509Certificate cert)
+ {
+ String serialNumber = String.valueOf(cert.getSerialNumber());
+ return makeValueLabel(serialNumber);
+ }
+
+ private JComponent createSignatureComponent(X509Certificate cert)
+ {
+ String signature = String.valueOf(cert.getSignature());
+ return makeValueLabel(signature);
+ }
+
+ private JComponent createSignatureAlgorithmComponent(X509Certificate cert)
+ {
+ String signature = String.valueOf(cert.getSigAlgName());
+ return makeValueLabel(signature);
+ }
+
+ private JComponent createVersionComponent(X509Certificate cert)
+ {
+ String version = String.valueOf(cert.getVersion());
+ return makeValueLabel(version);
+ }
+
+ private JComponent createPublicKeyComponent(X509Certificate cert)
+ {
+ return UIFactory.makeTextPane(cert.getPublicKey().toString(),
+ UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+ }
+
+ private JLabel makeValueLabel(String value)
+ {
+ if (value == null)
+ {
+ value = getMsg("not-available-label");
+ }
+ return UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, value,
+ UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+ }
+
+ private String getName(X509Certificate cert)
+ {
+ String name = cert.getSubjectX500Principal().getName();
+ try
+ {
+ LdapName dn = new LdapName(name);
+ Rdn rdn = dn.getRdn(0);
+ name = rdn.getValue().toString();
+ }
+ catch (Throwable t)
+ {
+ LOG.log(Level.WARNING, "Error parsing subject dn: "+
+ cert.getSubjectX500Principal(), t);
+ }
+ return name;
+ }
+
+ /**
+ * Method called when user clicks on ok.
+ *
+ */
+ private void okClicked()
+ {
+ isAccepted = true;
+ dispose();
+ }
+
+ /**
+ * Method called when user clicks on cancel.
+ *
+ */
+ private void cancelClicked()
+ {
+ isAccepted = false;
+ dispose();
+ }
+
+ /**
+ * Method written for testing purposes.
+ * @param args the arguments to be passed to the test program.
+ */
+ /*
+ public static void main(String[] args)
+ {
+ try
+ {
+ // TODO
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ */
+}
+
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java
index 5415ca7..72bb85f 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java
@@ -48,6 +48,10 @@
/**
* The value associated with this is a String.
*/
+ HOST_NAME,
+ /**
+ * The value associated with this is a String.
+ */
SERVER_PORT,
/**
* The value associated with this is a String.
@@ -96,6 +100,10 @@
/**
* The value associated with this is a String.
*/
+ REPLICATION_PORT,
+ /**
+ * The value associated with this is a String.
+ */
REMOTE_SERVER_DN,
/**
* The value associated with this is a String.
@@ -110,6 +118,11 @@
*/
REMOTE_SERVER_PORT,
/**
+ * Whether the Remote Server Port is a secure port or not. The value
+ * associated with this is a Boolean.
+ */
+ REMOTE_SERVER_IS_SECURE_PORT,
+ /**
* The value associated with this is a String.
*/
GLOBAL_ADMINISTRATOR_UID,
@@ -122,6 +135,11 @@
*/
GLOBAL_ADMINISTRATOR_PWD_CONFIRM,
/**
+ * The value associated with this is a Map where the key is a ServerDescriptor
+ * and the value an Integer.
+ */
+ REMOTE_REPLICATION_PORT,
+ /**
* The value associated with this is a Boolean.
*/
SERVER_START,
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FramePanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FramePanel.java
index e006439..93a2cb4 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FramePanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FramePanel.java
@@ -35,8 +35,8 @@
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
-import javax.swing.Box;
import javax.swing.Icon;
+import javax.swing.JLabel;
import javax.swing.JPanel;
/**
@@ -64,6 +64,8 @@
private int stepsPanelHorizontalInsets;
+ private JLabel progressLabel;
+
/**
* The constructor of the FramePanel.
* @param stepsPanel the steps panel that on the top-left side of the
@@ -108,10 +110,17 @@
gbc.insets = UIFactory.getEmptyInsets();
add(currentPanelContainer, gbc);
+ progressLabel = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, null,
+ UIFactory.TextStyle.READ_ONLY);
+ gbc.weighty = 0.0;
+ gbc.insets.left = UIFactory.getStepsPanelInsets().left;
+ gbc.insets.bottom = UIFactory.getButtonsPanelInsets().bottom;
+ add(progressLabel, gbc);
gbc.gridwidth = GridBagConstraints.RELATIVE;
+ gbc.anchor = GridBagConstraints.WEST;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
- add(Box.createHorizontalGlue(), gbc);
+ add(progressLabel, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1.0;
@@ -142,6 +151,19 @@
}
/**
+ * This method sets up an icon on the bottom left side of the dialog.
+ * Generally this method is called with an animated gif that is passed to
+ * display progress.
+ * @param iconType the icon type to be set.
+ */
+ public void setProgressIcon(UIFactory.IconType iconType)
+ {
+ // For the moment we are lacking of a decent progress dialog to be
+ // displayed.
+ //progressLabel.setIcon(UIFactory.getImageIcon(iconType));
+ }
+
+ /**
* {@inheritDoc}
*
* This method has been overwritten to be able to have a transparency effect
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java
index 3a69f96..440b5be 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java
@@ -38,6 +38,7 @@
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.File;
+import java.security.cert.X509Certificate;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.logging.Level;
@@ -389,6 +390,43 @@
}
/**
+ * Updates the list of certificates accepted by the user in the trust manager
+ * based on the information stored in the UserDataCertificateException we got
+ * when trying to connect in secure mode.
+ * @param ce the UserDataCertificateException that contains the information to
+ * be used.
+ */
+ protected void acceptCertificateForException(UserDataCertificateException ce)
+ {
+ X509Certificate[] chain = ce.getChain();
+ String authType = ce.getAuthType();
+ String host = ce.getHost();
+
+ if ((chain != null) && (authType != null) && (host != null))
+ {
+ getTrustManager().acceptCertificate(chain, authType, host);
+ }
+ else
+ {
+ if (chain == null)
+ {
+ LOG.log(Level.WARNING,
+ "The chain is null for the UserDataCertificateException");
+ }
+ if (authType == null)
+ {
+ LOG.log(Level.WARNING,
+ "The auth type is null for the UserDataCertificateException");
+ }
+ if (host == null)
+ {
+ LOG.log(Level.WARNING,
+ "The host is null for the UserDataCertificateException");
+ }
+ }
+ }
+
+ /**
* Begins downloading webstart jars in another thread
* for WebStart applications only.
*/
@@ -511,8 +549,10 @@
protected void notifyListenersOfLog() {
File logFile = QuickSetupLog.getLogFile();
if (logFile != null) {
- notifyListeners(getMsg("general-see-for-details", logFile.getPath()) +
- formatter.getLineBreak());
+ notifyListeners(
+ getFormattedProgress(getMsg("general-see-for-details",
+ logFile.getPath())) +
+ formatter.getLineBreak());
}
}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetup.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetup.java
index 94e94b4..50276d2 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetup.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetup.java
@@ -248,7 +248,9 @@
{
final WizardStep cStep = getCurrentStep();
application.nextClicked(cStep, this);
- updateUserData(cStep);
+ BackgroundTask worker = new NextClickedBackgroundTask(cStep);
+ getDialog().workerStarted();
+ worker.startBackgroundTask();
}
private void updateUserData(final WizardStep cStep) {
@@ -278,7 +280,14 @@
if (displayConfirmation(ude.getLocalizedMessage(),
getMsg("confirmation-title")))
{
+ try
+ {
setCurrentStep(application.getNextWizardStep(cStep));
+ }
+ catch (Throwable t)
+ {
+ t.printStackTrace();
+ }
}
}
else
@@ -553,6 +562,29 @@
}
/**
+ * Displays a dialog asking the user to accept a certificate.
+ *
+ * @param ce
+ * the certificate exception that occurred.
+ * @param title
+ * the title of the dialog.
+ * @return <CODE>true</CODE> if the user confirms the message, or
+ * <CODE>false</CODE> if not.
+ */
+ private boolean askToAcceptCertificate(UserDataCertificateException ce)
+ {
+ boolean accept = false;
+ CertificateDialog dlg = new CertificateDialog(getDialog().getFrame(), ce);
+ dlg.pack();
+ dlg.setVisible(true);
+ if (dlg.isAccepted())
+ {
+ accept = true;
+ }
+ return accept;
+ }
+
+ /**
* Gets the string value for a given field name.
*
* @param fieldName
@@ -650,4 +682,78 @@
{
return Utils.isWebStart();
}
+
+ /**
+ * This is a class used when the user clicks on next and that extends
+ * BackgroundTask.
+ */
+ private class NextClickedBackgroundTask extends BackgroundTask
+ {
+ private WizardStep cStep;
+ public NextClickedBackgroundTask(WizardStep cStep)
+ {
+ this.cStep = cStep;
+ }
+
+ public Object processBackgroundTask() throws UserDataException {
+ try {
+ application.updateUserData(cStep, QuickSetup.this);
+ }
+ catch (UserDataException uide) {
+ throw uide;
+ }
+ catch (Throwable t) {
+ throw new UserDataException(cStep,
+ getThrowableMsg("bug-msg", t));
+ }
+ return null;
+ }
+
+ public void backgroundTaskCompleted(Object returnValue,
+ Throwable throwable) {
+ getDialog().workerFinished();
+
+ if (throwable != null)
+ {
+ if (!(throwable instanceof UserDataException))
+ {
+ LOG.log(Level.WARNING, "Unhandled exception.", throwable);
+ }
+ else
+ {
+ UserDataException ude = (UserDataException) throwable;
+ if (ude instanceof UserDataConfirmationException)
+ {
+ if (displayConfirmation(ude.getLocalizedMessage(),
+ getMsg("confirmation-title")))
+ {
+ setCurrentStep(application.getNextWizardStep(cStep));
+ }
+ }
+ else if (ude instanceof UserDataCertificateException)
+ {
+ final UserDataCertificateException ce =
+ (UserDataCertificateException)ude;
+ if (askToAcceptCertificate(ce))
+ {
+ /*
+ * Retry the click but now with the certificate accepted.
+ */
+ application.acceptCertificateForException(ce);
+ application.nextClicked(cStep, QuickSetup.this);
+ BackgroundTask worker = new NextClickedBackgroundTask(cStep);
+ getDialog().workerStarted();
+ worker.startBackgroundTask();
+ }
+ }
+ else
+ {
+ displayError(ude.getLocalizedMessage(), getMsg("error-title"));
+ }
+ }
+ } else {
+ setCurrentStep(application.getNextWizardStep(cStep));
+ }
+ }
+ }
}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java
index 6f40872..77cd309 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java
@@ -302,7 +302,7 @@
{
public void run()
{
- // TODO: here we could have an animated gif.
+ displayWorkingProgressImage(true);
setButtonEnabled(ButtonName.NEXT, false);
setButtonEnabled(ButtonName.PREVIOUS, false);
setButtonEnabled(ButtonName.FINISH, false);
@@ -325,7 +325,7 @@
{
public void run()
{
- // TO COMPLETE: here we could have an animated gif.
+ displayWorkingProgressImage(false);
setButtonEnabled(ButtonName.NEXT, true);
setButtonEnabled(ButtonName.PREVIOUS, true);
setButtonEnabled(ButtonName.FINISH, true);
@@ -543,4 +543,13 @@
li.buttonActionPerformed(be);
}
}
+
+ private void displayWorkingProgressImage(boolean display)
+ {
+ if (getFramePanel() instanceof FramePanel)
+ {
+ ((FramePanel)getFramePanel()).setProgressIcon(display ?
+ UIFactory.IconType.WAIT : UIFactory.IconType.NO_ICON);
+ }
+ }
}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ReviewPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ReviewPanel.java
index 3482c67..ae414cc 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ReviewPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ReviewPanel.java
@@ -68,7 +68,7 @@
addVerticalGlue(panel);
- JCheckBox chk = getCheckBox();
+ JComponent chk = getBottomComponent();
if (chk != null) {
gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
gbc.weighty = 0.0;
@@ -80,9 +80,11 @@
}
/**
- * Returns the start server check box.
- * If it does not exist creates the start server check box.
- * @return the start server check box.
+ * Returns the component that will placed at the bottom of the panel.
+ * In the case of the installer and the uninstaller this is basically the
+ * start server check box.
+ * If it does not exist creates the component.
+ * @return the component that will placed at the bottom of the panel.
*/
- protected abstract JCheckBox getCheckBox();
+ protected abstract JComponent getBottomComponent();
}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
index be5e00d..9152b8c 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
@@ -1497,6 +1497,10 @@
key = "wait-tiny";
break;
+ case WAIT:
+ key = "wait";
+ break;
+
default:
throw new IllegalArgumentException("Unknown iconName: " + iconType);
}
@@ -1577,6 +1581,10 @@
description = getMsg("help-wait-description");
break;
+ case WAIT:
+ description = getMsg("help-wait-description");
+ break;
+
case NO_ICON:
description = null;
break;
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
index 4b2077c..cfdc148 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
@@ -88,7 +88,7 @@
public Object getFieldValue(FieldName fieldName) {
Object value = null;
if (fieldName == FieldName.SERVER_START) {
- value = getCheckBox().isSelected();
+ value = getBottomComponent().isSelected();
}
return value;
}
@@ -230,7 +230,7 @@
/**
* {@inheritDoc}
*/
- protected JCheckBox getCheckBox()
+ protected JCheckBox getBottomComponent()
{
if (checkBox == null)
{
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
index ab56bdf..fc78b0e 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
@@ -38,20 +38,22 @@
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
-import java.net.ConnectException;
+import java.security.GeneralSecurityException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.naming.CommunicationException;
-import javax.naming.Context;
import javax.naming.NamingException;
-import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapName;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.TrustManager;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
+import org.opends.admin.ads.util.ConnectionUtils;
import org.opends.quicksetup.*;
import org.opends.quicksetup.webstart.JnlpProperties;
import org.opends.quicksetup.i18n.ResourceProvider;
@@ -67,8 +69,6 @@
private static final Logger LOG =
Logger.getLogger(Utils.class.getName());
- private static final int DEFAULT_LDAP_CONNECT_TIMEOUT = 3000;
-
private static final int BUFFER_SIZE = 1024;
private static final int MAX_LINE_WIDTH = 80;
@@ -757,6 +757,20 @@
return p.waitFor();
}
+ /**
+ * Returns the String that can be used to represent a given host name in a
+ * LDAP URL.
+ * This method must be used when we have IPv6 addresses (the address in the
+ * LDAP URL must be enclosed with brackets).
+ * @param host the host name.
+ * @return the String that can be used to represent a given host name in a
+ * LDAP URL.
+ */
+ public static String getHostNameForLdapUrl(String host)
+ {
+ return ConnectionUtils.getHostNameForLdapUrl(host);
+ }
+
// Very limited for the moment: apply only permissions to the current user and
// does not work in non-English environments... to work in non English we
// should use xcalcs but it does not come in the windows default install...
@@ -847,56 +861,83 @@
String pwd, int timeout, Hashtable<String, String> env)
throws NamingException
{
- if (env != null)
- { // We clone 'env' so that we can modify it freely
- env = new Hashtable<String, String>(env);
- } else
- {
- env = new Hashtable<String, String>();
- }
- env
- .put(Context.INITIAL_CONTEXT_FACTORY,
- "com.sun.jndi.ldap.LdapCtxFactory");
- env.put(Context.PROVIDER_URL, ldapURL);
- if (timeout >= 1)
- {
- env.put("com.sun.jndi.ldap.connect.timeout", String.valueOf(timeout));
- }
- if (dn != null)
- {
- env.put(Context.SECURITY_PRINCIPAL, dn);
- }
- if (pwd != null)
- {
- env.put(Context.SECURITY_CREDENTIALS, pwd);
- }
-
- /* Contains the DirContext and the Exception if any */
- final Object[] pair = new Object[]
- { null, null };
- final Hashtable fEnv = env;
- Thread t = new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- pair[0] = new InitialLdapContext(fEnv, null);
-
- } catch (NamingException ne)
- {
- pair[1] = ne;
-
- } catch (Throwable t)
- {
- pair[1] = t;
- }
- }
- });
- return getInitialLdapContext(t, pair, timeout);
+ return ConnectionUtils.createLdapContext(ldapURL, dn, pwd, timeout, env);
}
/**
+ * Creates an LDAPS connection and returns the corresponding LdapContext.
+ * This method uses the TrusteSocketFactory class so that the specified
+ * trust manager gets called during the SSL handshake. If trust manager is
+ * null, certificates are not verified during SSL handshake.
+ *
+ * @param ldapsURL the target *LDAPS* URL.
+ * @param dn passed as Context.SECURITY_PRINCIPAL if not null.
+ * @param pwd passed as Context.SECURITY_CREDENTIALS if not null.
+ * @param timeout passed as com.sun.jndi.ldap.connect.timeout if > 0.
+ * @param env null or additional environment properties.
+ * @param trustManager null or the trust manager to be invoked during SSL
+ * negociation.
+ *
+ * @return the established connection with the given parameters.
+ *
+ * @throws NamingException the exception thrown when instantiating
+ * InitialLdapContext.
+ *
+ * @see javax.naming.Context
+ * @see javax.naming.ldap.InitialLdapContext
+ * @see TrustedSocketFactory
+ */
+ public static InitialLdapContext createLdapsContext(String ldapsURL,
+ String dn, String pwd, int timeout, Hashtable<String, String> env,
+ TrustManager trustManager) throws NamingException {
+ return ConnectionUtils.createLdapsContext(ldapsURL, dn, pwd, timeout, env,
+ trustManager);
+ }
+
+ /**
+ * Creates an LDAP+StartTLS connection and returns the corresponding
+ * LdapContext.
+ * This method first creates an LdapContext with anonymous bind. Then it
+ * requests a StartTlsRequest extended operation. The StartTlsResponse is
+ * setup with the specified hostname verifier. Negotiation is done using a
+ * TrustSocketFactory so that the specified TrustManager gets called during
+ * the SSL handshake.
+ * If trust manager is null, certificates are not checked during SSL
+ * handshake.
+ *
+ * @param ldapsURL the target *LDAPS* URL.
+ * @param dn passed as Context.SECURITY_PRINCIPAL if not null.
+ * @param pwd passed as Context.SECURITY_CREDENTIALS if not null.
+ * @param timeout passed as com.sun.jndi.ldap.connect.timeout if > 0.
+ * @param env null or additional environment properties.
+ * @param trustManager null or the trust manager to be invoked during SSL.
+ * negociation.
+ * @param verifier null or the hostname verifier to be setup in the
+ * StartTlsResponse.
+ *
+ * @return the established connection with the given parameters.
+ *
+ * @throws NamingException the exception thrown when instantiating
+ * InitialLdapContext.
+ *
+ * @see javax.naming.Context
+ * @see javax.naming.ldap.InitialLdapContext
+ * @see javax.naming.ldap.StartTlsRequest
+ * @see javax.naming.ldap.StartTlsResponse
+ * @see TrustedSocketFactory
+ */
+
+ public static InitialLdapContext createStartTLSContext(String ldapsURL,
+ String dn, String pwd, int timeout, Hashtable<String, String> env,
+ TrustManager trustManager, HostnameVerifier verifier)
+ throws NamingException
+ {
+ return ConnectionUtils.createStartTLSContext(ldapsURL, dn, pwd, timeout,
+ env, trustManager, verifier);
+ }
+
+
+ /**
* Method used to know if we can connect as administrator in a server with a
* given password and dn.
* @param ldapUrl the ldap URL of the server.
@@ -908,33 +949,40 @@
public static boolean canConnectAsAdministrativeUser(String ldapUrl,
String dn, String pwd)
{
- boolean canConnectAsAdministrativeUser = false;
- try
- {
- InitialLdapContext ctx =
- Utils.createLdapContext(ldapUrl, dn, pwd,
- Utils.getDefaultLDAPTimeout(), null);
+ return ConnectionUtils.canConnectAsAdministrativeUser(ldapUrl, dn, pwd);
+ }
- /*
- * Search for the config to check that it is the directory manager.
- */
- SearchControls searchControls = new SearchControls();
- searchControls.setCountLimit(1);
- searchControls.setSearchScope(
- SearchControls. OBJECT_SCOPE);
- searchControls.setReturningAttributes(
- new String[] {"dn"});
- ctx.search("cn=config", "objectclass=*", searchControls);
+/**
+ * Tells whether the provided Throwable was caused because of a problem with
+ * a certificate while trying to establish a connection.
+ * @param t the Throwable to analyze.
+ * @return <CODE>true</CODE> if the provided Throwable was caused because of a
+ * problem with a certificate while trying to establish a connection and
+ * <CODE>false</CODE> otherwise.
+ */
+ public static boolean isCertificateException(Throwable t)
+ {
+ boolean returnValue = false;
- canConnectAsAdministrativeUser = true;
- } catch (NamingException ne)
+ while (!returnValue && (t != null))
{
- // Nothing to do.
- } catch (Throwable t)
- {
- throw new IllegalStateException("Unexpected throwable.", t);
+ returnValue = (t instanceof SSLHandshakeException) ||
+ (t instanceof GeneralSecurityException);
+ t = t.getCause();
}
- return canConnectAsAdministrativeUser;
+
+ return returnValue;
+ }
+
+ /**
+ * Returns the default LDAP timeout in milliseconds when we try to connect to
+ * a server.
+ * @return the default LDAP timeout in milliseconds when we try to connect to
+ * a server.
+ */
+ public static int getDefaultLDAPTimeout()
+ {
+ return ConnectionUtils.getDefaultLDAPTimeout();
}
/**
@@ -999,7 +1047,7 @@
String title)
{
return JOptionPane.YES_OPTION == JOptionPane.showOptionDialog(
- parent, msg, title, JOptionPane.YES_NO_OPTION,
+ parent, wrapMsg(msg, 100), title, JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null, // don't use a custom
// Icon
null, // the titles of buttons
@@ -1018,7 +1066,7 @@
*/
public static void displayError(Component parent, String msg, String title)
{
- JOptionPane.showMessageDialog(parent, msg, title,
+ JOptionPane.showMessageDialog(parent, wrapMsg(msg, 100), title,
JOptionPane.ERROR_MESSAGE);
}
@@ -1035,7 +1083,7 @@
public static void displayInformationMessage(JFrame parent, String msg,
String title)
{
- JOptionPane.showMessageDialog(parent, msg, title,
+ JOptionPane.showMessageDialog(parent, wrapMsg(msg, 100), title,
JOptionPane.INFORMATION_MESSAGE);
}
@@ -1087,95 +1135,6 @@
return outsideLogs;
}
- /**
- * This is just a commodity method used to try to get an InitialLdapContext.
- * @param t the Thread to be used to create the InitialLdapContext.
- * @param pair an Object[] array that contains the InitialLdapContext and the
- * Throwable if any occurred.
- * @param timeout the timeout. If we do not get to create the connection
- * before the timeout a CommunicationException will be thrown.
- * @return the created InitialLdapContext
- * @throws NamingException if something goes wrong during the creation.
- */
- private static InitialLdapContext getInitialLdapContext(Thread t,
- Object[] pair, int timeout) throws NamingException
- {
- try
- {
- if (timeout > 0)
- {
- t.start();
- t.join(timeout);
- } else
- {
- t.run();
- }
-
- } catch (InterruptedException x)
- {
- // This might happen for problems in sockets
- // so it does not necessarily imply a bug
- }
-
- boolean throwException = false;
-
- if ((timeout > 0) && t.isAlive())
- {
- t.interrupt();
- try
- {
- t.join(2000);
- } catch (InterruptedException x)
- {
- // This might happen for problems in sockets
- // so it does not necessarily imply a bug
- }
- throwException = true;
- }
-
- if ((pair[0] == null) && (pair[1] == null))
- {
- throwException = true;
- }
-
- if (throwException)
- {
- NamingException xx;
- ConnectException x = new ConnectException("Connection timed out");
- xx = new CommunicationException("Connection timed out");
- xx.initCause(x);
- throw xx;
- }
-
- if (pair[1] != null)
- {
- if (pair[1] instanceof NamingException)
- {
- throw (NamingException) pair[1];
-
- } else if (pair[1] instanceof RuntimeException)
- {
- throw (RuntimeException) pair[1];
-
- } else if (pair[1] instanceof Throwable)
- {
- throw new IllegalStateException("Unexpected throwable occurred",
- (Throwable) pair[1]);
- }
- }
- return (InitialLdapContext) pair[0];
- }
-
- /**
- * Returns the default LDAP timeout in milliseconds when we try to connect to
- * a server.
- * @return the default LDAP timeout in milliseconds when we try to connect to
- * a server.
- */
- public static int getDefaultLDAPTimeout()
- {
- return DEFAULT_LDAP_CONNECT_TIMEOUT;
- }
/**
@@ -1392,6 +1351,133 @@
}
/**
+ * Returns the String representation of the first value of an attribute in a
+ * LDAP entry.
+ * @param entry the entry.
+ * @param attrName the attribute name.
+ * @return the String representation of the first value of an attribute in a
+ * LDAP entry.
+ * @throws NamingException if there is an error processing the entry.
+ */
+ static public String getFirstValue(SearchResult entry, String attrName)
+ throws NamingException
+ {
+ return ConnectionUtils.getFirstValue(entry, attrName);
+ }
+
+ /**
+ * Private method used to wrap the messages that are displayed in dialogs
+ * of type JOptionPane.
+ * @param msg the message.
+ * @param width the maximum width of the column.
+ * @return the wrapped message.
+ */
+ private static String wrapMsg(String msg, int width)
+ {
+ StringBuilder buffer = new StringBuilder();
+ StringTokenizer lineTokenizer = new StringTokenizer(msg, "\n", true);
+ while (lineTokenizer.hasMoreTokens())
+ {
+ String line = lineTokenizer.nextToken();
+ if (line.equals("\n"))
+ {
+ // It's an end-of-line character, so append it as-is.
+ buffer.append(line);
+ }
+ else if (line.length() < width)
+ {
+ // The line fits in the specified width, so append it as-is.
+ buffer.append(line);
+ }
+ else
+ {
+ // The line doesn't fit in the specified width, so it needs to be
+ // wrapped. Do so at space boundaries.
+ StringBuilder lineBuffer = new StringBuilder();
+ StringBuilder delimBuffer = new StringBuilder();
+ StringTokenizer wordTokenizer = new StringTokenizer(line, " ", true);
+ while (wordTokenizer.hasMoreTokens())
+ {
+ String word = wordTokenizer.nextToken();
+ if (word.equals(" "))
+ {
+ // It's a space, so add it to the delim buffer only if the line
+ // buffer is not empty.
+ if (lineBuffer.length() > 0)
+ {
+ delimBuffer.append(word);
+ }
+ }
+ else if (word.length() > width)
+ {
+ // This is a long word that can't be wrapped, so we'll just have to
+ // make do.
+ if (lineBuffer.length() > 0)
+ {
+ buffer.append(lineBuffer);
+ buffer.append("\n");
+ lineBuffer = new StringBuilder();
+ }
+ buffer.append(word);
+
+ if (wordTokenizer.hasMoreTokens())
+ {
+ // The next token must be a space, so remove it. If there are
+ // still more tokens after that, then append an EOL.
+ wordTokenizer.nextToken();
+ if (wordTokenizer.hasMoreTokens())
+ {
+ buffer.append("\n");
+ }
+ }
+
+ if (delimBuffer.length() > 0)
+ {
+ delimBuffer = new StringBuilder();
+ }
+ }
+ else
+ {
+ // It's not a space, so see if we can fit it on the current line.
+ int newLineLength = lineBuffer.length() + delimBuffer.length() +
+ word.length();
+ if (newLineLength < width)
+ {
+ // It does fit on the line, so add it.
+ lineBuffer.append(delimBuffer).append(word);
+
+ if (delimBuffer.length() > 0)
+ {
+ delimBuffer = new StringBuilder();
+ }
+ }
+ else
+ {
+ // It doesn't fit on the line, so end the current line and start
+ // a new one.
+ buffer.append(lineBuffer);
+ buffer.append("\n");
+
+ lineBuffer = new StringBuilder();
+ lineBuffer.append(word);
+
+ if (delimBuffer.length() > 0)
+ {
+ delimBuffer = new StringBuilder();
+ }
+ }
+ }
+ }
+
+ // If there's anything left in the line buffer, then add it to the
+ // final buffer.
+ buffer.append(lineBuffer);
+ }
+ }
+ return buffer.toString();
+ }
+
+ /**
* Inserts HTML break tags into <code>d</code> breaking it up
* so that no line is longer than <code>maxll</code>.
* @param d String to break
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java
index 22c9722..d7b366b 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java
+++ b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java
@@ -835,17 +835,7 @@
private String getFirstValue(SearchResult entry, String attrName)
throws NamingException
{
- String v = null;
- Attributes attrs = entry.getAttributes();
- if (attrs != null)
- {
- Attribute attr = attrs.get(attrName);
- if ((attr != null) && (attr.size() > 0))
- {
- v = (String)attr.get();
- }
- }
- return v;
+ return Utils.getFirstValue(entry, attrName);
}
private Set<String> getValues(SearchResult entry, String attrName)
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
index ccdd7b6..0588ec8 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
+++ b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
@@ -49,7 +49,6 @@
quit-status-panel-button-tooltip=Quit Status Panel
server-status-title=Server Status
server-status-label=Server Run Status:
-not-available-label=<not available>
not-available-server-down-tooltip=<html>Information is only available if \
server is running and you are authenticated<br>as an administrative user.
not-available-authentication-required-tooltip=<html>Information is only \
--
Gitblit v1.10.0