mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

jvergara
05.13.2007 18bef688bddb3ed5cef3b7ee54eb278ffe5d56c5
Fix for issue 2422.

Create an initialize-all subcommand that allows to initialize a whole topology by giving a base DN and the connection parameters of the server containing the data that must be used to perform the initialization of the other servers.
1 files added
5 files modified
1150 ■■■■■ changed files
opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/InitializeAllReplicationUserData.java 118 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliArgumentParser.java 146 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java 772 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/StatusReplicationUserData.java 81 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/messages/messages/admin_tool.properties 31 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/PeerNotFoundException.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/InitializeAllReplicationUserData.java
New file
@@ -0,0 +1,118 @@
/*
 * 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
 * iniitalize a complete replication topology.  It is required because when we
 * are in interactive mode the ReplicationCliArgumentParser is not enough.
 *
 */
class InitializeAllReplicationUserData 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;
  }
}
opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliArgumentParser.java
@@ -59,6 +59,7 @@
  private SubCommand enableReplicationSubCmd;
  private SubCommand disableReplicationSubCmd;
  private SubCommand initializeReplicationSubCmd;
  private SubCommand initializeAllReplicationSubCmd;
  private SubCommand statusReplicationSubCmd;
  private BooleanArgument noPromptArg;
@@ -249,6 +250,12 @@
  public static final String INITIALIZE_REPLICATION_SUBCMD_NAME = "initialize";
  /**
   * The text of the initialize all replication subcommand.
   */
  public static final String INITIALIZE_ALL_REPLICATION_SUBCMD_NAME =
    "initialize-all";
  /**
   * The text of the status replication subcommand.
   */
  public static final String STATUS_REPLICATION_SUBCMD_NAME = "status";
@@ -286,6 +293,7 @@
    createEnableReplicationSubCommand();
    createDisableReplicationSubCommand();
    createInitializeReplicationSubCommand();
    createInitializeAllReplicationSubCommand();
    createStatusReplicationSubCommand();
  }
@@ -616,7 +624,8 @@
    initializeReplicationSubCmd = new SubCommand(this,
        INITIALIZE_REPLICATION_SUBCMD_NAME,
        INFO_DESCRIPTION_SUBCMD_INITIALIZE_REPLICATION.get());
        INFO_DESCRIPTION_SUBCMD_INITIALIZE_REPLICATION.get(
            INITIALIZE_ALL_REPLICATION_SUBCMD_NAME));
    Argument[] argsToAdd = {
        hostNameSourceArg, portSourceArg, useSSLSourceArg, useStartTLSSourceArg,
@@ -630,6 +639,28 @@
  }
  /**
   * Creates the initialize all 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 createInitializeAllReplicationSubCommand()
  throws ArgumentException
  {
    initializeAllReplicationSubCmd = new SubCommand(this,
        INITIALIZE_ALL_REPLICATION_SUBCMD_NAME,
        INFO_DESCRIPTION_SUBCMD_INITIALIZE_ALL_REPLICATION.get(
            INITIALIZE_REPLICATION_SUBCMD_NAME));
    Argument[] argsToAdd = { secureArgsList.hostNameArg,
        secureArgsList.portArg, secureArgsList.useSSLArg,
        secureArgsList.useStartTLSArg };
    for (int i=0; i<argsToAdd.length; i++)
    {
      initializeAllReplicationSubCmd.addArgument(argsToAdd[i]);
    }
  }
  /**
   * Creates the status replication subcommand and all the specific options
   * for the subcommand.  Note: this method assumes that
   * initializeGlobalArguments has already been called and that hostNameArg,
@@ -920,6 +951,30 @@
  }
  /**
   * Indicate if the SSL mode is required for the server in the initialize all
   * replication subcommand.
   *
   * @return <CODE>true</CODE> if SSL mode is required for the server in the
   * initialize all replication subcommand and <CODE>false</CODE> otherwise.
   */
  public boolean useSSLToInitializeAll()
  {
    return secureArgsList.useSSLArg.isPresent();
  }
  /**
   * Indicate if the SSL mode is required for the server in the initialize all
   * replication subcommand.
   *
   * @return <CODE>true</CODE> if StartTLS mode is required for the server in
   * the initialize all replication subcommand and <CODE>false</CODE> otherwise.
   */
  public boolean useStartTLSToInitializeAll()
  {
    return secureArgsList.useStartTLSArg.isPresent();
  }
  /**
   * Indicate if the SSL mode is required for the server in the status
   * replication subcommand.
   *
@@ -1246,6 +1301,28 @@
  }
  /**
   * Returns the host name explicitly provided in the initialize all replication
   * subcommand.
   * @return the host name explicitly provided in the initialize all replication
   * subcommand.
   */
  public String getHostNameToInitializeAll()
  {
    return getValue(secureArgsList.hostNameArg);
  }
  /**
   * Returns the host name default value in the initialize all replication
   * subcommand.
   * @return the host name default value in the initialize all replication
   * subcommand.
   */
  public String getDefaultHostNameToInitializeAll()
  {
    return getDefaultValue(secureArgsList.hostNameArg);
  }
  /**
   * Returns the source host name explicitly provided in the initialize
   * replication subcommand.
   * @return the source host name explicitly provided in the initialize
@@ -1356,6 +1433,28 @@
  }
  /**
   * Returns the server port explicitly provided in the initialize all
   * replication subcommand.
   * @return the server port explicitly provided in the initialize all
   * replication subcommand.  Returns -1 if no port was explicitly provided.
   */
  public int getPortToInitializeAll()
  {
    return getValue(secureArgsList.portArg);
  }
  /**
   * Returns the server port default value in the initialize all replication
   * subcommand.
   * @return the server port default value in the initialize all replication
   * subcommand.
   */
  public int getDefaultPortToInitializeAll()
  {
    return getDefaultValue(secureArgsList.portArg);
  }
  /**
   * Returns the server port explicitly provided in the status replication
   * subcommand.
   * @return the server port explicitly provided in the status replication
@@ -1483,6 +1582,10 @@
    {
      validateInitializeReplicationOptions(buf);
    }
    else if (isInitializeAllReplicationSubcommand())
    {
      validateInitializeAllReplicationOptions(buf);
    }
    else
    {
@@ -1526,6 +1629,17 @@
  }
  /**
   * Returns whether the user provided subcommand is the initialize all
   * replication or not.
   * @return <CODE>true</CODE> if the user provided subcommand is the
   * initialize all replication and <CODE>false</CODE> otherwise.
   */
  public boolean isInitializeAllReplicationSubcommand()
  {
    return isSubcommand(INITIALIZE_ALL_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
@@ -1630,6 +1744,36 @@
  }
  /**
   * Checks the initialize all 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 validateInitializeAllReplicationOptions(MessageBuilder buf)
  {
    Argument[][] conflictingPairs =
    {
        {secureArgsList.useStartTLSArg, secureArgsList.useSSLArg}
    };
    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);
      }
    }
  }
  /**
   * Checks the status replication subcommand options and updates the provided
   * MessageBuilder with the errors that were encountered with the subcommand
   * options.
opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java
@@ -31,6 +31,8 @@
import static org.opends.messages.AdminToolMessages.*;
import static org.opends.messages.QuickSetupMessages.*;
import static org.opends.messages.ToolMessages.*;
import static org.opends.quicksetup.util.Utils.getFirstValue;
import static org.opends.quicksetup.util.Utils.getThrowableMsg;
import static org.opends.server.util.ServerConstants.MAX_LINE_WIDTH;
import static org.opends.server.util.StaticUtils.wrapText;
@@ -51,7 +53,16 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import org.opends.admin.ads.ADSContext;
@@ -70,6 +81,7 @@
import org.opends.quicksetup.CliApplicationHelper;
import org.opends.quicksetup.Constants;
import org.opends.quicksetup.QuickSetupLog;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.event.ProgressUpdateEvent;
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.installer.InstallerHelper;
@@ -314,6 +326,10 @@
        {
          returnValue = initializeReplication();
        }
        else if (argParser.isInitializeAllReplicationSubcommand())
        {
          returnValue = initializeAllReplication();
        }
        else if (argParser.isStatusReplicationSubcommand())
        {
          returnValue = statusReplication();
@@ -396,6 +412,36 @@
  }
  /**
   * Based on the data provided in the command-line initialize the contents
   * of the whole replication topology.
   * @return the error code if the operation failed and SUCCESSFUL if it was
   * successful.
   */
  private ReplicationCliReturnCode initializeAllReplication()
  {
    ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP;
    InitializeAllReplicationUserData uData =
      new InitializeAllReplicationUserData();
    if (argParser.isInteractive())
    {
      if (promptIfRequired(uData))
      {
        returnValue = initializeAllReplication(uData);
      }
      else
      {
        returnValue = USER_CANCELLED;
      }
    }
    else
    {
      initializeWithArgParser(uData);
      returnValue = initializeAllReplication(uData);
    }
    return returnValue;
  }
  /**
   * Based on the data provided in the command-line it displays replication
   * status.
   * @return the error code if the operation failed and SUCCESSFUL if it was
@@ -1178,6 +1224,167 @@
  }
  /**
   * Updates the contents of the provided InitializeAllReplicationUserData
   * 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(InitializeAllReplicationUserData uData)
  {
    boolean cancelled = false;
    String adminPwd = argParser.getBindPasswordAdmin();
    String adminUid = argParser.getAdministratorUID();
    String host = argParser.getHostNameToInitializeAll();
    if (host == null)
    {
      host = promptForString(
          INFO_REPLICATION_INITIALIZE_ALL_HOSTNAME_PROMPT.get(),
          argParser.getDefaultHostNameToInitializeAll(), false);
    }
    int port = argParser.getPortToInitializeAll();
    if (port == -1)
    {
      port = promptForPort(
          INFO_REPLICATION_INITIALIZE_ALL_PORT_PROMPT.get(),
          argParser.getDefaultPortToInitializeAll(), false);
    }
    boolean useSSL = argParser.useSSLToInitializeAll();
    boolean useStartTLS = argParser.useStartTLSToInitializeAll();
    if (!useSSL && !useStartTLS)
    {
      useSSL = confirm(INFO_CLI_USESSL_PROMPT.get(), false);
      if (!useSSL)
      {
        useStartTLS =
          confirm(INFO_CLI_USESTARTTLS_PROMPT.get(), false);
      }
    }
    if (adminUid == null)
    {
      adminUid = askForAdministratorUID(argParser.getDefaultAdministratorUID());
    }
    if (adminPwd == null)
    {
      adminPwd = askForAdministratorPwd();
    }
    /*
     * Try to connect to the server.
     */
    InitialLdapContext ctx = 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 = ConnectionUtils.getLDAPUrl(host, port, useSSL);
          if (!promptForCertificateConfirmation(ne, getTrustManager(), usedUrl,
              getTrustManager()))
          {
            cancelled = true;
          }
        }
        else
        {
          printLineBreak();
          printErrorMessage(ERR_ERROR_CONNECTING_TO_SERVER_PROMPT_AGAIN.get(
              host+":"+port, ne.toString()));
          printLineBreak();
          host = promptForString(
                INFO_REPLICATION_INITIALIZE_ALL_HOSTNAME_PROMPT.get(),
                getValue(host, argParser.getDefaultHostNameToInitializeAll()),
                false);
          port = promptForPort(
                INFO_REPLICATION_INITIALIZE_ALL_PORT_PROMPT.get(),
              getValue(port, argParser.getDefaultPortToInitializeAll()), false);
          useSSL = confirm(INFO_CLI_USESSL_PROMPT.get(), useSSL);
          if (!useSSL)
          {
            useStartTLS =
              confirm(INFO_CLI_USESTARTTLS_PROMPT.get(), useStartTLS);
          }
          adminUid = askForAdministratorUID(adminUid);
          adminPwd = askForAdministratorPwd();
        }
      }
    }
    if (!cancelled)
    {
      uData.setHostName(host);
      uData.setPort(port);
      uData.setUseSSL(useSSL);
      uData.setUseStartTLS(useStartTLS);
      uData.setAdminUid(adminUid);
      uData.setAdminPwd(adminPwd);
    }
    if (!cancelled)
    {
      LinkedList<String> suffixes = argParser.getBaseDNs();
      checkSuffixesForInitializeAllReplication(suffixes, ctx, true);
      cancelled = suffixes.isEmpty();
      uData.setBaseDNs(suffixes);
    }
    if (!cancelled)
    {
      // Ask for confirmation to initialize.
      boolean initializeADS = false;
      for (String dn : uData.getBaseDNs())
      {
        if (Utils.areDnsEqual(ADSContext.getAdministrationSuffixDN(), dn))
        {
          initializeADS = true;
        }
      }
      String hostPortSource = ConnectionUtils.getHostPort(ctx);
      if (initializeADS)
      {
        printLineBreak();
        cancelled = !confirm(INFO_REPLICATION_CONFIRM_INITIALIZE_ALL_ADS.get(
            ADSContext.getAdministrationSuffixDN(), hostPortSource));
      }
      else
      {
        printLineBreak();
        cancelled = !confirm(
            INFO_REPLICATION_CONFIRM_INITIALIZE_ALL_GENERIC.get(
                hostPortSource));
      }
    }
    if (ctx != null)
    {
      try
      {
        ctx.close();
      }
      catch (Throwable t)
      {
      }
    }
    return !cancelled;
  }
  /**
   * Updates the contents of the provided StatusReplicationUserData object
   * with the information provided in the command-line.  If some information
   * is missing, ask the user to provide valid data.
@@ -1848,6 +2055,31 @@
    uData.setUseStartTLS(argParser.useStartTLSToDisable());
  }
  /**
   * Initializes the contents of the provided initialize all 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(InitializeAllReplicationUserData 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.getHostNameToInitializeAll(),
        argParser.getDefaultHostNameToInitializeAll());
    uData.setHostName(hostName);
    int port = getValue(argParser.getPortToInitializeAll(),
        argParser.getDefaultPortToInitializeAll());
    uData.setPort(port);
    uData.setUseSSL(argParser.useSSLToInitializeAll());
    uData.setUseStartTLS(argParser.useStartTLSToInitializeAll());
  }
  /**
   * Initializes the contents of the provided status replication user data
@@ -2745,6 +2977,87 @@
  }
  /**
   * Initializes the contents of a whole topology with the contents of the other
   * using the parameters in the provided InitializeAllReplicationUserData.
   * This method does not prompt to the user for information if something is
   * missing.
   * @param uData the InitializeAllReplicationUserData object.
   * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was
   * successful.
   * and the replication could be enabled and an error code otherwise.
   */
  private ReplicationCliReturnCode initializeAllReplication(
      InitializeAllReplicationUserData uData)
  {
    ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP;
    InitialLdapContext ctx = null;
    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)
    {
      LinkedList<String> baseDNs = uData.getBaseDNs();
      checkSuffixesForInitializeAllReplication(baseDNs, ctx, false);
      if (!baseDNs.isEmpty())
      {
        for (String baseDN : baseDNs)
        {
          try
          {
            printProgressLineBreak();
            Message msg = formatter.getFormattedProgress(
                INFO_PROGRESS_INITIALIZING_SUFFIX.get(baseDN,
                    ConnectionUtils.getHostPort(ctx)));
            printProgressMessage(msg);
            printProgressLineBreak();
            initializeAllSuffix(baseDN, ctx, true);
          }
          catch (ReplicationCliException rce)
          {
            printLineBreak();
            printErrorMessage(getCriticalExceptionMessage(rce));
            returnValue = rce.getErrorCode();
            LOG.log(Level.SEVERE, "Complete error stack:", rce);
          }
        }
      }
      else
      {
        returnValue = REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN;
      }
    }
    else
    {
      returnValue = ERROR_CONNECTING;
    }
    if (ctx != null)
    {
      try
      {
        ctx.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
@@ -2899,7 +3212,7 @@
   * 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
   * updated by removing the base DNs that cannot be disabled 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
@@ -3053,6 +3366,165 @@
  }
  /**
   * Checks that replication can actually be initialized 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 initialized 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 initialized.
   */
  private void checkSuffixesForInitializeAllReplication(
      Collection<String> suffixes, InitialLdapContext ctx, boolean interactive)
  {
    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_INITIALIZE_ALL_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)
      {
        printLineBreak();
        printErrorMessage(
            INFO_ALREADY_NOT_REPLICATED_SUFFIXES.get(
                Utils.getStringFromCollection(
                    userProvidedNotReplicatedSuffixes,
                    Constants.LINE_SEPARATOR)));
      }
      suffixes.clear();
    }
    else
    {
      // 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_INITIALIZE_ALL_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())
        {
          boolean noSchemaOrAds = false;
          for (String s: availableSuffixes)
          {
            if (!Utils.areDnsEqual(s, ADSContext.getAdministrationSuffixDN()) &&
                !Utils.areDnsEqual(s, Constants.SCHEMA_DN) &&
                !Utils.areDnsEqual(s, Constants.REPLICATION_CHANGES_DN))
            {
              noSchemaOrAds = true;
            }
          }
          if (!noSchemaOrAds)
          {
            // In interactive mode we do not propose to manage the
            // administration suffix.
            printLineBreak();
            printErrorMessage(
                ERR_NO_SUFFIXES_AVAILABLE_TO_INITIALIZE_ALL_REPLICATION.get());
            break;
          }
          else
          {
            printLineBreak();
            printErrorMessage(ERR_NO_SUFFIXES_SELECTED_TO_INITIALIZE_ALL.get());
            for (String dn : availableSuffixes)
            {
              if (!Utils.areDnsEqual(dn,
                  ADSContext.getAdministrationSuffixDN()) &&
                  !Utils.areDnsEqual(dn, Constants.SCHEMA_DN) &&
                  !Utils.areDnsEqual(dn, Constants.REPLICATION_CHANGES_DN))
              {
                if (confirm(INFO_REPLICATION_INITIALIZE_ALL_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
@@ -4675,8 +5147,7 @@
    int replicationId = -1;
    try
    {
      ServerDescriptor source = ServerDescriptor.createStandalone(
          ctxSource);
      ServerDescriptor source = ServerDescriptor.createStandalone(ctxSource);
      for (ReplicaDescriptor replica : source.getReplicas())
      {
        if (Utils.areDnsEqual(replica.getSuffix().getDN(), baseDN))
@@ -4753,6 +5224,301 @@
    }
  }
  private void initializeAllSuffix(String baseDN, InitialLdapContext ctx,
  boolean displayProgress) throws ReplicationCliException
  {
    int nTries = 5;
    boolean initDone = false;
    while (!initDone)
    {
      try
      {
        initializeAllSuffixTry(baseDN, ctx, displayProgress);
        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--;
    }
  }
  /**
   * 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 baseDN the dn of the suffix.
   * @param displayProgress whether we want to display progress or not.
   * @throws ApplicationException if an unexpected error occurs.
   * @throws PeerNotFoundException if the replication mechanism cannot find
   * a peer.
   */
  public void initializeAllSuffixTry(String baseDN, InitialLdapContext ctx,
      boolean displayProgress)
  throws ApplicationException, PeerNotFoundException
  {
    boolean taskCreated = false;
    int i = 1;
    boolean isOver = false;
    String dn = null;
    String serverDisplay = ConnectionUtils.getHostPort(ctx);
    BasicAttributes attrs = new BasicAttributes();
    Attribute oc = new BasicAttribute("objectclass");
    oc.add("top");
    oc.add("ds-task");
    oc.add("ds-task-initialize-remote-replica");
    attrs.put(oc);
    attrs.put("ds-task-class-name",
        "org.opends.server.tasks.InitializeTargetTask");
    attrs.put("ds-task-initialize-domain-dn", baseDN);
    attrs.put("ds-task-initialize-replica-server-id", "all");
    while (!taskCreated)
    {
      String id = "quicksetup-initialize"+i;
      dn = "ds-task-id="+id+",cn=Scheduled Tasks,cn=Tasks";
      attrs.put("ds-task-id", id);
      try
      {
        DirContext dirCtx = ctx.createSubcontext(dn, attrs);
        taskCreated = true;
        LOG.log(Level.INFO, "created task entry: "+attrs);
        dirCtx.close();
      }
      catch (NameAlreadyBoundException x)
      {
        LOG.log(Level.WARNING, "A task with dn: "+dn+" already existed.");
      }
      catch (NamingException ne)
      {
        LOG.log(Level.SEVERE, "Error creating task "+attrs, ne);
        throw new ApplicationException(
            ReturnCode.APPLICATION_ERROR,
                getThrowableMsg(INFO_ERROR_LAUNCHING_INITIALIZATION.get(
                        serverDisplay), ne), ne);
      }
      i++;
    }
    // Wait until it is over
    SearchControls searchControls = new SearchControls();
    searchControls.setCountLimit(1);
    searchControls.setSearchScope(
        SearchControls. OBJECT_SCOPE);
    String filter = "objectclass=*";
    searchControls.setReturningAttributes(
        new String[] {
            "ds-task-unprocessed-entry-count",
            "ds-task-processed-entry-count",
            "ds-task-log-message",
            "ds-task-state"
        });
    Message lastDisplayedMsg = null;
    String lastLogMsg = null;
    long lastTimeMsgDisplayed = -1;
    long lastTimeMsgLogged = -1;
    int totalEntries = 0;
    while (!isOver)
    {
      try
      {
        Thread.sleep(500);
      }
      catch (Throwable t)
      {
      }
      try
      {
        NamingEnumeration res = ctx.search(dn, filter, searchControls);
        SearchResult sr = (SearchResult)res.next();
        // Get the number of entries that have been handled and
        // a percentage...
        Message msg;
        String sProcessed = getFirstValue(sr,
        "ds-task-processed-entry-count");
        String sUnprocessed = getFirstValue(sr,
        "ds-task-unprocessed-entry-count");
        int processed = -1;
        int unprocessed = -1;
        if (sProcessed != null)
        {
          processed = Integer.parseInt(sProcessed);
        }
        if (sUnprocessed != null)
        {
          unprocessed = Integer.parseInt(sUnprocessed);
        }
        totalEntries = Math.max(totalEntries, processed+unprocessed);
        if ((processed != -1) && (unprocessed != -1))
        {
          if (processed + unprocessed > 0)
          {
            int perc = (100 * processed) / (processed + unprocessed);
            msg = INFO_INITIALIZE_PROGRESS_WITH_PERCENTAGE.get(sProcessed,
                String.valueOf(perc));
          }
          else
          {
            //msg = INFO_NO_ENTRIES_TO_INITIALIZE.get();
            msg = null;
          }
        }
        else if (processed != -1)
        {
          msg = INFO_INITIALIZE_PROGRESS_WITH_PROCESSED.get(sProcessed);
        }
        else if (unprocessed != -1)
        {
          msg = INFO_INITIALIZE_PROGRESS_WITH_UNPROCESSED.get(sUnprocessed);
        }
        else
        {
          msg = lastDisplayedMsg;
        }
        if (msg != null)
        {
          long currentTime = System.currentTimeMillis();
          /* Refresh period: to avoid having too many lines in the log */
          long minRefreshPeriod;
          if (totalEntries < 100)
          {
            minRefreshPeriod = 0;
          }
          else if (totalEntries < 1000)
          {
            minRefreshPeriod = 1000;
          }
          else if (totalEntries < 10000)
          {
            minRefreshPeriod = 5000;
          }
          else
          {
            minRefreshPeriod = 10000;
          }
          if (((currentTime - minRefreshPeriod) > lastTimeMsgLogged))
          {
            lastTimeMsgLogged = currentTime;
            LOG.log(Level.INFO, "Progress msg: "+msg);
          }
          if (displayProgress)
          {
            if (!msg.equals(lastDisplayedMsg) &&
                ((currentTime - minRefreshPeriod) > lastTimeMsgDisplayed) &&
                !msg.equals(lastDisplayedMsg))
            {
              printProgressMessage(msg);
              lastDisplayedMsg = msg;
              printProgressLineBreak();
              lastTimeMsgDisplayed = currentTime;
            }
          }
        }
        String logMsg = getFirstValue(sr, "ds-task-log-message");
        if (logMsg != null)
        {
          if (!logMsg.equals(lastLogMsg))
          {
            LOG.log(Level.INFO, logMsg);
            lastLogMsg = logMsg;
          }
        }
        InstallerHelper helper = new InstallerHelper();
        String state = getFirstValue(sr, "ds-task-state");
        if (helper.isDone(state) || helper.isStoppedByError(state))
        {
          isOver = true;
          Message errorMsg;
          if (lastLogMsg == null)
          {
            errorMsg = INFO_ERROR_DURING_INITIALIZATION_NO_LOG.get(
                    serverDisplay, state, serverDisplay);
          }
          else
          {
            errorMsg = INFO_ERROR_DURING_INITIALIZATION_LOG.get(
                serverDisplay, lastLogMsg, state, serverDisplay);
          }
          LOG.log(Level.WARNING, "Processed errorMsg: "+errorMsg);
          if (helper.isCompletedWithErrors(state))
          {
            if (displayProgress)
            {
              printWarningMessage(errorMsg);
            }
          }
          else if (!helper.isSuccessful(state) ||
              helper.isStoppedByError(state))
          {
            ApplicationException ae = new ApplicationException(
                ReturnCode.APPLICATION_ERROR, errorMsg,
                null);
            if ((lastLogMsg == null) ||
                helper.isPeersNotFoundError(lastLogMsg))
            {
              LOG.log(Level.WARNING, "Throwing peer not found error.  "+
                  "Last Log Msg: "+lastLogMsg);
              // Assume that this is a peer not found error.
              throw new PeerNotFoundException(errorMsg);
            }
            else
            {
              LOG.log(Level.SEVERE, "Throwing ApplicationException.");
              throw ae;
            }
          }
          else if (displayProgress)
          {
            LOG.log(Level.INFO, "Initialization completed successfully.");
            printProgressMessage(INFO_SUFFIX_INITIALIZED_SUCCESSFULLY.get());
            printProgressLineBreak();
          }
        }
      }
      catch (NameNotFoundException x)
      {
        isOver = true;
        LOG.log(Level.INFO, "Initialization entry not found.");
        if (displayProgress)
        {
          printProgressMessage(INFO_SUFFIX_INITIALIZED_SUCCESSFULLY.get());
          printProgressLineBreak();
        }
      }
      catch (NamingException ne)
      {
        throw new ApplicationException(
            ReturnCode.APPLICATION_ERROR,
                getThrowableMsg(INFO_ERROR_POOLING_INITIALIZATION.get(
                    serverDisplay), ne), ne);
      }
    }
  }
  /**
   * Returns a set of error messages encountered in the provided TopologyCache.
   * @param cache the topology cache.
opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/StatusReplicationUserData.java
@@ -33,90 +33,11 @@
 * interactive mode the ReplicationCliArgumentParser is not enough.
 *
 */
class StatusReplicationUserData extends ReplicationUserData
class StatusReplicationUserData extends InitializeAllReplicationUserData
{
  private String hostName;
  private int port;
  private boolean useStartTLS;
  private boolean useSSL;
  private boolean scriptFriendly;
  /**
   * 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;
  }
  /**
   * Whether we must display information in a script-friendly mode or not.
   * @return <CODE>true</CODE> if we must display the information in a
   * script-friendly mode and <CODE>false</CODE> otherwise.
opendj-sdk/opends/src/messages/messages/admin_tool.properties
@@ -493,9 +493,14 @@
 password provided for the Global Administrator will be used when specifying \
 this option.
INFO_DESCRIPTION_SUBCMD_INITIALIZE_REPLICATION=Initialize the contents of the \
 data under the specified Bind DN on the destination server with the contents \
 data under the specified Base DN on the destination server with the contents \
 on the source server.  This operation is required after enabling replication \
 in order replication to work.
 in order replication to work ({%s} can also be used for this purpose).
INFO_DESCRIPTION_SUBCMD_INITIALIZE_ALL_REPLICATION=Initialize the contents of \
 the data under the specified Base DN on all the servers whose contents are \
 being replicated with the contents on the specified server.  This operation \
 is required after enabling replication in order replication to work ({%s} \
 applied to each server can also be used for this purpose).
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 \
@@ -586,6 +591,8 @@
INFO_REPLICATION_DISABLE_BINDDN_PROMPT=Global Administrator User ID (or bind \
 DN if no Global Administrator is defined)
INFO_REPLICATION_DISABLE_PASSWORD_PROMPT=Password for %s:
INFO_REPLICATION_INITIALIZE_ALL_HOSTNAME_PROMPT=Host name of the server
INFO_REPLICATION_INITIALIZE_ALL_PORT_PROMPT=LDAP port of the server
INFO_REPLICATION_STATUS_HOSTNAME_PROMPT=Host name of the server
INFO_REPLICATION_STATUS_PORT_PROMPT=LDAP port of the server
INFO_REPLICATION_INITIALIZE_HOSTNAMEDESTINATION_PROMPT=Host name of the \
@@ -604,8 +611,8 @@
 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
INFO_ALREADY_NOT_REPLICATED_SUFFIXES=The following base DNs are not \
 replicated:%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
@@ -622,11 +629,19 @@
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.
SEVERE_ERR_NO_SUFFIXES_AVAILABLE_TO_INITIALIZE_ALL_REPLICATION=There are no \
 base DNs replicated in the server.  The base DNs must be replicated to be \
 able to use their contents to initialize the base DNs on the other servers.
MILD_ERR_REPLICATION_DISABLE_SUFFIXES_NOT_FOUND=The following base DNs could \
 not be found on the server:%n%s
 MILD_ERR_REPLICATION_INITIALIZE_ALL_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.
MILD_ERR_NO_SUFFIXES_SELECTED_TO_INITIALIZE_ALL=You must choose at least one \
 base DN to initialize.
INFO_REPLICATION_DISABLE_SUFFIX_PROMPT=Disable replication on base DN %s?
INFO_REPLICATION_INITIALIZE_ALL_SUFFIX_PROMPT=Initialize 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%n%nIf you continue the replication tool will to try to update \
@@ -656,6 +671,14 @@
 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?
INFO_REPLICATION_CONFIRM_INITIALIZE_ALL_ADS=You chose to initialize the contents \
 of base DN %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_ALL_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 the replicated servers 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 \
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/PeerNotFoundException.java
@@ -43,7 +43,7 @@
   * The constructor for the exception.
   * @param message the localized message.
   */
  PeerNotFoundException(Message message)
  public PeerNotFoundException(Message message)
  {
    super(message);
  }