| | |
| | | import java.net.InetAddress; |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.Comparator; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | |
| | | import java.util.LinkedList; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | import java.util.logging.Level; |
| | | import java.util.logging.Logger; |
| | |
| | | import javax.naming.directory.SearchControls; |
| | | import javax.naming.directory.SearchResult; |
| | | import javax.naming.ldap.InitialLdapContext; |
| | | import javax.naming.ldap.LdapName; |
| | | import javax.net.ssl.TrustManager; |
| | | |
| | | import org.opends.admin.ads.ADSContext; |
| | | import org.opends.admin.ads.ADSContextException; |
| | | import org.opends.admin.ads.ADSContextHelper; |
| | | import org.opends.admin.ads.ReplicaDescriptor; |
| | | import org.opends.admin.ads.ServerDescriptor; |
| | | import org.opends.admin.ads.SuffixDescriptor; |
| | |
| | | import org.opends.admin.ads.TopologyCacheFilter; |
| | | import org.opends.admin.ads.ADSContext.ADSPropertySyntax; |
| | | import org.opends.admin.ads.ADSContext.AdministratorProperty; |
| | | 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.PreferredConnection; |
| | |
| | | } |
| | | int replicationPort1 = -1; |
| | | boolean secureReplication1 = argParser.isSecureReplication1(); |
| | | boolean configureReplicationServer1 = |
| | | !argParser.noReplicationServer1Arg.isPresent(); |
| | | boolean configureReplicationDomain1 = |
| | | !argParser.onlyReplicationServer1Arg.isPresent(); |
| | | if (ctx1 != null) |
| | | { |
| | | int repPort1 = getReplicationPort(ctx1); |
| | | boolean replicationServer1Configured = repPort1 > 0; |
| | | if (replicationServer1Configured && !configureReplicationServer1) |
| | | { |
| | | try |
| | | { |
| | | if (!askConfirmation( |
| | | INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT. |
| | | get(ConnectionUtils.getHostPort(ctx1), repPort1), false, LOG)) |
| | | { |
| | | cancelled = true; |
| | | } |
| | | } |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | cancelled = true; |
| | | } |
| | | } |
| | | |
| | | // Try to get the replication port for server 1 only if it is required. |
| | | if (!hasReplicationPort(ctx1)) |
| | | if (!replicationServer1Configured && configureReplicationServer1 && |
| | | !cancelled) |
| | | { |
| | | if (argParser.advancedArg.isPresent() && |
| | | configureReplicationDomain1) |
| | | { |
| | | // Only ask if the replication domain will be configured (if not |
| | | // the replication server MUST be configured). |
| | | try |
| | | { |
| | | configureReplicationServer1 = askConfirmation( |
| | | INFO_REPLICATION_ENABLE_REPLICATION_SERVER1_PROMPT.get(), |
| | | true, LOG); |
| | | } |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | cancelled = true; |
| | | } |
| | | } |
| | | } |
| | | if (!cancelled && |
| | | !replicationServer1Configured && configureReplicationServer1) |
| | | { |
| | | boolean tryWithDefault = argParser.getReplicationPort1() != -1; |
| | | while (replicationPort1 == -1) |
| | |
| | | println(); |
| | | } |
| | | } |
| | | if (!cancelled && |
| | | configureReplicationDomain1 && |
| | | configureReplicationServer1 && |
| | | argParser.advancedArg.isPresent()) |
| | | { |
| | | // Only necessary to ask if the replication server will be configured |
| | | try |
| | | { |
| | | configureReplicationDomain1 = askConfirmation( |
| | | INFO_REPLICATION_ENABLE_REPLICATION_DOMAIN1_PROMPT.get(), |
| | | true, LOG); |
| | | } |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | cancelled = true; |
| | | } |
| | | } |
| | | // 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 |
| | |
| | | } |
| | | uData.setReplicationPort1(replicationPort1); |
| | | uData.setSecureReplication1(secureReplication1); |
| | | uData.setConfigureReplicationServer1(configureReplicationServer1); |
| | | uData.setConfigureReplicationDomain1(configureReplicationDomain1); |
| | | firstServerCommandBuilder = new CommandBuilder(null); |
| | | if (mustPrintCommandBuilder()) |
| | | { |
| | |
| | | |
| | | int replicationPort2 = -1; |
| | | boolean secureReplication2 = argParser.isSecureReplication2(); |
| | | boolean configureReplicationServer2 = |
| | | !argParser.noReplicationServer2Arg.isPresent(); |
| | | boolean configureReplicationDomain2 = |
| | | !argParser.onlyReplicationServer2Arg.isPresent(); |
| | | if (ctx2 != null) |
| | | { |
| | | if (!hasReplicationPort(ctx2)) |
| | | int repPort2 = getReplicationPort(ctx2); |
| | | boolean replicationServer2Configured = repPort2 > 0; |
| | | if (replicationServer2Configured && !configureReplicationServer2) |
| | | { |
| | | boolean tryWithDefault = argParser.getReplicationPort2() != -1; |
| | | while (replicationPort2 == -1) |
| | | try |
| | | { |
| | | if (tryWithDefault) |
| | | if (!askConfirmation( |
| | | INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT. |
| | | get(ConnectionUtils.getHostPort(ctx2), repPort2), false, LOG)) |
| | | { |
| | | replicationPort2 = argParser.getReplicationPort2(); |
| | | tryWithDefault = false; |
| | | } |
| | | else |
| | | { |
| | | replicationPort2 = askPort( |
| | | INFO_REPLICATION_ENABLE_REPLICATIONPORT2_PROMPT.get(), |
| | | argParser.getDefaultReplicationPort2()); |
| | | println(); |
| | | } |
| | | if (!argParser.skipReplicationPortCheck() && isLocalHost(host2)) |
| | | { |
| | | if (!SetupUtils.canUseAsPort(replicationPort2)) |
| | | { |
| | | println(); |
| | | println(getCannotBindToPortError(replicationPort2)); |
| | | println(); |
| | | replicationPort2 = -1; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // This is something that we must do in any case... this test is |
| | | // already included when we call SetupUtils.canUseAsPort |
| | | if (replicationPort2 == port2) |
| | | { |
| | | println(); |
| | | println( |
| | | ERR_REPLICATION_PORT_AND_REPLICATION_PORT_EQUAL.get( |
| | | host2, String.valueOf(replicationPort2))); |
| | | replicationPort2 = -1; |
| | | } |
| | | } |
| | | if (host1.equalsIgnoreCase(host2)) |
| | | { |
| | | if ((replicationPort1 > 0) && |
| | | (replicationPort1 == replicationPort2)) |
| | | { |
| | | println(); |
| | | println(ERR_REPLICATION_SAME_REPLICATION_PORT.get( |
| | | String.valueOf(replicationPort2), host1)); |
| | | println(); |
| | | replicationPort2 = -1; |
| | | } |
| | | cancelled = true; |
| | | } |
| | | } |
| | | if (!secureReplication2) |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | cancelled = true; |
| | | } |
| | | } |
| | | |
| | | // Try to get the replication port for server 2 only if it is required. |
| | | if (!replicationServer2Configured && configureReplicationServer2 && |
| | | !cancelled) |
| | | { |
| | | // Only ask if the replication domain will be configured (if not the |
| | | // replication server MUST be configured). |
| | | if (argParser.advancedArg.isPresent() && |
| | | configureReplicationDomain2) |
| | | { |
| | | try |
| | | { |
| | | secureReplication2 = |
| | | askConfirmation(INFO_REPLICATION_ENABLE_SECURE2_PROMPT.get( |
| | | String.valueOf(replicationPort2)), false, LOG); |
| | | configureReplicationServer2 = askConfirmation( |
| | | INFO_REPLICATION_ENABLE_REPLICATION_SERVER2_PROMPT.get(), |
| | | true, LOG); |
| | | } |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | cancelled = true; |
| | | } |
| | | println(); |
| | | } |
| | | if (!cancelled && |
| | | !replicationServer2Configured && configureReplicationServer2) |
| | | { |
| | | boolean tryWithDefault = argParser.getReplicationPort2() != -1; |
| | | while (replicationPort2 == -1) |
| | | { |
| | | if (tryWithDefault) |
| | | { |
| | | replicationPort2 = argParser.getReplicationPort2(); |
| | | tryWithDefault = false; |
| | | } |
| | | else |
| | | { |
| | | replicationPort2 = askPort( |
| | | INFO_REPLICATION_ENABLE_REPLICATIONPORT2_PROMPT.get(), |
| | | argParser.getDefaultReplicationPort2()); |
| | | println(); |
| | | } |
| | | if (!argParser.skipReplicationPortCheck() && isLocalHost(host2)) |
| | | { |
| | | if (!SetupUtils.canUseAsPort(replicationPort2)) |
| | | { |
| | | println(); |
| | | println(getCannotBindToPortError(replicationPort2)); |
| | | println(); |
| | | replicationPort2 = -1; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // This is something that we must do in any case... this test is |
| | | // already included when we call SetupUtils.canUseAsPort |
| | | if (replicationPort2 == port2) |
| | | { |
| | | println(); |
| | | println( |
| | | ERR_REPLICATION_PORT_AND_REPLICATION_PORT_EQUAL.get( |
| | | host2, String.valueOf(replicationPort2))); |
| | | replicationPort2 = -1; |
| | | } |
| | | } |
| | | if (host1.equalsIgnoreCase(host2)) |
| | | { |
| | | if ((replicationPort1 > 0) && |
| | | (replicationPort1 == replicationPort2)) |
| | | { |
| | | println(); |
| | | println(ERR_REPLICATION_SAME_REPLICATION_PORT.get( |
| | | String.valueOf(replicationPort2), host1)); |
| | | println(); |
| | | replicationPort2 = -1; |
| | | } |
| | | } |
| | | } |
| | | if (!secureReplication2) |
| | | { |
| | | try |
| | | { |
| | | secureReplication2 = |
| | | askConfirmation(INFO_REPLICATION_ENABLE_SECURE2_PROMPT.get( |
| | | String.valueOf(replicationPort2)), false, LOG); |
| | | } |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | cancelled = true; |
| | | } |
| | | println(); |
| | | } |
| | | } |
| | | } |
| | | if (!cancelled && |
| | | configureReplicationDomain2 && |
| | | configureReplicationServer2 && |
| | | argParser.advancedArg.isPresent()) |
| | | { |
| | | // Only necessary to ask if the replication server will be configured |
| | | try |
| | | { |
| | | configureReplicationDomain2 = askConfirmation( |
| | | INFO_REPLICATION_ENABLE_REPLICATION_DOMAIN2_PROMPT.get(), |
| | | true, LOG); |
| | | } |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | cancelled = true; |
| | | } |
| | | } |
| | | // If the server contains an ADS. Try to load it and only load it: if |
| | |
| | | } |
| | | uData.setReplicationPort2(replicationPort2); |
| | | uData.setSecureReplication2(secureReplication2); |
| | | uData.setConfigureReplicationServer2(configureReplicationServer2); |
| | | uData.setConfigureReplicationDomain2(configureReplicationDomain2); |
| | | |
| | | // If the adminUid and adminPwd are not set in the EnableReplicationUserData |
| | | // object, that means that there are no administrators and that they |
| | |
| | | if (!cancelled) |
| | | { |
| | | LinkedList<String> suffixes = argParser.getBaseDNs(); |
| | | checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, true); |
| | | checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, true, uData); |
| | | cancelled = suffixes.isEmpty(); |
| | | |
| | | uData.setBaseDNs(suffixes); |
| | |
| | | ctx = aux[0]; |
| | | } |
| | | |
| | | if (!cancelled) |
| | | boolean disableAll = argParser.disableAllArg.isPresent(); |
| | | boolean disableReplicationServer = |
| | | argParser.disableReplicationServerArg.isPresent(); |
| | | if (disableAll || |
| | | (argParser.advancedArg.isPresent() && |
| | | argParser.getBaseDNs().isEmpty() && |
| | | !disableReplicationServer)) |
| | | { |
| | | try |
| | | { |
| | | disableAll = askConfirmation(INFO_REPLICATION_PROMPT_DISABLE_ALL.get(), |
| | | disableAll, LOG); |
| | | } |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | cancelled = true; |
| | | } |
| | | } |
| | | int repPort = getReplicationPort(ctx); |
| | | if (!disableAll && |
| | | (argParser.advancedArg.isPresent() || |
| | | disableReplicationServer)) |
| | | { |
| | | if (repPort > 0) |
| | | { |
| | | try |
| | | { |
| | | disableReplicationServer = askConfirmation( |
| | | INFO_REPLICATION_PROMPT_DISABLE_REPLICATION_SERVER.get(repPort), |
| | | disableReplicationServer, |
| | | LOG); |
| | | } |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | cancelled = true; |
| | | } |
| | | } |
| | | } |
| | | if (disableReplicationServer && repPort < 0) |
| | | { |
| | | disableReplicationServer = false; |
| | | try |
| | | { |
| | | cancelled = askConfirmation( |
| | | INFO_REPLICATION_PROMPT_NO_REPLICATION_SERVER_TO_DISABLE.get( |
| | | ConnectionUtils.getHostPort(ctx)), |
| | | false, |
| | | LOG); |
| | | } |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | cancelled = true; |
| | | } |
| | | } |
| | | if (repPort > 0 && disableAll) |
| | | { |
| | | disableReplicationServer = true; |
| | | } |
| | | uData.setDisableAll(disableAll); |
| | | uData.setDisableReplicationServer(disableReplicationServer); |
| | | if (!cancelled && !disableAll) |
| | | { |
| | | LinkedList<String> suffixes = argParser.getBaseDNs(); |
| | | checkSuffixesForDisableReplication(suffixes, ctx, true); |
| | | cancelled = suffixes.isEmpty(); |
| | | |
| | | checkSuffixesForDisableReplication(suffixes, ctx, true, |
| | | !disableReplicationServer, !disableReplicationServer); |
| | | cancelled = suffixes.isEmpty() && !disableReplicationServer; |
| | | |
| | | uData.setBaseDNs(suffixes); |
| | | |
| | | if (!uData.disableReplicationServer() && repPort > 0 && |
| | | disableAllBaseDns(ctx, uData) && !argParser.advancedArg.isPresent()) |
| | | { |
| | | try |
| | | { |
| | | uData.setDisableReplicationServer(askConfirmation( |
| | | INFO_REPLICATION_DISABLE_ALL_SUFFIXES_DISABLE_REPLICATION_SERVER.get( |
| | | ConnectionUtils.getHostPort(ctx), repPort), true, LOG)); |
| | | } |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | cancelled = true; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!cancelled) |
| | | { |
| | | // Ask for confirmation to disable. |
| | | // Ask for confirmation to disable if not already done. |
| | | boolean disableADS = false; |
| | | boolean disableSchema = false; |
| | | for (String dn : uData.getBaseDNs()) |
| | |
| | | println(); |
| | | try |
| | | { |
| | | if (disableAllBaseDns(ctx, uData)) |
| | | if (uData.disableAll()) |
| | | { |
| | | cancelled = !askConfirmation( |
| | | INFO_REPLICATION_CONFIRM_DISABLE_LAST_SUFFIXES.get(), true, |
| | | LOG); |
| | | // Another confirmation is redundant: we already asked the user... |
| | | } |
| | | else |
| | | { |
| | | cancelled = !askConfirmation( |
| | | INFO_REPLICATION_CONFIRM_DISABLE_GENERIC.get(), true, LOG); |
| | | if (!uData.getBaseDNs().isEmpty()) |
| | | { |
| | | cancelled = !askConfirmation( |
| | | INFO_REPLICATION_CONFIRM_DISABLE_GENERIC.get(), true, |
| | | LOG); |
| | | } |
| | | else |
| | | { |
| | | // Another confirmation for the replication server is redundant. |
| | | } |
| | | } |
| | | } |
| | | catch (CLIException ce) |
| | |
| | | uData.setReplicationPort2(replicationPort2); |
| | | uData.setSecureReplication2(argParser.isSecureReplication2()); |
| | | uData.setReplicateSchema(!argParser.noSchemaReplication()); |
| | | uData.setConfigureReplicationDomain1( |
| | | !argParser.onlyReplicationServer1Arg.isPresent()); |
| | | uData.setConfigureReplicationDomain2( |
| | | !argParser.onlyReplicationServer2Arg.isPresent()); |
| | | uData.setConfigureReplicationServer1( |
| | | !argParser.noReplicationServer1Arg.isPresent()); |
| | | uData.setConfigureReplicationServer2( |
| | | !argParser.noReplicationServer2Arg.isPresent()); |
| | | } |
| | | |
| | | /** |
| | |
| | | int port = getValue(argParser.getPortToDisable(), |
| | | argParser.getDefaultPortToDisable()); |
| | | uData.setPort(port); |
| | | |
| | | uData.setDisableAll(argParser.disableAllArg.isPresent()); |
| | | uData.setDisableReplicationServer( |
| | | argParser.disableReplicationServerArg.isPresent()); |
| | | } |
| | | |
| | | /** |
| | |
| | | println(); |
| | | println( |
| | | ERR_ERROR_CONNECTING_TO_SERVER_PROMPT_AGAIN.get( |
| | | host+":"+port, t.getMessage())); |
| | | getServerRepresentation(host, port), t.getMessage())); |
| | | LOG.log(Level.WARNING, "Complete error stack:", t); |
| | | println(); |
| | | } |
| | |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | String hostPort = host1+":"+port1; |
| | | String hostPort = getServerRepresentation(host1, port1); |
| | | errorMessages.add(getMessageForException(ne, hostPort)); |
| | | |
| | | LOG.log(Level.SEVERE, "Complete error stack:", ne); |
| | |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | String hostPort = host2+":"+port2; |
| | | String hostPort = getServerRepresentation(host2, port2); |
| | | errorMessages.add(getMessageForException(ne, hostPort)); |
| | | |
| | | LOG.log(Level.SEVERE, "Complete error stack:", ne); |
| | |
| | | if (errorMessages.isEmpty()) |
| | | { |
| | | LinkedList<String> suffixes = uData.getBaseDNs(); |
| | | checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, false); |
| | | checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, false, uData); |
| | | if (!suffixes.isEmpty()) |
| | | { |
| | | uData.setBaseDNs(suffixes); |
| | |
| | | t); |
| | | } |
| | | } |
| | | |
| | | if (!isInteractive()) |
| | | { |
| | | int repPort1 = getReplicationPort(ctx1); |
| | | int repPort2 = getReplicationPort(ctx2); |
| | | |
| | | if (!uData.configureReplicationServer1() && repPort1 > 0) |
| | | { |
| | | |
| | | println(INFO_REPLICATION_SERVER_CONFIGURED_WARNING.get( |
| | | ConnectionUtils.getHostPort(ctx1), repPort1)); |
| | | println(); |
| | | } |
| | | if (!uData.configureReplicationServer2() && repPort2 > 0) |
| | | { |
| | | println(INFO_REPLICATION_SERVER_CONFIGURED_WARNING.get( |
| | | ConnectionUtils.getHostPort(ctx2), repPort2)); |
| | | println(); |
| | | } |
| | | } |
| | | |
| | | try |
| | | { |
| | | updateConfiguration(ctx1, ctx2, uData); |
| | |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | String hostPort = uData.getHostName()+":"+uData.getPort(); |
| | | String hostPort = |
| | | getServerRepresentation(uData.getHostName(), uData.getPort()); |
| | | println(); |
| | | println(getMessageForException(ne, hostPort)); |
| | | LOG.log(Level.SEVERE, "Complete error stack:", ne); |
| | |
| | | printProgress(formatter.getFormattedDone()); |
| | | printlnProgress(); |
| | | LinkedList<String> suffixes = uData.getBaseDNs(); |
| | | checkSuffixesForDisableReplication(suffixes, ctx, false); |
| | | if (!suffixes.isEmpty()) |
| | | checkSuffixesForDisableReplication(suffixes, ctx, false, |
| | | !uData.disableReplicationServer(), !uData.disableReplicationServer()); |
| | | if (!suffixes.isEmpty() || uData.disableReplicationServer() || |
| | | uData.disableAll()) |
| | | { |
| | | uData.setBaseDNs(suffixes); |
| | | |
| | | if (!isInteractive()) |
| | | { |
| | | boolean hasReplicationPort = hasReplicationPort(ctx); |
| | | if (uData.disableAll() && hasReplicationPort) |
| | | { |
| | | uData.setDisableReplicationServer(true); |
| | | } |
| | | else if (uData.disableReplicationServer() && !hasReplicationPort && |
| | | !uData.disableAll()) |
| | | { |
| | | uData.setDisableReplicationServer(false); |
| | | println( |
| | | INFO_REPLICATION_WARNING_NO_REPLICATION_SERVER_TO_DISABLE.get( |
| | | ConnectionUtils.getHostPort(ctx))); |
| | | println(); |
| | | } |
| | | } |
| | | |
| | | if (mustPrintCommandBuilder()) |
| | | { |
| | | try |
| | |
| | | t); |
| | | } |
| | | } |
| | | |
| | | if (!isInteractive() && !uData.disableReplicationServer() && |
| | | !uData.disableAll() && disableAllBaseDns(ctx, uData)) |
| | | { |
| | | // Inform the user that the replication server will not be disabled. |
| | | // Inform also of the user of the disableReplicationServerArg |
| | | println( |
| | | INFO_REPLICATION_DISABLE_ALL_SUFFIXES_KEEP_REPLICATION_SERVER.get( |
| | | ConnectionUtils.getHostPort(ctx), |
| | | argParser.disableReplicationServerArg.getLongIdentifier(), |
| | | argParser.disableAllArg.getLongIdentifier())); |
| | | } |
| | | try |
| | | { |
| | | updateConfiguration(ctx, uData); |
| | |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | String hostPort = uData.getHostName()+":"+uData.getPort(); |
| | | String hostPort = |
| | | getServerRepresentation(uData.getHostName(), uData.getPort()); |
| | | println(); |
| | | println(getMessageForException(ne, hostPort)); |
| | | LOG.log(Level.SEVERE, "Complete error stack:", ne); |
| | |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | String hostPort = uData.getHostNameSource()+":"+uData.getPortSource(); |
| | | String hostPort = getServerRepresentation(uData.getHostNameSource(), |
| | | uData.getPortSource()); |
| | | println(); |
| | | println(getMessageForException(ne, hostPort)); |
| | | LOG.log(Level.SEVERE, "Complete error stack:", ne); |
| | |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | String hostPort = uData.getHostNameDestination()+":"+ |
| | | uData.getPortDestination(); |
| | | String hostPort = getServerRepresentation(uData.getHostNameDestination(), |
| | | uData.getPortDestination()); |
| | | println(); |
| | | println(getMessageForException(ne, hostPort)); |
| | | LOG.log(Level.SEVERE, "Complete error stack:", ne); |
| | |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | String hostPort = uData.getHostName()+":"+uData.getPort(); |
| | | String hostPort = |
| | | getServerRepresentation(uData.getHostName(), uData.getPort()); |
| | | println(); |
| | | println(getMessageForException(ne, hostPort)); |
| | | LOG.log(Level.SEVERE, "Complete error stack:", ne); |
| | |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | String hostPort = uData.getHostName()+":"+uData.getPort(); |
| | | String hostPort = |
| | | getServerRepresentation(uData.getHostName(), uData.getPort()); |
| | | println(); |
| | | println(getMessageForException(ne, hostPort)); |
| | | LOG.log(Level.SEVERE, "Complete error stack:", ne); |
| | |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | String hostPort = uData.getHostName()+":"+uData.getPort(); |
| | | String hostPort = |
| | | getServerRepresentation(uData.getHostName(), uData.getPort()); |
| | | println(); |
| | | println(getMessageForException(ne, hostPort)); |
| | | LOG.log(Level.SEVERE, "Complete error stack:", ne); |
| | |
| | | * @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. |
| | | * @param uData the user data. This object will not be updated by this method |
| | | * but it is assumed that it contains information about whether the |
| | | * replication domains must be configured or not. |
| | | */ |
| | | private void checkSuffixesForEnableReplication(Collection<String> suffixes, |
| | | InitialLdapContext ctx1, InitialLdapContext ctx2, |
| | | boolean interactive) |
| | | boolean interactive, EnableReplicationUserData uData) |
| | | { |
| | | 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)); |
| | | |
| | | TreeSet<String> availableSuffixes; |
| | | TreeSet<String> alreadyReplicatedSuffixes; |
| | | |
| | | if (uData.configureReplicationDomain1() && |
| | | uData.configureReplicationDomain2()) |
| | | { |
| | | availableSuffixes = |
| | | new TreeSet<String>(getCommonSuffixes(ctx1, ctx2, |
| | | SuffixRelationType.NOT_FULLY_REPLICATED)); |
| | | alreadyReplicatedSuffixes = |
| | | new TreeSet<String>(getCommonSuffixes(ctx1, ctx2, |
| | | SuffixRelationType.FULLY_REPLICATED)); |
| | | } |
| | | else if (uData.configureReplicationDomain1()) |
| | | { |
| | | availableSuffixes = new TreeSet<String>(); |
| | | alreadyReplicatedSuffixes = new TreeSet<String>(); |
| | | |
| | | updateAvailableAndReplicatedSuffixesForOneDomain(ctx1, ctx2, |
| | | availableSuffixes, alreadyReplicatedSuffixes); |
| | | } |
| | | else if (uData.configureReplicationDomain2()) |
| | | { |
| | | availableSuffixes = new TreeSet<String>(); |
| | | alreadyReplicatedSuffixes = new TreeSet<String>(); |
| | | |
| | | updateAvailableAndReplicatedSuffixesForOneDomain(ctx2, ctx1, |
| | | availableSuffixes, alreadyReplicatedSuffixes); |
| | | } |
| | | else |
| | | { |
| | | availableSuffixes = new TreeSet<String>(); |
| | | alreadyReplicatedSuffixes = new TreeSet<String>(); |
| | | |
| | | updateAvailableAndReplicatedSuffixesForNoDomain(ctx1, ctx2, |
| | | availableSuffixes, alreadyReplicatedSuffixes); |
| | | } |
| | | |
| | | if (availableSuffixes.size() == 0) |
| | | { |
| | | println(); |
| | | println( |
| | | if (!uData.configureReplicationDomain1() && |
| | | !uData.configureReplicationDomain1() && |
| | | alreadyReplicatedSuffixes.isEmpty()) |
| | | { |
| | | // Use a clarifying message: there is no replicated base DN. |
| | | println( |
| | | ERR_NO_SUFFIXES_AVAILABLE_TO_ENABLE_REPLICATION_NO_DOMAIN.get()); |
| | | } |
| | | else |
| | | { |
| | | println( |
| | | ERR_NO_SUFFIXES_AVAILABLE_TO_ENABLE_REPLICATION.get()); |
| | | } |
| | | |
| | | LinkedList<String> userProvidedSuffixes = argParser.getBaseDNs(); |
| | | TreeSet<String> userProvidedReplicatedSuffixes = new TreeSet<String>(); |
| | |
| | | * @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. |
| | | * @param displayErrors whether to display errors or not. |
| | | * @param areSuffixRequired whether the user must provide base DNs or not |
| | | * (if it is <CODE>false</CODE> the user will be proposed the suffixes |
| | | * only once). |
| | | */ |
| | | private void checkSuffixesForDisableReplication(Collection<String> suffixes, |
| | | InitialLdapContext ctx, boolean interactive) |
| | | InitialLdapContext ctx, boolean interactive, boolean displayErrors, |
| | | boolean areSuffixRequired) |
| | | { |
| | | TreeSet<String> availableSuffixes = new TreeSet<String>(); |
| | | TreeSet<String> notReplicatedSuffixes = new TreeSet<String>(); |
| | |
| | | } |
| | | if (availableSuffixes.size() == 0) |
| | | { |
| | | println(); |
| | | println(ERR_NO_SUFFIXES_AVAILABLE_TO_DISABLE_REPLICATION.get()); |
| | | if (displayErrors) |
| | | { |
| | | println(); |
| | | println(ERR_NO_SUFFIXES_AVAILABLE_TO_DISABLE_REPLICATION.get()); |
| | | } |
| | | LinkedList<String> userProvidedSuffixes = argParser.getBaseDNs(); |
| | | TreeSet<String> userProvidedNotReplicatedSuffixes = |
| | | new TreeSet<String>(); |
| | |
| | | } |
| | | } |
| | | } |
| | | if (userProvidedNotReplicatedSuffixes.size() > 0) |
| | | if (userProvidedNotReplicatedSuffixes.size() > 0 && displayErrors) |
| | | { |
| | | println(); |
| | | println(INFO_ALREADY_NOT_REPLICATED_SUFFIXES.get( |
| | |
| | | } |
| | | suffixes.removeAll(notFound); |
| | | suffixes.removeAll(alreadyNotReplicated); |
| | | if (notFound.size() > 0) |
| | | if (notFound.size() > 0 && displayErrors) |
| | | { |
| | | println(); |
| | | println(ERR_REPLICATION_DISABLE_SUFFIXES_NOT_FOUND.get( |
| | | Utils.getStringFromCollection(notFound, |
| | | Constants.LINE_SEPARATOR))); |
| | | } |
| | | if (alreadyNotReplicated.size() > 0) |
| | | if (alreadyNotReplicated.size() > 0 && displayErrors) |
| | | { |
| | | println(); |
| | | println(INFO_ALREADY_NOT_REPLICATED_SUFFIXES.get( |
| | |
| | | { |
| | | // In interactive mode we do not propose to manage the |
| | | // administration suffix. |
| | | println(); |
| | | println(ERR_NO_SUFFIXES_AVAILABLE_TO_DISABLE_REPLICATION.get()); |
| | | if (displayErrors) |
| | | { |
| | | println(); |
| | | println(ERR_NO_SUFFIXES_AVAILABLE_TO_DISABLE_REPLICATION.get()); |
| | | } |
| | | break; |
| | | } |
| | | else |
| | | { |
| | | println(); |
| | | println(ERR_NO_SUFFIXES_SELECTED_TO_DISABLE.get()); |
| | | if (areSuffixRequired) |
| | | { |
| | | println(); |
| | | println(ERR_NO_SUFFIXES_SELECTED_TO_DISABLE.get()); |
| | | } |
| | | for (String dn : availableSuffixes) |
| | | { |
| | | if (!Utils.areDnsEqual(dn, |
| | |
| | | try |
| | | { |
| | | if (askConfirmation( |
| | | INFO_REPLICATION_DISABLE_SUFFIX_PROMPT.get(dn), true,LOG)) |
| | | INFO_REPLICATION_DISABLE_SUFFIX_PROMPT.get(dn), true, |
| | | LOG)) |
| | | { |
| | | suffixes.add(dn); |
| | | } |
| | |
| | | suffixes.clear(); |
| | | break; |
| | | } |
| | | if (!areSuffixRequired) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | Constants.LINE_SEPARATOR).toString())); |
| | | } |
| | | } |
| | | // Check whether there is more than one replication server in the |
| | | // topology. |
| | | Set<String> baseDNsWithOneReplicationServer = new TreeSet<String>(); |
| | | Set<String> baseDNsWithNoReplicationServer = new TreeSet<String>(); |
| | | updateBaseDnsWithNotEnoughReplicationServer(adsCtx1, adsCtx2, uData, |
| | | baseDNsWithNoReplicationServer, baseDNsWithOneReplicationServer); |
| | | |
| | | if (!baseDNsWithNoReplicationServer.isEmpty()) |
| | | { |
| | | Message errorMsg = |
| | | ERR_REPLICATION_NO_REPLICATION_SERVER.get( |
| | | Utils.getStringFromCollection(baseDNsWithNoReplicationServer, |
| | | Constants.LINE_SEPARATOR)); |
| | | throw new ReplicationCliException( |
| | | errorMsg, |
| | | ReplicationCliReturnCode.ERROR_USER_DATA, null); |
| | | } |
| | | else if (!baseDNsWithOneReplicationServer.isEmpty()) |
| | | { |
| | | if (isInteractive()) |
| | | { |
| | | Message confirmMsg = |
| | | INFO_REPLICATION_ONLY_ONE_REPLICATION_SERVER_CONFIRM.get( |
| | | Utils.getStringFromCollection(baseDNsWithOneReplicationServer, |
| | | Constants.LINE_SEPARATOR)); |
| | | try |
| | | { |
| | | if (!confirmAction(confirmMsg, false)) |
| | | { |
| | | throw new ReplicationCliException( |
| | | ERR_REPLICATION_USER_CANCELLED.get(), |
| | | ReplicationCliReturnCode.USER_CANCELLED, null); |
| | | } |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | throw new ReplicationCliException( |
| | | ERR_REPLICATION_USER_CANCELLED.get(), |
| | | ReplicationCliReturnCode.USER_CANCELLED, t); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Message warningMsg = |
| | | INFO_REPLICATION_ONLY_ONE_REPLICATION_SERVER_WARNING.get( |
| | | Utils.getStringFromCollection(baseDNsWithOneReplicationServer, |
| | | Constants.LINE_SEPARATOR)); |
| | | println(warningMsg); |
| | | println(); |
| | | } |
| | | } |
| | | |
| | | // These are used to identify which server we use to initialize |
| | | // the contents of the other server (if any). |
| | |
| | | twoReplServers.add(server1.getReplicationServerHostPort()); |
| | | usedReplicationServerIds.add(server1.getReplicationServerId()); |
| | | } |
| | | else |
| | | else if (uData.configureReplicationServer1()) |
| | | { |
| | | twoReplServers.add( |
| | | ConnectionUtils.getHostName(ctx1)+":"+uData.getReplicationPort1()); |
| | | twoReplServers.add(getReplicationServer( |
| | | ConnectionUtils.getHostName(ctx1), uData.getReplicationPort1())); |
| | | } |
| | | if (server2.isReplicationServer()) |
| | | { |
| | | twoReplServers.add(server2.getReplicationServerHostPort()); |
| | | usedReplicationServerIds.add(server2.getReplicationServerId()); |
| | | } |
| | | else |
| | | else if (uData.configureReplicationServer2()) |
| | | { |
| | | twoReplServers.add( |
| | | ConnectionUtils.getHostName(ctx2)+":"+uData.getReplicationPort2()); |
| | | twoReplServers.add(getReplicationServer( |
| | | ConnectionUtils.getHostName(ctx2), uData.getReplicationPort2())); |
| | | } |
| | | |
| | | for (String baseDN : uData.getBaseDNs()) |
| | |
| | | } |
| | | |
| | | Set<String> alreadyConfiguredReplicationServers = new HashSet<String>(); |
| | | if (!server1.isReplicationServer()) |
| | | if (!server1.isReplicationServer() && uData.configureReplicationServer1()) |
| | | { |
| | | try |
| | | { |
| | |
| | | ERROR_CONFIGURING_REPLICATIONSERVER, ode); |
| | | } |
| | | } |
| | | else |
| | | else if (server1.isReplicationServer()) |
| | | { |
| | | try |
| | | { |
| | |
| | | } |
| | | } |
| | | alreadyConfiguredReplicationServers.add(server1.getId()); |
| | | if (!server2.isReplicationServer()) |
| | | if (!server2.isReplicationServer() && uData.configureReplicationServer2()) |
| | | { |
| | | try |
| | | { |
| | |
| | | ERROR_CONFIGURING_REPLICATIONSERVER, ode); |
| | | } |
| | | } |
| | | else |
| | | else if (server2.isReplicationServer()) |
| | | { |
| | | try |
| | | { |
| | |
| | | Set<Integer> usedIds = hmUsedReplicationDomainIds.get(baseDN); |
| | | Set<String> alreadyConfiguredServers = new HashSet<String>(); |
| | | |
| | | try |
| | | if (uData.configureReplicationDomain1() || |
| | | Utils.areDnsEqual(baseDN, ADSContext.getAdministrationSuffixDN())) |
| | | { |
| | | 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); |
| | | 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 |
| | | |
| | | if (uData.configureReplicationDomain2() || |
| | | Utils.areDnsEqual(baseDN, ADSContext.getAdministrationSuffixDN())) |
| | | { |
| | | 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); |
| | | 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 we must initialize the schema do so. |
| | | if (mustInitializeSchema(server1, server2)) |
| | | if (mustInitializeSchema(server1, server2, uData)) |
| | | { |
| | | if (argParser.useSecondServerAsSchemaSource()) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | boolean disableReplicationServer = false; |
| | | if (server.isReplicationServer() && |
| | | (uData.disableReplicationServer() || uData.disableAll())) |
| | | { |
| | | disableReplicationServer = true; |
| | | } |
| | | |
| | | if ((cache != null) && disableReplicationServer) |
| | | { |
| | | String replicationServer = server.getReplicationServerHostPort(); |
| | | // Figure out if this is the last replication server for a given |
| | | // topology (containing a different replica) or there will be only |
| | | // another replication server left (single point of failure). |
| | | Set<SuffixDescriptor> lastRepServer = |
| | | new TreeSet<SuffixDescriptor>(new SuffixComparator()); |
| | | |
| | | Set<SuffixDescriptor> beforeLastRepServer = |
| | | new TreeSet<SuffixDescriptor>(new SuffixComparator()); |
| | | |
| | | for (SuffixDescriptor suffix : cache.getSuffixes()) |
| | | { |
| | | if (Utils.areDnsEqual(suffix.getDN(), |
| | | ADSContext.getAdministrationSuffixDN()) || |
| | | Utils.areDnsEqual(suffix.getDN(), Constants.SCHEMA_DN)) |
| | | { |
| | | // Do not display these suffixes. |
| | | continue; |
| | | } |
| | | |
| | | Set<String> repServers = suffix.getReplicationServers(); |
| | | |
| | | if (repServers.size() <= 2) |
| | | { |
| | | boolean found = false; |
| | | for (String repServer : repServers) |
| | | { |
| | | if (repServer.equalsIgnoreCase(replicationServer)) |
| | | { |
| | | found = true; |
| | | break; |
| | | } |
| | | } |
| | | if (found) |
| | | { |
| | | if (repServers.size() == 2) |
| | | { |
| | | beforeLastRepServer.add(suffix); |
| | | } |
| | | else |
| | | { |
| | | lastRepServer.add(suffix); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Inform the user |
| | | if (beforeLastRepServer.size() > 0) |
| | | { |
| | | LinkedHashSet<String> baseDNs = new LinkedHashSet<String>(); |
| | | for (SuffixDescriptor suffix : beforeLastRepServer) |
| | | { |
| | | if (!Utils.areDnsEqual(suffix.getDN(), |
| | | ADSContext.getAdministrationSuffixDN()) && |
| | | !Utils.areDnsEqual(suffix.getDN(), Constants.SCHEMA_DN)) |
| | | { |
| | | // Do not display these suffixes. |
| | | baseDNs.add(suffix.getDN()); |
| | | } |
| | | } |
| | | if (!baseDNs.isEmpty()) |
| | | { |
| | | String arg = |
| | | Utils.getStringFromCollection(baseDNs, Constants.LINE_SEPARATOR); |
| | | if (!isInteractive()) |
| | | { |
| | | println(INFO_DISABLE_REPLICATION_ONE_POINT_OF_FAILURE.get(arg)); |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | if (!askConfirmation( |
| | | INFO_DISABLE_REPLICATION_ONE_POINT_OF_FAILURE_PROMPT.get(arg), |
| | | false, LOG)) |
| | | { |
| | | throw new ReplicationCliException( |
| | | ERR_REPLICATION_USER_CANCELLED.get(), |
| | | ReplicationCliReturnCode.USER_CANCELLED, null); |
| | | } |
| | | } |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | throw new ReplicationCliException( |
| | | ERR_REPLICATION_USER_CANCELLED.get(), |
| | | ReplicationCliReturnCode.USER_CANCELLED, null); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (lastRepServer.size() > 0) |
| | | { |
| | | // Check that there are other replicas and that this message, really |
| | | // makes sense to be displayed. |
| | | LinkedHashSet<String> suffixArg = new LinkedHashSet<String>(); |
| | | for (SuffixDescriptor suffix : lastRepServer) |
| | | { |
| | | boolean baseDNSpecified = false; |
| | | for (String baseDN : uData.getBaseDNs()) |
| | | { |
| | | if (Utils.areDnsEqual(baseDN, |
| | | ADSContext.getAdministrationSuffixDN()) || |
| | | Utils.areDnsEqual(baseDN, Constants.SCHEMA_DN)) |
| | | { |
| | | // Do not display these suffixes. |
| | | continue; |
| | | } |
| | | if (Utils.areDnsEqual(baseDN, suffix.getDN())) |
| | | { |
| | | baseDNSpecified = true; |
| | | break; |
| | | } |
| | | } |
| | | if (!baseDNSpecified) |
| | | { |
| | | Set<ServerDescriptor> servers = |
| | | new TreeSet<ServerDescriptor>(new ServerComparator()); |
| | | for (ReplicaDescriptor replica : suffix.getReplicas()) |
| | | { |
| | | servers.add(replica.getServer()); |
| | | } |
| | | suffixArg.add(getSuffixDisplay(suffix.getDN(), servers)); |
| | | } |
| | | else |
| | | { |
| | | // Check that there are other replicas. |
| | | if (suffix.getReplicas().size() > 1) |
| | | { |
| | | // If there is just one replica, it is the one in this server. |
| | | Set<ServerDescriptor> servers = |
| | | new TreeSet<ServerDescriptor>(new ServerComparator()); |
| | | for (ReplicaDescriptor replica : suffix.getReplicas()) |
| | | { |
| | | if (!areSameServer(replica.getServer(), server)) |
| | | { |
| | | servers.add(replica.getServer()); |
| | | } |
| | | } |
| | | if (!servers.isEmpty()) |
| | | { |
| | | suffixArg.add(getSuffixDisplay(suffix.getDN(), servers)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!suffixArg.isEmpty()) |
| | | { |
| | | String arg = |
| | | Utils.getStringFromCollection(suffixArg, Constants.LINE_SEPARATOR); |
| | | if (!isInteractive()) |
| | | { |
| | | println(INFO_DISABLE_REPLICATION_DISABLE_IN_REMOTE.get(arg)); |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | if (!askConfirmation( |
| | | INFO_DISABLE_REPLICATION_DISABLE_IN_REMOTE_PROMPT.get(arg), |
| | | false, LOG)) |
| | | { |
| | | throw new ReplicationCliException( |
| | | ERR_REPLICATION_USER_CANCELLED.get(), |
| | | ReplicationCliReturnCode.USER_CANCELLED, null); |
| | | } |
| | | } |
| | | catch (CLIException ce) |
| | | { |
| | | println(ce.getMessageObject()); |
| | | throw new ReplicationCliException( |
| | | ERR_REPLICATION_USER_CANCELLED.get(), |
| | | ReplicationCliReturnCode.USER_CANCELLED, null); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Try to figure out if we must explicitly disable replication on |
| | | * cn=admin data and cn=schema. |
| | |
| | | } |
| | | } |
| | | |
| | | boolean recreateServerKey = false ; |
| | | Object keyId = null ; |
| | | Object certValue = null ; |
| | | if (disableAllBaseDns) |
| | | |
| | | if (disableAllBaseDns && |
| | | (disableReplicationServer || !server.isReplicationServer())) |
| | | { |
| | | // Unregister the server from the ADS |
| | | // Unregister the server from the ADS if no other server has dependencies |
| | | // with it (no replicated base DNs and no replication server). |
| | | server.updateAdsPropertiesWithServerProperties(); |
| | | recreateServerKey = true ; |
| | | keyId = server.getAdsProperties(). |
| | | get(ADSContext.ServerProperty.INSTANCE_KEY_ID); |
| | | certValue = server.getAdsProperties(). |
| | | get(ADSContext.ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE); |
| | | try |
| | | { |
| | | adsCtx.unregisterServer(server.getAdsProperties()); |
| | |
| | | catch (Throwable t) |
| | | { |
| | | } |
| | | recreateServerKey = true ; |
| | | } |
| | | catch (ADSContextException adce) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | if (disableAllBaseDns) |
| | | Set<String> suffixesToDisable = new HashSet<String>(); |
| | | |
| | | if (uData.disableAll()) |
| | | { |
| | | forceDisableSchema = schemaReplicated; |
| | | forceDisableADS = adsReplicated; |
| | | suffixesToDisable.clear(); |
| | | for (ReplicaDescriptor replica : server.getReplicas()) |
| | | { |
| | | if (replica.isReplicated()) |
| | | { |
| | | suffixesToDisable.add(replica.getSuffix().getDN()); |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | suffixesToDisable.addAll(uData.getBaseDNs()); |
| | | |
| | | if (disableAllBaseDns && |
| | | (disableReplicationServer || !server.isReplicationServer())) |
| | | { |
| | | forceDisableSchema = schemaReplicated; |
| | | forceDisableADS = adsReplicated; |
| | | } |
| | | for (String dn : uData.getBaseDNs()) |
| | | { |
| | | if (Utils.areDnsEqual(ADSContext.getAdministrationSuffixDN(), dn)) |
| | |
| | | forceDisableSchema = false; |
| | | } |
| | | } |
| | | } |
| | | Set<String> suffixesToDisable = new HashSet<String>(uData.getBaseDNs()); |
| | | if (forceDisableSchema) |
| | | { |
| | | suffixesToDisable.add(Constants.SCHEMA_DN); |
| | | } |
| | | if (forceDisableADS) |
| | | { |
| | | suffixesToDisable.add(ADSContext.getAdministrationSuffixDN()); |
| | | |
| | | if (forceDisableSchema) |
| | | { |
| | | suffixesToDisable.add(Constants.SCHEMA_DN); |
| | | } |
| | | if (forceDisableADS) |
| | | { |
| | | suffixesToDisable.add(ADSContext.getAdministrationSuffixDN()); |
| | | } |
| | | } |
| | | |
| | | String replicationServerHostPort = server.getReplicationServerHostPort(); |
| | | String replicationServerHostPort = null; |
| | | if (server.isReplicationServer()) |
| | | { |
| | | replicationServerHostPort = server.getReplicationServerHostPort(); |
| | | } |
| | | boolean replicationServerDisabled = false; |
| | | |
| | | for (String baseDN : suffixesToDisable) |
| | | { |
| | | try |
| | |
| | | { |
| | | Set<ServerDescriptor> serversToUpdate = |
| | | new LinkedHashSet<ServerDescriptor>(); |
| | | for (String baseDN : suffixesToDisable) |
| | | Set<String> baseDNsToUpdate = new HashSet<String>(suffixesToDisable); |
| | | for (String baseDN : baseDNsToUpdate) |
| | | { |
| | | SuffixDescriptor suffix = getSuffix(baseDN, cache, server); |
| | | if (suffix != null) |
| | |
| | | } |
| | | } |
| | | } |
| | | if (disableReplicationServer) |
| | | { |
| | | // Find references in all servers. |
| | | Set<SuffixDescriptor> suffixes = cache.getSuffixes(); |
| | | for (SuffixDescriptor suffix : suffixes) |
| | | { |
| | | boolean found = false; |
| | | for (String repServer : suffix.getReplicationServers()) |
| | | { |
| | | found = repServer.equalsIgnoreCase(replicationServerHostPort); |
| | | if (found) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | if (found) |
| | | { |
| | | baseDNsToUpdate.add(suffix.getDN()); |
| | | 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, |
| | | suffixesToDisable, disableAllBaseDns, getPreferredConnections(ctx)); |
| | | baseDNsToUpdate, disableReplicationServer, |
| | | getPreferredConnections(ctx)); |
| | | } |
| | | |
| | | if (disableAllBaseDns) |
| | | if (disableReplicationServer) |
| | | { |
| | | // Disable replication server |
| | | disableReplicationServer(ctx); |
| | | replicationServerDisabled = true; |
| | | // Wait to be sure that changes are taken into account and reset the |
| | | // contents of the ADS. |
| | | try |
| | |
| | | catch (Throwable t) |
| | | { |
| | | } |
| | | } |
| | | else if (disableReplicationServer) |
| | | { |
| | | for (ServerDescriptor s: serversToUpdate) |
| | | { |
| | | try |
| | |
| | | } |
| | | catch (ADSContextException adce) |
| | | { |
| | | LOG.log(Level.INFO, "Error unregistering server: "+ |
| | | LOG.log(Level.WARNING, "Error unregistering server: "+ |
| | | s.getAdsProperties(), adce); |
| | | println(); |
| | | println( |
| | |
| | | } |
| | | } |
| | | } |
| | | if (recreateServerKey) |
| | | if (disableReplicationServer && !replicationServerDisabled) |
| | | { |
| | | Map<ServerProperty, Object> serverProperties = |
| | | new HashMap<ServerProperty, Object>(); |
| | | serverProperties.put(ServerProperty.INSTANCE_KEY_ID, keyId); |
| | | serverProperties.put(ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE, |
| | | certValue); |
| | | LdapName ldapName = null ; |
| | | ADSContextHelper helper = new ADSContextHelper(); |
| | | // This can happen if we could not retrieve the TopologyCache |
| | | disableReplicationServer(ctx); |
| | | replicationServerDisabled = true; |
| | | } |
| | | |
| | | if (uData.disableAll()) |
| | | { |
| | | try |
| | | { |
| | | helper.registerInstanceKeyCertificate( |
| | | adsCtx.getDirContext(),serverProperties,ldapName); |
| | | // Delete all contents from ADSContext. |
| | | printProgress(formatter.getFormattedWithPoints( |
| | | INFO_REPLICATION_DISABLE_ADS_CONTENTS.get())); |
| | | adsCtx.removeAdminData(); |
| | | String adminBackendName = null; |
| | | for (ReplicaDescriptor replica : server.getReplicas()) |
| | | { |
| | | if (Utils.areDnsEqual(ADSContext.getAdministrationSuffixDN(), |
| | | replica.getSuffix().getDN())) |
| | | { |
| | | adminBackendName = replica.getBackendName(); |
| | | break; |
| | | } |
| | | } |
| | | adsCtx.createAdminData(adminBackendName); |
| | | printProgress(formatter.getFormattedDone()); |
| | | } |
| | | catch (ADSContextException e) |
| | | catch (ADSContextException adce) |
| | | { |
| | | LOG.log(Level.SEVERE, "Error resetting contents of cn=admin data: "+ |
| | | adce, adce); |
| | | println(); |
| | | println( |
| | | ERR_REPLICATION_UPDATING_ADS.get(adce.getMessage())); |
| | | println(); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | |
| | | new LinkedList<Set<ReplicaDescriptor>>(); |
| | | |
| | | boolean oneReplicated = false; |
| | | |
| | | boolean displayAll = userBaseDNs.isEmpty(); |
| | | for (SuffixDescriptor suffix : cache.getSuffixes()) |
| | | { |
| | | String dn = suffix.getDN(); |
| | | |
| | | // If no base DNs where specified display all the base DNs but the schema |
| | | // and cn=admin data. |
| | | boolean found = userBaseDNs.isEmpty() && |
| | | boolean found = displayAll && |
| | | !Utils.areDnsEqual(dn, ADSContext.getAdministrationSuffixDN()) && |
| | | !Utils.areDnsEqual(dn, Constants.SCHEMA_DN) && |
| | | !Utils.areDnsEqual(dn, Constants.REPLICATION_CHANGES_DN); |
| | |
| | | } |
| | | } |
| | | |
| | | if (replicaLists.isEmpty()) |
| | | if (!oneReplicated) |
| | | { |
| | | printProgress(INFO_REPLICATION_STATUS_NO_BASEDNS.get()); |
| | | printlnProgress(); |
| | | if (displayAll) |
| | | { |
| | | // Maybe there are some replication server configured... |
| | | SortedSet<ServerDescriptor> rServers = |
| | | new TreeSet<ServerDescriptor>(new ReplicationServerComparator()); |
| | | for (ServerDescriptor server : cache.getServers()) |
| | | { |
| | | if (server.isReplicationServer()) |
| | | { |
| | | rServers.add(server); |
| | | } |
| | | } |
| | | if (!rServers.isEmpty()) |
| | | { |
| | | displayStatus(rServers, uData.isScriptFriendly(), |
| | | getPreferredConnections(ctx)); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | printProgress(INFO_REPLICATION_STATUS_NO_BASEDNS.get()); |
| | | printlnProgress(); |
| | | } |
| | | } |
| | | else |
| | | |
| | | if (!replicaLists.isEmpty()) |
| | | { |
| | | LinkedList<Set<ReplicaDescriptor>> orderedReplicaLists = |
| | | new LinkedList<Set<ReplicaDescriptor>>(); |
| | | for (Set<ReplicaDescriptor> replicas1 : replicaLists) |
| | | for (Set<ReplicaDescriptor> replicas : replicaLists) |
| | | { |
| | | String dn1 = replicas1.iterator().next().getSuffix().getDN(); |
| | | String dn1 = replicas.iterator().next().getSuffix().getDN(); |
| | | boolean inserted = false; |
| | | for (int i=0; i<orderedReplicaLists.size() && !inserted; i++) |
| | | { |
| | |
| | | orderedReplicaLists.get(i).iterator().next().getSuffix().getDN(); |
| | | if (dn1.compareTo(dn2) < 0) |
| | | { |
| | | orderedReplicaLists.add(i, replicas1); |
| | | orderedReplicaLists.add(i, replicas); |
| | | inserted = true; |
| | | } |
| | | } |
| | | if (!inserted) |
| | | { |
| | | orderedReplicaLists.add(replicas1); |
| | | orderedReplicaLists.add(replicas); |
| | | } |
| | | } |
| | | Set<ReplicaDescriptor> replicasWithNoReplicationServer = |
| | | new HashSet<ReplicaDescriptor>(); |
| | | Set<ServerDescriptor> serversWithNoReplica = |
| | | new HashSet<ServerDescriptor>(); |
| | | for (Set<ReplicaDescriptor> replicas : orderedReplicaLists) |
| | | { |
| | | printlnProgress(); |
| | | displayStatus(replicas, uData.isScriptFriendly(), |
| | | getPreferredConnections(ctx)); |
| | | getPreferredConnections(ctx), cache.getServers(), |
| | | replicasWithNoReplicationServer, serversWithNoReplica); |
| | | } |
| | | if (oneReplicated && !uData.isScriptFriendly()) |
| | | { |
| | | printlnProgress(); |
| | | printProgress(INFO_REPLICATION_STATUS_REPLICATED_LEGEND.get()); |
| | | if (!replicasWithNoReplicationServer.isEmpty()) |
| | | { |
| | | printlnProgress(); |
| | | printProgress( |
| | | INFO_REPLICATION_STATUS_NOT_A_REPLICATION_SERVER_LEGEND.get()); |
| | | } |
| | | if (!replicasWithNoReplicationServer.isEmpty()) |
| | | { |
| | | printlnProgress(); |
| | | printProgress( |
| | | INFO_REPLICATION_STATUS_NOT_A_REPLICATION_DOMAIN_LEGEND.get()); |
| | | } |
| | | printlnProgress(); |
| | | } |
| | | } |
| | |
| | | * Displays the replication status of the replicas provided. The code assumes |
| | | * that all the replicas have the same baseDN and that if they are replicated |
| | | * all the replicas are replicated with each other. |
| | | * Note: the code assumes that all the objects come from the same read of the |
| | | * topology cache. So comparisons in terms of pointers can be made. |
| | | * @param replicas the list of replicas that we are trying to display. |
| | | * @param cnx the preferred connections used to connect to the server. |
| | | * @param scriptFriendly wheter to display it on script-friendly mode or not. |
| | | * @param servers all the servers configured in the topology. |
| | | * @param replicasWithNoReplicationServer the set of replicas that will be |
| | | * updated with all the replicas that have no replication server. |
| | | * @param serversWithNoReplica the set of servers that will be updated with |
| | | * all the servers that act as replication server in the topology but have |
| | | * no replica. |
| | | */ |
| | | private void displayStatus(Set<ReplicaDescriptor> replicas, |
| | | boolean scriptFriendly, LinkedHashSet<PreferredConnection> cnx) |
| | | boolean scriptFriendly, LinkedHashSet<PreferredConnection> cnx, |
| | | Set<ServerDescriptor> servers, |
| | | Set<ReplicaDescriptor> replicasWithNoReplicationServer, |
| | | Set<ServerDescriptor> serversWithNoReplica) |
| | | { |
| | | |
| | | boolean isReplicated = false; |
| | | Set<ReplicaDescriptor> orderedReplicas = |
| | | new LinkedHashSet<ReplicaDescriptor>(); |
| | | Set<String> hostPorts = new TreeSet<String>(); |
| | | Set<ServerDescriptor> notAddedReplicationServers = |
| | | new TreeSet<ServerDescriptor>(new ReplicationServerComparator()); |
| | | for (ReplicaDescriptor replica : replicas) |
| | | { |
| | | if (replica.isReplicated()) |
| | |
| | | } |
| | | } |
| | | } |
| | | for (ServerDescriptor server : servers) |
| | | { |
| | | if (server.isReplicationServer()) |
| | | { |
| | | boolean isDomain = false; |
| | | boolean isRepServer = false; |
| | | String replicationServer = server.getReplicationServerHostPort(); |
| | | for (ReplicaDescriptor replica : replicas) |
| | | { |
| | | if (!isRepServer) |
| | | { |
| | | Set<String> repServers = replica.getReplicationServers(); |
| | | for (String repServer : repServers) |
| | | { |
| | | if (replicationServer.equalsIgnoreCase(repServer)) |
| | | { |
| | | isRepServer = true; |
| | | } |
| | | } |
| | | } |
| | | if (replica.getServer() == server) |
| | | { |
| | | isDomain = true; |
| | | } |
| | | if (isDomain && isRepServer) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | if (!isDomain && isRepServer) |
| | | { |
| | | notAddedReplicationServers.add(server); |
| | | } |
| | | } |
| | | } |
| | | final int SERVERPORT = 0; |
| | | final int NUMBER_ENTRIES = 1; |
| | | final int MISSING_CHANGES = 2; |
| | |
| | | }; |
| | | } |
| | | } |
| | | Message[][] values = new Message[orderedReplicas.size()][headers.length]; |
| | | Message[][] values = new Message[ |
| | | notAddedReplicationServers.size() +orderedReplicas.size()][headers.length]; |
| | | |
| | | int i = 0; |
| | | |
| | | for (ServerDescriptor server : notAddedReplicationServers) |
| | | { |
| | | serversWithNoReplica.add(server); |
| | | Message v; |
| | | for (int j=0; j<headers.length; j++) |
| | | { |
| | | switch (j) |
| | | { |
| | | case SERVERPORT: |
| | | v = Message.raw(getHostPort(server, cnx)); |
| | | break; |
| | | case NUMBER_ENTRIES: |
| | | if (scriptFriendly) |
| | | { |
| | | v = INFO_REPLICATION_STATUS_NOT_A_REPLICATION_DOMAIN_LONG.get(); |
| | | } |
| | | else |
| | | { |
| | | v = INFO_REPLICATION_STATUS_NOT_A_REPLICATION_DOMAIN_SHORT.get(); |
| | | } |
| | | break; |
| | | case MISSING_CHANGES: |
| | | v = INFO_NOT_APPLICABLE_LABEL.get(); |
| | | break; |
| | | case AGE_OF_OLDEST_MISSING_CHANGE: |
| | | v = INFO_NOT_APPLICABLE_LABEL.get(); |
| | | break; |
| | | case REPLICATION_PORT: |
| | | int replicationPort = server.getReplicationServerPort(); |
| | | if (replicationPort >= 0) |
| | | { |
| | | v = Message.raw(String.valueOf(replicationPort)); |
| | | } |
| | | else |
| | | { |
| | | v = INFO_NOT_AVAILABLE_SHORT_LABEL.get(); |
| | | } |
| | | break; |
| | | case SECURE: |
| | | if (server.isReplicationSecure()) |
| | | { |
| | | v = INFO_REPLICATION_STATUS_SECURITY_ENABLED.get(); |
| | | } |
| | | else |
| | | { |
| | | v = INFO_REPLICATION_STATUS_SECURITY_DISABLED.get(); |
| | | } |
| | | break; |
| | | default: |
| | | throw new IllegalStateException("Unknown index: "+j); |
| | | } |
| | | values[i][j] = v; |
| | | } |
| | | i++; |
| | | } |
| | | |
| | | for (ReplicaDescriptor replica : orderedReplicas) |
| | | { |
| | | Message v; |
| | |
| | | break; |
| | | case REPLICATION_PORT: |
| | | int replicationPort = replica.getServer().getReplicationServerPort(); |
| | | if (replicationPort >= 0) |
| | | if (!replica.getServer().isReplicationServer()) |
| | | { |
| | | if (scriptFriendly) |
| | | { |
| | | v = INFO_REPLICATION_STATUS_NOT_A_REPLICATION_SERVER_LONG.get(); |
| | | } |
| | | else |
| | | { |
| | | v = INFO_REPLICATION_STATUS_NOT_A_REPLICATION_SERVER_SHORT.get(); |
| | | } |
| | | replicasWithNoReplicationServer.add(replica); |
| | | } |
| | | else if (replicationPort >= 0) |
| | | { |
| | | v = Message.raw(String.valueOf(replicationPort)); |
| | | } |
| | |
| | | } |
| | | break; |
| | | case SECURE: |
| | | if (replica.getServer().isReplicationSecure()) |
| | | if (!replica.getServer().isReplicationServer()) |
| | | { |
| | | v = INFO_NOT_APPLICABLE_LABEL.get(); |
| | | } |
| | | else if (replica.getServer().isReplicationSecure()) |
| | | { |
| | | v = INFO_REPLICATION_STATUS_SECURITY_ENABLED.get(); |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * Displays the replication status of the replication servers provided. The |
| | | * code assumes that all the servers have a replication server and that there |
| | | * are associated with no replication domain. |
| | | * @param servers the servers |
| | | * @param cnx the preferred connections used to connect to the server. |
| | | * @param scriptFriendly wheter to display it on script-friendly mode or not. |
| | | */ |
| | | private void displayStatus(Set<ServerDescriptor> servers, |
| | | boolean scriptFriendly, LinkedHashSet<PreferredConnection> cnx) |
| | | { |
| | | final int SERVERPORT = 0; |
| | | final int REPLICATION_PORT = 1; |
| | | final int SECURE = 2; |
| | | Message[] headers; |
| | | if (scriptFriendly) |
| | | { |
| | | headers = new Message[] { |
| | | INFO_REPLICATION_STATUS_LABEL_SERVERPORT.get(), |
| | | INFO_REPLICATION_STATUS_LABEL_REPLICATION_PORT.get(), |
| | | INFO_REPLICATION_STATUS_LABEL_SECURE.get() |
| | | }; |
| | | } |
| | | else |
| | | { |
| | | headers = new Message[] { |
| | | INFO_REPLICATION_STATUS_HEADER_SERVERPORT.get(), |
| | | INFO_REPLICATION_STATUS_HEADER_REPLICATION_PORT.get(), |
| | | INFO_REPLICATION_STATUS_HEADER_SECURE.get() |
| | | }; |
| | | } |
| | | Message[][] values = new Message[servers.size()][headers.length]; |
| | | |
| | | int i = 0; |
| | | |
| | | for (ServerDescriptor server : servers) |
| | | { |
| | | Message v; |
| | | for (int j=0; j<headers.length; j++) |
| | | { |
| | | switch (j) |
| | | { |
| | | case SERVERPORT: |
| | | v = Message.raw(getHostPort(server, cnx)); |
| | | break; |
| | | case REPLICATION_PORT: |
| | | int replicationPort = server.getReplicationServerPort(); |
| | | if (replicationPort >= 0) |
| | | { |
| | | v = Message.raw(String.valueOf(replicationPort)); |
| | | } |
| | | else |
| | | { |
| | | v = INFO_NOT_AVAILABLE_SHORT_LABEL.get(); |
| | | } |
| | | break; |
| | | case SECURE: |
| | | if (server.isReplicationSecure()) |
| | | { |
| | | v = INFO_REPLICATION_STATUS_SECURITY_ENABLED.get(); |
| | | } |
| | | else |
| | | { |
| | | v = INFO_REPLICATION_STATUS_SECURITY_DISABLED.get(); |
| | | } |
| | | break; |
| | | default: |
| | | throw new IllegalStateException("Unknown index: "+j); |
| | | } |
| | | values[i][j] = v; |
| | | } |
| | | i++; |
| | | } |
| | | |
| | | if (scriptFriendly) |
| | | { |
| | | printProgress( |
| | | INFO_REPLICATION_STATUS_INDEPENDENT_REPLICATION_SERVERS.get()); |
| | | printlnProgress(); |
| | | |
| | | for (i=0; i<values.length; i++) |
| | | { |
| | | printProgress(Message.raw("-")); |
| | | printlnProgress(); |
| | | for (int j=0; j<values[i].length; j++) |
| | | { |
| | | printProgress(Message.raw(headers[j]+" "+values[i][j])); |
| | | printlnProgress(); |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Message msg = |
| | | INFO_REPLICATION_STATUS_INDEPENDENT_REPLICATION_SERVERS.get(); |
| | | printProgressMessageNoWrap(msg); |
| | | printlnProgress(); |
| | | int length = msg.length(); |
| | | StringBuffer buf = new StringBuffer(); |
| | | for (i=0; i<length; i++) |
| | | { |
| | | buf.append("="); |
| | | } |
| | | printProgressMessageNoWrap(Message.raw(buf.toString())); |
| | | printlnProgress(); |
| | | |
| | | TableBuilder table = new TableBuilder(); |
| | | for (i=0; i< headers.length; i++) |
| | | { |
| | | table.appendHeading(headers[i]); |
| | | } |
| | | for (i=0; i<values.length; i++) |
| | | { |
| | | table.startRow(); |
| | | for (int j=0; j<headers.length; j++) |
| | | { |
| | | table.appendCell(values[i][j]); |
| | | } |
| | | } |
| | | TextTablePrinter printer = new TextTablePrinter(getOutputStream()); |
| | | printer.setColumnSeparator(ToolConstants.LIST_TABLE_SEPARATOR); |
| | | table.print(printer); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | InitialLdapContext ctx = null; |
| | | String lastBaseDN = null; |
| | | String hostPort = null; |
| | | |
| | | try |
| | | { |
| | | ctx = loader.createContext(); |
| | |
| | | MessageBuilder mb = new MessageBuilder(); |
| | | mb.append(rce.getMessageObject()); |
| | | File logFile = QuickSetupLog.getLogFile(); |
| | | if (logFile != null) |
| | | if ((logFile != null) && |
| | | (rce.getErrorCode() != ReplicationCliReturnCode.USER_CANCELLED)) |
| | | { |
| | | mb.append(Constants.LINE_SEPARATOR); |
| | | mb.append(INFO_GENERAL_SEE_FOR_DETAILS.get(logFile.getPath())); |
| | |
| | | } |
| | | |
| | | private boolean mustInitializeSchema(ServerDescriptor server1, |
| | | ServerDescriptor server2) |
| | | ServerDescriptor server2, EnableReplicationUserData uData) |
| | | { |
| | | boolean mustInitializeSchema = false; |
| | | if (!argParser.noSchemaReplication()) |
| | |
| | | mustInitializeSchema = true; |
| | | } |
| | | } |
| | | if (mustInitializeSchema) |
| | | { |
| | | // Check that both will contain replication data |
| | | mustInitializeSchema = uData.configureReplicationDomain1() && |
| | | uData.configureReplicationDomain2(); |
| | | } |
| | | return mustInitializeSchema; |
| | | } |
| | | |
| | |
| | | private boolean disableAllBaseDns(InitialLdapContext ctx, |
| | | DisableReplicationUserData uData) |
| | | { |
| | | if (uData.disableAll()) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | boolean returnValue = true; |
| | | Collection<ReplicaDescriptor> replicas = getReplicas(ctx); |
| | | Set<String> replicatedSuffixes = new HashSet<String>(); |
| | |
| | | boolean found = false; |
| | | for (String dn2 : uData.getBaseDNs()) |
| | | { |
| | | found = Utils.areDnsEqual(dn1, dn2); |
| | | break; |
| | | if (Utils.areDnsEqual(dn1, dn2)) |
| | | { |
| | | found = true; |
| | | break; |
| | | } |
| | | } |
| | | if (!found) |
| | | { |
| | | returnValue = false; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | |
| | | break; |
| | | } |
| | | } |
| | | // This is required when both the bindDN and the admin UID are provided |
| | | // in the command-line. |
| | | boolean forceAddBindDN1 = false; |
| | | boolean forceAddBindPwdFile1 = false; |
| | | if (useAdminUID) |
| | | { |
| | | String bindDN1 = uData.getBindDn1(); |
| | | String adminUID = uData.getAdminUid(); |
| | | if (bindDN1 != null && adminUID != null) |
| | | { |
| | | if (!Utils.areDnsEqual(ADSContext.getAdministratorDN(adminUID), |
| | | bindDN1)) |
| | | { |
| | | forceAddBindDN1 = true; |
| | | |
| | | for (Argument arg : firstServerCommandBuilder.getArguments()) |
| | | { |
| | | if (arg.getLongIdentifier().equals(OPTION_LONG_BINDPWD_FILE)) |
| | | { |
| | | forceAddBindPwdFile1 = true; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | for (Argument arg : firstServerCommandBuilder.getArguments()) |
| | | { |
| | | if (arg.getLongIdentifier().equals(OPTION_LONG_HOST)) |
| | |
| | | INFO_DESCRIPTION_ENABLE_REPLICATION_SERVER_PORT1.get()); |
| | | port.addValue(String.valueOf(uData.getPort1())); |
| | | commandBuilder.addArgument(port); |
| | | |
| | | if (forceAddBindDN1) |
| | | { |
| | | StringArgument bindDN = new StringArgument("bindDN1", |
| | | OPTION_SHORT_BINDDN, |
| | | "bindDN1", false, false, true, INFO_BINDDN_PLACEHOLDER.get(), |
| | | "cn=Directory Manager", null, |
| | | INFO_DESCRIPTION_ENABLE_REPLICATION_BINDDN1.get()); |
| | | bindDN.addValue(uData.getBindDn1()); |
| | | commandBuilder.addArgument(bindDN); |
| | | if (forceAddBindPwdFile1) |
| | | { |
| | | FileBasedArgument bindPasswordFileArg = new FileBasedArgument( |
| | | "bindPasswordFile1", |
| | | null, "bindPasswordFile1", false, false, |
| | | INFO_BINDPWD_FILE_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORDFILE1.get()); |
| | | bindPasswordFileArg.getNameToValueMap().put("{password file}", |
| | | "{password file}"); |
| | | commandBuilder.addArgument(bindPasswordFileArg); |
| | | } |
| | | else |
| | | { |
| | | StringArgument bindPasswordArg = new StringArgument( |
| | | "bindPassword1", |
| | | null, "bindPassword1", false, false, true, |
| | | INFO_BINDPWD_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORD1.get()); |
| | | bindPasswordArg.addValue(arg.getValue()); |
| | | commandBuilder.addObfuscatedArgument(bindPasswordArg); |
| | | } |
| | | } |
| | | } |
| | | else if (arg.getLongIdentifier().equals(OPTION_LONG_BINDDN)) |
| | | { |
| | |
| | | break; |
| | | } |
| | | } |
| | | // This is required when both the bindDN and the admin UID are provided |
| | | // in the command-line. |
| | | boolean forceAddBindDN2 = false; |
| | | boolean forceAddBindPwdFile2 = false; |
| | | if (useAdminUID) |
| | | { |
| | | String bindDN2 = uData.getBindDn2(); |
| | | String adminUID = uData.getAdminUid(); |
| | | if (bindDN2 != null && adminUID != null) |
| | | { |
| | | if (!Utils.areDnsEqual(ADSContext.getAdministratorDN(adminUID), |
| | | bindDN2)) |
| | | { |
| | | forceAddBindDN2 = true; |
| | | |
| | | for (Argument arg : interactionBuilder.getArguments()) |
| | | { |
| | | if (arg.getLongIdentifier().equals(OPTION_LONG_BINDPWD_FILE)) |
| | | { |
| | | forceAddBindPwdFile2 = true; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | ArrayList<Argument> argsToAnalyze = new ArrayList<Argument>(); |
| | | for (Argument arg : interactionBuilder.getArguments()) |
| | | { |
| | |
| | | INFO_DESCRIPTION_ENABLE_REPLICATION_SERVER_PORT2.get()); |
| | | port.addValue(String.valueOf(uData.getPort2())); |
| | | commandBuilder.addArgument(port); |
| | | |
| | | if (forceAddBindDN2) |
| | | { |
| | | StringArgument bindDN = new StringArgument("bindDN2", |
| | | OPTION_SHORT_BINDDN, |
| | | "bindDN2", false, false, true, INFO_BINDDN_PLACEHOLDER.get(), |
| | | "cn=Directory Manager", null, |
| | | INFO_DESCRIPTION_ENABLE_REPLICATION_BINDDN2.get()); |
| | | bindDN.addValue(uData.getBindDn2()); |
| | | commandBuilder.addArgument(bindDN); |
| | | if (forceAddBindPwdFile2) |
| | | { |
| | | FileBasedArgument bindPasswordFileArg = new FileBasedArgument( |
| | | "bindPasswordFile2", |
| | | null, "bindPasswordFile2", false, false, |
| | | INFO_BINDPWD_FILE_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORDFILE2.get()); |
| | | bindPasswordFileArg.getNameToValueMap().put("{password file}", |
| | | "{password file}"); |
| | | commandBuilder.addArgument(bindPasswordFileArg); |
| | | } |
| | | else |
| | | { |
| | | StringArgument bindPasswordArg = new StringArgument( |
| | | "bindPassword2", |
| | | null, "bindPassword2", false, false, true, |
| | | INFO_BINDPWD_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORD2.get()); |
| | | bindPasswordArg.addValue(arg.getValue()); |
| | | commandBuilder.addObfuscatedArgument(bindPasswordArg); |
| | | } |
| | | } |
| | | } |
| | | else if (arg.getLongIdentifier().equals(OPTION_LONG_BINDDN)) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | if (uData.getReplicationPort1() > 0) |
| | | if (uData.configureReplicationServer1() && |
| | | !uData.configureReplicationDomain1()) |
| | | { |
| | | commandBuilder.addArgument(new BooleanArgument( |
| | | argParser.onlyReplicationServer1Arg.getName(), |
| | | argParser.onlyReplicationServer1Arg.getShortIdentifier(), |
| | | argParser.onlyReplicationServer1Arg.getLongIdentifier(), |
| | | INFO_DESCRIPTION_ENABLE_REPLICATION_ONLY_REPLICATION_SERVER1.get())); |
| | | } |
| | | |
| | | if (!uData.configureReplicationServer1() && |
| | | uData.configureReplicationDomain1()) |
| | | { |
| | | commandBuilder.addArgument(new BooleanArgument( |
| | | argParser.noReplicationServer1Arg.getName(), |
| | | argParser.noReplicationServer1Arg.getShortIdentifier(), |
| | | argParser.noReplicationServer1Arg.getLongIdentifier(), |
| | | INFO_DESCRIPTION_ENABLE_REPLICATION_NO_REPLICATION_SERVER1.get())); |
| | | } |
| | | |
| | | if (uData.configureReplicationServer1() && |
| | | uData.getReplicationPort1() > 0) |
| | | { |
| | | IntegerArgument replicationPort1 = new IntegerArgument( |
| | | "replicationPort1", 'r', |
| | |
| | | "secureReplication1", |
| | | INFO_DESCRIPTION_ENABLE_SECURE_REPLICATION1.get())); |
| | | } |
| | | if (uData.getReplicationPort2() > 0) |
| | | |
| | | |
| | | if (uData.configureReplicationServer2() && |
| | | !uData.configureReplicationDomain2()) |
| | | { |
| | | commandBuilder.addArgument(new BooleanArgument( |
| | | argParser.onlyReplicationServer2Arg.getName(), |
| | | argParser.onlyReplicationServer2Arg.getShortIdentifier(), |
| | | argParser.onlyReplicationServer2Arg.getLongIdentifier(), |
| | | INFO_DESCRIPTION_ENABLE_REPLICATION_ONLY_REPLICATION_SERVER2.get())); |
| | | } |
| | | |
| | | if (!uData.configureReplicationServer2() && |
| | | uData.configureReplicationDomain2()) |
| | | { |
| | | commandBuilder.addArgument(new BooleanArgument( |
| | | argParser.noReplicationServer2Arg.getName(), |
| | | argParser.noReplicationServer2Arg.getShortIdentifier(), |
| | | argParser.noReplicationServer2Arg.getLongIdentifier(), |
| | | INFO_DESCRIPTION_ENABLE_REPLICATION_NO_REPLICATION_SERVER2.get())); |
| | | } |
| | | if (uData.configureReplicationServer2() && |
| | | uData.getReplicationPort2() > 0) |
| | | { |
| | | IntegerArgument replicationPort2 = new IntegerArgument( |
| | | "replicationPort2", 'r', |
| | |
| | | "secureReplication2", |
| | | INFO_DESCRIPTION_ENABLE_SECURE_REPLICATION2.get())); |
| | | } |
| | | |
| | | |
| | | if (!uData.replicateSchema()) |
| | | { |
| | | commandBuilder.addArgument(new BooleanArgument( |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void updateAvailableAndReplicatedSuffixesForOneDomain( |
| | | InitialLdapContext ctxDomain, InitialLdapContext ctxOther, |
| | | Collection<String> availableSuffixes, |
| | | Collection<String> alreadyReplicatedSuffixes) |
| | | { |
| | | Collection<ReplicaDescriptor> replicas = getReplicas(ctxDomain); |
| | | int replicationPort = getReplicationPort(ctxOther); |
| | | boolean isReplicationServerConfigured = replicationPort != -1; |
| | | String replicationServer = getReplicationServer( |
| | | ConnectionUtils.getHostName(ctxOther), replicationPort); |
| | | for (ReplicaDescriptor replica : replicas) |
| | | { |
| | | if (!isReplicationServerConfigured) |
| | | { |
| | | if (replica.isReplicated()) |
| | | { |
| | | alreadyReplicatedSuffixes.add(replica.getSuffix().getDN()); |
| | | } |
| | | availableSuffixes.add(replica.getSuffix().getDN()); |
| | | } |
| | | if (!isReplicationServerConfigured) |
| | | { |
| | | availableSuffixes.add(replica.getSuffix().getDN()); |
| | | } |
| | | else |
| | | { |
| | | if (!replica.isReplicated()) |
| | | { |
| | | availableSuffixes.add(replica.getSuffix().getDN()); |
| | | } |
| | | else |
| | | { |
| | | // Check if the replica is already configured with the replication |
| | | // server. |
| | | boolean alreadyReplicated = false; |
| | | Set<String> rServers = replica.getReplicationServers(); |
| | | for (String rServer : rServers) |
| | | { |
| | | if (replicationServer.equalsIgnoreCase(rServer)) |
| | | { |
| | | alreadyReplicated = true; |
| | | } |
| | | } |
| | | if (alreadyReplicated) |
| | | { |
| | | alreadyReplicatedSuffixes.add(replica.getSuffix().getDN()); |
| | | } |
| | | else |
| | | { |
| | | availableSuffixes.add(replica.getSuffix().getDN()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void updateAvailableAndReplicatedSuffixesForNoDomain( |
| | | InitialLdapContext ctx1, InitialLdapContext ctx2, |
| | | Collection<String> availableSuffixes, |
| | | Collection<String> alreadyReplicatedSuffixes) |
| | | { |
| | | int replicationPort1 = getReplicationPort(ctx1); |
| | | boolean isReplicationServer1Configured = replicationPort1 != -1; |
| | | String replicationServer1 = getReplicationServer( |
| | | ConnectionUtils.getHostName(ctx1), replicationPort1); |
| | | |
| | | int replicationPort2 = getReplicationPort(ctx2); |
| | | boolean isReplicationServer2Configured = replicationPort2 != -1; |
| | | String replicationServer2 = getReplicationServer( |
| | | ConnectionUtils.getHostName(ctx2), replicationPort2); |
| | | |
| | | TopologyCache cache1 = null; |
| | | TopologyCache cache2 = null; |
| | | |
| | | if (isReplicationServer1Configured) |
| | | { |
| | | try |
| | | { |
| | | ADSContext adsContext = new ADSContext(ctx1); |
| | | if (adsContext.hasAdminData()) |
| | | { |
| | | cache1 = new TopologyCache(adsContext, getTrustManager()); |
| | | } |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | LOG.log(Level.WARNING, "Error loading topology cache in "+ |
| | | ConnectionUtils.getLdapUrl(ctx1)+": "+t, t); |
| | | } |
| | | } |
| | | |
| | | if (isReplicationServer2Configured) |
| | | { |
| | | try |
| | | { |
| | | ADSContext adsContext = new ADSContext(ctx2); |
| | | if (adsContext.hasAdminData()) |
| | | { |
| | | cache2 = new TopologyCache(adsContext, getTrustManager()); |
| | | } |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | LOG.log(Level.WARNING, "Error loading topology cache in "+ |
| | | ConnectionUtils.getLdapUrl(ctx2)+": "+t, t); |
| | | } |
| | | } |
| | | |
| | | if (cache1 != null && cache2 != null) |
| | | { |
| | | // Check common suffixes |
| | | Set<String> dns1 = new HashSet<String>(); |
| | | Set<String> dns2 = new HashSet<String>(); |
| | | |
| | | Set<SuffixDescriptor> suffixes = cache1.getSuffixes(); |
| | | for (SuffixDescriptor suffix : suffixes) |
| | | { |
| | | for (String rServer : suffix.getReplicationServers()) |
| | | { |
| | | if (rServer.equalsIgnoreCase(replicationServer1)) |
| | | { |
| | | dns1.add(suffix.getDN()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | suffixes = cache2.getSuffixes(); |
| | | for (SuffixDescriptor suffix : suffixes) |
| | | { |
| | | for (String rServer : suffix.getReplicationServers()) |
| | | { |
| | | if (rServer.equalsIgnoreCase(replicationServer2)) |
| | | { |
| | | dns2.add(suffix.getDN()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | availableSuffixes.addAll(dns1); |
| | | availableSuffixes.removeAll(dns2); |
| | | |
| | | alreadyReplicatedSuffixes.addAll(dns1); |
| | | alreadyReplicatedSuffixes.retainAll(dns2); |
| | | } |
| | | else if (cache1 != null) |
| | | { |
| | | Set<SuffixDescriptor> suffixes = cache1.getSuffixes(); |
| | | for (SuffixDescriptor suffix : suffixes) |
| | | { |
| | | for (String rServer : suffix.getReplicationServers()) |
| | | { |
| | | if (rServer.equalsIgnoreCase(replicationServer1)) |
| | | { |
| | | availableSuffixes.add(suffix.getDN()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else if (cache2 != null) |
| | | { |
| | | Set<SuffixDescriptor> suffixes = cache2.getSuffixes(); |
| | | for (SuffixDescriptor suffix : suffixes) |
| | | { |
| | | for (String rServer : suffix.getReplicationServers()) |
| | | { |
| | | if (rServer.equalsIgnoreCase(replicationServer2)) |
| | | { |
| | | availableSuffixes.add(suffix.getDN()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void updateBaseDnsWithNotEnoughReplicationServer(ADSContext adsCtx1, |
| | | ADSContext adsCtx2, EnableReplicationUserData uData, |
| | | Set<String> baseDNsWithNoReplicationServer, |
| | | Set<String> baseDNsWithOneReplicationServer) |
| | | { |
| | | if (uData.configureReplicationServer1() && |
| | | uData.configureReplicationServer2()) |
| | | { |
| | | return; |
| | | } |
| | | Set<SuffixDescriptor> suffixes = new HashSet<SuffixDescriptor>(); |
| | | try |
| | | { |
| | | if (adsCtx1.hasAdminData()) |
| | | { |
| | | TopologyCache cache = new TopologyCache(adsCtx1, |
| | | getTrustManager()); |
| | | cache.getFilter().setSearchMonitoringInformation(false); |
| | | for (String dn : uData.getBaseDNs()) |
| | | { |
| | | cache.getFilter().addBaseDNToSearch(dn); |
| | | } |
| | | cache.reloadTopology(); |
| | | suffixes.addAll(cache.getSuffixes()); |
| | | } |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | LOG.log(Level.WARNING, "Error loading topology cache from "+ |
| | | ConnectionUtils.getHostPort(adsCtx1.getDirContext())+": "+t, t); |
| | | } |
| | | |
| | | try |
| | | { |
| | | if (adsCtx2.hasAdminData()) |
| | | { |
| | | TopologyCache cache = new TopologyCache(adsCtx2, |
| | | getTrustManager()); |
| | | cache.getFilter().setSearchMonitoringInformation(false); |
| | | cache.reloadTopology(); |
| | | for (String dn : uData.getBaseDNs()) |
| | | { |
| | | cache.getFilter().addBaseDNToSearch(dn); |
| | | } |
| | | suffixes.addAll(cache.getSuffixes()); |
| | | } |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | LOG.log(Level.WARNING, "Error loading topology cache from "+ |
| | | ConnectionUtils.getHostPort(adsCtx2.getDirContext())+": "+t, t); |
| | | } |
| | | |
| | | int repPort1 = getReplicationPort(adsCtx1.getDirContext()); |
| | | String repServer1 = getReplicationServer(uData.getHostName1(), repPort1); |
| | | int repPort2 = getReplicationPort(adsCtx2.getDirContext()); |
| | | String repServer2 = getReplicationServer(uData.getHostName2(), repPort2); |
| | | for (String baseDN : uData.getBaseDNs()) |
| | | { |
| | | int nReplicationServers = 0; |
| | | for (SuffixDescriptor suffix : suffixes) |
| | | { |
| | | if (Utils.areDnsEqual(suffix.getDN(), baseDN)) |
| | | { |
| | | Set<String> replicationServers = suffix.getReplicationServers(); |
| | | nReplicationServers += replicationServers.size(); |
| | | for (String repServer : replicationServers) |
| | | { |
| | | if (uData.configureReplicationServer1() && |
| | | repServer.equalsIgnoreCase(repServer1)) |
| | | { |
| | | nReplicationServers --; |
| | | } |
| | | if (uData.configureReplicationServer2() && |
| | | repServer.equalsIgnoreCase(repServer2)) |
| | | { |
| | | nReplicationServers --; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (uData.configureReplicationServer1()) |
| | | { |
| | | nReplicationServers ++; |
| | | } |
| | | if (uData.configureReplicationServer2()) |
| | | { |
| | | nReplicationServers ++; |
| | | } |
| | | if (nReplicationServers == 1) |
| | | { |
| | | baseDNsWithOneReplicationServer.add(baseDN); |
| | | } |
| | | else if (nReplicationServers == 0) |
| | | { |
| | | baseDNsWithNoReplicationServer.add(baseDN); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private String getReplicationServer(String hostName, int replicationPort) |
| | | { |
| | | return hostName.toLowerCase() + ":" + replicationPort; |
| | | } |
| | | |
| | | private String getServerRepresentation(String hostName, int port) |
| | | { |
| | | return hostName.toLowerCase() + ":" + port; |
| | | } |
| | | |
| | | private String getSuffixDisplay(String baseDN, Set<ServerDescriptor> servers) |
| | | { |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append(baseDN); |
| | | for (ServerDescriptor server : servers) |
| | | { |
| | | sb.append(Constants.LINE_SEPARATOR+" "); |
| | | sb.append(server.getHostPort(true)); |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | |
| | | private boolean areSameServer(ServerDescriptor server1, |
| | | ServerDescriptor server2) |
| | | { |
| | | return server1.getId().equals(server2.getId()); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Class used to compare replication servers. |
| | | * |
| | | */ |
| | | class ReplicationServerComparator implements Comparator<ServerDescriptor> |
| | | { |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int compare(ServerDescriptor s1, ServerDescriptor s2) |
| | | { |
| | | int compare = s1.getHostName().compareTo(s2.getHostName()); |
| | | if (compare == 0) |
| | | { |
| | | if (s1.getReplicationServerPort() > s2.getReplicationServerPort()) |
| | | { |
| | | compare = 1; |
| | | } |
| | | else if (s1.getReplicationServerPort() < s2.getReplicationServerPort()) |
| | | { |
| | | compare = -1; |
| | | } |
| | | } |
| | | return compare; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Class used to compare suffixes. |
| | | * |
| | | */ |
| | | class SuffixComparator implements Comparator<SuffixDescriptor> |
| | | { |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int compare(SuffixDescriptor s1, SuffixDescriptor s2) |
| | | { |
| | | return s1.getId().compareTo(s2.getId()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Class used to compare servers. |
| | | * |
| | | */ |
| | | class ServerComparator implements Comparator<ServerDescriptor> |
| | | { |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int compare(ServerDescriptor s1, ServerDescriptor s2) |
| | | { |
| | | return s1.getId().compareTo(s2.getId()); |
| | | } |
| | | } |