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 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); } } 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. */ 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"), 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); } } opends/src/quicksetup/org/opends/quicksetup/UserDataCertificateException.java
New file @@ -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; } } 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. */ opends/src/quicksetup/org/opends/quicksetup/images/wait.gif
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; } } 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, 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); } } 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; } } 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) { 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); } /** 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); } } opends/src/quicksetup/org/opends/quicksetup/installer/ui/RemoteReplicationPortsPanel.java
New file @@ -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; } } 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; 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, 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); 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) { 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 opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java
New file @@ -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(); } } */ } 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, 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 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()); } } 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)); } } } } 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); } } } 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(); } 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; 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) { 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 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) 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 \