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

Gaetan Boismal
22.52.2015 986733aa01992e78f973cddbd18f3d02bb62f60e
OPENDJ-2017 (CR-7035) Setup GUI: Fix replication setup

* src/main/java/org/opends/admin/ads/ReplicaDescriptor.java
** Add the backend object classes as field to retrieve type of backend (JE, persistit...)

* src/main/java/org/opends/admin/ads/ServerDescriptor.java
** Add logic to add backend object classes to the replica descriptor

* src/main/java/org/opends/quicksetup/installer/Installer.java
** Fix a regression introduced in r10231
** Do nothing if the server is the first in replication topology instead of seting baseDNs of userRoot backend
** Remove the userRoot backend deletion (as it is not hardcoded in the config.ldif since r12022)
** Retrieve backend type from backend object classes to allow creation of different kind of backend

* src/main/java/org/opends/quicksetup/installer/InstallerHelper.java
** Replace createLocalDBBackend(...) by createBackend(...) and change the code to be generic to allow both creation of JE and pluggable backends

* src/main/java/org/opends/quicksetup/util/Utils.java
** Removes the dsconfig create-replication-domain added in equivalent command line. This comment is not needed and avoid replication of suffix content.

* src/main/java/org/opends/server/tools/BackendTypeHelper.java
** Add methods to adapt a backend type from a config object or a backend name
7 files modified
221 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/admin/ads/ReplicaDescriptor.java 22 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/admin/ads/ServerDescriptor.java 16 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java 21 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java 95 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/InstallerHelper.java 14 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/quicksetup/util/Utils.java 23 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/tools/BackendTypeHelper.java 30 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/admin/ads/ReplicaDescriptor.java
@@ -45,6 +45,7 @@
  private int missingChanges = -1;
  private long ageOfOldestMissingChange = -1;
  private String backendName;
  private Set<String> objectClasses;
  /**
   * Returns the number of entries contained in the replica.
@@ -226,4 +227,25 @@
  {
    this.backendName = backendName;
  }
  /**
   * Returns object classes of the backend attached to this replica.
   *
   * @return object classes of the backend attached to this replica.
   */
  public Set<String> getObjectClasses()
  {
    return objectClasses;
  }
  /**
   * Sets the object classes of the backend attached to this replica.
   *
   * @param objectClasses
   *          object classes of the backend attached to this replica.
   */
  public void setObjectClasses(Set<String> objectClasses)
  {
    this.objectClasses = objectClasses;
  }
}
opendj-server-legacy/src/main/java/org/opends/admin/ads/ServerDescriptor.java
@@ -26,6 +26,8 @@
 */
package org.opends.admin.ads;
import static org.opends.admin.ads.util.ConnectionUtils.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -38,7 +40,12 @@
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
@@ -48,10 +55,9 @@
import org.opends.admin.ads.util.ConnectionUtils;
import org.opends.quicksetup.Constants;
import org.opends.quicksetup.util.Utils;
import org.opends.server.config.ConfigConstants;
import org.opends.server.schema.SchemaConstants;
import static org.opends.admin.ads.util.ConnectionUtils.*;
/**
 * The object of this class represent an OpenDS server.
 */
@@ -935,7 +941,8 @@
    ctls.setReturningAttributes(
        new String[] {
            "ds-cfg-base-dn",
            "ds-cfg-backend-id"
            "ds-cfg-backend-id",
            ConfigConstants.ATTR_OBJECTCLASS
        });
    String filter = "(objectclass=ds-cfg-backend)";
@@ -986,6 +993,7 @@
              suffix.setDN(baseDn);
              ReplicaDescriptor replica = new ReplicaDescriptor();
              replica.setServer(desc);
              replica.setObjectClasses(getValues(sr, ConfigConstants.ATTR_OBJECTCLASS));
              replica.setBackendName(id);
              replicas.add(replica);
              HashSet<ReplicaDescriptor> r = new HashSet<>();
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java
@@ -123,6 +123,7 @@
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.util.Utils;
import org.opends.server.admin.ClassLoaderProvider;
import org.opends.server.api.AttributeSyntax;
import org.opends.server.api.ConfigHandler;
import org.opends.server.config.ConfigEntry;
@@ -2934,4 +2935,24 @@
    }
  }
  /** Initialize the legacy configuration framework. */
  public static void initializeLegacyConfigurationFramework()
  {
    try
    {
      final ClassLoaderProvider provider = ClassLoaderProvider.getInstance();
      if (!provider.isEnabled())
      {
        provider.enable();
      }
    }
    catch (Exception e)
    {
      final LocalizableMessage message = ERROR_CTRL_PANEL_INITIALIZE_CONFIG_OFFLINE.get(e.getLocalizedMessage());
      logger.error(message);
      throw new RuntimeException(message.toString(), e);
    }
  }
}
opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java
@@ -32,6 +32,7 @@
import static org.opends.admin.ads.util.ConnectionUtils.*;
import static org.opends.messages.QuickSetupMessages.*;
import static org.opends.quicksetup.Step.*;
import static org.opends.quicksetup.installer.DataReplicationOptions.Type.*;
import static org.opends.quicksetup.util.Utils.*;
import static com.forgerock.opendj.cli.ArgumentConstants.*;
@@ -125,7 +126,9 @@
import org.opends.quicksetup.util.FileManager;
import org.opends.quicksetup.util.IncompatibleVersionException;
import org.opends.quicksetup.util.Utils;
import org.opends.server.config.ConfigConstants;
import org.opends.server.tools.BackendTypeHelper;
import org.opends.server.tools.BackendTypeHelper.BackendTypeUIAdapter;
import org.opends.server.util.CertificateManager;
import org.opends.server.util.DynamicConstants;
import org.opends.server.util.SetupUtils;
@@ -1545,56 +1548,40 @@
   */
  protected void createReplicatedBackendsIfRequired() throws ApplicationException
  {
    final boolean isFirstInTopology = getUserData().getReplicationOptions().getType() ==
                                      DataReplicationOptions.Type.FIRST_IN_TOPOLOGY;
    final List<String> baseDns = getUserData().getNewSuffixOptions().getBaseDns();
    if (isFirstInTopology && baseDns.isEmpty())
    if (FIRST_IN_TOPOLOGY == getUserData().getReplicationOptions().getType())
    {
      // There is nothing to do.
      return;
    }
    notifyListeners(getFormattedWithPoints(INFO_PROGRESS_CREATING_REPLICATED_BACKENDS.get()));
    // The keys are the backend IDs and the values the list of base DNs.
    final Map<String, Set<String>> hmBackendSuffix = new HashMap<>();
    boolean deleteUserRoot = false;
    if (isFirstInTopology)
    {
      hmBackendSuffix.put(ROOT_BACKEND_NAME, new HashSet<>(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.
      populateBackendsToCreate(hmBackendSuffix, suffixes);
      deleteUserRoot = true;
      for (String backendName : hmBackendSuffix.keySet())
      {
        if (ROOT_BACKEND_NAME.equalsIgnoreCase(backendName))
        {
          deleteUserRoot = false;
          break;
        }
      }
    }
    createReplicatedBackends(hmBackendSuffix, deleteUserRoot);
    final Map<String, BackendTypeUIAdapter> backendTypes = new HashMap<>();
    final Set<SuffixDescriptor> suffixes = getUserData().getSuffixesToReplicateOptions().getSuffixes();
    populateBackendsToCreate(hmBackendSuffix, suffixes, backendTypes);
    createReplicatedBackends(hmBackendSuffix, backendTypes);
    notifyListeners(getFormattedDoneWithLineBreak());
    checkAbort();
  }
  private void populateBackendsToCreate(Map<String, Set<String>> hmBackendSuffix, Set<SuffixDescriptor> suffixes)
  /**
   * 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.
   */
  private void populateBackendsToCreate(Map<String, Set<String>> hmBackendSuffix, Set<SuffixDescriptor> suffixes,
      Map<String, BackendTypeUIAdapter> backendTypes)
  {
    Set<ServerDescriptor> serverList = getServerListFromSuffixes(suffixes);
    for (SuffixDescriptor suffix : suffixes)
    {
      final String backendName = retrieveBackendNameForSuffix(serverList, suffix);
      if (backendName != null)
      final ReplicaDescriptor replica = retrieveReplicaForSuffix(serverList, suffix);
      if (replica != null)
      {
        final String backendNameKey = getOrAddBackend(hmBackendSuffix, backendName);
        final String backendNameKey = getOrAddBackend(hmBackendSuffix, replica.getBackendName());
        hmBackendSuffix.get(backendNameKey).add(suffix.getDN());
        backendTypes.put(backendNameKey, getBackendType(replica.getObjectClasses()));
      }
    }
  }
@@ -1612,7 +1599,7 @@
    return serverList;
  }
  private String retrieveBackendNameForSuffix(Set<ServerDescriptor> serverList, SuffixDescriptor suffix)
  private ReplicaDescriptor retrieveReplicaForSuffix(Set<ServerDescriptor> serverList, SuffixDescriptor suffix)
  {
    for (ServerDescriptor server : serverList)
    {
@@ -1620,13 +1607,27 @@
      {
        if (replica.getServer() == server)
        {
          return replica.getBackendName();
          return replica;
        }
      }
    }
    return null;
  }
  private BackendTypeUIAdapter getBackendType(Set<String> objectClasses)
  {
    for (String objectClass : objectClasses)
    {
      BackendTypeUIAdapter adapter =
          BackendTypeHelper.getBackendTypeAdapter(objectClass.replace(ConfigConstants.NAME_PREFIX_CFG, ""));
      if (adapter != null)
      {
        return adapter;
      }
    }
    return null;
  }
  private String getOrAddBackend(Map<String, Set<String>> hmBackendSuffix, String backendName)
  {
    for (String storedBackend : hmBackendSuffix.keySet())
@@ -1640,30 +1641,18 @@
    return backendName;
  }
  private void createReplicatedBackends(final Map<String, Set<String>> hmBackendSuffix, boolean deleteUserRoot)
      throws ApplicationException
  private void createReplicatedBackends(final Map<String, Set<String>> hmBackendSuffix,
      final Map<String, BackendTypeUIAdapter> backendTypes) throws ApplicationException
  {
    InstallerHelper helper = new InstallerHelper();
    InitialLdapContext ctx = null;
    try
    {
      ctx = createLocalContext();
      if (deleteUserRoot)
      {
        // Delete the userRoot backend.
        helper.deleteBackend(ctx, ROOT_BACKEND_NAME, ConnectionUtils.getHostPort(ctx));
      }
      final InstallerHelper helper = new InstallerHelper();
      for (String backendName : hmBackendSuffix.keySet())
      {
        if (ROOT_BACKEND_NAME.equalsIgnoreCase(backendName))
        {
          helper.setBaseDns(ctx, backendName, hmBackendSuffix.get(backendName), ConnectionUtils.getHostPort(ctx));
        }
        else
        {
          helper.createLocalDBBackend(
              ctx, backendName, hmBackendSuffix.get(backendName), ConnectionUtils.getHostPort(ctx));
        }
        helper.createBackend(ctx, backendName, hmBackendSuffix.get(backendName), ConnectionUtils.getHostPort(ctx),
            backendTypes.get(backendName).getLegacyConfigurationFrameworkBackend());
      }
    }
    catch (NamingException ne)
@@ -2764,7 +2753,7 @@
    adminProperties.put(ADSContext.AdministratorProperty.UID, userData.getGlobalAdministratorUID());
    adminProperties.put(ADSContext.AdministratorProperty.PASSWORD, userData.getGlobalAdministratorPassword());
    adminProperties.put(ADSContext.AdministratorProperty.DESCRIPTION,
                        INFO_GLOBAL_ADMINISTRATOR_DESCRIPTION.get());
                        INFO_GLOBAL_ADMINISTRATOR_DESCRIPTION.get().toString());
    return adminProperties;
  }
opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/InstallerHelper.java
@@ -71,6 +71,7 @@
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.util.OutputReader;
import org.opends.quicksetup.util.Utils;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.ManagedObjectNotFoundException;
import org.opends.server.admin.PropertyException;
import org.opends.server.admin.client.ManagementContext;
@@ -78,16 +79,15 @@
import org.opends.server.admin.client.ldap.LDAPManagementContext;
import org.opends.server.admin.std.client.BackendCfgClient;
import org.opends.server.admin.std.client.CryptoManagerCfgClient;
import org.opends.server.admin.std.client.LocalDBBackendCfgClient;
import org.opends.server.admin.std.client.ReplicationDomainCfgClient;
import org.opends.server.admin.std.client.ReplicationServerCfgClient;
import org.opends.server.admin.std.client.ReplicationSynchronizationProviderCfgClient;
import org.opends.server.admin.std.client.RootCfgClient;
import org.opends.server.admin.std.meta.BackendCfgDefn;
import org.opends.server.admin.std.meta.LocalDBBackendCfgDefn;
import org.opends.server.admin.std.meta.ReplicationDomainCfgDefn;
import org.opends.server.admin.std.meta.ReplicationServerCfgDefn;
import org.opends.server.admin.std.meta.ReplicationSynchronizationProviderCfgDefn;
import org.opends.server.admin.std.server.BackendCfg;
import org.opends.server.backends.task.TaskState;
import org.opends.server.core.DirectoryServer;
import org.opends.server.tools.ConfigureDS;
@@ -361,9 +361,8 @@
    }
  }
  /**
   * Creates a local database backend on the server.
   * Creates a database backend on the server.
   *
   * @param ctx
   *          the connection to the server.
@@ -373,17 +372,20 @@
   *          the list of base DNs to be defined on the server.
   * @param serverDisplay
   *          the server display.
   * @param backendType
   *          the backend type.
   * @throws ApplicationException
   *           if something goes wrong.
   */
  public void createLocalDBBackend(DirContext ctx, String backendName, Set<String> baseDNs, String serverDisplay)
  public void createBackend(DirContext ctx, String backendName, Set<String> baseDNs, String serverDisplay,
      ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backendType)
      throws ApplicationException
  {
    try
    {
      ManagementContext mCtx = LDAPManagementContext.createFromContext(JNDIDirContextAdaptor.adapt(ctx));
      RootCfgClient root = mCtx.getRootConfiguration();
      LocalDBBackendCfgClient backend = root.createBackend(LocalDBBackendCfgDefn.getInstance(), backendName, null);
      BackendCfgClient backend = root.createBackend(backendType, backendName, null);
      backend.setEnabled(true);
      Set<DN> setBaseDNs = new HashSet<DN>();
      for (String baseDN : baseDNs)
opendj-server-legacy/src/main/java/org/opends/quicksetup/util/Utils.java
@@ -2260,29 +2260,6 @@
    cmdReplicationServer.addAll(connectionArgs);
    cmdLines.add(cmdReplicationServer);
    for (String baseDN : getBaseDNs(userData))
    {
      List<String> cmdDomain = new ArrayList<>();
      cmdDomain.add(cmdName);
      cmdDomain.add("create-replication-domain");
      cmdDomain.add("--provider-name");
      cmdDomain.add("Multimaster Synchronization");
      cmdDomain.add("--set");
      cmdDomain.add("base-dn:" + baseDN);
      cmdDomain.add("--set");
      cmdDomain.add("replication-server:" + userData.getHostName() + ":"
          + userData.getReplicationOptions().getReplicationPort());
      cmdDomain.add("--set");
      cmdDomain.add("server-id:1");
      cmdDomain.add("--type");
      cmdDomain.add("generic");
      cmdDomain.add("--domain-name");
      cmdDomain.add(baseDN);
      cmdDomain.addAll(connectionArgs);
      cmdLines.add(cmdDomain);
    }
    return cmdLines;
  }
}
opendj-server-legacy/src/main/java/org/opends/server/tools/BackendTypeHelper.java
@@ -113,6 +113,7 @@
        ? extends org.opends.server.admin.std.client.BackendCfgClient,
        ? extends org.opends.server.admin.std.server.BackendCfg> getLegacyConfigurationFrameworkBackend()
    {
      Utilities.initializeLegacyConfigurationFramework();
      if (isLocalDBBackend())
      {
        return org.opends.server.admin.std.meta.LocalDBBackendCfgDefn.getInstance();
@@ -223,4 +224,33 @@
    return adaptors.toArray(new BackendTypeUIAdapter[adaptors.size()]);
  }
  /**
   * Return a BackendTypeUIAdapter which adapts the backend identified by the
   * provided backend name.
   *
   * @param backendName
   *          the backend name which identifies the backend to adapt.
   * @return a BackendTypeUIAdapter which adapts the backend identified by the
   *         provided backend name.
   */
  public static BackendTypeUIAdapter getBackendTypeAdapter(String backendName)
  {
    ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backend =
        new BackendTypeHelper().retrieveBackendTypeFromName(backendName);
    return backend != null ? getBackendTypeAdapter(backend) : null;
  }
  /**
   * Return a BackendTypeUIAdapter which adapts the provided backend.
   *
   * @param backend
   *          the backend type to adapt.
   * @return a BackendTypeUIAdapter which adapts the provided backend.
   */
  public static BackendTypeUIAdapter getBackendTypeAdapter(
      ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backend)
  {
    return new BackendTypeUIAdapter(backend);
  }
}