opends/src/ads/org/opends/admin/ads/ADSContext.java
@@ -338,7 +338,7 @@ } private static HashMap<String, AdministratorProperty> nameToAdminUSerProperty = null; nameToAdminUserProperty = null; /** * Get a AdministratorProperty associated to a name. @@ -347,17 +347,17 @@ * @return The corresponding AdministratorProperty or null if name * doesn't match with an existing property. */ public static AdministratorProperty getAdminUSerPropFromName(String name) public static AdministratorProperty getAdminUserPropFromName(String name) { if (nameToAdminUSerProperty == null) if (nameToAdminUserProperty == null) { nameToAdminUSerProperty = new HashMap<String, AdministratorProperty>(); nameToAdminUserProperty = new HashMap<String, AdministratorProperty>(); for (AdministratorProperty u : AdministratorProperty.values()) { nameToAdminUSerProperty.put(u.getAttributeName(), u); nameToAdminUserProperty.put(u.getAttributeName(), u); } } return nameToAdminUSerProperty.get(name); return nameToAdminUserProperty.get(name); } // The context used to retrieve information @@ -898,6 +898,8 @@ * So this should not be called by the Java Web Start before being sure that * this jar is loaded. * @param backendName the backend name which will handle admin information. * <CODE>null</CODE> to use the default backend name for the admin * information. * @throws ADSContextException if something goes wrong. */ public void createAdminData(String backendName) throws ADSContextException opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
@@ -27,17 +27,14 @@ package org.opends.admin.ads; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.Context; import javax.naming.NameNotFoundException; import javax.naming.NamingEnumeration; import javax.naming.NamingException; @@ -181,6 +178,69 @@ } /** * Tells whether this server is a replication server or not. * @return <CODE>true</CODE> if the server is a replication server and * <CODE>false</CODE> otherwise. */ public boolean isReplicationServer() { return Boolean.TRUE.equals( serverProperties.get(ServerProperty.IS_REPLICATION_SERVER)); } /** * Returns the String representation of this replication server based * on the information we have ("hostname":"replication port") and * <CODE>null</CODE> if this is not a replication server. * @return the String representation of this replication server based * on the information we have ("hostname":"replication port") and * <CODE>null</CODE> if this is not a replication server. */ public String getReplicationServerHostPort() { String hostPort = null; if (isReplicationServer()) { hostPort = getHostName().toLowerCase()+ ":" + getReplicationServerPort(); } return hostPort; } /** * Returns the replication server ID of this server and -1 if this is not a * replications server. * @return the replication server ID of this server and -1 if this is not a * replications server. */ public int getReplicationServerId() { int port = -1; if (isReplicationServer()) { port = (Integer)serverProperties.get( ServerProperty.REPLICATION_SERVER_ID); } return port; } /** * Returns the replication port of this server and -1 if this is not a * replications server. * @return the replication port of this server and -1 if this is not a * replications server. */ public int getReplicationServerPort() { int port = -1; if (isReplicationServer()) { port = (Integer)serverProperties.get( ServerProperty.REPLICATION_SERVER_PORT); } return port; } /** * Sets the ADS properties of the server. * @param adsProperties a Map containing the ADS properties of the server. */ @@ -405,6 +465,7 @@ adsProperties.put(adsProps[i][1], String.valueOf(port)); } } adsProperties.put(ADSContext.ServerProperty.ID, getHostPort(true)); } /** @@ -442,17 +503,9 @@ updateReplicas(desc, ctx); updateReplication(desc, ctx); String s = (String)ctx.getEnvironment().get(Context.PROVIDER_URL); try { URI ldapURL = new URI(s); desc.serverProperties.put(ServerProperty.HOST_NAME, ldapURL.getHost()); } catch (URISyntaxException use) { // This is really strange. Seems like a bug somewhere. LOG.log(Level.WARNING, "Error parsing ldap URL "+s, use); } desc.serverProperties.put(ServerProperty.HOST_NAME, ConnectionUtils.getHostName(ctx)); return desc; } @@ -683,7 +736,14 @@ if (areDnsEqual(replica.getSuffix().getDN(), dn)) { replica.setReplicationId(id); replica.setReplicationServers(replicationServers); // Keep the values of the replication servers in lower case // to make use of Sets as String simpler. LinkedHashSet<String> repServers = new LinkedHashSet<String>(); for (String s: replicationServers) { repServers.add(s.toLowerCase()); } replica.setReplicationServers(repServers); } } } @@ -724,8 +784,15 @@ desc.serverProperties.put(ServerProperty.REPLICATION_SERVER_ID, Integer.parseInt(v)); Set<String> values = getValues(sr, "ds-cfg-replication-server"); // Keep the values of the replication servers in lower case // to make use of Sets as String simpler. LinkedHashSet<String> repServers = new LinkedHashSet<String>(); for (String s: values) { repServers.add(s.toLowerCase()); } desc.serverProperties.put(ServerProperty.EXTERNAL_REPLICATION_SERVERS, values); repServers); } } catch (NameNotFoundException nse) opends/src/ads/org/opends/admin/ads/TopologyCache.java
@@ -36,12 +36,11 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.ldap.LdapName; import org.opends.admin.ads.ADSContext.ServerProperty; import org.opends.admin.ads.util.ApplicationTrustManager; import org.opends.admin.ads.util.ConnectionUtils; import org.opends.admin.ads.util.ServerLoader; /** @@ -72,27 +71,14 @@ * @param trustManager the ApplicationTrustManager that must be used to trust * certificates when we create connections to the registered servers to read * their configuration. * @throws TopologyCacheException if an error occurred reading the * authentication data in the DirContext associated with the provided * ADSContext. */ public TopologyCache(ADSContext adsContext, ApplicationTrustManager trustManager) throws TopologyCacheException { this.adsContext = adsContext; this.trustManager = trustManager; try { dn = (String)adsContext.getDirContext().getEnvironment().get( Context.SECURITY_PRINCIPAL); pwd = (String)adsContext.getDirContext().getEnvironment().get( Context.SECURITY_CREDENTIALS); } catch (NamingException ne) { throw new TopologyCacheException(TopologyCacheException.Type.BUG, ne); } dn = ConnectionUtils.getBindDN(adsContext.getDirContext()); pwd = ConnectionUtils.getBindPassword(adsContext.getDirContext()); } /** @@ -256,4 +242,13 @@ return new ServerLoader(serverProperties, dn, pwd, trustManager.createCopy()); } /** * Returns the adsContext used by this TopologyCache. * @return the adsContext used by this TopologyCache. */ public ADSContext getAdsContext() { return adsContext; } } opends/src/ads/org/opends/admin/ads/TopologyCacheException.java
@@ -141,6 +141,19 @@ } /** * Returns the host port representation of the server we where connected to * (or trying to connect) when this exception was generated. * @return the host port representation of the server we where connected to * (or trying to connect) when this exception was generated. */ public String getHostPort() { int index = ldapUrl.indexOf("//"); String hostPort = ldapUrl.substring(index + 2); return hostPort; } /** * Returns the ApplicationTrustManager that we were using when this exception * was generated. * @return the ApplicationTrustManager that we were using when this exception opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java
@@ -29,10 +29,13 @@ import java.io.IOException; import java.net.ConnectException; import java.net.URI; import java.security.GeneralSecurityException; import java.util.HashSet; import java.util.Hashtable; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.CommunicationException; import javax.naming.Context; @@ -58,6 +61,12 @@ { private static final int DEFAULT_LDAP_CONNECT_TIMEOUT = 10000; private static final String STARTTLS_PROPERTY = "org.opends.connectionutils.isstarttls"; static private final Logger LOG = Logger.getLogger(ConnectionUtils.class.getName()); /** * Private constructor: this class cannot be instantiated. */ @@ -313,8 +322,10 @@ throw xx; } result.addToEnvironment(STARTTLS_PROPERTY, "true"); if (fDn != null) { result.addToEnvironment(Context.SECURITY_AUTHENTICATION , "simple"); result.addToEnvironment(Context.SECURITY_PRINCIPAL, fDn); if (fPwd != null) @@ -338,6 +349,168 @@ return getInitialLdapContext(t, pair, timeout); } /** * Returns the LDAP URL used in the provided InitialLdapContext. * @param ctx the context to analyze. * @return the LDAP URL used in the provided InitialLdapContext. */ public static String getLdapUrl(InitialLdapContext ctx) { String s = null; try { s = (String)ctx.getEnvironment().get(Context.PROVIDER_URL); } catch (NamingException ne) { // This is really strange. Seems like a bug somewhere. LOG.log(Level.WARNING, "Naming exception getting environment of "+ctx, ne); } return s; } /** * Returns the host name used in the provided InitialLdapContext. * @param ctx the context to analyze. * @return the host name used in the provided InitialLdapContext. */ public static String getHostName(InitialLdapContext ctx) { String s = null; try { URI ldapURL = new URI(getLdapUrl(ctx)); s = ldapURL.getHost(); } catch (Throwable t) { // This is really strange. Seems like a bug somewhere. LOG.log(Level.WARNING, "Error getting host: "+t, t); } return s; } /** * Returns the port number used in the provided InitialLdapContext. * @param ctx the context to analyze. * @return the port number used in the provided InitialLdapContext. */ public static int getPort(InitialLdapContext ctx) { int port = -1; try { URI ldapURL = new URI(getLdapUrl(ctx)); port = ldapURL.getPort(); } catch (Throwable t) { // This is really strange. Seems like a bug somewhere. LOG.log(Level.WARNING, "Error getting port: "+t, t); } return port; } /** * Returns the host port representation of the server to which this * context is connected. * @param ctx the context to analyze. * @return the host port representation of the server to which this * context is connected. */ public static String getHostPort(InitialLdapContext ctx) { return getHostName(ctx)+":"+getPort(ctx); } /** * Returns the bind DN used in the provided InitialLdapContext. * @param ctx the context to analyze. * @return the bind DN used in the provided InitialLdapContext. */ public static String getBindDN(InitialLdapContext ctx) { String bindDN = null; try { bindDN = (String)ctx.getEnvironment().get(Context.SECURITY_PRINCIPAL); } catch (NamingException ne) { // This is really strange. Seems like a bug somewhere. LOG.log(Level.WARNING, "Naming exception getting environment of "+ctx, ne); } return bindDN; } /** * Returns the password used in the provided InitialLdapContext. * @param ctx the context to analyze. * @return the password used in the provided InitialLdapContext. */ public static String getBindPassword(InitialLdapContext ctx) { String bindPwd = null; try { bindPwd = (String)ctx.getEnvironment().get(Context.SECURITY_CREDENTIALS); } catch (NamingException ne) { // This is really strange. Seems like a bug somewhere. LOG.log(Level.WARNING, "Naming exception getting environment of "+ctx, ne); } return bindPwd; } /** * Tells whether we are using SSL in the provided InitialLdapContext. * @param ctx the context to analyze. * @return <CODE>true</CODE> if we are using SSL and <CODE>false</CODE> * otherwise. */ public static boolean isSSL(InitialLdapContext ctx) { boolean isSSL = false; String s = null; try { s = getLdapUrl(ctx); isSSL = s.toLowerCase().startsWith("ldaps"); } catch (Throwable t) { // This is really strange. Seems like a bug somewhere. LOG.log(Level.WARNING, "Error getting if is SSL "+t, t); } return isSSL; } /** * Tells whether we are using StartTLS in the provided InitialLdapContext. * @param ctx the context to analyze. * @return <CODE>true</CODE> if we are using StartTLS and <CODE>false</CODE> * otherwise. */ public static boolean isStartTLS(InitialLdapContext ctx) { boolean isStartTLS = false; try { isStartTLS = "true".equalsIgnoreCase((String)ctx.getEnvironment().get( STARTTLS_PROPERTY)); } catch (NamingException ne) { // This is really strange. Seems like a bug somewhere. LOG.log(Level.WARNING, "Naming exception getting environment of "+ctx, ne); } return isStartTLS; } /** * Method used to know if we can connect as administrator in a server with a @@ -354,21 +527,19 @@ boolean canConnectAsAdministrativeUser = false; try { InitialLdapContext ctx = createLdapContext(ldapUrl, dn, pwd, getDefaultLDAPTimeout(), null); InitialLdapContext ctx; if (ldapUrl.toLowerCase().startsWith("ldap:")) { ctx = createLdapContext(ldapUrl, dn, pwd, getDefaultLDAPTimeout(), null); } else { ctx = createLdapsContext(ldapUrl, dn, pwd, getDefaultLDAPTimeout(), null, null, null); } /* * 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); canConnectAsAdministrativeUser = true; canConnectAsAdministrativeUser = connectedAsAdministrativeUser(ctx); } catch (NamingException ne) { // Nothing to do. @@ -380,6 +551,40 @@ } /** * Method used to know if we are connected as administrator in a server with a * given InitialLdapContext. * @param ctx the context. * @return <CODE>true</CODE> if we are connected and read the configuration * and <CODE>false</CODE> otherwise. */ public static boolean connectedAsAdministrativeUser(InitialLdapContext ctx) { boolean connectedAsAdministrativeUser = false; try { /* * 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); connectedAsAdministrativeUser = true; } catch (NamingException ne) { // Nothing to do. } catch (Throwable t) { throw new IllegalStateException("Unexpected throwable.", t); } return connectedAsAdministrativeUser; } /** * 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 opends/src/guitools/org/opends/guitools/replicationcli/DisableReplicationUserData.java
New file @@ -0,0 +1,117 @@ /* * 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.guitools.replicationcli; /** * This class is used to store the information provided by the user to * disable replication. It is required because when we are in interactive * mode the ReplicationCliArgumentParser is not enough. * */ class DisableReplicationUserData extends ReplicationUserData { private String hostName; private int port; private boolean useStartTLS; private boolean useSSL; /** * Returns the host name of the server. * @return the host name of the server. */ String getHostName() { return hostName; } /** * Sets the host name of the server. * @param hostName the host name of the server. */ void setHostName(String hostName) { this.hostName = hostName; } /** * Returns the port of the server. * @return the port of the server. */ int getPort() { return port; } /** * Sets the port of the server. * @param port the port of the server. */ void setPort(int port) { this.port = port; } /** * Returns <CODE>true</CODE> if we must use SSL to connect to the server and * <CODE>false</CODE> otherwise. * @return <CODE>true</CODE> if we must use SSL to connect to the server and * <CODE>false</CODE> otherwise. */ boolean useSSL() { return useSSL; } /** * Sets whether we must use SSL to connect to the server or not. * @param useSSL whether we must use SSL to connect to the server or not. */ void setUseSSL(boolean useSSL) { this.useSSL = useSSL; } /** * Returns <CODE>true</CODE> if we must use StartTLS to connect to the server * and <CODE>false</CODE> otherwise. * @return <CODE>true</CODE> if we must use StartTLS to connect to the server * and <CODE>false</CODE> otherwise. */ boolean useStartTLS() { return useStartTLS; } /** * Sets whether we must use StartTLS to connect to the server or not. * @param useStartTLS whether we must use SSL to connect to the server or not. */ void setUseStartTLS(boolean useStartTLS) { this.useStartTLS = useStartTLS; } } opends/src/guitools/org/opends/guitools/replicationcli/EnableReplicationUserData.java
New file @@ -0,0 +1,325 @@ /* * 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.guitools.replicationcli; /** * This class is used to store the information provided by the user to enable * replication. It is required because when we are in interactive mode the * ReplicationCliArgumentParser is not enough. * */ class EnableReplicationUserData extends ReplicationUserData { private String hostName1; private int port1; private String bindDn1; private String pwd1; private boolean useStartTLS1; private boolean useSSL1; private int replicationPort1; private String hostName2; private int port2; private String pwd2; private String bindDn2; private boolean useStartTLS2; private boolean useSSL2; private int replicationPort2; /** * Returns the host name of the first server. * @return the host name of the first server. */ String getHostName1() { return hostName1; } /** * Sets the host name of the first server. * @param hostName1 the host name of the first server. */ void setHostName1(String hostName1) { this.hostName1 = hostName1; } /** * Returns the port of the first server. * @return the port of the first server. */ int getPort1() { return port1; } /** * Sets the port of the first server. * @param port1 the port of the first server. */ void setPort1(int port1) { this.port1 = port1; } /** * Returns the password for the first server. * @return the password for the first server. */ String getPwd1() { return pwd1; } /** * Sets the password for the first server. * @param pwd1 the password for the first server. */ void setPwd1(String pwd1) { this.pwd1 = pwd1; } /** * Returns <CODE>true</CODE> if we must use SSL to connect to the first * server and <CODE>false</CODE> otherwise. * @return <CODE>true</CODE> if we must use SSL to connect to the first * server and <CODE>false</CODE> otherwise. */ boolean useSSL1() { return useSSL1; } /** * Sets whether we must use SSL to connect to the first server or not. * @param useSSL1 whether we must use SSL to connect to the first server or * not. */ void setUseSSL1(boolean useSSL1) { this.useSSL1 = useSSL1; } /** * Returns <CODE>true</CODE> if we must use StartTLS to connect to the first * server and <CODE>false</CODE> otherwise. * @return <CODE>true</CODE> if we must use StartTLS to connect to the first * server and <CODE>false</CODE> otherwise. */ boolean useStartTLS1() { return useStartTLS1; } /** * Sets whether we must use StartTLS to connect to the first server or not. * @param useStartTLS1 whether we must use SSL to connect to the first server * or not. */ void setUseStartTLS1(boolean useStartTLS1) { this.useStartTLS1 = useStartTLS1; } /** * Returns the host name of the second server. * @return the host name of the second server. */ String getHostName2() { return hostName2; } /** * Sets the host name of the second server. * @param host2Name the host name of the second server. */ void setHostName2(String host2Name) { this.hostName2 = host2Name; } /** * Returns the port of the second server. * @return the port of the second server. */ int getPort2() { return port2; } /** * Sets the port of the second server. * @param port2 the port of the second server. */ void setPort2(int port2) { this.port2 = port2; } /** * Returns the password for the second server. * @return the password for the second server. */ String getPwd2() { return pwd2; } /** * Sets the password for the second server. * @param pwd2 the password for the second server. */ void setPwd2(String pwd2) { this.pwd2 = pwd2; } /** * Returns <CODE>true</CODE> if we must use SSL to connect to the second * server and <CODE>false</CODE> otherwise. * @return <CODE>true</CODE> if we must use SSL to connect to the second * server and <CODE>false</CODE> otherwise. */ boolean useSSL2() { return useSSL2; } /** * Sets whether we must use SSL to connect to the second server or not. * @param useSSL2 whether we must use SSL to connect to the second server or * not. */ void setUseSSL2(boolean useSSL2) { this.useSSL2 = useSSL2; } /** * Returns <CODE>true</CODE> if we must use StartTLS to connect to the second * server and <CODE>false</CODE> otherwise. * @return <CODE>true</CODE> if we must use StartTLS to connect to the second * server and <CODE>false</CODE> otherwise. */ boolean useStartTLS2() { return useStartTLS2; } /** * Sets whether we must use StartTLS to connect to the second server or not. * @param useStartTLS2 whether we must use SSL to connect to the second server * or not. */ void setUseStartTLS2(boolean useStartTLS2) { this.useStartTLS2 = useStartTLS2; } /** * Returns the dn to be used to bind to the first server. * @return the dn to be used to bind to the first server. */ String getBindDn1() { return bindDn1; } /** * Sets the dn to be used to bind to the first server. * @param bindDn1 the dn to be used to bind to the first server. */ void setBindDn1(String bindDn1) { this.bindDn1 = bindDn1; } /** * Returns the dn to be used to bind to the second server. * @return the dn to be used to bind to the second server. */ String getBindDn2() { return bindDn2; } /** * Sets the dn to be used to bind to the second server. * @param bindDn2 the dn to be used to bind to the second server. */ void setBindDn2(String bindDn2) { this.bindDn2 = bindDn2; } /** * Returns the replication port to be used on the first server if it is not * defined yet. * @return the replication port to be used on the first server if it is not * defined yet. */ int getReplicationPort1() { return replicationPort1; } /** * Sets the replication port to be used on the first server if it is not * defined yet. * @param replicationPort1 the replication port to be used on the first server * if it is not defined yet. */ void setReplicationPort1(int replicationPort1) { this.replicationPort1 = replicationPort1; } /** * Returns the replication port to be used on the second server if it is not * defined yet. * @return the replication port to be used on the second server if it is not * defined yet. */ int getReplicationPort2() { return replicationPort2; } /** * Sets the replication port to be used on the second server if it is not * defined yet. * @param replicationPort2 the replication port to be used on the second * server if it is not defined yet. */ void setReplicationPort2(int replicationPort2) { this.replicationPort2 = replicationPort2; } } opends/src/guitools/org/opends/guitools/replicationcli/InitializeReplicationUserData.java
New file @@ -0,0 +1,203 @@ /* * 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.guitools.replicationcli; /** * This class is used to store the information provided by the user to * initialize replication. It is required because when we are in interactive * mode the ReplicationCliArgumentParser is not enough. * */ class InitializeReplicationUserData extends ReplicationUserData { private String hostNameSource; private int portSource; private boolean useStartTLSSource; private boolean useSSLSource; private String hostNameDestination; private int portDestination; private boolean useStartTLSDestination; private boolean useSSLDestination; /** * Returns the host name of the source server. * @return the host name of the source server. */ String getHostNameSource() { return hostNameSource; } /** * Sets the host name of the source server. * @param hostNameSource the host name of the source server. */ void setHostNameSource(String hostNameSource) { this.hostNameSource = hostNameSource; } /** * Returns the port of the source server. * @return the port of the source server. */ int getPortSource() { return portSource; } /** * Sets the port of the source server. * @param portSource the port of the source server. */ void setPortSource(int portSource) { this.portSource = portSource; } /** * Returns <CODE>true</CODE> if we must use SSL to connect to the source * server and <CODE>false</CODE> otherwise. * @return <CODE>true</CODE> if we must use SSL to connect to the source * server and <CODE>false</CODE> otherwise. */ boolean useSSLSource() { return useSSLSource; } /** * Sets whether we must use SSL to connect to the source server or not. * @param useSSLSource whether we must use SSL to connect to the source server * or not. */ void setUseSSLSource(boolean useSSLSource) { this.useSSLSource = useSSLSource; } /** * Returns <CODE>true</CODE> if we must use StartTLS to connect to the source * server and <CODE>false</CODE> otherwise. * @return <CODE>true</CODE> if we must use StartTLS to connect to the source * server and <CODE>false</CODE> otherwise. */ boolean useStartTLSSource() { return useStartTLSSource; } /** * Sets whether we must use StartTLS to connect to the source server or not. * @param useStartTLSSource whether we must use SSL to connect to the source * server or not. */ void setUseStartTLSSource(boolean useStartTLSSource) { this.useStartTLSSource = useStartTLSSource; } /** * Returns the host name of the destination server. * @return the host name of the destination server. */ String getHostNameDestination() { return hostNameDestination; } /** * Sets the host name of the destination server. * @param hostNameDestination the host name of the destination server. */ void setHostNameDestination(String hostNameDestination) { this.hostNameDestination = hostNameDestination; } /** * Returns the port of the destination server. * @return the port of the destination server. */ int getPortDestination() { return portDestination; } /** * Sets the port of the destination server. * @param portDestination the port of the destination server. */ void setPortDestination(int portDestination) { this.portDestination = portDestination; } /** * Returns <CODE>true</CODE> if we must use SSL to connect to the destination * server and <CODE>false</CODE> otherwise. * @return <CODE>true</CODE> if we must use SSL to connect to the destination * server and <CODE>false</CODE> otherwise. */ boolean useSSLDestination() { return useSSLDestination; } /** * Sets whether we must use SSL to connect to the destination server or not. * @param useSSLDestination whether we must use SSL to connect to the * destination server or not. */ void setUseSSLDestination(boolean useSSLDestination) { this.useSSLDestination = useSSLDestination; } /** * Returns <CODE>true</CODE> if we must use StartTLS to connect to the * destination server and <CODE>false</CODE> otherwise. * @return <CODE>true</CODE> if we must use StartTLS to connect to the * destination server and <CODE>false</CODE> otherwise. */ boolean useStartTLSDestination() { return useStartTLSDestination; } /** * Sets whether we must use StartTLS to connect to the destination server or * not. * @param useStartTLSDestination whether we must use SSL to connect to the * destination server or not. */ void setUseStartTLSDestination(boolean useStartTLSDestination) { this.useStartTLSDestination = useStartTLSDestination; } } opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliException.java
New file @@ -0,0 +1,63 @@ /* * 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.guitools.replicationcli; import org.opends.messages.Message; import org.opends.server.types.OpenDsException; /** * The exception that is thrown during the replication command-line execution. * */ public class ReplicationCliException extends OpenDsException { private static final long serialVersionUID = -8085682356609610678L; private ReplicationCliReturnCode errorCode; /** * The constructor for the exception. * @param message the localized message. * @param errorCode the error code associated with this exception. * @param cause the cause that generated this exception. */ ReplicationCliException(Message message, ReplicationCliReturnCode errorCode, Throwable cause) { super(message, cause); this.errorCode = errorCode; } /** * Returns the error code associated with this exception. * @return the error code associated with this exception. */ public ReplicationCliReturnCode getErrorCode() { return errorCode; } } opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java
New file @@ -0,0 +1,3780 @@ /* * 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.guitools.replicationcli; import static org.opends.guitools.replicationcli.ReplicationCliReturnCode.*; import static org.opends.messages.AdminToolMessages.*; import static org.opends.messages.QuickSetupMessages.*; import static org.opends.messages.ToolMessages.*; import static org.opends.server.util.ServerConstants.MAX_LINE_WIDTH; import static org.opends.server.util.StaticUtils.wrapText; import java.io.OutputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.NamingException; import javax.naming.NoPermissionException; 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.ConnectionUtils; import org.opends.admin.ads.util.ServerLoader; import org.opends.messages.Message; import org.opends.messages.MessageBuilder; import org.opends.quicksetup.ApplicationException; import org.opends.quicksetup.CliApplicationHelper; import org.opends.quicksetup.Constants; import org.opends.quicksetup.event.ProgressUpdateEvent; import org.opends.quicksetup.event.ProgressUpdateListener; import org.opends.quicksetup.installer.InstallerHelper; import org.opends.quicksetup.installer.PeerNotFoundException; import org.opends.quicksetup.installer.offline.OfflineInstaller; import org.opends.quicksetup.util.PlainTextProgressMessageFormatter; 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.JNDIDirContextAdaptor; import org.opends.server.admin.client.ldap.LDAPManagementContext; import org.opends.server.admin.std.client.*; import org.opends.server.admin.std.meta.*; import org.opends.server.types.DN; import org.opends.server.types.NullOutputStream; import org.opends.server.types.OpenDsException; import org.opends.server.util.args.ArgumentException; /** * This class provides a tool that can be used to enable and disable replication * and also to initialize the contents of a replicated suffix with the contents * of another suffix. */ public class ReplicationCliMain extends CliApplicationHelper { /** * The fully-qualified name of this class. */ private static final String CLASS_NAME = ReplicationCliMain.class.getName(); private static final Logger LOG = Logger.getLogger(CliApplicationHelper.class.getName()); // The print stream to use for standard error. private PrintStream err; // The print stream to use for standard output. private PrintStream out; // The argument parser to be used. private ReplicationCliParser argParser; // The message formatter PlainTextProgressMessageFormatter formatter = new PlainTextProgressMessageFormatter(); /** * Constructor for the ReplicationCliMain object. * * @param out the print stream to use for standard output. * @param err the print stream to use for standard error. */ public ReplicationCliMain(PrintStream out, PrintStream err) { this.out = out; this.err = err; } /** * The main method for the replication tool. * * @param args the command-line arguments provided to this program. */ public static void main(String[] args) { int retCode = mainCLI(args, true, System.out, System.err); if(retCode != 0) { System.exit(retCode); } } /** * Parses the provided command-line arguments and uses that information to * run the replication tool. * * @param args the command-line arguments provided to this program. * * @return The error code. */ public static int mainCLI(String[] args) { return mainCLI(args, true, System.out, System.err); } /** * Parses the provided command-line arguments and uses that information to * run the replication tool. * * @param args The command-line arguments provided to this * program. * @param initializeServer Indicates whether to initialize the server. * @param outStream The output stream to use for standard output, or * <CODE>null</CODE> if standard output is not * needed. * @param errStream The output stream to use for standard error, or * <CODE>null</CODE> if standard error is not * needed. * @return The error code. */ public static int mainCLI(String[] args, boolean initializeServer, OutputStream outStream, OutputStream errStream) { PrintStream out; if (outStream == null) { out = NullOutputStream.printStream(); } else { out = new PrintStream(outStream); } PrintStream err; if (errStream == null) { err = NullOutputStream.printStream(); } else { err = new PrintStream(errStream); } ReplicationCliMain replicationCli = new ReplicationCliMain(out, err); return replicationCli.execute(args, initializeServer); } /** * Parses the provided command-line arguments and uses that information to * run the replication tool. * * @param args the command-line arguments provided to this program. * @param initializeServer Indicates whether to initialize the server. * * @return The error code. */ public int execute(String[] args, boolean initializeServer) { ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP; // Create the command-line argument parser for use with this // program. try { argParser = new ReplicationCliParser(CLASS_NAME); argParser.initializeParser(out); } catch (ArgumentException ae) { Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()); printErrorMessage(message); LOG.log(Level.SEVERE, "Complete error stack:", ae); returnValue = CANNOT_INITIALIZE_ARGS; } if (returnValue == SUCCESSFUL_NOP) { // Parse the command-line arguments provided to this program. try { argParser.parseArguments(args); } catch (ArgumentException ae) { Message message = ERR_ERROR_PARSING_ARGS.get(ae.getMessage()); printErrorMessage(message); err.println(argParser.getUsage()); LOG.log(Level.SEVERE, "Complete error stack:", ae); returnValue = ERROR_PARSING_ARGS; } } if (returnValue == SUCCESSFUL_NOP) { /* Check that the provided parameters are compatible. */ MessageBuilder buf = new MessageBuilder(); argParser.validateOptions(buf); if (buf.length() > 0) { err.println(wrapText(buf.toMessage(), MAX_LINE_WIDTH)); err.println(argParser.getUsage()); returnValue = ERROR_PARSING_ARGS; } } if (returnValue == SUCCESSFUL_NOP) { if (argParser.isEnableReplicationSubcommand()) { returnValue = enableReplication(); } else if (argParser.isDisableReplicationSubcommand()) { returnValue = disableReplication(); } else if (argParser.isInitializeReplicationSubcommand()) { returnValue = initializeReplication(); } else { err.println(wrapText(ERR_REPLICATION_VALID_SUBCOMMAND_NOT_FOUND.get(), MAX_LINE_WIDTH)); err.println(argParser.getUsage()); returnValue = ERROR_PARSING_ARGS; } } return returnValue.getReturnCode(); } /** * Displays an error message in the error output (wrapping it if necessary). * @param msg the error message to be displayed. */ protected void printErrorMessage(Message msg) { err.println(org.opends.server.util.StaticUtils.wrapText(msg, Utils.getCommandLineMaxLineWidth())); LOG.log(Level.SEVERE, msg.toString()); } /** * Displays a progress message in the error output (wrapping it if necessary). * @param msg the error message to be displayed. */ protected void printProgressMessage(Message msg) { if (!argParser.isQuiet()) { out.print(org.opends.server.util.StaticUtils.wrapText(msg, Utils.getCommandLineMaxLineWidth())); out.flush(); } LOG.log(Level.INFO, msg.toString()); } /** * Prints a line break in the standard output if we are not in quite mode. */ protected void printProgressLineBreak() { if (!argParser.isQuiet()) { out.println(); } } /** * Displays a warning message in the error output (wrapping it if necessary). * @param msg the warning message to be displayed. */ protected void printWarningMessage(Message msg) { if (!argParser.isQuiet()) { // TODO: decide if even in quiet mode we must display this message or not. out.print(org.opends.server.util.StaticUtils.wrapText(msg, Utils.getCommandLineMaxLineWidth())); out.flush(); } LOG.log(Level.WARNING, msg.toString()); } /** * Prints a line break in the standard output. */ protected void printLineBreak() { out.println(); } /** * Based on the data provided in the command-line it enables replication * between two servers. * @return the error code if the operation failed and 0 if it was successful. */ private ReplicationCliReturnCode enableReplication() { ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP; EnableReplicationUserData uData = new EnableReplicationUserData(); if (argParser.isInteractive()) { if (promptIfRequired(uData)) { returnValue = enableReplication(uData); } else { returnValue = USER_CANCELLED; } } else { initializeWithArgParser(uData); returnValue = enableReplication(uData); } return returnValue; } /** * Based on the data provided in the command-line it disables replication * in the server. * @return the error code if the operation failed and SUCCESSFUL if it was * successful. */ private ReplicationCliReturnCode disableReplication() { ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP; DisableReplicationUserData uData = new DisableReplicationUserData(); if (argParser.isInteractive()) { if (promptIfRequired(uData)) { returnValue = disableReplication(uData); } else { returnValue = USER_CANCELLED; } } else { initializeWithArgParser(uData); returnValue = disableReplication(uData); } return returnValue; } /** * Based on the data provided in the command-line it initializes replication * between two servers. * @return the error code if the operation failed and SUCCESSFUL if it was * successful. */ private ReplicationCliReturnCode initializeReplication() { ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP; InitializeReplicationUserData uData = new InitializeReplicationUserData(); if (argParser.isInteractive()) { if (promptIfRequired(uData)) { returnValue = initializeReplication(uData); } else { returnValue = USER_CANCELLED; } } else { initializeWithArgParser(uData); returnValue = initializeReplication(uData); } return returnValue; } /** * Updates the contents of the provided EnableReplicationUserData object * with the information provided in the command-line. If some information * is missing, ask the user to provide valid data. * We assume that if this method is called we are in interactive mode. * @param uData the object to be updated. * @return <CODE>true</CODE> if the object was successfully updated and * <CODE>false</CODE> if the user cancelled the operation. */ private boolean promptIfRequired(EnableReplicationUserData uData) { boolean cancelled = false; String adminPwd = argParser.getBindPasswordAdmin(); String adminUid = argParser.getAdministratorUID(); /* * Try to connect to the first server. */ String host1 = getValue(argParser.getHostName1(), argParser.getDefaultHostName1()); int port1 = getValue(argParser.getPort1(), argParser.getDefaultPort1()); String bindDn1 = getValue(argParser.getBindDn1(), argParser.getDefaultBindDn1()); String pwd1 = argParser.getBindPassword1(); if ((pwd1 == null) && (adminPwd != null) && (adminUid != null)) { // No information provided to connect to the first server. Try // to use global administrator. bindDn1 = ADSContext.getAdministratorDN(adminUid); pwd1 = adminPwd; } boolean useSSL1 = argParser.useSSL1(); boolean useStartTLS1 = argParser.useStartTLS1(); InitialLdapContext ctx1 = null; // Boolean used to only ask for the information that was not explicitly // provided the first time we ask. After we ask for all the information. boolean firstTimeAsked = (argParser.getHostName1() == null) || (argParser.getPort1() == -1) || (argParser.getBindDn1() == null) || (argParser.getBindPassword1() == null); while ((ctx1 == null) && !cancelled) { try { ctx1 = createContext(host1, port1, useSSL1, useStartTLS1, bindDn1, pwd1, getTrustManager()); } catch (NamingException ne) { LOG.log(Level.WARNING, "Error connecting to "+host1+":"+port1, ne); if (Utils.isCertificateException(ne)) { String usedUrl = getLDAPUrl(host1, port1, useSSL1); if (!promptForCertificateConfirmation(ne, getTrustManager(), usedUrl)) { cancelled = true; } } else { if (pwd1 != null) { printLineBreak(); printErrorMessage(ERR_ERROR_CONNECTING_TO_SERVER_PROMPT_AGAIN.get( host1+":"+port1)); } printLineBreak(); if (!firstTimeAsked || (argParser.getHostName1() == null)) { host1 = promptForString( INFO_REPLICATION_ENABLE_HOSTNAME1_PROMPT.get(), getValue(host1, argParser.getDefaultHostName1())); } if (!firstTimeAsked || (argParser.getPort1() == -1)) { port1 = promptForPort(INFO_REPLICATION_ENABLE_PORT1_PROMPT.get(), getValue(port1, argParser.getDefaultPort1())); } if (!firstTimeAsked || (argParser.getBindDn1() == null)) { bindDn1 = promptForString( INFO_REPLICATION_BINDDN_PROMPT.get(), getValue(bindDn1, argParser.getDefaultBindDn1())); } if (!firstTimeAsked || (argParser.getBindPassword1() == null)) { pwd1 = promptForPassword(INFO_REPLICATION_PASSWORD_PROMPT.get()); } if (!firstTimeAsked || (!useSSL1 && !useStartTLS1)) { useSSL1 = confirm(INFO_REPLICATION_USESSL_PROMPT.get(), useSSL1); if (!useSSL1) { useStartTLS1 = confirm(INFO_REPLICATION_USESTARTTLS_PROMPT.get(), useStartTLS1); } } firstTimeAsked = false; } } } if (!cancelled) { uData.setHostName1(host1); uData.setPort1(port1); uData.setBindDn1(bindDn1); uData.setPwd1(pwd1); uData.setUseSSL1(useSSL1); uData.setUseStartTLS1(useStartTLS1); } if (ctx1 != null) { // Try to get the replication port for server 1 only if the user did // not explicitly provide it and if it is required. int replicationPort1 = argParser.getReplicationPort1(); if (replicationPort1 == -1) { if (!hasReplicationPort(ctx1)) { while (replicationPort1 == -1) { replicationPort1 = promptForPort( INFO_REPLICATION_ENABLE_REPLICATIONPORT1_PROMPT.get(), argParser.getDefaultReplicationPort1()); if (replicationPort1 == port1) { replicationPort1 = -1; printLineBreak(); printErrorMessage( ERR_REPLICATION_PORT_AND_REPLICATION_PORT_EQUAL.get( String.valueOf(port1))); } } uData.setReplicationPort1(replicationPort1); } } else { uData.setReplicationPort1(replicationPort1); } // If the server contains an ADS. Try to load it and only load it: if // there are issues with the ADS they will be encountered in the // enableReplication(EnableReplicationUserData) method. Here we have // to load the ADS to ask the user to accept the certificates and // eventually admin authentication data. cancelled = loadADSAndAcceptCertificates(ctx1, uData, true); } /* * Try to connect to the second server. */ String host2 = getValue(argParser.getHostName2(), argParser.getDefaultHostName2()); int port2 = getValue(argParser.getPort2(), argParser.getDefaultPort2()); String bindDn2 = getValue(argParser.getBindDn2(), argParser.getDefaultBindDn2()); String pwd2 = argParser.getBindPassword2(); if ((pwd2 == null) && (adminPwd != null) && (adminUid != null)) { // No information provided to connect to the second server. Try // to use global administrator. bindDn2 = ADSContext.getAdministratorDN(adminUid); pwd2 = adminPwd; } boolean useSSL2 = argParser.useSSL2(); boolean useStartTLS2 = argParser.useStartTLS2(); InitialLdapContext ctx2 = null; firstTimeAsked = (argParser.getHostName2() == null) || (argParser.getPort2() == -1) || (argParser.getBindDn2() == null) || (argParser.getBindPassword2() == null); while ((ctx2 == null) && !cancelled) { try { ctx2 = createContext(host2, port2, useSSL2, useStartTLS2, bindDn2, pwd2, getTrustManager()); } catch (NamingException ne) { LOG.log(Level.WARNING, "Error connecting to "+host2+":"+port2, ne); if (Utils.isCertificateException(ne)) { String usedUrl = getLDAPUrl(host2, port2, useSSL2); if (!promptForCertificateConfirmation(ne, getTrustManager(), usedUrl)) { cancelled = true; } } else { if (pwd2 != null) { printLineBreak(); printErrorMessage(ERR_ERROR_CONNECTING_TO_SERVER_PROMPT_AGAIN.get( host2+":"+port2)); } printLineBreak(); if (!firstTimeAsked || (argParser.getHostName2() == null)) { host2 = promptForString( INFO_REPLICATION_ENABLE_HOSTNAME2_PROMPT.get(), getValue(host2, argParser.getDefaultHostName2())); } if (!firstTimeAsked || (argParser.getPort2() == -1)) { port2 = promptForPort(INFO_REPLICATION_ENABLE_PORT2_PROMPT.get(), getValue(port2, argParser.getDefaultPort2())); } if (!firstTimeAsked || (argParser.getBindDn2() == null)) { bindDn2 = promptForString( INFO_REPLICATION_BINDDN_PROMPT.get(), getValue(bindDn2, argParser.getDefaultBindDn2())); } if (!firstTimeAsked || (argParser.getBindPassword2() == null)) { pwd2 = promptForPassword(INFO_REPLICATION_PASSWORD_PROMPT.get()); } if (!firstTimeAsked || !useSSL2 || !useStartTLS2) { useSSL2 = confirm(INFO_REPLICATION_USESSL_PROMPT.get(), useSSL2); if (!useSSL2) { useStartTLS2 = confirm(INFO_REPLICATION_USESTARTTLS_PROMPT.get(), useStartTLS2); } } firstTimeAsked = false; } } } if (!cancelled) { uData.setHostName2(host2); uData.setPort2(port2); uData.setBindDn2(bindDn2); uData.setPwd2(pwd2); uData.setUseSSL2(useSSL2); uData.setUseStartTLS2(useStartTLS2); } if (ctx2 != null) { int replicationPort2 = argParser.getReplicationPort2(); if (replicationPort2 == -1) { if (!hasReplicationPort(ctx2)) { while (replicationPort2 == -1) { replicationPort2 = promptForPort( INFO_REPLICATION_ENABLE_REPLICATIONPORT2_PROMPT.get(), argParser.getDefaultReplicationPort2()); if (replicationPort2 == port2) { replicationPort2 = -1; printLineBreak(); printErrorMessage( ERR_REPLICATION_PORT_AND_REPLICATION_PORT_EQUAL.get( String.valueOf(port2))); } } uData.setReplicationPort2(replicationPort2); } } else { uData.setReplicationPort2(replicationPort2); } // If the server contains an ADS. Try to load it and only load it: if // there are issues with the ADS they will be encountered in the // enableReplication(EnableReplicationUserData) method. Here we have // to load the ADS to ask the user to accept the certificates. cancelled = loadADSAndAcceptCertificates(ctx2, uData, false); } // If the adminUid and adminPwd are not set in the EnableReplicationUserData // object, that means that there are no administrators and that they // must be created. The adminUId and adminPwd are updated inside // loadADSAndAcceptCertificates. if (!cancelled && (uData.getAdminUid() == null)) { if (adminUid == null) { adminUid= askForAdministratorUID( argParser.getDefaultAdministratorUID()); } uData.setAdminUid(adminUid); } if (!cancelled && (uData.getAdminPwd() == null)) { boolean adminDefined = hasAdministrator(ctx1) || hasAdministrator(ctx2); while ((adminPwd == null) && !adminDefined) { adminPwd = askForAdministratorPwd(); String adminPwdConfirm = promptForPassword(INFO_ADMINISTRATOR_PWD_CONFIRM_PROMPT.get()); if (!adminPwd.equals(adminPwdConfirm)) { printErrorMessage(ERR_ADMINISTRATOR_PWD_DO_NOT_MATCH.get()); printLineBreak(); adminPwd = null; } } uData.setAdminPwd(adminPwd); } if (!cancelled) { LinkedList<String> suffixes = argParser.getBaseDNs(); checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, true); cancelled = suffixes.isEmpty(); uData.setBaseDNs(suffixes); } if (ctx1 != null) { try { ctx1.close(); } catch (Throwable t) { } } if (ctx2 != null) { try { ctx2.close(); } catch (Throwable t) { } } return cancelled; } /** * Updates the contents of the provided DisableReplicationUserData object * with the information provided in the command-line. If some information * is missing, ask the user to provide valid data. * We assume that if this method is called we are in interactive mode. * @param uData the object to be updated. * @return <CODE>true</CODE> if the object was successfully updated and * <CODE>false</CODE> if the user cancelled the operation. */ private boolean promptIfRequired(DisableReplicationUserData uData) { boolean cancelled = false; String adminPwd = argParser.getBindPasswordAdmin(); String adminUid = argParser.getAdministratorUID(); if (adminPwd == null) { adminPwd = askForAdministratorPwd(); } /* * Try to connect to the server. */ String host = getValue(argParser.getHostNameToDisable(), argParser.getDefaultHostNameToDisable()); int port = getValue(argParser.getPortToDisable(), argParser.getDefaultPortToDisable()); boolean useSSL = argParser.useSSLToDisable(); boolean useStartTLS = argParser.useStartTLSToDisable(); InitialLdapContext ctx = null; boolean firstTimeAsked = (argParser.getHostNameToDisable() == null) || (argParser.getPortToDisable() == -1) || (argParser.getAdministratorUID() == null) || (argParser.getBindPasswordAdmin() == null); while ((ctx == null) && !cancelled) { try { ctx = createContext(host, port, useSSL, useStartTLS, ADSContext.getAdministratorDN(adminUid), adminPwd, getTrustManager()); } catch (NamingException ne) { LOG.log(Level.WARNING, "Error connecting to "+host+":"+port, ne); if (Utils.isCertificateException(ne)) { String usedUrl = getLDAPUrl(host, port, useSSL); if (!promptForCertificateConfirmation(ne, getTrustManager(), usedUrl)) { cancelled = true; } } else { printLineBreak(); printErrorMessage(ERR_ERROR_CONNECTING_TO_SERVER_PROMPT_AGAIN.get( host+":"+port)); printLineBreak(); if (!firstTimeAsked || (argParser.getHostNameToDisable() == null)) { host = promptForString( INFO_REPLICATION_DISABLE_HOSTNAME_PROMPT.get(), getValue(host, argParser.getDefaultHostNameToDisable())); } if (!firstTimeAsked || (argParser.getPortToDisable() == -1)) { port = promptForPort( INFO_REPLICATION_DISABLE_PORT_PROMPT.get(), getValue(port, argParser.getDefaultPortToDisable())); } if (!firstTimeAsked || (argParser.getAdministratorUID() == null)) { adminUid = askForAdministratorUID(adminUid); } if (!firstTimeAsked || (argParser.getBindPasswordAdmin() == null)) { adminPwd = askForAdministratorPwd(); } if (!firstTimeAsked || useSSL) { useSSL = confirm(INFO_REPLICATION_USESSL_PROMPT.get(), useSSL); if (!useSSL) { useStartTLS = confirm(INFO_REPLICATION_USESTARTTLS_PROMPT.get(), useStartTLS); } } firstTimeAsked = false; } } } if (!cancelled) { uData.setHostName(host); uData.setPort(port); uData.setUseSSL(useSSL); uData.setUseStartTLS(useStartTLS); uData.setAdminUid(adminUid); uData.setAdminPwd(adminPwd); } if (ctx != null) { // If the server contains an ADS, try to load it and only load it: if // there are issues with the ADS they will be encountered in the // disableReplication(DisableReplicationUserData) method. Here we have // to load the ADS to ask the user to accept the certificates and // eventually admin authentication data. cancelled = loadADSAndAcceptCertificates(ctx, uData, false); } if (!cancelled) { LinkedList<String> suffixes = argParser.getBaseDNs(); checkSuffixesForDisableReplication(suffixes, ctx, true); cancelled = suffixes.isEmpty(); uData.setBaseDNs(suffixes); } if (!cancelled) { // Ask for confirmation to disable. boolean disableADS = false; for (String dn : uData.getBaseDNs()) { if (Utils.areDnsEqual(ADSContext.getAdministrationSuffixDN(), dn)) { disableADS = true; break; } } if (disableADS) { cancelled = !confirm(INFO_REPLICATION_CONFIRM_DISABLE_ADS.get( ADSContext.getAdministrationSuffixDN())); } else { cancelled = !confirm(INFO_REPLICATION_CONFIRM_DISABLE_GENERIC.get()); } } if (ctx != null) { try { ctx.close(); } catch (Throwable t) { } } return cancelled; } /** * Updates the contents of the provided InitializeReplicationUserData object * with the information provided in the command-line. If some information * is missing, ask the user to provide valid data. * We assume that if this method is called we are in interactive mode. * @param uData the object to be updated. * @return <CODE>true</CODE> if the object was successfully updated and * <CODE>false</CODE> if the user cancelled the operation. */ private boolean promptIfRequired(InitializeReplicationUserData uData) { boolean cancelled = false; String adminPwd = argParser.getBindPasswordAdmin(); String adminUid = argParser.getAdministratorUID(); if (adminPwd == null) { adminPwd = askForAdministratorPwd(); } /* * Try to connect to the source server. */ String hostSource = getValue(argParser.getHostNameSource(), argParser.getDefaultHostNameSource()); int portSource = getValue(argParser.getPortSource(), argParser.getDefaultPortSource()); boolean useSSLSource = argParser.useSSLSource(); boolean useStartTLSSource = argParser.useStartTLSSource(); InitialLdapContext ctxSource = null; boolean firstTimeAsked = (argParser.getHostNameSource() == null) || (argParser.getPortSource() == -1) || (argParser.getAdministratorUID() == null) || (argParser.getBindPasswordAdmin() == null); while ((ctxSource == null) && !cancelled) { try { ctxSource = createContext(hostSource, portSource, useSSLSource, useStartTLSSource, ADSContext.getAdministratorDN(adminUid), adminPwd, getTrustManager()); } catch (NamingException ne) { LOG.log(Level.WARNING, "Error connecting to "+hostSource+":"+portSource, ne); if (Utils.isCertificateException(ne)) { String usedUrl = getLDAPUrl(hostSource, portSource, useSSLSource); if (!promptForCertificateConfirmation(ne, getTrustManager(), usedUrl)) { cancelled = true; } } else { printLineBreak(); printErrorMessage(ERR_ERROR_CONNECTING_TO_SERVER_PROMPT_AGAIN.get( hostSource+":"+portSource)); printLineBreak(); if (!firstTimeAsked || (argParser.getHostNameSource() == null)) { hostSource = promptForString( INFO_REPLICATION_INITIALIZE_HOSTNAMESOURCE_PROMPT.get(), getValue(hostSource, argParser.getDefaultHostNameSource())); } if (!firstTimeAsked || (argParser.getPortSource() == -1)) { portSource = promptForPort( INFO_REPLICATION_INITIALIZE_PORTSOURCE_PROMPT.get(), getValue(portSource, argParser.getDefaultPortSource())); } if (!firstTimeAsked || (argParser.getAdministratorUID() == null)) { adminUid = askForAdministratorUID(adminUid); } if (!firstTimeAsked || (argParser.getBindPasswordAdmin() == null)) { adminPwd = askForAdministratorPwd(); } if (!firstTimeAsked || useSSLSource) { useSSLSource = confirm(INFO_REPLICATION_USESSL_PROMPT.get(), useSSLSource); if (!useSSLSource) { useStartTLSSource = confirm(INFO_REPLICATION_USESTARTTLS_PROMPT.get(), useStartTLSSource); } } firstTimeAsked = false; } } } if (!cancelled) { uData.setHostNameSource(hostSource); uData.setPortSource(portSource); uData.setUseSSLSource(useSSLSource); uData.setUseStartTLSSource(useStartTLSSource); uData.setAdminUid(adminUid); uData.setAdminPwd(adminPwd); } /* * Try to connect to the destination server. */ String hostDestination = getValue(argParser.getHostNameDestination(), argParser.getDefaultHostNameDestination()); int portDestination = getValue(argParser.getPortDestination(), argParser.getDefaultPortDestination()); boolean useSSLDestination = argParser.useSSLDestination(); boolean useStartTLSDestination = argParser.useStartTLSDestination(); InitialLdapContext ctxDestination = null; firstTimeAsked = (argParser.getHostNameDestination() == null) || (argParser.getPortDestination() == -1); while ((ctxDestination == null) && !cancelled) { try { ctxDestination = createContext(hostDestination, portDestination, useSSLDestination, useStartTLSDestination, ADSContext.getAdministratorDN(adminUid), adminPwd, getTrustManager()); } catch (NamingException ne) { LOG.log(Level.WARNING, "Error connecting to "+hostDestination+":"+ portDestination, ne); if (Utils.isCertificateException(ne)) { String usedUrl = getLDAPUrl(hostDestination, portDestination, useSSLDestination); if (!promptForCertificateConfirmation(ne, getTrustManager(), usedUrl)) { cancelled = true; } } else { printLineBreak(); printErrorMessage(ERR_ERROR_CONNECTING_TO_SERVER_PROMPT_AGAIN.get( hostDestination+":"+portDestination)); printLineBreak(); if (!firstTimeAsked || (argParser.getHostNameDestination() == null)) { hostDestination = promptForString( INFO_REPLICATION_INITIALIZE_HOSTNAMEDESTINATION_PROMPT.get(), getValue(hostDestination, argParser.getDefaultHostNameDestination())); } if (!firstTimeAsked || (argParser.getPortDestination() == -1)) { portDestination = promptForPort( INFO_REPLICATION_INITIALIZE_PORTDESTINATION_PROMPT.get(), getValue(portDestination, argParser.getDefaultPortDestination())); } if (!firstTimeAsked || useSSLDestination) { useSSLDestination = confirm(INFO_REPLICATION_USESSL_PROMPT.get(), useSSLDestination); if (!useSSLDestination) { useStartTLSDestination = confirm(INFO_REPLICATION_USESTARTTLS_PROMPT.get(), useStartTLSDestination); } } } } } if (!cancelled) { uData.setHostNameDestination(hostDestination); uData.setPortDestination(portDestination); uData.setUseSSLDestination(useSSLDestination); uData.setUseStartTLSDestination(useStartTLSDestination); } if (!cancelled) { LinkedList<String> suffixes = argParser.getBaseDNs(); checkSuffixesForInitializeReplication(suffixes, ctxSource, ctxDestination, true); cancelled = suffixes.isEmpty(); uData.setBaseDNs(suffixes); } if (!cancelled) { // Ask for confirmation to disable. boolean initializeADS = false; for (String dn : uData.getBaseDNs()) { if (Utils.areDnsEqual(ADSContext.getAdministrationSuffixDN(), dn)) { initializeADS = true; break; } } String hostPortSource = ConnectionUtils.getHostPort(ctxSource); String hostPortDestination = ConnectionUtils.getHostPort(ctxDestination); if (initializeADS) { cancelled = !confirm(INFO_REPLICATION_CONFIRM_INITIALIZE_ADS.get( ADSContext.getAdministrationSuffixDN(), hostPortDestination, hostPortSource)); } else { cancelled = !confirm(INFO_REPLICATION_CONFIRM_INITIALIZE_GENERIC.get( hostPortDestination, hostPortSource)); } } if (ctxSource != null) { try { ctxSource.close(); } catch (Throwable t) { } } if (ctxDestination != null) { try { ctxDestination.close(); } catch (Throwable t) { } } return cancelled; } /** * Commodity method that simply checks if a provided value is null or not, * if it is not <CODE>null</CODE> returns it and if it is <CODE>null</CODE> * returns the provided default value. * @param v the value to analyze. * @param defaultValue the default value. * @return if the provided value is not <CODE>null</CODE> returns it and if it * is <CODE>null</CODE> returns the provided default value. */ private String getValue(String v, String defaultValue) { if (v != null) { return v; } else { return defaultValue; } } /** * Commodity method that simply checks if a provided value is -1 or not, * if it is not -1 returns it and if it is -1 returns the provided default * value. * @param v the value to analyze. * @param defaultValue the default value. * @return if the provided value is not -1 returns it and if it is -1 returns * the provided default value. */ private int getValue(int v, int defaultValue) { if (v != -1) { return v; } else { return defaultValue; } } /** * Returns the trust manager to be used by this application. * @return the trust manager to be used by this application. */ private ApplicationTrustManager getTrustManager() { return argParser.getTrustManager(); } /** * Initializes the contents of the provided enable replication user data * object with what was provided in the command-line without prompting to the * user. * @param uData the enable replication user data object to be initialized. */ private void initializeWithArgParser(EnableReplicationUserData uData) { uData.setBaseDNs(new LinkedList<String>(argParser.getBaseDNs())); String adminUid = getValue(argParser.getAdministratorUID(), argParser.getDefaultAdministratorUID()); uData.setAdminUid(adminUid); String adminPwd = argParser.getBindPasswordAdmin(); uData.setAdminPwd(adminPwd); String host1Name = getValue(argParser.getHostName1(), argParser.getDefaultHostName1()); uData.setHostName1(host1Name); int port1 = getValue(argParser.getPort1(), argParser.getDefaultPort1()); uData.setPort1(port1); uData.setUseSSL1(argParser.useSSL1()); uData.setUseStartTLS1(argParser.useStartTLS1()); String pwd1 = argParser.getBindPassword1(); if (pwd1 == null) { uData.setBindDn1(ADSContext.getAdministratorDN(adminUid)); uData.setPwd1(adminPwd); } else { String bindDn = getValue(argParser.getBindDn1(), argParser.getDefaultBindDn1()); uData.setBindDn1(bindDn); uData.setPwd1(pwd1); } int replicationPort1 = getValue(argParser.getReplicationPort1(), argParser.getDefaultReplicationPort1()); uData.setReplicationPort1(replicationPort1); String host2Name = getValue(argParser.getHostName2(), argParser.getDefaultHostName2()); uData.setHostName2(host2Name); int port2 = getValue(argParser.getPort2(), argParser.getDefaultPort2()); uData.setPort2(port2); uData.setUseSSL2(argParser.useSSL2()); uData.setUseStartTLS2(argParser.useStartTLS2()); String pwd2 = argParser.getBindPassword2(); if (pwd2 == null) { uData.setBindDn2(ADSContext.getAdministratorDN(adminUid)); uData.setPwd2(adminPwd); } else { String bindDn = getValue(argParser.getBindDn2(), argParser.getDefaultBindDn2()); uData.setBindDn2(bindDn); uData.setPwd2(pwd2); } uData.setReplicationPort1(replicationPort1); } /** * Initializes the contents of the provided initialize replication user data * object with what was provided in the command-line without prompting to the * user. * @param uData the initialize replication user data object to be initialized. */ private void initializeWithArgParser(InitializeReplicationUserData uData) { uData.setBaseDNs(new LinkedList<String>(argParser.getBaseDNs())); String adminUid = getValue(argParser.getAdministratorUID(), argParser.getDefaultAdministratorUID()); uData.setAdminUid(adminUid); String adminPwd = argParser.getBindPasswordAdmin(); uData.setAdminPwd(adminPwd); String hostNameSource = getValue(argParser.getHostNameSource(), argParser.getDefaultHostNameSource()); uData.setHostNameSource(hostNameSource); int portSource = getValue(argParser.getPortSource(), argParser.getDefaultPortSource()); uData.setPortSource(portSource); uData.setUseSSLSource(argParser.useSSLSource()); uData.setUseStartTLSSource(argParser.useStartTLSSource()); String hostNameDestination = getValue( argParser.getHostNameDestination(), argParser.getDefaultHostNameDestination()); uData.setHostNameDestination(hostNameDestination); int portDestination = getValue(argParser.getPortSource(), argParser.getDefaultPortDestination()); uData.setPortDestination(portDestination); uData.setUseSSLDestination(argParser.useSSLDestination()); uData.setUseStartTLSDestination(argParser.useStartTLSDestination()); } /** * Initializes the contents of the provided disable replication user data * object with what was provided in the command-line without prompting to the * user. * @param uData the disable replication user data object to be initialized. */ private void initializeWithArgParser(DisableReplicationUserData uData) { uData.setBaseDNs(new LinkedList<String>(argParser.getBaseDNs())); String adminUid = getValue(argParser.getAdministratorUID(), argParser.getDefaultAdministratorUID()); uData.setAdminUid(adminUid); String adminPwd = argParser.getBindPasswordAdmin(); uData.setAdminPwd(adminPwd); String hostName = getValue(argParser.getHostNameToDisable(), argParser.getDefaultHostNameToDisable()); uData.setHostName(hostName); int port = getValue(argParser.getPortToDisable(), argParser.getDefaultPortToDisable()); uData.setPort(port); uData.setUseSSL(argParser.useSSLToDisable()); uData.setUseStartTLS(argParser.useStartTLSToDisable()); } /** * Returns an InitialLdapContext using the provided parameters. We try * to guarantee that the connection is able to read the configuration. * @param host the host name. * @param port the port to connect. * @param useSSL whether to use SSL or not. * @param useStartTLS whether to use StartTLS or not. * @param bindDn the bind dn to be used. * @param pwd the password. * @param trustManager the trust manager. * @return an InitialLdapContext connected. * @throws NamingException if there was an error establishing the connection. */ private InitialLdapContext createContext(String host, int port, boolean useSSL, boolean useStartTLS, String bindDn, String pwd, ApplicationTrustManager trustManager) throws NamingException { InitialLdapContext ctx; String ldapUrl = getLDAPUrl(host, port, useSSL); if (useSSL) { ctx = Utils.createLdapsContext(ldapUrl, bindDn, pwd, Utils.getDefaultLDAPTimeout(), null, trustManager); } else if (useStartTLS) { ctx = Utils.createStartTLSContext(ldapUrl, bindDn, pwd, Utils.getDefaultLDAPTimeout(), null, trustManager, null); } else { ctx = Utils.createLdapContext(ldapUrl, bindDn, pwd, Utils.getDefaultLDAPTimeout(), null); } if (!ConnectionUtils.connectedAsAdministrativeUser(ctx)) { throw new NoPermissionException( ERR_NOT_ADMINISTRATIVE_USER.get().toString()); } return ctx; } /** * Returns the LDAP URL for the provided parameters. * @param host the host name. * @param port the LDAP port. * @param useSSL whether to use SSL or not. * @return the LDAP URL for the provided parameters. */ private String getLDAPUrl(String host, int port, boolean useSSL) { String ldapUrl; host = Utils.getHostNameForLdapUrl(host); if (useSSL) { ldapUrl = "ldaps://"+host+":"+port; } else { ldapUrl = "ldap://"+host+":"+port; } return ldapUrl; } /** * Tells whether the server to which the LdapContext is connected has a * replication port or not. * @param ctx the InitialLdapContext to be used. * @return <CODE>true</CODE> if the replication port for the server could * be found and <CODE>false</CODE> otherwise. */ private boolean hasReplicationPort(InitialLdapContext ctx) { return getReplicationPort(ctx) != -1; } /** * Returns the replication port of server to which the LdapContext is * connected and -1 if the replication port could not be found. * @param ctx the InitialLdapContext to be used. * @return the replication port of server to which the LdapContext is * connected and -1 if the replication port could not be found. */ private int getReplicationPort(InitialLdapContext ctx) { int replicationPort = -1; try { ManagementContext mCtx = LDAPManagementContext.createFromContext( JNDIDirContextAdaptor.adapt(ctx)); RootCfgClient root = mCtx.getRootConfiguration(); MultimasterSynchronizationProviderCfgClient sync = null; sync = (MultimasterSynchronizationProviderCfgClient) root.getSynchronizationProvider("Multimaster Synchronization"); /* * Configure the replication server. */ if (sync.hasReplicationServer()) { ReplicationServerCfgClient replicationServer = sync.getReplicationServer(); replicationPort = replicationServer.getReplicationPort(); } } catch (Throwable t) { LOG.log(Level.WARNING, "Unexpected error retrieving the replication port: "+t, t); } return replicationPort; } /** * Loads the ADS with the provided context. If there are certificates to * be accepted we prompt them to the user. If there are errors loading the * servers we display them to the user and we ask for confirmation. If the * provided ctx is not using Global Administrator credentials, we prompt the * user to provide them and update the provide ReplicationUserData * accordingly. * @param ctx the Ldap context to be used. * @param uData the ReplicationUserData to be udpated. * @param isFirstOrSourceServer whether this is the first server in the * enable replication subcommand or the source server in the initialize server * subcommand. * @return <CODE>true</CODE> if everything went fine and the user accepted * all the certificates and confirmed everything. Returns <CODE>false</CODE> * if a critical error occurred or the user did not accept a certificate or * any of the confirmation messages. */ private boolean loadADSAndAcceptCertificates(InitialLdapContext ctx, ReplicationUserData uData, boolean isFirstOrSourceServer) { boolean cancelled = false; boolean triedWithUserProvidedAdmin = false; String host = ConnectionUtils.getHostName(ctx); int port = ConnectionUtils.getPort(ctx); boolean isSSL = ConnectionUtils.isSSL(ctx); boolean isStartTLS = ConnectionUtils.isStartTLS(ctx); try { ADSContext adsContext = new ADSContext(ctx); if (adsContext.hasAdminData()) { TopologyCache cache = new TopologyCache(adsContext, getTrustManager()); boolean reloadTopology = true; LinkedList<Message> exceptionMsgs = new LinkedList<Message>(); while (reloadTopology && !cancelled) { cache.reloadTopology(); reloadTopology = false; exceptionMsgs.clear(); /* 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<TopologyCacheException> exceptions = new HashSet<TopologyCacheException>(); Set<ServerDescriptor> servers = cache.getServers(); for (ServerDescriptor server : servers) { TopologyCacheException e = server.getLastException(); if (e != null) { exceptions.add(e); } } /* Check the exceptions and see if we throw them or not. */ for (TopologyCacheException e : exceptions) { switch (e.getType()) { case NOT_GLOBAL_ADMINISTRATOR: printLineBreak(); printErrorMessage(INFO_NOT_GLOBAL_ADMINISTRATOR_PROVIDED.get()); boolean connected = false; String adminUid = uData.getAdminUid(); String adminPwd = uData.getAdminPwd(); while (!connected) { if ((!triedWithUserProvidedAdmin) && (adminPwd == null)) { adminUid = getValue(argParser.getAdministratorUID(), argParser.getDefaultAdministratorUID()); adminPwd = argParser.getBindPasswordAdmin(); triedWithUserProvidedAdmin = true; } if (adminPwd == null) { adminUid = askForAdministratorUID( argParser.getDefaultAdministratorUID()); adminPwd = askForAdministratorPwd(); } try { ctx.close(); } catch (Throwable t) { } try { ctx = createContext(host, port, isSSL, isStartTLS, ADSContext.getAdministratorDN(adminUid), adminPwd, getTrustManager()); adsContext = new ADSContext(ctx); cache = new TopologyCache(adsContext, getTrustManager()); } catch (Throwable t) { printLineBreak(); printErrorMessage( ERR_ERROR_CONNECTING_TO_SERVER_PROMPT_AGAIN.get( host+":"+port)); LOG.log(Level.WARNING, "Complete error stack:", t); printLineBreak(); } } uData.setAdminUid(adminUid); uData.setAdminPwd(adminPwd); if (uData instanceof EnableReplicationUserData) { EnableReplicationUserData enableData = (EnableReplicationUserData)uData; if (isFirstOrSourceServer) { enableData.setBindDn1( ADSContext.getAdministratorDN(adminUid)); enableData.setPwd1(adminPwd); } else { enableData.setBindDn2( ADSContext.getAdministratorDN(adminUid)); enableData.setPwd2(adminPwd); } } reloadTopology = true; break; case GENERIC_CREATING_CONNECTION: if ((e.getCause() != null) && Utils.isCertificateException(e.getCause())) { reloadTopology = true; cancelled = !promptForCertificateConfirmation(e.getCause(), getTrustManager(), e.getLdapUrl()); } else { exceptionMsgs.add(Utils.getMessage(e)); } break; default: exceptionMsgs.add(Utils.getMessage(e)); } } } if ((exceptionMsgs.size() > 0) && !cancelled) { cancelled = !confirm( ERR_REPLICATION_READING_REGISTERED_SERVERS_CONFIRM_UPDATE_REMOTE. get(Utils.getMessageFromCollection(exceptionMsgs, Constants.LINE_SEPARATOR).toString())); } } } catch (ADSContextException ace) { printLineBreak(); printErrorMessage(Utils.getThrowableMsg(INFO_BUG_MSG.get(), ace)); LOG.log(Level.SEVERE, "Complete error stack:", ace); cancelled = true; } catch (TopologyCacheException tce) { printLineBreak(); printErrorMessage(Utils.getMessage(tce)); LOG.log(Level.SEVERE, "Complete error stack:", tce); cancelled = true; } return !cancelled; } /** * Tells whether there is a Global Administrator defined in the server * to which the InitialLdapContext is connected. * @param ctx the InitialLdapContext. * @return <CODE>true</CODE> if we could find an administrator and * <CODE>false</CODE> otherwise. */ private boolean hasAdministrator(InitialLdapContext ctx) { boolean isAdminDefined = false; try { ADSContext adsContext = new ADSContext(ctx); if (adsContext.hasAdminData()) { Set administrators = adsContext.readAdministratorRegistry(); isAdminDefined = administrators.size() > 0; } } catch (Throwable t) { LOG.log(Level.WARNING, "Unexpected error retrieving the ADS data: "+t, t); } return isAdminDefined; } /** * Returns a Collection containing a list of suffixes that are defined in * two servers at the same time (depending on the value of the argument * replicated this list contains only the suffixes that are replicated * between the servers or the list of suffixes that are not replicated * between the servers). * @param ctx1 the connection to the first server. * @param ctx2 the connection to the second server. * @param type whether to return a list with the suffixes that are * replicated, fully replicated (replicas have exactly the same list of * replication servers), not replicated or all the common suffixes. * @return a Collection containing a list of suffixes that are replicated * (or those that can be replicated) in two servers. */ private enum SuffixRelationType { NOT_REPLICATED, FULLY_REPLICATED, REPLICATED, NOT_FULLY_REPLICATED, ALL }; private Collection<String> getCommonSuffixes( InitialLdapContext ctx1, InitialLdapContext ctx2, SuffixRelationType type) { LinkedList<String> suffixes = new LinkedList<String>(); try { ServerDescriptor server1 = ServerDescriptor.createStandalone(ctx1); ServerDescriptor server2 = ServerDescriptor.createStandalone(ctx2); Set<ReplicaDescriptor> replicas1 = server1.getReplicas(); Set<ReplicaDescriptor> replicas2 = server2.getReplicas(); for (ReplicaDescriptor rep1 : replicas1) { for (ReplicaDescriptor rep2 : replicas2) { switch (type) { case NOT_REPLICATED: if (!areReplicated(rep1, rep2)) { suffixes.add(rep1.getSuffix().getDN()); } break; case FULLY_REPLICATED: if (areFullyReplicated(rep1, rep2)) { suffixes.add(rep1.getSuffix().getDN()); } break; case REPLICATED: if (areReplicated(rep1, rep2)) { suffixes.add(rep1.getSuffix().getDN()); } break; case NOT_FULLY_REPLICATED: if (!areFullyReplicated(rep1, rep2)) { suffixes.add(rep1.getSuffix().getDN()); } break; case ALL: if (Utils.areDnsEqual(rep1.getSuffix().getDN(), rep2.getSuffix().getDN())) { suffixes.add(rep1.getSuffix().getDN()); } break; default: throw new IllegalStateException("Unknown type: "+type); } } } } catch (Throwable t) { LOG.log(Level.WARNING, "Unexpected error retrieving the server configuration: "+t, t); } return suffixes; } /** * Tells whether the two provided replicas are fully replicated or not. The * code in fact checks that both replicas have the same DN that they are * replicated if both servers are replication servers and that both replicas * make reference to the other replication server. * @param rep1 the first replica. * @param rep2 the second replica. * @return <CODE>true</CODE> if we can assure that the two replicas are * replicated using the replication server and replication port information * and <CODE>false</CODE> otherwise. */ private boolean areFullyReplicated(ReplicaDescriptor rep1, ReplicaDescriptor rep2) { boolean areFullyReplicated = false; if (Utils.areDnsEqual(rep1.getSuffix().getDN(), rep2.getSuffix().getDN()) && rep1.isReplicated() && rep2.isReplicated() && rep1.getServer().isReplicationServer() && rep2.getServer().isReplicationServer()) { Set<String> servers1 = rep1.getReplicationServers(); Set<String> servers2 = rep2.getReplicationServers(); String server1 = rep1.getServer().getReplicationServerHostPort(); String server2 = rep2.getServer().getReplicationServerHostPort(); areFullyReplicated = servers1.contains(server2) && servers2.contains(server1); } return areFullyReplicated; } /** * Tells whether the two provided replicas are replicated or not. The * code in fact checks that both replicas have the same DN and that they * have at least one common replication server referenced. * @param rep1 the first replica. * @param rep2 the second replica. * @return <CODE>true</CODE> if we can assure that the two replicas are * replicated and <CODE>false</CODE> otherwise. */ private boolean areReplicated(ReplicaDescriptor rep1, ReplicaDescriptor rep2) { boolean areReplicated = false; if (Utils.areDnsEqual(rep1.getSuffix().getDN(), rep2.getSuffix().getDN()) && rep1.isReplicated() && rep2.isReplicated()) { Set<String> servers1 = rep1.getReplicationServers(); Set<String> servers2 = rep2.getReplicationServers(); servers1.retainAll(servers2); areReplicated = !servers1.isEmpty(); } return areReplicated; } /** * Returns a Collection containing a list of replicas in a server. * @param ctx the connection to the server. * @return a Collection containing a list of replicas in a server. */ private Collection<ReplicaDescriptor> getReplicas(InitialLdapContext ctx) { LinkedList<ReplicaDescriptor> suffixes = new LinkedList<ReplicaDescriptor>(); try { ServerDescriptor server = ServerDescriptor.createStandalone(ctx); suffixes.addAll(server.getReplicas()); } catch (Throwable t) { LOG.log(Level.WARNING, "Unexpected error retrieving the server configuration: "+t, t); } return suffixes; } /** * Enables the replication between two servers using the parameters in the * provided EnableReplicationUserData. This method does not prompt to the * user for information if something is missing. * @param uData the EnableReplicationUserData object. * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was * successful. * and the replication could be enabled and an error code otherwise. */ private ReplicationCliReturnCode enableReplication( EnableReplicationUserData uData) { ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP; InitialLdapContext ctx1 = null; InitialLdapContext ctx2 = null; printProgressMessage( formatter.getFormattedWithPoints(INFO_REPLICATION_CONNECTING.get())); try { ctx1 = createContext(uData.getHostName1(), uData.getPort1(), uData.useSSL1(), uData.useStartTLS1(), uData.getBindDn1(), uData.getPwd1(), getTrustManager()); } catch (NamingException ne) { String hostPort = uData.getHostName1()+":"+uData.getPort1(); printLineBreak(); printErrorMessage(getMessageForException(ne, hostPort)); LOG.log(Level.SEVERE, "Complete error stack:", ne); } try { ctx2 = createContext(uData.getHostName2(), uData.getPort2(), uData.useSSL2(), uData.useStartTLS2(), uData.getBindDn2(), uData.getPwd2(), getTrustManager()); } catch (NamingException ne) { String hostPort = uData.getHostName2()+":"+uData.getPort2(); printLineBreak(); printErrorMessage(getMessageForException(ne, hostPort)); LOG.log(Level.SEVERE, "Complete error stack:", ne); } if ((ctx1 != null) && (ctx2 != null)) { // This done is for the message informing that we are connecting. printProgressMessage(formatter.getFormattedDone()); printProgressMessage(formatter.getLineBreak()); LinkedList<String> suffixes = uData.getBaseDNs(); checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, false); if (!suffixes.isEmpty()) { uData.setBaseDNs(suffixes); try { updateConfiguration(ctx1, ctx2, uData); returnValue = SUCCESSFUL; } catch (ReplicationCliException rce) { returnValue = rce.getErrorCode(); printLineBreak(); printErrorMessage(rce.getMessageObject()); LOG.log(Level.SEVERE, "Complete error stack:", rce); } } else { // The error messages are already displayed in the method // checkSuffixesForEnableReplication. returnValue = REPLICATION_CANNOT_BE_ENABLED_ON_BASEDN; } } else { returnValue = ERROR_CONNECTING; } if (ctx1 != null) { try { ctx1.close(); } catch (Throwable t) { } } if (ctx2 != null) { try { ctx2.close(); } catch (Throwable t) { } } return returnValue; } /** * Disbles the replication in the server for the provided suffixes using the * data in the DisableReplicationUserData object. This method does not prompt * to the user for information if something is missing. * @param uData the DisableReplicationUserData object. * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was * successful. * and the replication could be enabled and an error code otherwise. */ private ReplicationCliReturnCode disableReplication( DisableReplicationUserData uData) { ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP; InitialLdapContext ctx = null; printProgressMessage( formatter.getFormattedWithPoints(INFO_REPLICATION_CONNECTING.get())); try { ctx = createContext(uData.getHostName(), uData.getPort(), uData.useSSL(), uData.useStartTLS(), ADSContext.getAdministratorDN(uData.getAdminUid()), uData.getAdminPwd(), getTrustManager()); } catch (NamingException ne) { String hostPort = uData.getHostName()+":"+uData.getPort(); printLineBreak(); printErrorMessage(getMessageForException(ne, hostPort)); LOG.log(Level.SEVERE, "Complete error stack:", ne); } if (ctx != null) { // This done is for the message informing that we are connecting. printProgressMessage(formatter.getFormattedDone()); printProgressMessage(formatter.getLineBreak()); LinkedList<String> suffixes = uData.getBaseDNs(); checkSuffixesForDisableReplication(suffixes, ctx, false); if (!suffixes.isEmpty()) { uData.setBaseDNs(suffixes); try { updateConfiguration(ctx, uData); returnValue = SUCCESSFUL; } catch (ReplicationCliException rce) { returnValue = rce.getErrorCode(); printLineBreak(); printErrorMessage(rce.getMessageObject()); LOG.log(Level.SEVERE, "Complete error stack:", rce); } } else { returnValue = REPLICATION_CANNOT_BE_DISABLED_ON_BASEDN; } } else { returnValue = ERROR_CONNECTING; } if (ctx != null) { try { ctx.close(); } catch (Throwable t) { } } return returnValue; } /** * Initializes the contents of one server with the contents of the other * using the parameters in the provided InitializeReplicationUserData. * This method does not prompt to the user for information if something is * missing. * @param uData the InitializeReplicationUserData object. * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was * successful. * and the replication could be enabled and an error code otherwise. */ private ReplicationCliReturnCode initializeReplication( InitializeReplicationUserData uData) { ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP; InitialLdapContext ctxSource = null; InitialLdapContext ctxDestination = null; try { ctxSource = createContext(uData.getHostNameSource(), uData.getPortSource(), uData.useSSLSource(), uData.useStartTLSSource(), ADSContext.getAdministratorDN(uData.getAdminUid()), uData.getAdminPwd(), getTrustManager()); } catch (NamingException ne) { String hostPort = uData.getHostNameSource()+":"+uData.getPortSource(); printLineBreak(); printErrorMessage(getMessageForException(ne, hostPort)); LOG.log(Level.SEVERE, "Complete error stack:", ne); } try { ctxDestination = createContext(uData.getHostNameDestination(), uData.getPortDestination(), uData.useSSLDestination(), uData.useStartTLSDestination(), ADSContext.getAdministratorDN(uData.getAdminUid()), uData.getAdminPwd(), getTrustManager()); } catch (NamingException ne) { String hostPort = uData.getHostNameDestination()+":"+ uData.getPortDestination(); printLineBreak(); printErrorMessage(getMessageForException(ne, hostPort)); LOG.log(Level.SEVERE, "Complete error stack:", ne); } if ((ctxSource != null) && (ctxDestination != null)) { LinkedList<String> baseDNs = uData.getBaseDNs(); checkSuffixesForInitializeReplication(baseDNs, ctxSource, ctxDestination, false); if (!baseDNs.isEmpty()) { for (String baseDN : baseDNs) { try { Message msg = formatter.getFormattedProgress( INFO_PROGRESS_INITIALIZING_SUFFIX.get(baseDN, ConnectionUtils.getHostPort(ctxDestination))); printProgressMessage(msg); printProgressLineBreak(); initializeSuffix(baseDN, ctxSource, ctxDestination, true); } catch (ReplicationCliException rce) { printLineBreak(); printErrorMessage(rce.getMessageObject()); returnValue = rce.getErrorCode(); LOG.log(Level.SEVERE, "Complete error stack:", rce); } } } else { returnValue = REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN; } } else { returnValue = ERROR_CONNECTING; } if (ctxSource != null) { try { ctxSource.close(); } catch (Throwable t) { } } if (ctxDestination != null) { try { ctxDestination.close(); } catch (Throwable t) { } } return returnValue; } /** * Checks that replication can actually be enabled in the provided baseDNs * for the two servers. * @param suffixes the suffixes provided by the user. This Collection is * updated by removing the base DNs that cannot be enabled and with the * base DNs that the user provided interactively. * @param ctx1 connection to the first server. * @param ctx2 connection to the second server. * @param interactive whether to ask the user to provide interactively * base DNs if none of the provided base DNs can be enabled. */ private void checkSuffixesForEnableReplication(Collection<String> suffixes, InitialLdapContext ctx1, InitialLdapContext ctx2, boolean interactive) { boolean cancelled = false; TreeSet<String> availableSuffixes = new TreeSet<String>(getCommonSuffixes(ctx1, ctx2, SuffixRelationType.NOT_FULLY_REPLICATED)); TreeSet<String> alreadyReplicatedSuffixes = new TreeSet<String>(getCommonSuffixes(ctx1, ctx2, SuffixRelationType.FULLY_REPLICATED)); if (availableSuffixes.size() == 0) { printLineBreak(); printErrorMessage( ERR_NO_SUFFIXES_AVAILABLE_TO_ENABLE_REPLICATION.get()); LinkedList<String> userProvidedSuffixes = argParser.getBaseDNs(); TreeSet<String> userProvidedReplicatedSuffixes = new TreeSet<String>(); for (String s1 : userProvidedSuffixes) { for (String s2 : alreadyReplicatedSuffixes) { if (Utils.areDnsEqual(s1, s2)) { userProvidedReplicatedSuffixes.add(s1); } } } if (userProvidedReplicatedSuffixes.size() > 0) { printErrorMessage( INFO_ALREADY_REPLICATED_SUFFIXES.get( Utils.getStringFromCollection(userProvidedReplicatedSuffixes, Constants.LINE_SEPARATOR))); } cancelled = true; } // Verify that the provided suffixes are configured in the servers. if (!cancelled) { TreeSet<String> notFound = new TreeSet<String>(); TreeSet<String> alreadyReplicated = new TreeSet<String>(); for (String dn : suffixes) { boolean found = false; for (String dn1 : availableSuffixes) { if (Utils.areDnsEqual(dn, dn1)) { found = true; break; } } if (!found) { boolean isReplicated = false; for (String s : alreadyReplicatedSuffixes) { if (Utils.areDnsEqual(s, dn)) { isReplicated = true; break; } } if (isReplicated) { alreadyReplicated.add(dn); } else { notFound.add(dn); } } } suffixes.removeAll(notFound); suffixes.removeAll(alreadyReplicated); if (notFound.size() > 0) { printLineBreak(); printErrorMessage(ERR_REPLICATION_ENABLE_SUFFIXES_NOT_FOUND.get( Utils.getStringFromCollection(notFound, Constants.LINE_SEPARATOR))); } if (alreadyReplicated.size() > 0) { printLineBreak(); printErrorMessage(INFO_ALREADY_REPLICATED_SUFFIXES.get( Utils.getStringFromCollection(alreadyReplicated, Constants.LINE_SEPARATOR))); } if (interactive) { while (suffixes.isEmpty()) { printLineBreak(); printErrorMessage(ERR_NO_SUFFIXES_SELECTED_TO_REPLICATE.get()); for (String dn : availableSuffixes) { if (confirm(INFO_REPLICATION_ENABLE_SUFFIX_PROMPT.get(dn))) { suffixes.add(dn); } } } } else if (suffixes.isEmpty()) { cancelled = true; } } } /** * Checks that replication can actually be disabled in the provided baseDNs * for the server. * @param suffixes the suffixes provided by the user. This Collection is * updated by removing the base DNs that cannot be enabled and with the * base DNs that the user provided interactively. * @param ctx connection to the server. * @param interactive whether to ask the user to provide interactively * base DNs if none of the provided base DNs can be disabled. */ private void checkSuffixesForDisableReplication(Collection<String> suffixes, InitialLdapContext ctx, boolean interactive) { boolean cancelled = false; TreeSet<String> availableSuffixes = new TreeSet<String>(); TreeSet<String> notReplicatedSuffixes = new TreeSet<String>(); Collection<ReplicaDescriptor> replicas = getReplicas(ctx); for (ReplicaDescriptor rep : replicas) { String dn = rep.getSuffix().getDN(); if (rep.isReplicated()) { availableSuffixes.add(dn); } else { notReplicatedSuffixes.add(dn); } } if (availableSuffixes.size() == 0) { printLineBreak(); printErrorMessage( ERR_NO_SUFFIXES_AVAILABLE_TO_DISABLE_REPLICATION.get()); LinkedList<String> userProvidedSuffixes = argParser.getBaseDNs(); TreeSet<String> userProvidedNotReplicatedSuffixes = new TreeSet<String>(); for (String s1 : userProvidedSuffixes) { for (String s2 : notReplicatedSuffixes) { if (Utils.areDnsEqual(s1, s2)) { userProvidedNotReplicatedSuffixes.add(s1); } } } if (userProvidedNotReplicatedSuffixes.size() > 0) { printErrorMessage( INFO_ALREADY_NOT_REPLICATED_SUFFIXES.get( Utils.getStringFromCollection( userProvidedNotReplicatedSuffixes, Constants.LINE_SEPARATOR))); } cancelled = true; } if (!cancelled) { // Verify that the provided suffixes are configured in the servers. TreeSet<String> notFound = new TreeSet<String>(); TreeSet<String> alreadyNotReplicated = new TreeSet<String>(); for (String dn : suffixes) { boolean found = false; for (String dn1 : availableSuffixes) { if (Utils.areDnsEqual(dn, dn1)) { found = true; break; } } if (!found) { boolean notReplicated = false; for (String s : notReplicatedSuffixes) { if (Utils.areDnsEqual(s, dn)) { notReplicated = true; break; } } if (notReplicated) { alreadyNotReplicated.add(dn); } else { notFound.add(dn); } } } suffixes.removeAll(notFound); suffixes.removeAll(alreadyNotReplicated); if (notFound.size() > 0) { printLineBreak(); printErrorMessage(ERR_REPLICATION_DISABLE_SUFFIXES_NOT_FOUND.get( Utils.getStringFromCollection(notFound, Constants.LINE_SEPARATOR))); } if (alreadyNotReplicated.size() > 0) { printLineBreak(); printErrorMessage(INFO_ALREADY_NOT_REPLICATED_SUFFIXES.get( Utils.getStringFromCollection(alreadyNotReplicated, Constants.LINE_SEPARATOR))); } if (interactive) { while (suffixes.isEmpty()) { printLineBreak(); printErrorMessage(ERR_NO_SUFFIXES_SELECTED_TO_DISABLE.get()); for (String dn : availableSuffixes) { if (confirm(INFO_REPLICATION_DISABLE_SUFFIX_PROMPT.get(dn))) { suffixes.add(dn); } } } } } } /** * Checks that we can initialize the provided baseDNs between the two servers. * @param suffixes the suffixes provided by the user. This Collection is * updated by removing the base DNs that cannot be enabled and with the * base DNs that the user provided interactively. * @param ctxSource connection to the source server. * @param ctxDestination connection to the destination server. * @param interactive whether to ask the user to provide interactively * base DNs if none of the provided base DNs can be initialized. */ private void checkSuffixesForInitializeReplication( Collection<String> suffixes, InitialLdapContext ctxSource, InitialLdapContext ctxDestination, boolean interactive) { boolean cancelled = false; TreeSet<String> availableSuffixes = new TreeSet<String>( getCommonSuffixes(ctxSource, ctxDestination, SuffixRelationType.REPLICATED)); if (availableSuffixes.size() == 0) { printLineBreak(); printErrorMessage( ERR_NO_SUFFIXES_AVAILABLE_TO_INITIALIZE_REPLICATION.get()); cancelled = true; } if (!cancelled) { // Verify that the provided suffixes are configured in the servers. LinkedList<String> notFound = new LinkedList<String>(); for (String dn : suffixes) { boolean found = false; for (String dn1 : availableSuffixes) { if (Utils.areDnsEqual(dn, dn1)) { found = true; break; } } if (!found) { notFound.add(dn); } } suffixes.removeAll(notFound); if (notFound.size() > 0) { printLineBreak(); printErrorMessage(ERR_SUFFIXES_CANNOT_BE_INITIALIZED.get( Utils.getStringFromCollection(notFound, Constants.LINE_SEPARATOR))); } if (interactive) { while (suffixes.isEmpty()) { printLineBreak(); printErrorMessage(ERR_NO_SUFFIXES_SELECTED_TO_INITIALIZE.get()); for (String dn : availableSuffixes) { if (confirm(INFO_REPLICATION_INITIALIZE_SUFFIX_PROMPT.get(dn))) { suffixes.add(dn); } } } } } } /** * Updates the configuration in the two servers (and in other servers if * they are referenced) to enable replication. * @param ctx1 the connection to the first server. * @param ctx2 the connection to the second server. * @param uData the EnableReplicationUserData object containing the required * parameters to update the confgiuration. * @throws ReplicationCliException if there is an error. */ private void updateConfiguration(InitialLdapContext ctx1, InitialLdapContext ctx2, EnableReplicationUserData uData) throws ReplicationCliException { LinkedHashSet<String> twoReplServers = new LinkedHashSet<String>(); LinkedHashSet<String> allRepServers = new LinkedHashSet<String>(); HashMap<String, LinkedHashSet<String>> hmRepServers = new HashMap<String, LinkedHashSet<String>>(); Set<Integer> usedReplicationServerIds = new HashSet<Integer>(); HashMap<String, HashSet<Integer>> hmUsedReplicationDomainIds = new HashMap<String, HashSet<Integer>>(); ServerDescriptor server1; try { server1 = ServerDescriptor.createStandalone(ctx1); } catch (NamingException ne) { throw new ReplicationCliException( getMessageForException(ne, ConnectionUtils.getHostPort(ctx1)), ERROR_READING_CONFIGURATION, ne); } ServerDescriptor server2; try { server2 = ServerDescriptor.createStandalone(ctx2); } catch (NamingException ne) { throw new ReplicationCliException( getMessageForException(ne, ConnectionUtils.getHostPort(ctx2)), ERROR_READING_CONFIGURATION, ne); } ADSContext adsCtx1 = new ADSContext(ctx1); ADSContext adsCtx2 = new ADSContext(ctx2); // These are used to identify which server we use to initialize // the contents of the other server (if any). InitialLdapContext ctxAdsSource = null; InitialLdapContext ctxAdsDestination = null; printProgressMessage(formatter.getFormattedWithPoints( INFO_REPLICATION_ENABLE_UPDATING_ADS_CONTENTS.get())); try { if (adsCtx1.hasAdminData() && adsCtx2.hasAdminData()) { Set<Map<ADSContext.ServerProperty, Object>> registry1 = adsCtx1.readServerRegistry(); Set<Map<ADSContext.ServerProperty, Object>> registry2 = adsCtx2.readServerRegistry(); if (registry2.size() <= 1) { // Only the server itself registered. if (!hasAdministrator(adsCtx1.getDirContext())) { adsCtx1.createAdministrator(getAdministratorProperties(uData)); } if (registry2.size() == 0) { server2.updateAdsPropertiesWithServerProperties(); adsCtx1.registerServer(server2.getAdsProperties()); } else { adsCtx1.registerServer(registry2.iterator().next()); } ctxAdsSource = ctx1; ctxAdsDestination = ctx2; } else if (registry1.size() <= 1) { // Only the server itself registered. if (!hasAdministrator(adsCtx2.getDirContext())) { adsCtx2.createAdministrator(getAdministratorProperties(uData)); } if (registry1.size() == 0) { server1.updateAdsPropertiesWithServerProperties(); adsCtx2.registerServer(server1.getAdsProperties()); } else { adsCtx2.registerServer(registry1.iterator().next()); } ctxAdsSource = ctx2; ctxAdsDestination = ctx1; } else if (!registry1.equals(registry2)) { // TO COMPLETE: we may want to merge the ADS but for the moment // just say this is not supported. throw new ReplicationCliException( ERR_REPLICATION_ADS_MERGE_NOT_SUPPORTED.get( ConnectionUtils.getHostPort(ctx1), ConnectionUtils.getHostPort(ctx2)), REPLICATION_ADS_MERGE_NOT_SUPPORTED, null); } else { // They are already replicated: nothing to do in terms of ADS // initialization or ADS update data } } else if (!adsCtx1.hasAdminData() && adsCtx2.hasAdminData()) { adsCtx1.createAdministrationSuffix(null); if (!hasAdministrator(adsCtx2.getDirContext())) { adsCtx2.createAdministrator(getAdministratorProperties(uData)); } server1.updateAdsPropertiesWithServerProperties(); adsCtx2.registerServer(server1.getAdsProperties()); ctxAdsSource = ctx2; ctxAdsDestination = ctx1; } else if (adsCtx1.hasAdminData() && !adsCtx2.hasAdminData()) { adsCtx2.createAdministrationSuffix(null); if (!hasAdministrator(adsCtx1.getDirContext())) { adsCtx1.createAdministrator(getAdministratorProperties(uData)); } server2.updateAdsPropertiesWithServerProperties(); adsCtx1.registerServer(server2.getAdsProperties()); ctxAdsSource = ctx1; ctxAdsDestination = ctx2; } else { adsCtx1.createAdminData(null); adsCtx1.createAdministrator(getAdministratorProperties(uData)); server1.updateAdsPropertiesWithServerProperties(); adsCtx1.registerServer(server1.getAdsProperties()); server2.updateAdsPropertiesWithServerProperties(); adsCtx1.registerServer(server2.getAdsProperties()); adsCtx2.createAdministrationSuffix(null); ctxAdsSource = ctx1; ctxAdsDestination = ctx2; } } catch (ADSContextException adce) { throw new ReplicationCliException( ERR_REPLICATION_UPDATING_ADS.get(adce.getMessage()), ERROR_UPDATING_ADS, adce); } printProgressMessage(formatter.getFormattedDone()); printProgressMessage(formatter.getLineBreak()); LinkedList<String> baseDNs = uData.getBaseDNs(); boolean found = false; for (String dn : baseDNs) { if (Utils.areDnsEqual(dn, ADSContext.getAdministrationSuffixDN())) { found = true; break; } } if (!found) { baseDNs.add(ADSContext.getAdministrationSuffixDN()); uData.setBaseDNs(baseDNs); } TopologyCache cache1 = null; TopologyCache cache2 = null; try { if (adsCtx1.hasAdminData()) { cache1 = new TopologyCache(adsCtx1, getTrustManager()); cache1.reloadTopology(); usedReplicationServerIds.addAll(getReplicationServerIds(cache1)); } if (adsCtx2.hasAdminData()) { cache2 = new TopologyCache(adsCtx2, getTrustManager()); cache2.reloadTopology(); usedReplicationServerIds.addAll(getReplicationServerIds(cache2)); } } catch (ADSContextException adce) { throw new ReplicationCliException( ERR_REPLICATION_READING_ADS.get(adce.getMessage()), ERROR_READING_ADS, adce); } catch (TopologyCacheException tce) { throw new ReplicationCliException( ERR_REPLICATION_READING_ADS.get(tce.getMessage()), ERROR_READING_TOPOLOGY_CACHE, tce); } if (!argParser.isInteractive()) { // Inform the user of the potential errors that we found. LinkedHashSet<Message> messages = new LinkedHashSet<Message>(); if (cache1 != null) { messages.addAll(getErrorMessages(cache1)); } if (cache2 != null) { messages.addAll(getErrorMessages(cache2)); } if (!messages.isEmpty()) { printWarningMessage( ERR_REPLICATION_READING_REGISTERED_SERVERS_WARNING.get( Utils.getMessageFromCollection(messages, Constants.LINE_SEPARATOR).toString())); } } if (server1.isReplicationServer()) { twoReplServers.add(server1.getReplicationServerHostPort()); usedReplicationServerIds.add(server1.getReplicationServerId()); } else { twoReplServers.add( ConnectionUtils.getHostName(ctx1)+":"+uData.getReplicationPort1()); } if (server2.isReplicationServer()) { twoReplServers.add(server2.getReplicationServerHostPort()); usedReplicationServerIds.add(server2.getReplicationServerId()); } else { twoReplServers.add( ConnectionUtils.getHostName(ctx2)+":"+uData.getReplicationPort2()); } for (String baseDN : uData.getBaseDNs()) { LinkedHashSet<String> repServersForBaseDN = new LinkedHashSet<String>(); repServersForBaseDN.addAll(getReplicationServers(baseDN, cache1, server1)); repServersForBaseDN.addAll(getReplicationServers(baseDN, cache2, server2)); repServersForBaseDN.addAll(twoReplServers); hmRepServers.put(baseDN, repServersForBaseDN); Set<Integer> ids = new HashSet<Integer>(); ids.addAll(getReplicationDomainIds(baseDN, server1)); ids.addAll(getReplicationDomainIds(baseDN, server2)); if (cache1 != null) { for (ServerDescriptor server : cache1.getServers()) { ids.addAll(getReplicationDomainIds(baseDN, server)); } } if (cache2 != null) { for (ServerDescriptor server : cache2.getServers()) { ids.addAll(getReplicationDomainIds(baseDN, server)); } } } for (LinkedHashSet<String> v : hmRepServers.values()) { allRepServers.addAll(v); } if (!server1.isReplicationServer()) { try { configureAsReplicationServer(ctx1, uData.getReplicationPort1(), allRepServers, usedReplicationServerIds); } catch (OpenDsException ode) { throw new ReplicationCliException( getMessageForReplicationServerException(ode, ConnectionUtils.getHostPort(ctx1)), ERROR_CONFIGURING_REPLICATIONSERVER, ode); } } if (!server2.isReplicationServer()) { try { configureAsReplicationServer(ctx2, uData.getReplicationPort2(), allRepServers, usedReplicationServerIds); } catch (OpenDsException ode) { throw new ReplicationCliException( getMessageForReplicationServerException(ode, ConnectionUtils.getHostPort(ctx1)), ERROR_CONFIGURING_REPLICATIONSERVER, ode); } } for (String baseDN : uData.getBaseDNs()) { LinkedHashSet<String> repServers = hmRepServers.get(baseDN); Set<Integer> usedIds = hmUsedReplicationDomainIds.get(baseDN); Set<String> alreadyConfiguredServers = new HashSet<String>(); try { configureToReplicateBaseDN(ctx1, baseDN, repServers, usedIds); } catch (OpenDsException ode) { Message msg = getMessageForEnableException(ode, ConnectionUtils.getHostPort(ctx1), baseDN); throw new ReplicationCliException(msg, ERROR_ENABLING_REPLICATION_ON_BASEDN, ode); } alreadyConfiguredServers.add(server1.getId()); try { configureToReplicateBaseDN(ctx2, baseDN, repServers, usedIds); } catch (OpenDsException ode) { Message msg = getMessageForEnableException(ode, ConnectionUtils.getHostPort(ctx2), baseDN); throw new ReplicationCliException(msg, ERROR_ENABLING_REPLICATION_ON_BASEDN, ode); } alreadyConfiguredServers.add(server2.getId()); if (cache1 != null) { configureToReplicateBaseDN(baseDN, repServers, usedIds, cache1, server1, alreadyConfiguredServers); } if (cache2 != null) { configureToReplicateBaseDN(baseDN, repServers, usedIds, cache2, server2, alreadyConfiguredServers); } } // Now that replication is configured in all servers, simply try to // initialize the contents of one ADS with the other (in the case where // already both servers were replicating the same ADS there is nothing to be // done). if ((ctxAdsSource != null) && (ctxAdsDestination != null)) { printProgressMessage(formatter.getFormattedWithPoints( INFO_ENABLE_REPLICATION_INITIALIZING_ADS.get( ConnectionUtils.getHostPort(ctxAdsDestination), ConnectionUtils.getHostPort(ctxAdsSource)))); initializeSuffix(ADSContext.getAdministrationSuffixDN(), ctxAdsSource, ctxAdsDestination, false); printProgressMessage(formatter.getFormattedDone()); printProgressMessage(formatter.getLineBreak()); } } /** * Updates the configuration in the server (and in other servers if * they are referenced) to disable replication. * @param ctx the connection to the server. * @param uData the DisableReplicationUserData object containing the required * parameters to update the confgiuration. * @throws ReplicationCliException if there is an error. */ private void updateConfiguration(InitialLdapContext ctx, DisableReplicationUserData uData) throws ReplicationCliException { ServerDescriptor server; try { server = ServerDescriptor.createStandalone(ctx); } catch (NamingException ne) { throw new ReplicationCliException( getMessageForException(ne, ConnectionUtils.getHostPort(ctx)), ERROR_READING_CONFIGURATION, ne); } ADSContext adsCtx = new ADSContext(ctx); TopologyCache cache = null; try { if (adsCtx.hasAdminData()) { cache = new TopologyCache(adsCtx, getTrustManager()); cache.reloadTopology(); } } catch (ADSContextException adce) { throw new ReplicationCliException( ERR_REPLICATION_READING_ADS.get(adce.getMessage()), ERROR_READING_ADS, adce); } catch (TopologyCacheException tce) { throw new ReplicationCliException( ERR_REPLICATION_READING_ADS.get(tce.getMessage()), ERROR_READING_TOPOLOGY_CACHE, tce); } if (!argParser.isInteractive()) { // Inform the user of the potential errors that we found. LinkedHashSet<Message> messages = new LinkedHashSet<Message>(); if (cache != null) { messages.addAll(getErrorMessages(cache)); } if (!messages.isEmpty()) { printWarningMessage( ERR_REPLICATION_READING_REGISTERED_SERVERS_WARNING.get( Utils.getMessageFromCollection(messages, Constants.LINE_SEPARATOR).toString())); } } String replicationServerHostPort = server.getReplicationServerHostPort(); for (String baseDN : uData.getBaseDNs()) { try { deleteReplicationDomain(ctx, baseDN); } catch (OpenDsException ode) { Message msg = getMessageForDisableException(ode, ConnectionUtils.getHostPort(ctx), baseDN); throw new ReplicationCliException(msg, ERROR_DISABLING_REPLICATION_ON_BASEDN, ode); } } if ((replicationServerHostPort != null) && (cache != null)) { Set<ServerDescriptor> serversToUpdate = new LinkedHashSet<ServerDescriptor>(); for (String baseDN : uData.getBaseDNs()) { SuffixDescriptor suffix = getSuffix(baseDN, cache, server); if (suffix != null) { for (ReplicaDescriptor replica : suffix.getReplicas()) { serversToUpdate.add(replica.getServer()); } } } String bindDn = ConnectionUtils.getBindDN(ctx); String pwd = ConnectionUtils.getBindPassword(ctx); for (ServerDescriptor s : serversToUpdate) { removeReferencesInServer(s, replicationServerHostPort, bindDn, pwd, uData.getBaseDNs()); } } } /** * Retrieves all the replication servers for a given baseDN. The * ServerDescriptor is used to identify the server where the suffix is * defined and it cannot be null. The TopologyCache is used to retrieve * replication servers defined in other replicas but not in the one we * get in the ServerDescriptor. * @param baseDN the base DN. * @param cache the TopologyCache (might be null). * @param server the ServerDescriptor. * @return a Set containing the replication servers currently being used * to replicate the baseDN defined in the server described by the * ServerDescriptor. */ private LinkedHashSet<String> getReplicationServers(String baseDN, TopologyCache cache, ServerDescriptor server) { LinkedHashSet<String> servers = new LinkedHashSet<String>(); for (ReplicaDescriptor replica : server.getReplicas()) { if (Utils.areDnsEqual(replica.getSuffix().getDN(), baseDN)) { servers.addAll(replica.getReplicationServers()); break; } } if (cache != null) { Set<SuffixDescriptor> suffixes = cache.getSuffixes(); for (SuffixDescriptor suffix : suffixes) { if (Utils.areDnsEqual(suffix.getDN(), baseDN)) { Set<String> s = suffix.getReplicationServers(); // Test that at least we share one of the replication servers. // If we do: we are dealing with the same replication topology // (we must consider the case of disjoint replication topologies // replicating the same base DN). HashSet<String> copy = new HashSet<String>(s); copy.retainAll(servers); if (!copy.isEmpty()) { servers.addAll(s); break; } } } } return servers; } /** * Retrieves the suffix in the TopologyCache for a given baseDN. The * ServerDescriptor is used to identify the server where the suffix is * defined. * @param baseDN the base DN. * @param cache the TopologyCache. * @param server the ServerDescriptor. * @return the suffix in the TopologyCache for a given baseDN. */ private SuffixDescriptor getSuffix(String baseDN, TopologyCache cache, ServerDescriptor server) { SuffixDescriptor returnValue = null; Set<String> servers = new LinkedHashSet<String>(); for (ReplicaDescriptor replica : server.getReplicas()) { if (Utils.areDnsEqual(replica.getSuffix().getDN(), baseDN)) { servers.addAll(replica.getReplicationServers()); break; } } Set<SuffixDescriptor> suffixes = cache.getSuffixes(); for (SuffixDescriptor suffix : suffixes) { if (Utils.areDnsEqual(suffix.getDN(), baseDN)) { Set<String> s = suffix.getReplicationServers(); // Test that at least we share one of the replication servers. // If we do: we are dealing with the same replication topology // (we must consider the case of disjoint replication topologies // replicating the same base DN). HashSet<String> copy = new HashSet<String>(s); copy.retainAll(servers); if (!copy.isEmpty()) { returnValue = suffix; break; } } } return returnValue; } /** * Retrieves all the replication domain IDs for a given baseDN in the * ServerDescriptor. * @param baseDN the base DN. * @param server the ServerDescriptor. * @return a Set containing the replication domain IDs for a given baseDN in * the ServerDescriptor. */ private Set<Integer> getReplicationDomainIds(String baseDN, ServerDescriptor server) { Set<Integer> ids = new HashSet<Integer>(); for (ReplicaDescriptor replica : server.getReplicas()) { if ((replica.isReplicated()) && Utils.areDnsEqual(replica.getSuffix().getDN(), baseDN)) { ids.add(replica.getReplicationId()); break; } } return ids; } /** * Configures the server to which the provided InitialLdapContext is connected * as a replication server. The replication server listens in the provided * port. * @param ctx the context connected to the server that we want to configure. * @param replicationPort the replication port of the replication server. * @param replicationServers the list of replication servers to which the * replication server will communicate with. * @param usedReplicationServerIds the set of replication server IDs that * are already in use. The set will be updated with the replication ID * that will be used by the newly configured replication server. * @throws OpenDsException if there is an error updating the configuration. */ private void configureAsReplicationServer(InitialLdapContext ctx, int replicationPort, LinkedHashSet<String> replicationServers, Set<Integer> usedReplicationServerIds) throws OpenDsException { printProgressMessage(formatter.getFormattedWithPoints( INFO_REPLICATION_ENABLE_CONFIGURING_REPLICATION_SERVER.get( ConnectionUtils.getHostPort(ctx)))); ManagementContext mCtx = LDAPManagementContext.createFromContext( JNDIDirContextAdaptor.adapt(ctx)); RootCfgClient root = mCtx.getRootConfiguration(); /* * Configure Synchronization plugin. */ MultimasterSynchronizationProviderCfgClient sync = null; try { sync = (MultimasterSynchronizationProviderCfgClient) root.getSynchronizationProvider("Multimaster Synchronization"); } catch (ManagedObjectNotFoundException monfe) { LOG.log(Level.INFO, "Synchronization server does not exist in "+ ConnectionUtils.getHostPort(ctx)); } if (sync == null) { MultimasterSynchronizationProviderCfgDefn provider = MultimasterSynchronizationProviderCfgDefn.getInstance(); sync = root.createSynchronizationProvider(provider, "Multimaster Synchronization", new ArrayList<DefaultBehaviorException>()); sync.setJavaImplementationClass( org.opends.server.replication.plugin.MultimasterReplication.class. getName()); sync.setEnabled(Boolean.TRUE); } else { if (!sync.isEnabled()) { sync.setEnabled(Boolean.TRUE); } } sync.commit(); /* * Configure the replication server. */ ReplicationServerCfgClient replicationServer = null; boolean mustCommit = false; if (!sync.hasReplicationServer()) { int id = InstallerHelper.getReplicationId(usedReplicationServerIds); usedReplicationServerIds.add(id); replicationServer = sync.createReplicationServer( ReplicationServerCfgDefn.getInstance(), new ArrayList<DefaultBehaviorException>()); replicationServer.setReplicationServerId(id); replicationServer.setReplicationPort(replicationPort); replicationServer.setReplicationServer(replicationServers); mustCommit = true; } else { replicationServer = sync.getReplicationServer(); usedReplicationServerIds.add( replicationServer.getReplicationServerId()); Set<String> servers = replicationServer.getReplicationServer(); if (servers == null) { replicationServer.setReplicationServer(servers); mustCommit = true; } else if (!servers.equals(replicationServers)) { replicationServers.addAll(servers); replicationServer.setReplicationServer(replicationServers); mustCommit = true; } } if (mustCommit) { replicationServer.commit(); } printProgressMessage(formatter.getFormattedDone()); printProgressMessage(formatter.getLineBreak()); } /** * Returns a Set containing all the replication server ids found in the * servers of a given TopologyCache object. * @param cache the TopologyCache object to use. * @return a Set containing all the replication server ids found in a given * TopologyCache object. */ private Set<Integer> getReplicationServerIds(TopologyCache cache) { Set<Integer> ids = new HashSet<Integer>(); for (ServerDescriptor server : cache.getServers()) { if (server.isReplicationServer()) { ids.add(server.getReplicationServerId()); } } return ids; } /** * Configures a replication domain for a given base DN in the server to which * the provided InitialLdapContext is connected. * @param ctx the context connected to the server that we want to configure. * @param baseDN the base DN of the replication domain to configure. * @param replicationServers the list of replication servers to which the * replication domain will communicate with. * @param usedReplicationDomainIds the set of replication domain IDs that * are already in use. The set will be updated with the replication ID * that will be used by the newly configured replication server. * @throws OpenDsException if there is an error updating the configuration. */ private void configureToReplicateBaseDN(InitialLdapContext ctx, String baseDN, LinkedHashSet<String> replicationServers, Set<Integer> usedReplicationDomainIds) throws OpenDsException { printProgressMessage(formatter.getFormattedWithPoints( INFO_REPLICATION_ENABLE_CONFIGURING_BASEDN.get(baseDN, ConnectionUtils.getHostPort(ctx)))); ManagementContext mCtx = LDAPManagementContext.createFromContext( JNDIDirContextAdaptor.adapt(ctx)); RootCfgClient root = mCtx.getRootConfiguration(); MultimasterSynchronizationProviderCfgClient sync = (MultimasterSynchronizationProviderCfgClient) root.getSynchronizationProvider("Multimaster Synchronization"); 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]); } MultimasterDomainCfgClient domain = null; String domainName = null; for (int i=0; i<domains.length && (domain == null); i++) { if (Utils.areDnsEqual(baseDN, domains[i].getReplicationDN().toString())) { domain = domains[i]; domainName = domainNames[i]; } } boolean mustCommit = false; if (domain == null) { int domainId = InstallerHelper.getReplicationId(usedReplicationDomainIds); usedReplicationDomainIds.add(domainId); domainName = InstallerHelper.getDomainName(domainNames, domainId); domain = sync.createMultimasterDomain( MultimasterDomainCfgDefn.getInstance(), domainName, new ArrayList<DefaultBehaviorException>()); domain.setServerId(domainId); domain.setReplicationDN(DN.decode(baseDN)); domain.setReplicationServer(replicationServers); mustCommit = true; } else { Set<String> servers = domain.getReplicationServer(); if (servers == null) { domain.setReplicationServer(servers); mustCommit = true; } else if (!servers.equals(replicationServers)) { replicationServers.addAll(servers); domain.setReplicationServer(replicationServers); mustCommit = true; } } if (mustCommit) { domain.commit(); } printProgressMessage(formatter.getFormattedDone()); printProgressMessage(formatter.getLineBreak()); } /** * Configures the baseDN to replicate in all the Replicas found in a Topology * Cache that are replicated with the Replica of the same base DN in the * provided ServerDescriptor object. * @param baseDN the base DN to replicate. * @param repServers the replication servers to be defined in the domain. * @param usedIds the replication domain Ids already used. This Set is * updated with the new domains that are used. * @param cache the TopologyCache used to retrieve the different defined * replicas. * @param server the ServerDescriptor that is used to identify the * replication topology that we are interested at (we only update the replicas * that are already replicated with this server). * @param alreadyConfiguredServers the list of already configured servers. If * a server is in this list no updates are performed. * @throws ReplicationCliException if something goes wrong. */ private void configureToReplicateBaseDN(String baseDN, LinkedHashSet<String> repServers, Set<Integer> usedIds, TopologyCache cache, ServerDescriptor server, Set<String>alreadyConfiguredServers) throws ReplicationCliException { SuffixDescriptor suffix = getSuffix(baseDN, cache, server); if (suffix != null) { for (ReplicaDescriptor replica: suffix.getReplicas()) { ServerDescriptor s = replica.getServer(); if (!alreadyConfiguredServers.contains(s.getId())) { String dn = ConnectionUtils.getBindDN( cache.getAdsContext().getDirContext()); String pwd = ConnectionUtils.getBindPassword( cache.getAdsContext().getDirContext()); ServerLoader loader = new ServerLoader(server.getAdsProperties(), dn, pwd, getTrustManager()); InitialLdapContext ctx = null; try { ctx = loader.createContext(); configureToReplicateBaseDN(ctx, baseDN, repServers, usedIds); } catch (NamingException ne) { String hostPort = server.getHostPort(true); Message msg = getMessageForException(ne, hostPort); throw new ReplicationCliException(msg, ERROR_CONNECTING, ne); } catch (OpenDsException ode) { String hostPort = server.getHostPort(true); Message msg = getMessageForEnableException(ode, hostPort, baseDN); throw new ReplicationCliException(msg, ERROR_ENABLING_REPLICATION_ON_BASEDN, ode); } finally { if (ctx != null) { try { ctx.close(); } catch (Throwable t) { } } } alreadyConfiguredServers.add(s.getId()); } } } } /** * Returns the Map of properties to be used to update the ADS. * This map uses the data provided by the user. * @return the Map of properties to be used to update the ADS. * This map uses the data provided by the user */ private Map<ADSContext.AdministratorProperty, Object> getAdministratorProperties(ReplicationUserData uData) { Map<ADSContext.AdministratorProperty, Object> adminProperties = new HashMap<ADSContext.AdministratorProperty, Object>(); adminProperties.put(ADSContext.AdministratorProperty.UID, uData.getAdminUid()); adminProperties.put(ADSContext.AdministratorProperty.PASSWORD, uData.getAdminPwd()); adminProperties.put(ADSContext.AdministratorProperty.DESCRIPTION, INFO_GLOBAL_ADMINISTRATOR_DESCRIPTION.get().toString()); return adminProperties; } private void initializeSuffix(String baseDN, InitialLdapContext ctxSource, InitialLdapContext ctxDestination, boolean displayProgress) throws ReplicationCliException { int replicationId = -1; try { ServerDescriptor source = ServerDescriptor.createStandalone( ctxSource); for (ReplicaDescriptor replica : source.getReplicas()) { if (Utils.areDnsEqual(replica.getSuffix().getDN(), baseDN)) { replicationId = replica.getReplicationId(); break; } } } catch (NamingException ne) { String hostPort = ConnectionUtils.getHostPort(ctxSource); Message msg = getMessageForException(ne, hostPort); throw new ReplicationCliException(msg, ERROR_READING_CONFIGURATION, ne); } if (replicationId == -1) { throw new ReplicationCliException( ERR_INITIALIZING_REPLICATIONID_NOT_FOUND.get( ConnectionUtils.getHostPort(ctxSource), baseDN), REPLICATIONID_NOT_FOUND, null); } OfflineInstaller installer = new OfflineInstaller(); installer.setProgressMessageFormatter(formatter); installer.addProgressUpdateListener(new ProgressUpdateListener() { public void progressUpdate(ProgressUpdateEvent ev) { Message newLogDetails = ev.getNewLogs(); if (newLogDetails != null) { printProgressMessage(newLogDetails); printProgressLineBreak(); } } }); int nTries = 5; boolean initDone = false; while (!initDone) { try { installer.initializeSuffix(ctxDestination, replicationId, baseDN, displayProgress, ConnectionUtils.getHostPort(ctxSource)); initDone = true; } catch (PeerNotFoundException pnfe) { LOG.log(Level.INFO, "Peer could not be found"); if (nTries == 1) { throw new ReplicationCliException( ERR_REPLICATION_INITIALIZING_TRIES_COMPLETED.get( pnfe.getMessageObject().toString()), INITIALIZING_TRIES_COMPLETED, pnfe); } try { Thread.sleep((5 - nTries) * 3000); } catch (Throwable t) { } } catch (ApplicationException ae) { throw new ReplicationCliException(ae.getMessageObject(), ERROR_INITIALIZING_BASEDN_GENERIC, ae); } nTries--; } } /** * Returns a set of error messages encountered in the provided TopologyCache. * @param cache the topology cache. * @return a set of error messages encountered in the provided TopologyCache. */ private LinkedHashSet<Message> getErrorMessages(TopologyCache cache) { Set<TopologyCacheException> exceptions = new HashSet<TopologyCacheException>(); Set<ServerDescriptor> servers = cache.getServers(); LinkedHashSet<Message> exceptionMsgs = new LinkedHashSet<Message>(); for (ServerDescriptor server : servers) { TopologyCacheException e = server.getLastException(); if (e != null) { exceptions.add(e); } } /* Check the exceptions and see if we throw them or not. */ for (TopologyCacheException e : exceptions) { switch (e.getType()) { case NOT_GLOBAL_ADMINISTRATOR: exceptionMsgs.add(INFO_NOT_GLOBAL_ADMINISTRATOR_PROVIDED.get()); break; case GENERIC_CREATING_CONNECTION: if ((e.getCause() != null) && Utils.isCertificateException(e.getCause())) { exceptionMsgs.add( INFO_ERROR_READING_CONFIG_LDAP_CERTIFICATE_SERVER.get( e.getHostPort(), e.getCause().getMessage())); } else { exceptionMsgs.add(Utils.getMessage(e)); } break; default: exceptionMsgs.add(Utils.getMessage(e)); } } return exceptionMsgs; } /** * Removes the references to a replication server in the base DNs of a * given server. * @param server the server that we want to update. * @param replicationServer the replication server whose references we want * to remove. * @param bindDn the bindDn that must be used to log to the server. * @param pwd the password that must be used to log to the server. * @param baseDNs the list of base DNs where we want to remove the references * to the provided replication server. * @throws ReplicationCliException if there is an error updating the * configuration. */ private void removeReferencesInServer(ServerDescriptor server, String replicationServer, String bindDn, String pwd, Collection<String> baseDNs) throws ReplicationCliException { ServerLoader loader = new ServerLoader(server.getAdsProperties(), bindDn, pwd, getTrustManager()); InitialLdapContext ctx = null; String lastBaseDN = null; String hostPort = null; try { ctx = loader.createContext(); hostPort = ConnectionUtils.getHostPort(ctx); ManagementContext mCtx = LDAPManagementContext.createFromContext( JNDIDirContextAdaptor.adapt(ctx)); RootCfgClient root = mCtx.getRootConfiguration(); MultimasterSynchronizationProviderCfgClient sync = null; try { sync = (MultimasterSynchronizationProviderCfgClient) root.getSynchronizationProvider("Multimaster Synchronization"); } catch (ManagedObjectNotFoundException monfe) { // It does not exist. LOG.log(Level.INFO, "No synchronization found on "+ hostPort +".", monfe); } if (sync != null) { String[] domainNames = sync.listMultimasterDomains(); if (domainNames != null) { for (int i=0; i<domainNames.length; i++) { MultimasterDomainCfgClient domain = sync.getMultimasterDomain(domainNames[i]); for (String baseDN : baseDNs) { lastBaseDN = baseDN; if (Utils.areDnsEqual(domain.getReplicationDN().toString(), baseDN)) { printProgressMessage(formatter.getFormattedWithPoints( INFO_REPLICATION_REMOVING_REFERENCES_ON_REMOTE.get(baseDN, hostPort))); Set<String> replServers = domain.getReplicationServer(); if (replServers != null) { String replServer = null; for (String o : replServers) { if (replicationServer.equalsIgnoreCase(o)) { replServer = o; break; } } if (replServer != null) { LOG.log(Level.INFO, "Updating references in domain " + domain.getReplicationDN()+" on " + hostPort + "."); replServers.remove(replServer); if (replServers.size() > 0) { domain.setReplicationServer(replServers); domain.commit(); } else { sync.removeMultimasterDomain(domainNames[i]); sync.commit(); } } } printProgressMessage(formatter.getFormattedDone()); printProgressMessage(formatter.getLineBreak()); } } } } } } catch (NamingException ne) { hostPort = server.getHostPort(true); Message msg = getMessageForException(ne, hostPort); throw new ReplicationCliException(msg, ERROR_CONNECTING, ne); } catch (OpenDsException ode) { if (lastBaseDN != null) { Message msg = getMessageForDisableException(ode, hostPort, lastBaseDN); throw new ReplicationCliException(msg, ERROR_DISABLING_REPLICATION_REMOVE_REFERENCE_ON_BASEDN, ode); } else { Message msg = ERR_REPLICATION_ERROR_READING_CONFIGURATION.get(hostPort, ode.getMessage()); throw new ReplicationCliException(msg, ERROR_CONNECTING, ode); } } finally { if (ctx != null) { try { ctx.close(); } catch (Throwable t) { } } } } /** * Deletes a replication domain in a server for a given base DN (disable * replication of the base DN). * @param ctx the connection to the server. * @param baseDN the base DN of the replication domain that we want to * delete. * @throws ReplicationCliException if there is an error updating the * configuration of the server. */ private void deleteReplicationDomain(InitialLdapContext ctx, String baseDN) throws ReplicationCliException { String hostPort = ConnectionUtils.getHostPort(ctx); try { ManagementContext mCtx = LDAPManagementContext.createFromContext( JNDIDirContextAdaptor.adapt(ctx)); RootCfgClient root = mCtx.getRootConfiguration(); MultimasterSynchronizationProviderCfgClient sync = null; try { sync = (MultimasterSynchronizationProviderCfgClient) root.getSynchronizationProvider("Multimaster Synchronization"); } catch (ManagedObjectNotFoundException monfe) { // It does not exist. LOG.log(Level.INFO, "No synchronization found on "+ hostPort +".", monfe); } if (sync != null) { String[] domainNames = sync.listMultimasterDomains(); if (domainNames != null) { for (int i=0; i<domainNames.length; i++) { MultimasterDomainCfgClient domain = sync.getMultimasterDomain(domainNames[i]); if (Utils.areDnsEqual(domain.getReplicationDN().toString(), baseDN)) { printProgressMessage(formatter.getFormattedWithPoints( INFO_REPLICATION_DISABLING_BASEDN.get(baseDN, hostPort))); sync.removeMultimasterDomain(domainNames[i]); sync.commit(); printProgressMessage(formatter.getFormattedDone()); printProgressMessage(formatter.getLineBreak()); } } } } } catch (OpenDsException ode) { Message msg = getMessageForDisableException(ode, hostPort, baseDN); throw new ReplicationCliException(msg, ERROR_DISABLING_REPLICATION_REMOVE_REFERENCE_ON_BASEDN, ode); } } /** * Returns a message object for the given NamingException. * @param ne the NamingException. * @param hostPort the hostPort representation of the server we were * contacting when the NamingException occurred. * @return a message object for the given NamingException. */ private Message getMessageForException(NamingException ne, String hostPort) { Message msg; if (Utils.isCertificateException(ne)) { msg = INFO_ERROR_READING_CONFIG_LDAP_CERTIFICATE_SERVER.get( hostPort, ne.getMessage()); } else { msg = INFO_CANNOT_CONNECT_TO_REMOTE_GENERIC.get( hostPort, ne.getMessage()); } return msg; } /** * Returns a message for a given OpenDsException (we assume that was an * exception generated updating the configuration of the server) that * occurred when we were configuring the replication server. * @param ode the OpenDsException. * @param hostPort the hostPort representation of the server we were * contacting when the OpenDsException occurred. * @return a message for a given OpenDsException (we assume that was an * exception generated updating the configuration of the server) that * occurred when we were configuring the replication server. */ private Message getMessageForReplicationServerException(OpenDsException ode, String hostPort) { return ERR_REPLICATION_CONFIGURING_REPLICATIONSERVER.get(hostPort); } /** * Returns a message for a given OpenDsException (we assume that was an * exception generated updating the configuration of the server) that * occurred when we were configuring some replication domain (creating * the replication domain or updating the list of replication servers of * the replication domain). * @param ode the OpenDsException. * @param hostPort the hostPort representation of the server we were * contacting when the OpenDsException occurred. * @return a message for a given OpenDsException (we assume that was an * exception generated updating the configuration of the server) that * occurred when we were configuring some replication domain (creating * the replication domain or updating the list of replication servers of * the replication domain). */ private Message getMessageForEnableException(OpenDsException ode, String hostPort, String baseDN) { return ERR_REPLICATION_CONFIGURING_BASEDN.get(baseDN, hostPort); } /** * Returns a message for a given OpenDsException (we assume that was an * exception generated updating the configuration of the server) that * occurred when we were configuring some replication domain (deleting * the replication domain or updating the list of replication servers of * the replication domain). * @param ode the OpenDsException. * @param hostPort the hostPort representation of the server we were * contacting when the OpenDsException occurred. * @return a message for a given OpenDsException (we assume that was an * exception generated updating the configuration of the server) that * occurred when we were configuring some replication domain (deleting * the replication domain or updating the list of replication servers of * the replication domain). */ private Message getMessageForDisableException(OpenDsException ode, String hostPort, String baseDN) { return ERR_REPLICATION_CONFIGURING_BASEDN.get(baseDN, hostPort); } } opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliParser.java
New file @@ -0,0 +1,1462 @@ /* * 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.guitools.replicationcli; import static org.opends.messages.AdminToolMessages.*; import static org.opends.messages.ToolMessages.*; import static org.opends.server.tools.ToolConstants.*; import java.io.OutputStream; import java.util.ArrayList; import java.util.LinkedList; import org.opends.messages.Message; import org.opends.messages.MessageBuilder; import org.opends.quicksetup.Constants; import org.opends.quicksetup.util.Utils; import org.opends.server.admin.client.cli.SecureConnectionCliParser; import org.opends.server.util.args.Argument; import org.opends.server.util.args.ArgumentException; import org.opends.server.util.args.BooleanArgument; import org.opends.server.util.args.FileBasedArgument; import org.opends.server.util.args.IntegerArgument; import org.opends.server.util.args.StringArgument; import org.opends.server.util.args.SubCommand; /** * This class is used to parse the arguments passed to the replication CLI. * It also checks the compatibility between the values and that all the * required information has been provided. However it does not do any * verification that require connection to any server. */ public class ReplicationCliParser extends SecureConnectionCliParser { private SubCommand enableReplicationSubCmd; private SubCommand disableReplicationSubCmd; private SubCommand initializeReplicationSubCmd; private BooleanArgument interactive; /** * The 'hostName' global argument for the first server. */ private StringArgument hostName1Arg = null; /** * The 'port' global argument for the first server. */ private IntegerArgument port1Arg = null; /** * The 'binDN' global argument for the first server. */ private StringArgument bindDn1Arg = null; /** * The 'bindPasswordFile' global argument for the first server. */ private FileBasedArgument bindPasswordFile1Arg = null; /** * The 'bindPassword' global argument for the first server. */ private StringArgument bindPassword1Arg = null; /** * The 'useSSLArg' argument for the first server. */ protected BooleanArgument useSSL1Arg = null; /** * The 'useStartTLS1Arg' argument for the first server. */ protected BooleanArgument useStartTLS1Arg = null; /** * The 'replicationPort' global argument for the first server. */ private IntegerArgument replicationPort1Arg = null; /** * The 'hostName' global argument for the second server. */ private StringArgument hostName2Arg = null; /** * The 'port' global argument for the second server. */ private IntegerArgument port2Arg = null; /** * The 'binDN' global argument for the second server. */ private StringArgument bindDn2Arg = null; /** * The 'bindPasswordFile' global argument for the second server. */ private FileBasedArgument bindPasswordFile2Arg = null; /** * The 'bindPassword' global argument for the second server. */ private StringArgument bindPassword2Arg = null; /** * The 'useSSLArg' argument for the second server. */ protected BooleanArgument useSSL2Arg = null; /** * The 'useStartTLS2Arg' argument for the second server. */ protected BooleanArgument useStartTLS2Arg = null; /** * The 'replicationPort' global argument for the second server. */ private IntegerArgument replicationPort2Arg = null; /** * The 'hostName' global argument for the source server. */ private StringArgument hostNameSourceArg = null; /** * The 'port' global argument for the source server. */ private IntegerArgument portSourceArg = null; /** * The 'useSSLArg' argument for the source server. */ protected BooleanArgument useSSLSourceArg = null; /** * The 'useStartTLSSourceArg' argument for the source server. */ protected BooleanArgument useStartTLSSourceArg = null; /** * The 'hostName' global argument for the destination server. */ private StringArgument hostNameDestinationArg = null; /** * The 'port' global argument for the destination server. */ private IntegerArgument portDestinationArg = null; /** * The 'useSSLArg' argument for the destination server. */ protected BooleanArgument useSSLDestinationArg = null; /** * The 'useStartTLSDestinationArg' argument for the destination server. */ protected BooleanArgument useStartTLSDestinationArg = null; /** * The 'suffixes' global argument. */ private StringArgument baseDNsArg = null; /** * The 'admin UID' global argument. */ private StringArgument adminUidArg; /** * The 'admin Password' global argument. */ private StringArgument adminPasswordArg; /** * The 'admin Password File' global argument. */ private FileBasedArgument adminPasswordFileArg; /** * The 'quiet' argument. */ private BooleanArgument quietArg; /** * The text of the enable replication subcommand. */ public static final String ENABLE_REPLICATION_SUBCMD_NAME = "enable"; /** * The text of the disable replication subcommand. */ public static final String DISABLE_REPLICATION_SUBCMD_NAME = "disable"; /** * The text of the initialize replication subcommand. */ public static final String INITIALIZE_REPLICATION_SUBCMD_NAME = "initialize"; /** * Creates a new instance of this argument parser with no arguments. * * @param mainClassName * The fully-qualified name of the Java class that should * be invoked to launch the program with which this * argument parser is associated. */ public ReplicationCliParser(String mainClassName) { super(mainClassName, INFO_REPLICATION_TOOL_DESCRIPTION.get(ENABLE_REPLICATION_SUBCMD_NAME, INITIALIZE_REPLICATION_SUBCMD_NAME), false); } /** * Initialize the parser with the Global options and subcommands. * * @param outStream * The output stream to use for standard output, or <CODE>null</CODE> * if standard output is not needed. * @throws ArgumentException * If there is a problem with any of the parameters used * to create this argument. */ public void initializeParser(OutputStream outStream) throws ArgumentException { initializeGlobalArguments(outStream); createEnableReplicationSubCommand(); createDisableReplicationSubCommand(); createInitializeReplicationSubCommand(); } /** * Checks all the options parameters and updates the provided MessageBuilder * with the errors that where encountered. * * This method assumes that the method parseArguments for the parser has * already been called. * @param buf the MessageBuilder object where we add the error messages * describing the errors encountered. */ public void validateOptions(MessageBuilder buf) { validateGlobalOptions(buf); validateSubcommandOptions(buf); } /** * {@inheritDoc} */ public int validateGlobalOptions(MessageBuilder buf) { int returnValue; super.validateGlobalOptions(buf); ArrayList<Message> errors = new ArrayList<Message>(); if (adminPasswordArg.isPresent() && adminPasswordFileArg.isPresent()) { Message message = ERR_TOOL_CONFLICTING_ARGS.get( adminPasswordArg.getLongIdentifier(), adminPasswordFileArg.getLongIdentifier()); errors.add(message); } if (!isInteractive()) { // Check that we have the required data if (!baseDNsArg.isPresent()) { errors.add(ERR_REPLICATION_NO_BASE_DN_PROVIDED.get()); } if (getBindPasswordAdmin() == null) { errors.add(ERR_REPLICATION_NO_ADMINISTRATOR_PASSWORD_PROVIDED.get( adminPasswordArg.getLongIdentifier(), adminPasswordFileArg.getLongIdentifier())); } } if (baseDNsArg.isPresent()) { LinkedList<String> baseDNs = baseDNsArg.getValues(); for (String dn : baseDNs) { if (!Utils.isDn(dn)) { errors.add(ERR_REPLICATION_NOT_A_VALID_BASEDN.get(dn)); } } } if (errors.size() > 0) { for (Message error : errors) { addMessage(buf, error); } } if (buf.length() > 0) { returnValue = ReplicationCliReturnCode.CONFLICTING_ARGS.getReturnCode(); } else { returnValue = ReplicationCliReturnCode.SUCCESSFUL_NOP.getReturnCode(); } return returnValue; } /** * Initialize Global option. * * @param outStream * The output stream used for the usage. * @throws ArgumentException * If there is a problem with any of the parameters used * to create this argument. */ private void initializeGlobalArguments(OutputStream outStream) throws ArgumentException { ArrayList<Argument> defaultArgs = new ArrayList<Argument>(createGlobalArguments(outStream)); Argument[] argsToRemove = { hostNameArg, portArg, bindDnArg, bindPasswordFileArg, bindPasswordArg, useSSLArg, useStartTLSArg }; for (int i=0; i<argsToRemove.length; i++) { defaultArgs.remove(argsToRemove[i]); } baseDNsArg = new StringArgument("baseDNs", 'b', "baseDNs", false, true, true, OPTION_VALUE_BASEDN, null, null, INFO_DESCRIPTION_REPLICATION_BASEDNS.get()); defaultArgs.add(baseDNsArg); adminUidArg = new StringArgument("adminUID", 'I', "adminUID", false, false, true, "adminUID", Constants.GLOBAL_ADMIN_UID, null, INFO_DESCRIPTION_REPLICATION_ADMIN_UID.get( ENABLE_REPLICATION_SUBCMD_NAME)); defaultArgs.add(adminUidArg); adminPasswordArg = new StringArgument("adminPassword", OPTION_SHORT_BINDPWD, "adminPassword", false, false, true, OPTION_VALUE_BINDPWD, null, null, INFO_DESCRIPTION_REPLICATION_ADMIN_BINDPASSWORD.get()); defaultArgs.add(adminPasswordArg); adminPasswordFileArg = new FileBasedArgument("adminPasswordFile", OPTION_SHORT_BINDPWD_FILE, "adminPasswordFile", false, false, OPTION_VALUE_BINDPWD_FILE, null, null, INFO_DESCRIPTION_REPLICATION_ADMIN_BINDPASSWORDFILE.get()); defaultArgs.add(adminPasswordFileArg); defaultArgs.remove(verboseArg); interactive = new BooleanArgument( INTERACTIVE_OPTION_LONG, INTERACTIVE_OPTION_SHORT, INTERACTIVE_OPTION_LONG, INFO_DESCRIPTION_INTERACTIVE.get()); defaultArgs.add(interactive); quietArg = new BooleanArgument( SecureConnectionCliParser.QUIET_OPTION_LONG, SecureConnectionCliParser.QUIET_OPTION_SHORT, SecureConnectionCliParser.QUIET_OPTION_LONG, INFO_REPLICATION_DESCRIPTION_QUIET.get()); defaultArgs.add(quietArg); initializeGlobalArguments(defaultArgs); } /** * Creates the enable replication subcommand and all the specific options * for the subcommand. */ private void createEnableReplicationSubCommand() throws ArgumentException { hostName1Arg = new StringArgument("host1", 'h', "host1", false, false, true, OPTION_VALUE_HOST, "localhost", null, INFO_DESCRIPTION_ENABLE_REPLICATION_HOST1.get()); port1Arg = new IntegerArgument("port1", 'p', "port1", false, false, true, OPTION_VALUE_PORT, 389, null, INFO_DESCRIPTION_ENABLE_REPLICATION_SERVER_PORT1.get()); bindDn1Arg = new StringArgument("bindDN1", 'D', "bindDN1", false, false, true, OPTION_VALUE_BINDDN, "cn=Directory Manager", null, INFO_DESCRIPTION_ENABLE_REPLICATION_BINDDN1.get()); bindPassword1Arg = new StringArgument("bindPassword1", 'w', "bindPassword1", false, false, true, OPTION_VALUE_BINDPWD, null, null, INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORD1.get()); bindPasswordFile1Arg = new FileBasedArgument("bindPasswordFile1", 'j', "bindPasswordFile1", false, false, OPTION_VALUE_BINDPWD_FILE, null, null, INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORDFILE1.get()); useSSL1Arg = new BooleanArgument("useSSL1", 'Z', "useSSL1", INFO_DESCRIPTION_ENABLE_REPLICATION_USE_SSL1.get()); useStartTLS1Arg = new BooleanArgument("startTLS1", 'q', "startTLS1", INFO_DESCRIPTION_ENABLE_REPLICATION_STARTTLS1.get()); replicationPort1Arg = new IntegerArgument("replicationPort1", 'r', "replicationPort1", false, false, true, OPTION_VALUE_PORT, 8989, null, INFO_DESCRIPTION_ENABLE_REPLICATION_PORT1.get()); hostName2Arg = new StringArgument("host2", 'H', "host2", false, false, true, OPTION_VALUE_HOST, "localhost", null, INFO_DESCRIPTION_ENABLE_REPLICATION_HOST2.get()); port2Arg = new IntegerArgument("port2", 'P', "port2", false, false, true, OPTION_VALUE_PORT, 389, null, INFO_DESCRIPTION_ENABLE_REPLICATION_SERVER_PORT2.get()); bindDn2Arg = new StringArgument("bindDN2", 'N', "bindDN2", false, false, true, OPTION_VALUE_BINDDN, "cn=Directory Manager", null, INFO_DESCRIPTION_ENABLE_REPLICATION_BINDDN2.get()); bindPassword2Arg = new StringArgument("bindPassword2", 'W', "bindPassword2", false, false, true, OPTION_VALUE_BINDPWD, null, null, INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORD2.get()); bindPasswordFile2Arg = new FileBasedArgument("bindPasswordFile2", 'F', "bindPasswordFile2", false, false, OPTION_VALUE_BINDPWD_FILE, null, null, INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORDFILE2.get()); useSSL2Arg = new BooleanArgument("useSSL2", 'S', "useSSL2", INFO_DESCRIPTION_ENABLE_REPLICATION_USE_SSL2.get()); useStartTLS2Arg = new BooleanArgument("startTLS2", 'Q', "startTLS2", INFO_DESCRIPTION_ENABLE_REPLICATION_STARTTLS2.get()); replicationPort2Arg = new IntegerArgument("replicationPort2", 'R', "replicationPort2", false, false, true, OPTION_VALUE_PORT, 8989, null, INFO_DESCRIPTION_ENABLE_REPLICATION_PORT2.get()); enableReplicationSubCmd = new SubCommand(this, ENABLE_REPLICATION_SUBCMD_NAME, INFO_DESCRIPTION_SUBCMD_ENABLE_REPLICATION.get()); Argument[] argsToAdd = { hostName1Arg, port1Arg, bindDn1Arg, bindPassword1Arg, bindPasswordFile1Arg, useStartTLS1Arg, useSSL1Arg, replicationPort1Arg, hostName2Arg, port2Arg, bindDn2Arg, bindPassword2Arg, bindPasswordFile2Arg, useStartTLS2Arg, useSSL2Arg, replicationPort2Arg, }; for (int i=0; i<argsToAdd.length; i++) { enableReplicationSubCmd.addArgument(argsToAdd[i]); } } /** * Creates the disable replication subcommand and all the specific options * for the subcommand. Note: this method assumes that * initializeGlobalArguments has already been called and that hostNameArg, * portArg, startTLSArg and useSSLArg have been created. */ private void createDisableReplicationSubCommand() throws ArgumentException { disableReplicationSubCmd = new SubCommand(this, DISABLE_REPLICATION_SUBCMD_NAME, INFO_DESCRIPTION_SUBCMD_DISABLE_REPLICATION.get()); Argument[] argsToAdd = { hostNameArg, portArg, useSSLArg, useStartTLSArg }; for (int i=0; i<argsToAdd.length; i++) { disableReplicationSubCmd.addArgument(argsToAdd[i]); } } /** * Creates the initialize replication subcommand and all the specific options * for the subcommand. */ private void createInitializeReplicationSubCommand() throws ArgumentException { hostNameSourceArg = new StringArgument("hostSource", 'h', "hostSource", false, false, true, OPTION_VALUE_HOST, "localhost", null, INFO_DESCRIPTION_INITIALIZE_REPLICATION_HOST_SOURCE.get()); portSourceArg = new IntegerArgument("portSource", 'p', "portSource", false, false, true, OPTION_VALUE_PORT, 389, null, INFO_DESCRIPTION_INITIALIZE_REPLICATION_SERVER_PORT_SOURCE.get()); useSSLSourceArg = new BooleanArgument("useSSLSource", 'Z', "useSSLSource", INFO_DESCRIPTION_INITIALIZE_REPLICATION_USE_SSL_SOURCE.get()); useStartTLSSourceArg = new BooleanArgument("startTLSSource", 'q', "startTLSSource", INFO_DESCRIPTION_INITIALIZE_REPLICATION_STARTTLS_SOURCE.get()); hostNameDestinationArg = new StringArgument("hostDestination", 'H', "hostDestination", false, false, true, OPTION_VALUE_HOST, "localhost", null, INFO_DESCRIPTION_INITIALIZE_REPLICATION_HOST_DESTINATION.get()); portDestinationArg = new IntegerArgument("portDestination", 'P', "portDestination", false, false, true, OPTION_VALUE_PORT, 389, null, INFO_DESCRIPTION_INITIALIZE_REPLICATION_SERVER_PORT_DESTINATION.get()); useSSLDestinationArg = new BooleanArgument("useSSLDestination", 'S', "useSSLDestination", INFO_DESCRIPTION_INITIALIZE_REPLICATION_USE_SSL_DESTINATION.get()); useStartTLSDestinationArg = new BooleanArgument("startTLSDestination", 'Q', "startTLSDestination", INFO_DESCRIPTION_INITIALIZE_REPLICATION_STARTTLS_DESTINATION.get()); initializeReplicationSubCmd = new SubCommand(this, INITIALIZE_REPLICATION_SUBCMD_NAME, INFO_DESCRIPTION_SUBCMD_INITIALIZE_REPLICATION.get()); Argument[] argsToAdd = { hostNameSourceArg, portSourceArg, useSSLSourceArg, useStartTLSSourceArg, hostNameDestinationArg, portDestinationArg, useSSLDestinationArg, useStartTLSDestinationArg }; for (int i=0; i<argsToAdd.length; i++) { initializeReplicationSubCmd.addArgument(argsToAdd[i]); } } /** * Tells whether the user specified to have an interactive operation or not. * This method must be called after calling parseArguments. * @return <CODE>true</CODE> if the user specified to have an interactive * operation and <CODE>false</CODE> otherwise. */ public boolean isInteractive() { return interactive.isPresent(); } /** * Tells whether the user specified to have a quite operation or not. * This method must be called after calling parseArguments. * @return <CODE>true</CODE> if the user specified to have a quite operation * and <CODE>false</CODE> otherwise. */ public boolean isQuiet() { return quietArg.isPresent(); } /** * Get the password which has to be used for the command to connect to the * first server without prompting the user in the enable replication * subcommand. If no password was specified return null. * * @return the password which has to be used for the command to connect to the * first server without prompting the user in the enable replication * subcommand. If no password was specified return null. */ public String getBindPassword1() { return getBindPassword(bindPassword1Arg, bindPasswordFile1Arg); } /** * Get the password which has to be used for the command to connect to the * second server without prompting the user in the enable replication * subcommand. If no password was specified return null. * * @return the password which has to be used for the command to connect to the * second server without prompting the user in the enable replication * subcommand. If no password was specified return null. */ public String getBindPassword2() { return getBindPassword(bindPassword2Arg, bindPasswordFile2Arg); } /** * Get the global administrator password which has to be used for the command * to connect to the server(s) without prompting the user. If no password was * specified, return null. * * @return the global administrator password which has to be used for the * command to connect to the server(s) without prompting the user. If no * password was specified, return null. */ public String getBindPasswordAdmin() { return getBindPassword(adminPasswordArg, adminPasswordFileArg); } /** * Get the password of the first server which has to be used in the * enable replication subcommand. * * @param dn * The user DN for which to password could be asked. * @param out * The input stream to used if we have to prompt to the * user. * @param err * The error stream to used if we have to prompt to the * user. * @return the password of the first server which has to be used n the * enable replication subcommand. */ public String getBindPassword1( String dn, OutputStream out, OutputStream err) { return getBindPassword(dn, out, err, bindPassword1Arg, bindPasswordFile1Arg); } /** * Get the password of the second server which has to be used in the * enable replication subcommand. * * @param dn * The user DN for which to password could be asked. * @param out * The input stream to used if we have to prompt to the * user. * @param err * The error stream to used if we have to prompt to the * user. * @return the password of the second server which has to be used in the * enable replication subcommand. */ public String getBindPassword2( String dn, OutputStream out, OutputStream err) { return getBindPassword(dn, out, err, bindPassword2Arg, bindPasswordFile2Arg); } /** * Get the password of the global administrator which has to be used for the * command. * * @param dn * The user DN for which to password could be asked. * @param out * The input stream to used if we have to prompt to the * user. * @param err * The error stream to used if we have to prompt to the * user. * @return the password of the global administrator which has to be used for * the command. */ public String getBindPasswordAdmin( String dn, OutputStream out, OutputStream err) { return getBindPassword(dn, out, err, adminPasswordArg, adminPasswordFileArg); } /** * Indicate if the SSL mode is required for the first server in the enable * replication subcommand. * * @return <CODE>true</CODE> if SSL mode is required for the first server in * the enable replication subcommand and <CODE>false</CODE> otherwise. */ public boolean useSSL1() { return useSSL1Arg.isPresent(); } /** * Indicate if the startTLS mode is required for the first server in the * enable replication subcommand. * * @return <CODE>true</CODE> if startTLS mode is required for the first server * in the enable replication subcommand and <CODE>false</CODE> otherwise. */ public boolean useStartTLS1() { return useStartTLS1Arg.isPresent(); } /** * Indicate if the SSL mode is required for the second server in the enable * replication subcommand. * * @return <CODE>true</CODE> if SSL mode is required for the second server in * the enable replication subcommand and <CODE>false</CODE> otherwise. */ public boolean useSSL2() { return useSSL2Arg.isPresent(); } /** * Indicate if the startTLS mode is required for the second server in the * enable replication subcommand. * * @return <CODE>true</CODE> if startTLS mode is required for the second * server in the enable replication subcommand and <CODE>false</CODE> * otherwise. */ public boolean useStartTLS2() { return useStartTLS2Arg.isPresent(); } /** * Indicate if the SSL mode is required for the source server in the * initialize replication subcommand. * * @return <CODE>true</CODE> if SSL mode is required for the source server * in the initialize replication subcommand and <CODE>false</CODE> otherwise. */ public boolean useSSLSource() { return useSSLSourceArg.isPresent(); } /** * Indicate if the StartTLS mode is required for the source server in the * initialize replication subcommand. * * @return <CODE>true</CODE> if StartTLS mode is required for the source * server in the initialize replication subcommand and <CODE>false</CODE> * otherwise. */ public boolean useStartTLSSource() { return useStartTLSSourceArg.isPresent(); } /** * Indicate if the SSL mode is required for the destinaton server in the * initialize replication subcommand. * * @return <CODE>true</CODE> if SSL mode is required for the destination * server in the initialize replication subcommand and <CODE>false</CODE> * otherwise. */ public boolean useSSLDestination() { return useSSLDestinationArg.isPresent(); } /** * Indicate if the SSL mode is required for the destination server in the * initialize replication subcommand. * * @return <CODE>true</CODE> if StartTLS mode is required for the destination * server in the initialize replication subcommand and <CODE>false</CODE> * otherwise. */ public boolean useStartTLSDestination() { return useStartTLSDestinationArg.isPresent(); } /** * Indicate if the SSL mode is required for the server in the disable * replication subcommand. * * @return <CODE>true</CODE> if SSL mode is required for the server in the * disable replication subcommand and <CODE>false</CODE> otherwise. */ public boolean useSSLToDisable() { return useSSLArg.isPresent(); } /** * Indicate if the SSL mode is required for the server in the disable * replication subcommand. * * @return <CODE>true</CODE> if StartTLS mode is required for the server in * the disable replication subcommand and <CODE>false</CODE> otherwise. */ public boolean useStartTLSToDisable() { return useStartTLSArg.isPresent(); } /** * Returns the Administrator UID explicitly provided in the command-line. * @return the Administrator UID explicitly provided in the command-line. */ public String getAdministratorUID() { return getValue(adminUidArg); } /** * Returns the default Administrator UID value. * @return the default Administrator UID value. */ public String getDefaultAdministratorUID() { return getDefaultValue(adminUidArg); } /** * Returns the first host name explicitly provided in the enable replication * subcommand. * @return the first host name explicitly provided in the enable replication * subcommand. */ public String getHostName1() { return getValue(hostName1Arg); } /** * Returns the first host name default value in the enable replication * subcommand. * @return the first host name default value in the enable replication * subcommand. */ public String getDefaultHostName1() { return getDefaultValue(hostName1Arg); } /** * Returns the first server port explicitly provided in the enable replication * subcommand. * @return the first server port explicitly provided in the enable replication * subcommand. Returns -1 if no port was explicitly provided. */ public int getPort1() { return getValue(port1Arg); } /** * Returns the first server port default value in the enable replication * subcommand. * @return the first server port default value in the enable replication * subcommand. */ public int getDefaultPort1() { return getDefaultValue(port1Arg); } /** * Returns the first server bind dn explicitly provided in the enable * replication subcommand. * @return the first server bind dn explicitly provided in the enable * replication subcommand. Returns -1 if no port was explicitly provided. */ public String getBindDn1() { return getValue(bindDn1Arg); } /** * Returns the first server bind dn default value in the enable replication * subcommand. * @return the first server bind dn default value in the enable replication * subcommand. */ public String getDefaultBindDn1() { return getDefaultValue(bindDn1Arg); } /** * Returns the first server replication port explicitly provided in the enable * replication subcommand. * @return the first server replication port explicitly provided in the enable * replication subcommand. Returns -1 if no port was explicitly provided. */ public int getReplicationPort1() { return getValue(replicationPort1Arg); } /** * Returns the first server replication port default value in the enable * replication subcommand. * @return the first server replication port default value in the enable * replication subcommand. */ public int getDefaultReplicationPort1() { return getDefaultValue(replicationPort1Arg); } /** * Returns the second host name explicitly provided in the enable replication * subcommand. * @return the second host name explicitly provided in the enable replication * subcommand. */ public String getHostName2() { return getValue(hostName2Arg); } /** * Returns the second host name default value in the enable replication * subcommand. * @return the second host name default value in the enable replication * subcommand. */ public String getDefaultHostName2() { return getDefaultValue(hostName2Arg); } /** * Returns the second server port explicitly provided in the enable * replication subcommand. * @return the second server port explicitly provided in the enable * replication subcommand. Returns -1 if no port was explicitly provided. */ public int getPort2() { return getValue(port2Arg); } /** * Returns the second server port default value in the enable replication * subcommand. * @return the second server port default value in the enable replication * subcommand. */ public int getDefaultPort2() { return getDefaultValue(port2Arg); } /** * Returns the second server bind dn explicitly provided in the enable * replication subcommand. * @return the second server bind dn explicitly provided in the enable * replication subcommand. Returns -1 if no port was explicitly provided. */ public String getBindDn2() { return getValue(bindDn2Arg); } /** * Returns the second server bind dn default value in the enable replication * subcommand. * @return the second server bind dn default value in the enable replication * subcommand. */ public String getDefaultBindDn2() { return getDefaultValue(bindDn2Arg); } /** * Returns the second server replication port explicitly provided in the * enable replication subcommand. * @return the second server replication port explicitly provided in the * enable replication subcommand. Returns -1 if no port was explicitly * provided. */ public int getReplicationPort2() { return getValue(replicationPort2Arg); } /** * Returns the second server replication port default value in the enable * replication subcommand. * @return the second server replication port default value in the enable * replication subcommand. */ public int getDefaultReplicationPort2() { return getDefaultValue(replicationPort2Arg); } /** * Returns the host name explicitly provided in the disable replication * subcommand. * @return the host name explicitly provided in the disable replication * subcommand. */ public String getHostNameToDisable() { return getValue(hostNameArg); } /** * Returns the host name default value in the disable replication * subcommand. * @return the host name default value in the disable replication * subcommand. */ public String getDefaultHostNameToDisable() { return getDefaultValue(hostNameArg); } /** * Returns the source host name explicitly provided in the initialize * replication subcommand. * @return the source host name explicitly provided in the initialize * replication subcommand. */ public String getHostNameSource() { return getValue(hostNameSourceArg); } /** * Returns the first host name default value in the initialize replication * subcommand. * @return the first host name default value in the initialize replication * subcommand. */ public String getDefaultHostNameSource() { return getDefaultValue(hostNameSourceArg); } /** * Returns the destination host name explicitly provided in the initialize * replication subcommand. * @return the destination host name explicitly provided in the initialize * replication subcommand. */ public String getHostNameDestination() { return getValue(hostNameDestinationArg); } /** * Returns the destination host name default value in the initialize * replication subcommand. * @return the destination host name default value in the initialize * replication subcommand. */ public String getDefaultHostNameDestination() { return getDefaultValue(hostNameDestinationArg); } /** * Returns the source server port explicitly provided in the initialize * replication subcommand. * @return the source server port explicitly provided in the initialize * replication subcommand. Returns -1 if no port was explicitly provided. */ public int getPortSource() { return getValue(portSourceArg); } /** * Returns the source server port default value in the initialize replication * subcommand. * @return the source server port default value in the initialize replication * subcommand. */ public int getDefaultPortSource() { return getDefaultValue(portSourceArg); } /** * Returns the destination server port explicitly provided in the initialize * replication subcommand. * @return the destination server port explicitly provided in the initialize * replication subcommand. Returns -1 if no port was explicitly provided. */ public int getPortDestination() { return getValue(portDestinationArg); } /** * Returns the destination server port default value in the initialize * replication subcommand. * @return the destination server port default value in the initialize * replication subcommand. */ public int getDefaultPortDestination() { return getDefaultValue(portDestinationArg); } /** * Returns the server port explicitly provided in the disable replication * subcommand. * @return the server port explicitly provided in the disable replication * subcommand. Returns -1 if no port was explicitly provided. */ public int getPortToDisable() { return getValue(portArg); } /** * Returns the server port default value in the disable replication * subcommand. * @return the server port default value in the disable replication * subcommand. */ public int getDefaultPortToDisable() { return getDefaultValue(portArg); } /** * Returns the list of base DNs provided by the user. * @return the list of base DNs provided by the user. */ public LinkedList<String> getBaseDNs() { return baseDNsArg.getValues(); } /** * Returns the value of the provided argument only if the user provided it * explicitly. * @param arg the StringArgument to be handled. * @return the value of the provided argument only if the user provided it * explicitly. */ private String getValue(StringArgument arg) { String v = null; if (arg.isPresent()) { v = arg.getValue(); } return v; } /** * Returns the default value of the provided argument. * @param arg the StringArgument to be handled. * @return the default value of the provided argument. */ private String getDefaultValue(StringArgument arg) { return arg.getDefaultValue(); } /** * Returns the value of the provided argument only if the user provided it * explicitly. * @param arg the StringArgument to be handled. * @return the value of the provided argument only if the user provided it * explicitly. */ private int getValue(IntegerArgument arg) { int v = -1; if (arg.isPresent()) { try { v = arg.getIntValue(); } catch (ArgumentException ae) { // This is a bug throw new IllegalStateException( "There was an argument exception calling "+ "ReplicationCliParser.getValue(). This appears to be a bug "+ "because this method should be called after calling "+ "parseArguments which should result in an error.", ae); } } return v; } /** * Returns the default value of the provided argument. * @param arg the StringArgument to be handled. * @return the default value of the provided argument. */ private int getDefaultValue(IntegerArgument arg) { int returnValue = -1; String defaultValue = arg.getDefaultValue(); if (defaultValue != null) { returnValue = Integer.parseInt(arg.getDefaultValue()); } return returnValue; } /** * Checks the subcommand options and updates the provided MessageBuilder * with the errors that were encountered with the subcommand options. * * This method assumes that the method parseArguments for the parser has * already been called. * @param buf the MessageBuilder object where we add the error messages * describing the errors encountered. */ public void validateSubcommandOptions(MessageBuilder buf) { if (isEnableReplicationSubcommand()) { validateEnableReplicationOptions(buf); } else if (isDisableReplicationSubcommand()) { validateDisableReplicationOptions(buf); } else if (isInitializeReplicationSubcommand()) { validateInitializeReplicationOptions(buf); } else { // This can occur if the user did not provide any subcommand. We assume // that the error informing of this will be generated in // validateGlobalOptions. } } /** * Returns whether the user provided subcommand is the enable replication * or not. * @return <CODE>true</CODE> if the user provided subcommand is the * enable replication and <CODE>false</CODE> otherwise. */ public boolean isEnableReplicationSubcommand() { return isSubcommand(ENABLE_REPLICATION_SUBCMD_NAME); } /** * Returns whether the user provided subcommand is the disable replication * or not. * @return <CODE>true</CODE> if the user provided subcommand is the * disable replication and <CODE>false</CODE> otherwise. */ public boolean isDisableReplicationSubcommand() { return isSubcommand(DISABLE_REPLICATION_SUBCMD_NAME); } /** * Returns whether the user provided subcommand is the initialize replication * or not. * @return <CODE>true</CODE> if the user provided subcommand is the * initialize replication and <CODE>false</CODE> otherwise. */ public boolean isInitializeReplicationSubcommand() { return isSubcommand(INITIALIZE_REPLICATION_SUBCMD_NAME); } /** * Returns whether the command-line subcommand has the name provided * or not. * @param name the name of the subcommand. * @return <CODE>true</CODE> if command-line subcommand has the name provided * and <CODE>false</CODE> otherwise. */ private boolean isSubcommand(String name) { boolean isSubcommand = false; SubCommand subCommand = getSubCommand(); if (subCommand != null) { isSubcommand = subCommand.getName().equalsIgnoreCase(name); } return isSubcommand; } /** * Checks the enable replication subcommand options and updates the provided * MessageBuilder with the errors that were encountered with the subcommand * options. * * This method assumes that the method parseArguments for the parser has * already been called. * @param buf the MessageBuilder object where we add the error messages * describing the errors encountered. */ private void validateEnableReplicationOptions(MessageBuilder buf) { Argument[][] conflictingPairs = { {bindPassword1Arg, bindPasswordFile1Arg}, {useStartTLS1Arg, useSSL1Arg}, {bindPassword2Arg, bindPasswordFile2Arg}, {useStartTLS2Arg, useSSL2Arg} }; for (int i=0; i< conflictingPairs.length; i++) { Argument arg1 = conflictingPairs[i][0]; Argument arg2 = conflictingPairs[i][1]; if (arg1.isPresent() && arg2.isPresent()) { Message message = ERR_TOOL_CONFLICTING_ARGS.get( arg1.getLongIdentifier(), arg2.getLongIdentifier()); addMessage(buf, message); } } if (hostName1Arg.getValue().equalsIgnoreCase(hostName2Arg.getValue())) { if (port1Arg.getValue() == port2Arg.getValue()) { Message message = ERR_REPLICATION_SAME_SERVER_PORT.get( hostName1Arg.getValue(), port1Arg.getValue()); addMessage(buf, message); } // If the user explicitly provides the same port in the same host, // reject it. if (getValue(replicationPort1Arg) == getValue(replicationPort2Arg)) { Message message = ERR_REPLICATION_SAME_REPLICATION_PORT.get( replicationPort1Arg.getValue(), hostName1Arg.getValue()); addMessage(buf, message); } try { if (replicationPort1Arg.getIntValue() == port1Arg.getIntValue()) { Message message = ERR_REPLICATION_SAME_REPLICATION_PORT.get( replicationPort1Arg.getValue(), hostName1Arg.getValue()); addMessage(buf, message); } } catch (ArgumentException ae) { // This is a bug throw new IllegalStateException( "There was an argument exception calling "+ "ReplicationCliParser.validateEnableReplicationOptions(). "+ "This appears to be a bug "+ "because this method should be called after calling "+ "parseArguments which should result in an error.", ae); } } } /** * Checks the disable replication subcommand options and updates the provided * MessageBuilder with the errors that were encountered with the subcommand * options. * * This method assumes that the method parseArguments for the parser has * already been called. * @param buf the MessageBuilder object where we add the error messages * describing the errors encountered. */ private void validateDisableReplicationOptions(MessageBuilder buf) { Argument[][] conflictingPairs = { {useStartTLSSourceArg, useSSLSourceArg}, {useStartTLSDestinationArg, useSSLDestinationArg} }; for (int i=0; i< conflictingPairs.length; i++) { Argument arg1 = conflictingPairs[i][0]; Argument arg2 = conflictingPairs[i][1]; if (arg1.isPresent() && arg2.isPresent()) { Message message = ERR_TOOL_CONFLICTING_ARGS.get( arg1.getLongIdentifier(), arg2.getLongIdentifier()); addMessage(buf, message); } } if (hostNameSourceArg.getValue().equalsIgnoreCase( hostNameDestinationArg.getValue())) { if (portSourceArg.getValue() == portDestinationArg.getValue()) { Message message = ERR_REPLICATION_SAME_SERVER_PORT.get( hostNameSourceArg.getValue(), portSourceArg.getValue()); addMessage(buf, message); } } } /** * Checks the initialize replication subcommand options and updates the * provided MessageBuilder with the errors that were encountered with the * subcommand options. * * This method assumes that the method parseArguments for the parser has * already been called. * @param buf the MessageBuilder object where we add the error messages * describing the errors encountered. */ private void validateInitializeReplicationOptions(MessageBuilder buf) { // The startTLS and useSSL arguments are already validated in // SecureConnectionCliParser.validateGlobalOptions. } /** * Adds a message to the provided MessageBuilder. * @param buf the MessageBuilder. * @param message the message to be added. */ private void addMessage(MessageBuilder buf, Message message) { if (buf.length() > 0) { buf.append(EOL); } buf.append(message); } } opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliReturnCode.java
New file @@ -0,0 +1,188 @@ /* * 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.guitools.replicationcli; import static org.opends.messages.AdminToolMessages.*; import org.opends.messages.Message; /** * * The enumeration which defines the return code. * */ public enum ReplicationCliReturnCode { /** * successful. */ SUCCESSFUL(0, INFO_REPLICATION_SUCCESSFUL.get()), /** * successful but no operation was performed. */ SUCCESSFUL_NOP(SUCCESSFUL.getReturnCode(), INFO_REPLICATION_SUCCESSFUL_NOP.get()), /** * Unable to initialize arguments. */ CANNOT_INITIALIZE_ARGS(1, ERR_REPLICATION_NO_MESSAGE.get()), /** * Cannot parse argument. */ ERROR_PARSING_ARGS(2, ERR_REPLICATION_NO_MESSAGE.get()), /** * The user cancelled the operation in interactive mode. */ USER_CANCELLED(3, ERR_REPLICATION_USER_CANCELLED.get()), /** * Unexpected error (potential bug). */ CONFLICTING_ARGS(4, ERR_REPLICATION_NO_MESSAGE.get()), /** * The provided base DNs cannot be used to enable replication. */ REPLICATION_CANNOT_BE_ENABLED_ON_BASEDN(5, ERR_REPLICATION_NO_MESSAGE.get()), /** * The provided base DNs cannot be used to disable replication. */ REPLICATION_CANNOT_BE_DISABLED_ON_BASEDN(6, ERR_REPLICATION_NO_MESSAGE.get()), /** * The provided base DNs cannot be used to initialize the contents of the * replicas. */ REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN(7, ERR_REPLICATION_NO_MESSAGE.get()), /** * Error connecting with the provided credentials. */ ERROR_CONNECTING(8, ERR_REPLICATION_NO_MESSAGE.get()), /** * Could not find the replication ID of the domain to be used to initialize * the replica. */ REPLICATIONID_NOT_FOUND(9, ERR_REPLICATION_NO_MESSAGE.get()), /** * The number of tries we perform to start the initialization are over. * We systematically receive a peer not found error. */ INITIALIZING_TRIES_COMPLETED(10, ERR_REPLICATION_NO_MESSAGE.get()), /** * Error enabling replication on a base DN. */ ERROR_ENABLING_REPLICATION_ON_BASEDN(11, ERR_REPLICATION_NO_MESSAGE.get()), /** * Error initializing base DN. */ ERROR_INITIALIZING_BASEDN_GENERIC(12, ERR_REPLICATION_NO_MESSAGE.get()), /** * Error reading configuration. */ ERROR_READING_CONFIGURATION(13, ERR_REPLICATION_NO_MESSAGE.get()), /** * Error updating ADS. */ ERROR_UPDATING_ADS(14, ERR_REPLICATION_NO_MESSAGE.get()), /** * Error reading ADS. */ ERROR_READING_ADS(15, ERR_REPLICATION_NO_MESSAGE.get()), /** * Error reading TopologyCache. */ ERROR_READING_TOPOLOGY_CACHE(16, ERR_REPLICATION_NO_MESSAGE.get()), /** * Error configuring replication server. */ ERROR_CONFIGURING_REPLICATIONSERVER(17, ERR_REPLICATION_NO_MESSAGE.get()), /** * Unsupported ADS scenario. */ REPLICATION_ADS_MERGE_NOT_SUPPORTED(18, ERR_REPLICATION_NO_MESSAGE.get()), /** * Error disabling replication on base DN. */ ERROR_DISABLING_REPLICATION_ON_BASEDN(19, ERR_REPLICATION_NO_MESSAGE.get()), /** * Error removing replication port reference on base DN. */ ERROR_DISABLING_REPLICATION_REMOVE_REFERENCE_ON_BASEDN(20, ERR_REPLICATION_NO_MESSAGE.get()); private Message message; private int returnCode; // Private constructor. private ReplicationCliReturnCode(int returnCode, Message message) { this.returnCode = returnCode; this.message = message; } /** * Get the corresponding message. * * @return The corresponding message. */ public Message getMessage() { return message; } /** * Get the corresponding return code value. * * @return The corresponding return code value. */ public int getReturnCode() { return returnCode; } } opends/src/guitools/org/opends/guitools/replicationcli/ReplicationUserData.java
New file @@ -0,0 +1,98 @@ /* * 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.guitools.replicationcli; import java.util.LinkedList; /** * This class is used to store the information provided by the user in the * replication command line. It is required because when we are in interactive * mode the ReplicationCliArgumentParser is not enough. * */ abstract class ReplicationUserData { private LinkedList<String> baseDNs = new LinkedList<String>(); private String adminUid; private String adminPwd; /** * Returns the Global Administrator password. * @return the Global Administrator password. */ String getAdminPwd() { return adminPwd; } /** * Sets the Global Administrator password. * @param adminPwd the Global Administrator password. */ void setAdminPwd(String adminPwd) { this.adminPwd = adminPwd; } /** * Returns the Global Administrator UID. * @return the Global Administrator UID. */ String getAdminUid() { return adminUid; } /** * Sets the Global Administrator UID. * @param adminUid the Global Administrator UID. */ void setAdminUid(String adminUid) { this.adminUid = adminUid; } /** * Returns the Base DNs to replicate. * @return the Base DNs to replicate. */ LinkedList<String> getBaseDNs() { return new LinkedList<String>(baseDNs); } /** * Sets the Base DNs to replicate. * @param baseDNs the Base DNs to replicate. */ void setBaseDNs(LinkedList<String> baseDNs) { this.baseDNs.clear(); this.baseDNs.addAll(baseDNs); } } opends/src/guitools/org/opends/guitools/replicationcli/package-info.java
New file @@ -0,0 +1,40 @@ /* * 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. */ /** * Defines the classes that are you used by the replication * command lines. This includes the command line parsers * (ReplicationCliParser), the classes that actually execute the configuration * operations (ReplicationCliMain), the enumeration that defines the return * codes of the command-line (ReplicationCliReturnCode), a particular exception * used only for the package (ReplicationCliException) and the different data * models that represent the data provided by the user directly as command-line * parameters and also interactively. * */ package org.opends.guitools.replicationcli; opends/src/guitools/org/opends/guitools/statuspanel/StatusCli.java
@@ -178,7 +178,7 @@ directoryManagerDn, directoryManagerPwd); ConfigFromLDAP onLineConf = new ConfigFromLDAP(); ConnectionProtocolPolicy policy; if (startTLSArg.isPresent()) if (useStartTLSArg.isPresent()) { policy = ConnectionProtocolPolicy.USE_STARTTLS; } opends/src/guitools/org/opends/guitools/uninstaller/UninstallCliHelper.java
@@ -555,25 +555,6 @@ return confirm(INFO_CLI_UNINSTALL_CONFIRM_DELETE_FILES.get()); } private boolean confirm(Message msg) { boolean confirm = true; Message[] validValues = { INFO_CLI_YES_SHORT.get(), INFO_CLI_NO_SHORT.get(), INFO_CLI_YES_LONG.get(), INFO_CLI_NO_LONG.get(), }; Message answer = promptConfirm(msg, validValues[2], validValues); if (INFO_CLI_NO_SHORT.get().toString() .equalsIgnoreCase(answer.toString()) || INFO_CLI_NO_LONG.get().toString() .equalsIgnoreCase(answer.toString())) { confirm = false; } return confirm; } /** * Ask for confirmation to update configuration on remote servers. * @return <CODE>true</CODE> if the user wants to continue and stop the @@ -626,7 +607,7 @@ { while (uid == null) { uid = askForAdministratorUID(); uid = askForAdministratorUID(parser.getDefaultAdministratorUID()); } while (pwd == null) { @@ -727,17 +708,6 @@ return accepted; } private String askForAdministratorUID() { return promptForString(INFO_UNINSTALL_CLI_ADMINISTRATOR_UID_PROMPT.get(), Constants.GLOBAL_ADMIN_UID); } private String askForAdministratorPwd() { return promptForPassword(INFO_UNINSTALL_CLI_ADMINISTRATOR_PWD_PROMPT.get()); } private String askForReferencedHostName(String defaultHostName) { return promptForString(INFO_UNINSTALL_CLI_REFERENCED_HOSTNAME_PROMPT.get(), @@ -916,7 +886,7 @@ } catch (TopologyCacheException te) { LOG.log(Level.WARNING, "Error connecting to server: "+te, te); printErrorMessage(Utils.getStringRepresentation(te)); printErrorMessage(Utils.getMessage(te)); } catch (Throwable t) { @@ -973,7 +943,7 @@ exceptions.add(e); } } Set<String> exceptionMsgs = new LinkedHashSet<String>(); Set<Message> exceptionMsgs = new LinkedHashSet<Message>(); /* Check the exceptions and see if we throw them or not. */ for (TopologyCacheException e : exceptions) { @@ -1007,21 +977,18 @@ else { stopProcessing = true; String url = e.getLdapUrl(); int index = url.indexOf("//"); String hostPort = url.substring(index + 2); printErrorMessage( INFO_ERROR_READING_CONFIG_LDAP_CERTIFICATE_SERVER.get( hostPort, e.getCause().getMessage())); e.getHostPort(), e.getCause().getMessage())); } } else { exceptionMsgs.add(Utils.getStringRepresentation(e)); exceptionMsgs.add(Utils.getMessage(e)); } break; default: exceptionMsgs.add(Utils.getStringRepresentation(e)); exceptionMsgs.add(Utils.getMessage(e)); } } if (interactive) @@ -1029,9 +996,9 @@ if (!stopProcessing && (exceptionMsgs.size() > 0)) { returnValue = confirm( ERR_READING_REGISTERED_SERVERS_CONFIRM_UPDATE_REMOTE.get( Utils.getStringFromCollection(exceptionMsgs, Constants.LINE_SEPARATOR))); ERR_UNINSTALL_READING_REGISTERED_SERVERS_CONFIRM_UPDATE_REMOTE.get( Utils.getMessageFromCollection(exceptionMsgs, Constants.LINE_SEPARATOR).toString())); } else if (reloadTopologyCache) { @@ -1047,7 +1014,7 @@ { if (exceptionMsgs.size() > 0) { printErrorMessage(Utils.getStringFromCollection(exceptionMsgs, printErrorMessage(Utils.getMessageFromCollection(exceptionMsgs, Constants.LINE_SEPARATOR)); returnValue = false; } opends/src/guitools/org/opends/guitools/uninstaller/Uninstaller.java
@@ -1374,8 +1374,8 @@ if (throwable instanceof TopologyCacheException) { qs.displayError( Message.raw(getStringRepresentation( (TopologyCacheException)throwable)), getMessage( (TopologyCacheException)throwable), INFO_ERROR_TITLE.get()); } else @@ -1438,7 +1438,7 @@ exceptions.add(e); } } Set<String> exceptionMsgs = new LinkedHashSet<String>(); Set<Message> exceptionMsgs = new LinkedHashSet<Message>(); /* Check the exceptions and see if we throw them or not. */ for (TopologyCacheException e : exceptions) { @@ -1504,13 +1504,13 @@ } } } exceptionMsgs.add(getStringRepresentation(e)); exceptionMsgs.add(getMessage(e)); } if (!stopProcessing && (exceptionMsgs.size() > 0)) { Message confirmationMsg = ERR_READING_REGISTERED_SERVERS_CONFIRM_UPDATE_REMOTE.get( getStringFromCollection(exceptionMsgs, "n")); ERR_UNINSTALL_READING_REGISTERED_SERVERS_CONFIRM_UPDATE_REMOTE.get( getMessageFromCollection(exceptionMsgs, "\n").toString()); stopProcessing = !qs.displayConfirmation(confirmationMsg, INFO_CONFIRMATION_TITLE.get()); } @@ -1568,8 +1568,7 @@ { if (throwable instanceof TopologyCacheException) { qs.displayError(Message.raw( getStringRepresentation((TopologyCacheException)throwable)), qs.displayError(getMessage((TopologyCacheException)throwable), INFO_ERROR_TITLE.get()); } else opends/src/guitools/org/opends/guitools/uninstaller/UninstallerArgumentParser.java
@@ -167,7 +167,7 @@ SecureConnectionCliParser.QUIET_OPTION_LONG, SecureConnectionCliParser.QUIET_OPTION_SHORT, SecureConnectionCliParser.QUIET_OPTION_LONG, INFO_UNINSTALLDS_DESCRIPTION_SILENT.get()); INFO_UNINSTALLDS_DESCRIPTION_QUIET.get()); args.add(quiet); adminUidArg = new StringArgument("adminUID", 'I', opends/src/messages/messages/admin_tool.properties
@@ -103,8 +103,6 @@ OpenDS servers the server must be started and then you must provide \ administrator authentication. Do you want to start the server and then \ provide authentication to remove the remote references? INFO_UNINSTALL_CLI_ADMINISTRATOR_UID_PROMPT=Global Administrator User ID INFO_UNINSTALL_CLI_ADMINISTRATOR_PWD_PROMPT=Global Administrator Password: INFO_UNINSTALL_CLI_REFERENCED_HOSTNAME_PROMPT=The name of this host (or IP \ address) as it is referenced in remote servers for replication INFO_UNINSTALL_CONFIRM_PROVIDE_AUTHENTICATION_AGAIN=Do you want to provide \ @@ -159,8 +157,8 @@ 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. MILD_ERR_READING_REGISTERED_SERVERS_CONFIRM_UPDATE_REMOTE=The following \ errors were encountered reading the configuration of the existing \ MILD_ERR_UNINSTALL_READING_REGISTERED_SERVERS_CONFIRM_UPDATE_REMOTE=The \ following errors were encountered reading the configuration of the existing \ servers:\n%s\nDo you want the uninstaller to try to remove the references to \ this server in a best-effort mode? INFO_CONFIRM_UNINSTALL_SERVER_RUNNING_TITLE=Server is Running @@ -347,7 +345,7 @@ install. If not specified the graphical interface will be launched. The \ rest of the options (excluding help and version) will only be taken into \ account if this option is specified INFO_UNINSTALLDS_DESCRIPTION_SILENT=Perform a quiet uninstall (no \ INFO_UNINSTALLDS_DESCRIPTION_QUIET=Perform a quiet uninstall (no \ progress information is written to the standard output) INFO_UNINSTALLDS_DESCRIPTION_REMOVE_ALL=Remove all components of \ OpenDS (this option is not compatible with the rest of remove options) @@ -441,15 +439,21 @@ StartTLS to secure communication with the source server INFO_REPLICATION_TOOL_DESCRIPTION=This utility may be used to configure \ replication between servers so that the data of the servers is synchronized.\ In order replication to work you have first to enable replication between two \ servers using the {%s} subcommand and then initialize the contents of one of \ In order replication to work you have first to enable replication using the \ {%s} subcommand and then initialize the contents of one of \ servers with the contents of the other using the {%s} subcommand. INFO_REPLICATION_DESCRIPTION_QUIET=Perform a quiet operation (no \ progress information is written to the standard output) INFO_DESCRIPTION_SUBCMD_INITIALIZE_REPLICATION=Initialize the contents of the \ data under the specified Bind DN on the destination server with the contents \ on the source server. This operation is required after enabling replication \ in order replication to work. INFO_DESCRIPTION_SUBCMD_ENABLE_REPLICATION=Configures the two specified \ servers to replicate the data under the specified Bind DN. INFO_DESCRIPTION_SUBCMD_ENABLE_REPLICATION=Updates the configuration of the \ servers to replicate the data under the specified Base DN. If one of the \ specified servers is already replicating the data under the Base DN with \ other servers, executing this subcommand will update the configuration of all \ the servers (so it is sufficient to execute the command line once for each \ server we add to the replication topology). INFO_DESCRIPTION_SUBCMD_DISABLE_REPLICATION=Disables replication on the \ specified server for the provided Base DN and removes references in the other \ servers with which it is replicating data. @@ -460,3 +464,130 @@ provide it using the {%s} or the {%s} options. SEVERE_ERR_REPLICATION_NOT_A_VALID_BASEDN=The provided value %s is not a valid \ base DN. SEVERE_ERR_REPLICATION_SAME_SERVER_PORT=You have to provide two different \ servers to replicate. You have provided twice the server %s:%s SEVERE_ERR_REPLICATION_SAME_REPLICATION_PORT=You have provided the same \ replication port (%s) for two servers located on the same machine (%s). SEVERE_ERR_REPLICATION_VALID_SUBCOMMAND_NOT_FOUND=Could not find a valid \ subcommand. INFO_REPLICATION_SUCCESSFUL=The operation has been successfully completed INFO_REPLICATION_SUCCESSFUL_NOP=The operation has been successfully completed, \ but no action was required MILD_ERR_REPLICATION_USER_CANCELLED=User cancelled the operation SEVERE_ERR_REPLICATION_NO_MESSAGE= INFO_ADMINISTRATOR_UID_PROMPT=Global Administrator User ID: INFO_ADMINISTRATOR_PWD_PROMPT=Global Administrator Password: INFO_ADMINISTRATOR_PWD_CONFIRM_PROMPT=Confirm Password: MILD_ERR_ADMINISTRATOR_PWD_DO_NOT_MATCH=The provided passwords do not match. MILD_ERR_ERROR_CONNECTING_TO_SERVER_PROMPT_AGAIN=Could not connect to the \ Directory Server %s with the provided credentials.%nProvide again the \ required information to connect to the server: INFO_REPLICATION_ENABLE_HOSTNAME1_PROMPT=Host name of the first server: INFO_REPLICATION_ENABLE_PORT1_PROMPT=LDAP port of the first server: INFO_REPLICATION_ENABLE_REPLICATIONPORT1_PROMPT=Replication port for the first \ server (the port must be free): INFO_REPLICATION_ENABLE_HOSTNAME2_PROMPT=Host name of the second server: INFO_REPLICATION_ENABLE_PORT2_PROMPT=LDAP port of the second server: INFO_REPLICATION_ENABLE_REPLICATIONPORT2_PROMPT=Replication port for the \ second server (the port must be free): INFO_REPLICATION_INITIALIZE_HOSTNAMESOURCE_PROMPT=Host name of the source \ server: INFO_REPLICATION_INITIALIZE_PORTSOURCE_PROMPT=LDAP port of the source server: INFO_REPLICATION_DISABLE_HOSTNAME_PROMPT=Host name of the server: INFO_REPLICATION_DISABLE_PORT_PROMPT=LDAP port of the server: INFO_REPLICATION_INITIALIZE_HOSTNAMEDESTINATION_PROMPT=Host name of the \ destination server: INFO_REPLICATION_INITIALIZE_PORTDESTINATION_PROMPT=LDAP port of the \ destination server: INFO_REPLICATION_BINDDN_PROMPT=Bind DN INFO_REPLICATION_PASSWORD_PROMPT=Password INFO_REPLICATION_USESSL_PROMPT=Use SSL to connect INFO_CLI_INVALID_PORT=The provided value is not a valid port INFO_REPLICATION_USESTARTTLS_PROMPT=Use StartTLS to connect SEVERE_ERR_REPLICATION_PORT_AND_REPLICATION_PORT_EQUAL=The server LDAP port \ and the replication port cannot have the same value. You provided %s for both. SEVERE_ERR_NO_SUFFIXES_AVAILABLE_TO_ENABLE_REPLICATION=There are no base DNs \ available to enable replication between the two servers. INFO_ALREADY_REPLICATED_SUFFIXES=The following base DNs are already replicated \ between the two servers:%n%s INFO_ALREADY_NOT_REPLICATED_SUFFIXES=The following base DNs are not replicated \ between the two servers:%n%s MILD_ERR_REPLICATION_ENABLE_SUFFIXES_NOT_FOUND=The following base DNs cannot \ be replicated between the two servers because they could not be found in at \ least one of the servers:%n%s MILD_ERR_NO_SUFFIXES_SELECTED_TO_REPLICATE=You must choose at least one base \ DN to be replicated. INFO_REPLICATION_ENABLE_SUFFIX_PROMPT=Replicate base DN %s? SEVERE_ERR_NO_SUFFIXES_AVAILABLE_TO_INITIALIZE_REPLICATION=There are no base \ DNs replicated between the two servers. MILD_ERR_SUFFIXES_CANNOT_BE_INITIALIZED=The following base DNs cannot be \ initialized because they are not replicated or they are not configured on \ both servers:%n%s MILD_ERR_NO_SUFFIXES_SELECTED_TO_INITIALIZE=You must choose at least one \ base DN to be initialized. INFO_REPLICATION_INITIALIZE_SUFFIX_PROMPT=Initialize base DN %s? SEVERE_ERR_NO_SUFFIXES_AVAILABLE_TO_DISABLE_REPLICATION=There are no base \ DNs replicated in the server. MILD_ERR_REPLICATION_DISABLE_SUFFIXES_NOT_FOUND=The following base DNs could \ not be found on the server:%n%s MILD_ERR_NO_SUFFIXES_SELECTED_TO_DISABLE=You must choose at least one \ base DN to be disabled. INFO_REPLICATION_DISABLE_SUFFIX_PROMPT=Disable replication on base DN %s? MILD_ERR_REPLICATION_READING_REGISTERED_SERVERS_CONFIRM_UPDATE_REMOTE=The \ following errors were encountered reading the configuration of the existing \ servers:\n%s\nIf you continue the replication tool will to try to update the \ configuration of all the servers in a best-effort mode. However it cannot \ guarantee that the servers that are generating errors will be updated. Do \ you want to continue? MILD_ERR_NOT_ADMINISTRATIVE_USER=You do not have access rights to the \ configuration of the server. INFO_REPLICATION_CONFIRM_DISABLE_ADS=You chose to disable replication on \ base DN %s. This base DN is used by the replication mechanism and by some \ administrative tools and it is not recommended to configure it directly. Do \ you want to continue? INFO_REPLICATION_CONFIRM_DISABLE_GENERIC=Disabling replication will make the \ data under the selected base DNs not to be synchronized with other servers \ any more. Do you want to continue? INFO_REPLICATION_CONFIRM_INITIALIZE_ADS=You chose to initialize the contents \ of base DN %s on server %s with the contents in server %s. This base DN is \ used by the replication mechanism and by some administrative tools and it is \ not recommended to configure it directly. Do you want to continue? INFO_REPLICATION_CONFIRM_INITIALIZE_GENERIC=Initializing the contents of a \ base DN removes all the existing contents of that base DN. Do you want to \ remove the contents of the selected base DNs on server %s and replace them \ with the contents of server %s? MILD_ERR_REPLICATION_READING_REGISTERED_SERVERS_WARNING=The following errors \ were encountered reading the configuration of the existing servers:\n%s\nThe \ replication tool will to try to update the configuration of all the servers \ in a best-effort mode. However it cannot guarantee that the servers that are \ generating errors will be updated. INFO_REPLICATION_CONNECTING=Establishing connections INFO_REPLICATION_ENABLE_UPDATING_ADS_CONTENTS=Checking Registration information INFO_REPLICATION_ENABLE_CONFIGURING_REPLICATION_SERVER=Configuring Replication \ port on server %s INFO_REPLICATION_ENABLE_CONFIGURING_BASEDN=Enabling Replication for baseDN %s \ on server %s INFO_ENABLE_REPLICATION_INITIALIZING_ADS=Initializing Registration information \ on server %s with the contents of server %s SEVERE_ERR_INITIALIZING_REPLICATIONID_NOT_FOUND=Error initializing. Could not \ find replication ID in the server %s for base DN %s. SEVERE_ERR_REPLICATION_INITIALIZING_TRIES_COMPLETED=Error initializing. Could \ not find a peer to start the initialization after several tries. Details: %s SEVERE_ERR_REPLICATION_CONFIGURING_REPLICATIONSERVER=Error configuring \ replication port on server %s. SEVERE_ERR_REPLICATION_CONFIGURING_BASEDN=Error updating replication \ configuration on base DN %s of server %s. SEVERE_ERR_REPLICATION_UPDATING_ADS=Error updating Registration information. \ Details: %s SEVERE_ERR_REPLICATION_READING_ADS=Error reading Registration information. \ Details: %s SEVERE_ERR_REPLICATION_ADS_MERGE_NOT_SUPPORTED=The registry information found \ in servers %s and %s is different. This tool does not allow to handle this \ scenario. SEVERE_ERR_REPLICATION_ERROR_READING_CONFIGURATION=Error reading replication \ configuration of server %s. Details: %s INFO_REPLICATION_REMOVING_REFERENCES_ON_REMOTE=Removing references on base DN \ %s of server %s INFO_REPLICATION_DISABLING_BASEDN=Disabling replication on base DN %s of \ server %s opends/src/quicksetup/org/opends/quicksetup/Application.java
@@ -682,9 +682,9 @@ * @param e the exception we want to obtain the representation from. * @return a localized representation of a TopologyCacheException object. */ protected String getStringRepresentation(TopologyCacheException e) protected Message getMessage(TopologyCacheException e) { return Utils.getStringRepresentation(e); return Utils.getMessage(e); } /** opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java
@@ -195,6 +195,43 @@ } /** * Prompts the user to provide a port. * @param msg the message to be displayed. * @param defaultValue the default value to be proposed. * @return the user to provide a port. */ protected int promptForPort(Message msg, int defaultValue) { int port = -1; while (port == -1) { String s = promptForString(msg, String.valueOf(defaultValue)); if ((s != null) && (s.trim().length() > 0)) { try { port = Integer.parseInt(s); if ((port < 0) || (port > 65535)) { port = -1; } } catch (Throwable t) { port = -1; } if (port == -1) { Message message = INFO_CLI_INVALID_PORT.get(); System.err.println(StaticUtils.wrapText(message, Utils.getCommandLineMaxLineWidth())); } } } return port; } /** * Reads a line of text from standard input. * @return The line of text read from standard input, or <CODE>null</CODE> * if the end of the stream is reached or an error occurs while @@ -406,6 +443,74 @@ } /** * Prompts the user to give the Global Administrator UID. * @param defaultValue the default value that will be proposed in the prompt * message. * @return the Global Administrator UID as provided by the user. */ protected String askForAdministratorUID(String defaultValue) { return promptForString(INFO_ADMINISTRATOR_UID_PROMPT.get(), defaultValue); } /** * Prompts the user to give the Global Administrator password. * @return the Global Administrator password as provided by the user. */ protected String askForAdministratorPwd() { return promptForPassword(INFO_ADMINISTRATOR_PWD_PROMPT.get()); } /** * Prompts the user to confirm a question. The default proposed value as * answer is to confirm the question. * @param msg the message to be displayed to the user. * @return <CODE>true</CODE> if the user accepted the message and * <CODE>false</CODE> otherwise. */ protected boolean confirm(Message msg) { return confirm(msg, true); } /** * Prompts the user to confirm a question. * @param msg the message to be displayed to the user. * @param defaultTrue whether the default proposed value as answer is to * accept the message or not. * @return <CODE>true</CODE> if the user accepted the message and * <CODE>false</CODE> otherwise. */ protected boolean confirm(Message msg, boolean defaultTrue) { boolean confirm = true; Message[] validValues = { INFO_CLI_YES_SHORT.get(), INFO_CLI_NO_SHORT.get(), INFO_CLI_YES_LONG.get(), INFO_CLI_NO_LONG.get(), }; Message defaultMessage; if (defaultTrue) { defaultMessage = validValues[2]; } else { defaultMessage = validValues[3]; } Message answer = promptConfirm(msg, defaultMessage, validValues); if (INFO_CLI_NO_SHORT.get().toString() .equalsIgnoreCase(answer.toString()) || INFO_CLI_NO_LONG.get().toString() .equalsIgnoreCase(answer.toString())) { confirm = false; } return confirm; } /** * Prompts the user to accept the certificate. * @param t the throwable that was generated because the certificate was * not trusted. opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -74,7 +74,6 @@ import org.opends.quicksetup.installer.ui.ServerSettingsPanel; import org.opends.quicksetup.installer.ui.SuffixesToReplicatePanel; import org.opends.server.util.SetupUtils; import org.opends.server.types.OpenDsException; import org.opends.messages.Message; import org.opends.messages.MessageBuilder; import static org.opends.messages.QuickSetupMessages.*; @@ -1927,8 +1926,7 @@ adsContext.createAdminData(null); adsContext.createAdministrator(getAdministratorProperties()); adsContext.registerServer( getRemoteServerProperties(auth.getHostName(), adsContext.getDirContext())); getRemoteServerProperties(adsContext.getDirContext())); createdRemoteAds = true; notifyListeners(getFormattedDone()); notifyListeners(getLineBreak()); @@ -2841,7 +2839,7 @@ } Set<TopologyCacheException> exceptions = updateUserDataWithSuffixesInADS(adsContext, trustManager); Set<String> exceptionMsgs = new LinkedHashSet<String>(); Set<Message> exceptionMsgs = new LinkedHashSet<Message>(); /* Check the exceptions and see if we throw them or not. */ for (TopologyCacheException e : exceptions) { @@ -2901,13 +2899,13 @@ } } } exceptionMsgs.add(getStringRepresentation(e)); exceptionMsgs.add(getMessage(e)); } if (exceptionMsgs.size() > 0) { Message confirmationMsg = INFO_ERROR_READING_REGISTERED_SERVERS_CONFIRM.get( getStringFromCollection(exceptionMsgs, "n")); getMessageFromCollection(exceptionMsgs, "\n")); throw new UserDataConfirmationException(Step.REPLICATION_OPTIONS, confirmationMsg); } @@ -2984,7 +2982,6 @@ } else if (t instanceof ADSContextException) { String[] args = {host+":"+port, t.toString()}; errorMsgs.add(INFO_REMOTE_ADS_EXCEPTION.get( host+":"+port, t.toString())); } @@ -3365,66 +3362,11 @@ } private Map<ADSContext.ServerProperty, Object> getRemoteServerProperties( String hostName, InitialLdapContext ctx) throws NamingException InitialLdapContext ctx) throws NamingException { 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; server.updateAdsPropertiesWithServerProperties(); return server.getAdsProperties(); } /** @@ -3739,7 +3681,21 @@ trustManager); } private void initializeSuffix(InitialLdapContext ctx, int replicaId, /** * Initializes a suffix with the contents of a replica that has a given * replication id. * @param ctx the connection to the server whose suffix we want to initialize. * @param replicaId the replication ID of the replica we want to use to * initialize the contents of the suffix. * @param suffixDn the dn of the suffix. * @param displayProgress whether we want to display progress or not. * @param sourceServerDisplay the string to be used to represent the server * that contains the data that will be used to initialize the suffix. * @throws ApplicationException if an unexpected error occurs. * @throws PeerNotFoundException if the replication mechanism cannot find * a peer. */ public void initializeSuffix(InitialLdapContext ctx, int replicaId, String suffixDn, boolean displayProgress, String sourceServerDisplay) throws ApplicationException, PeerNotFoundException { @@ -3983,23 +3939,4 @@ value = (random.nextInt() & modulo); return value; } } /** * The exception that is thrown during initialization if the peer specified * could not be found. * */ class PeerNotFoundException extends OpenDsException { private static final long serialVersionUID = -362726764261560341L; /** * The constructor for the exception. * @param message the localized message. */ PeerNotFoundException(Message message) { super(message); } } } opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java
@@ -572,7 +572,12 @@ ERR_NO_REACHABLE_PEER_IN_THE_DOMAIN.getId()) != -1; } private int getReplicationId(Set<Integer> usedIds) /** * Returns the ID to be used for a new replication server or domain. * @param usedIds the list of already used ids. * @return the ID to be used for a new replication server or domain. */ public static int getReplicationId(Set<Integer> usedIds) { Random r = new Random(); int id = 0; @@ -583,7 +588,13 @@ return id; } private String getDomainName(String[] existingDomains, int newDomainId) /** * Returns the name to be used for a new replication domain. * @param existingDomains the existing domains names. * @param newDomainId the new domain replication id. * @return the name to be used for a new replication domain. */ public static String getDomainName(String[] existingDomains, int newDomainId) { String domainName = DOMAIN_BASE_NAME+newDomainId; boolean nameExists = true; opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
@@ -517,18 +517,17 @@ public static String getStringFromCollection(Collection<String> col, String separator) { String msg = null; StringBuffer msg = new StringBuffer(); for (String m : col) { if (msg == null) if (msg.length() > 0) { msg = m; } else { msg += separator + m; msg.append(separator); } msg.append(m); } return msg; return msg.toString(); } /** @@ -669,7 +668,7 @@ * @param te the exception. * @return a localized representation of the provide TopologyCacheException. */ public static String getStringRepresentation(TopologyCacheException te) public static Message getMessage(TopologyCacheException te) { MessageBuilder buf = new MessageBuilder(); @@ -690,7 +689,7 @@ // This is unexpected. buf.append(getThrowableMsg(INFO_BUG_MSG.get(), te.getCause())); } return buf.toString(); return buf.toMessage(); } /** opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliGlobalAdmin.java
@@ -690,7 +690,7 @@ // Check that propName is a known prop. AdministratorProperty adminUserProperty = ADSContext .getAdminUSerPropFromName(propertyName); .getAdminUserPropFromName(propertyName); if (adminUserProperty == null) { Message message = ERR_CLI_ERROR_PROPERTY_UNRECOGNIZED.get(propertyName); opends/src/server/org/opends/server/admin/client/cli/SecureConnectionCliParser.java
@@ -157,20 +157,20 @@ protected BooleanArgument useSSLArg = null; /** * The 'startTLSArg' global argument. * The 'useStartTLSArg' global argument. */ protected BooleanArgument startTLSArg = null; protected BooleanArgument useStartTLSArg = null; /** Short form of the option for specifying a noninteractive session. */ static public final Character INTERACTIVE_OPTION_SHORT = 'i'; /** Long form of the option for specifying a noninteractive session. */ /** Long form of the option for specifying a quiet session. */ static public final String QUIET_OPTION_LONG = "quiet"; /** Long form of the option for specifying a noninteractive session. */ static public final String INTERACTIVE_OPTION_LONG = "interactive"; /** Short form of the option for specifying a noninteractive session. */ /** Short form of the option for specifying a quiet session. */ static public final Character QUIET_OPTION_SHORT = 'Q'; /** @@ -181,7 +181,7 @@ /** * End Of Line. */ protected static String EOL = System.getProperty("line.separator"); public static String EOL = System.getProperty("line.separator"); /** * The Logger. @@ -400,10 +400,10 @@ OPTION_LONG_USE_SSL, INFO_DESCRIPTION_USE_SSL.get()); set.add(useSSLArg); startTLSArg = new BooleanArgument("startTLS", OPTION_SHORT_START_TLS, useStartTLSArg = new BooleanArgument("startTLS", OPTION_SHORT_START_TLS, OPTION_LONG_START_TLS, INFO_DESCRIPTION_START_TLS.get()); set.add(startTLSArg); set.add(useStartTLSArg); hostNameArg = new StringArgument("host", OPTION_SHORT_HOST, OPTION_LONG_HOST, false, false, true, OPTION_VALUE_HOST, "localhost", @@ -584,10 +584,10 @@ // Couldn't have at the same time startTLSArg and // useSSLArg if (startTLSArg.isPresent() if (useStartTLSArg.isPresent() && useSSLArg.isPresent()) { Message message = ERR_TOOL_CONFLICTING_ARGS.get( startTLSArg useStartTLSArg .getLongIdentifier(), useSSLArg.getLongIdentifier()); errors.add(message); } @@ -666,7 +666,7 @@ */ public boolean startTLS() { if (startTLSArg.isPresent()) if (useStartTLSArg.isPresent()) { return true; }