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

jvergara
10.15.2009 1c6e1841123f49cb25192fbf16a57e66203f3878
Fix for issue 3701 (The Setup is not managing properly the backends when the replication involves multiple base-dn)

With this fix the setup tries to use the same backend configuration of the servers that is replicating withFix for issue 3701 (The Setup is not managing properly the backends when the replication involves multiple base-dn)

With this fix the setup tries to use the same backend configuration of the servers that is replicating with. So, if all the base DNs are on the same backend of the remote server, all the base DNs will be on the same backend of the server that is being setup. If the base DNs are in different backends, the setup will create a backend for each base DN.
7 files modified
292 ■■■■■ changed files
opends/src/ads/org/opends/admin/ads/ReplicaDescriptor.java 19 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ServerDescriptor.java 1 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/quicksetup.properties 1 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java 158 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java 111 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java 1 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java 1 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ReplicaDescriptor.java
@@ -43,6 +43,7 @@
  private int replicationId = -1;
  private int missingChanges = -1;
  private long ageOfOldestMissingChange = -1;
  private String backendName;
  /**
   * Returns the number of entries contained in the replica.
@@ -198,4 +199,22 @@
  {
    this.missingChanges = missingChanges;
  }
  /**
   * Returns the name of the backend where this replica is defined.
   * @return the name of the backend where this replica is defined.
   */
  public String getBackendName()
  {
    return backendName;
  }
  /**
   * Sets the name of the backend where this replica is defined.
   * @param backendName the name of the backend.
   */
  public void setBackendName(String backendName)
  {
    this.backendName = backendName;
  }
}
opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
@@ -923,6 +923,7 @@
            suffix.setDN(baseDn);
            ReplicaDescriptor replica = new ReplicaDescriptor();
            replica.setServer(desc);
            replica.setBackendName(id);
            replicas.add(replica);
            HashSet<ReplicaDescriptor> r = new HashSet<ReplicaDescriptor>();
            r.add(replica);
opends/src/messages/messages/quicksetup.properties
@@ -721,6 +721,7 @@
INFO_PROGRESS_COLOR=000,000,000
INFO_PROGRESS_CONFIGURING=Configuring Directory Server
INFO_PROGRESS_CONFIGURING_REPLICATION=Configuring Replication
INFO_PROGRESS_CREATING_REPLICATED_BACKENDS=Creating Replicated Base DNs
INFO_PROGRESS_CONFIGURING_REPLICATION_REMOTE=Configuring Replication on %s
INFO_WARNING_SERVERS_CLOCK_DIFFERENCE=The clocks of servers %s and %s have a \
 difference superior to %s minutes.  Replication does not require clocks to \
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -932,17 +932,6 @@
        argList.add(baseDn);
      }
    }
    else
    {
      Set<SuffixDescriptor> suffixesToReplicate =
        getUserData().getSuffixesToReplicateOptions().getSuffixes();
      for (SuffixDescriptor suffix: suffixesToReplicate)
      {
        argList.add("-b");
        argList.add(suffix.getDN());
      }
    }
    argList.add("-R");
    argList.add(getInstallation().getRootDirectory().getAbsolutePath());
@@ -1604,6 +1593,151 @@
  }
  /**
   * This method configures the backends and suffixes that must be replicated.
   * The setup uses the same backend names as in the remote servers.  If
   * userRoot is not one of the backends defined in the remote servers, it
   * deletes it from the configuration.
   * NOTE: this method assumes that the server is running.
   * @throws ApplicationException if something goes wrong.
   */
  protected void createReplicatedBackends() throws ApplicationException
  {
    notifyListeners(getFormattedWithPoints(
        INFO_PROGRESS_CREATING_REPLICATED_BACKENDS.get()));
    // The keys are the backend IDs and the values the list of base DNs.
    Map<String, Set<String>> hmBackendSuffix =
      new HashMap<String, Set<String>>();
    boolean deleteUserRoot = false;
    if (getUserData().getReplicationOptions().getType()
        == DataReplicationOptions.Type.FIRST_IN_TOPOLOGY)
    {
      Set<String> baseDns = new HashSet<String>(
        getUserData().getNewSuffixOptions().getBaseDns());
      hmBackendSuffix.put(getBackendName(), baseDns);
    }
    else
    {
      Set<SuffixDescriptor> suffixes =
        getUserData().getSuffixesToReplicateOptions().getSuffixes();
      // The criteria to choose the name of the backend is to try to have the
      // configuration of the other server.  The algorithm consists on putting
      // the remote servers in a list and pick the backend as they appear on the
      // list.
      LinkedHashSet<ServerDescriptor> serverList =
        new LinkedHashSet<ServerDescriptor>();
      for (SuffixDescriptor suffix : suffixes)
      {
        for (ReplicaDescriptor replica : suffix.getReplicas())
        {
          serverList.add(replica.getServer());
        }
      }
      for (SuffixDescriptor suffix : suffixes)
      {
        String backendName = null;
        for (ServerDescriptor server : serverList)
        {
          for (ReplicaDescriptor replica : suffix.getReplicas())
          {
            if (replica.getServer() == server)
            {
              backendName = replica.getBackendName();
              break;
            }
          }
          if (backendName != null)
          {
            break;
          }
        }
        boolean found = false;
        for (String storedBackend : hmBackendSuffix.keySet())
        {
          if (storedBackend.equalsIgnoreCase(backendName))
          {
            found = true;
            hmBackendSuffix.get(storedBackend).add(suffix.getDN());
            break;
          }
        }
        if (!found)
        {
          Set<String> baseDns = new HashSet<String>();
          baseDns.add(suffix.getDN());
          hmBackendSuffix.put(backendName, baseDns);
        }
      }
      deleteUserRoot = true;
      for (String backendName : hmBackendSuffix.keySet())
      {
        if (backendName.equalsIgnoreCase(getBackendName()))
        {
          deleteUserRoot = false;
          break;
        }
      }
    }
    InstallerHelper helper = new InstallerHelper();
    InitialLdapContext ctx = null;
    try
    {
      ctx = createLocalContext();
      if (deleteUserRoot)
      {
        // Delete the userRoot backend.
        helper.deleteBackend(ctx, getBackendName(),
            ConnectionUtils.getHostPort(ctx));
      }
      for (String backendName : hmBackendSuffix.keySet())
      {
        if (backendName.equalsIgnoreCase(getBackendName()))
        {
          helper.setBaseDns(
              ctx, backendName, hmBackendSuffix.get(backendName),
              ConnectionUtils.getHostPort(ctx));
        }
        else
        {
          helper.createLocalDBBackend(
              ctx, backendName, hmBackendSuffix.get(backendName),
              ConnectionUtils.getHostPort(ctx));
        }
      }
    }
    catch (ApplicationException ae)
    {
      throw ae;
    }
    catch (NamingException ne)
    {
      Message failedMsg = getThrowableMsg(
              INFO_ERROR_CONNECTING_TO_LOCAL.get(), ne);
      throw new ApplicationException(
          ReturnCode.CONFIGURATION_ERROR, failedMsg, ne);
    }
    finally
    {
      try
      {
        if (ctx != null)
        {
          ctx.close();
        }
      }
      catch (Throwable t)
      {
      }
    }
    notifyListeners(getFormattedDoneWithLineBreak());
    checkAbort();
  }
  /**
   * This method creates the replication configuration for the suffixes on the
   * the local server (and eventually in the remote servers) to synchronize
   * things.
@@ -2062,7 +2196,7 @@
   * Returns the default backend name (the one that will be created).
   * @return the default backend name (the one that will be created).
   */
  protected String getBackendName()
  private String getBackendName()
  {
    return "userRoot";
  }
opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java
@@ -222,6 +222,117 @@
  }
  /**
   * Deletes a backend on the server.
   * @param ctx the connection to the server.
   * @param backendName the name of the backend to be deleted.
   * @param serverDisplay the server display.
   * @throws ApplicationException if something goes wrong.
   */
  public void deleteBackend(InitialLdapContext ctx, String backendName,
      String serverDisplay)
  throws ApplicationException
  {
    try
    {
      ManagementContext mCtx = LDAPManagementContext.createFromContext(
          JNDIDirContextAdaptor.adapt(ctx));
      RootCfgClient root = mCtx.getRootConfiguration();
      root.removeBackend(backendName);
    }
    catch (Throwable t)
    {
      Message errorMessage = INFO_ERROR_CONFIGURING_REMOTE_GENERIC.get(
              serverDisplay, t.toString());
      throw new ApplicationException(
          ReturnCode.CONFIGURATION_ERROR, errorMessage,
          t);
    }
  }
  /**
   * Creates a local database backend on the server.
   * @param ctx the connection to the server.
   * @param backendName the name of the backend to be created.
   * @param baseDNs the list of base DNs to be defined on the server.
   * @param serverDisplay the server display.
   * @throws ApplicationException if something goes wrong.
   */
  public void createLocalDBBackend(InitialLdapContext ctx,
      String backendName,
      Set<String> baseDNs,
      String serverDisplay)
  throws ApplicationException
  {
    try
    {
      ManagementContext mCtx = LDAPManagementContext.createFromContext(
          JNDIDirContextAdaptor.adapt(ctx));
      RootCfgClient root = mCtx.getRootConfiguration();
      LocalDBBackendCfgDefn provider = LocalDBBackendCfgDefn.getInstance();
      LocalDBBackendCfgClient backend = root.createBackend(provider,
          backendName, null);
      backend.setEnabled(true);
      Set<DN> setBaseDNs = new HashSet<DN>();
      for (String baseDN : baseDNs)
      {
        setBaseDNs.add(DN.decode(baseDN));
      }
      backend.setBaseDN(setBaseDNs);
      backend.setBackendId(backendName);
      backend.setWritabilityMode(BackendCfgDefn.WritabilityMode.ENABLED);
      backend.commit();
    }
    catch (Throwable t)
    {
      Message errorMessage = INFO_ERROR_CONFIGURING_REMOTE_GENERIC.get(
              serverDisplay, t.toString());
      throw new ApplicationException(
          ReturnCode.CONFIGURATION_ERROR, errorMessage,
          t);
    }
  }
  /**
   * Sets the base DNs on a given backend.
   * @param ctx the connection to the server.
   * @param backendName the name of the backend where the base Dns must be
   * defined.
   * @param baseDNs the list of base DNs to be defined on the server.
   * @param serverDisplay the server display.
   * @throws ApplicationException if something goes wrong.
   */
  public void setBaseDns(InitialLdapContext ctx,
      String backendName,
      Set<String> baseDNs,
      String serverDisplay)
  throws ApplicationException
  {
    try
    {
      ManagementContext mCtx = LDAPManagementContext.createFromContext(
          JNDIDirContextAdaptor.adapt(ctx));
      RootCfgClient root = mCtx.getRootConfiguration();
      BackendCfgClient backend = root.getBackend(backendName);
      Set<DN> setBaseDNs = new HashSet<DN>();
      for (String baseDN : baseDNs)
      {
        setBaseDNs.add(DN.decode(baseDN));
      }
      backend.setBaseDN(setBaseDNs);
      backend.commit();
    }
    catch (Throwable t)
    {
      Message errorMessage = INFO_ERROR_CONFIGURING_REMOTE_GENERIC.get(
              serverDisplay, t.toString());
      throw new ApplicationException(
          ReturnCode.CONFIGURATION_ERROR, errorMessage,
          t);
    }
  }
  /**
   * Configures the replication on a given server.
   * @param remoteCtx the conection to the server where we want to configure
   * the replication.
opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
@@ -175,6 +175,7 @@
          notifyListeners(getTaskSeparator());
        }
        setCurrentProgressStep(InstallProgressStep.CONFIGURING_REPLICATION);
        createReplicatedBackends();
        configureReplication();
        checkAbort();
      }
opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
@@ -224,6 +224,7 @@
          notifyListeners(getTaskSeparator());
        }
        setCurrentProgressStep(InstallProgressStep.CONFIGURING_REPLICATION);
        createReplicatedBackends();
        configureReplication();
        checkAbort();
      }