From 04f01423caa7ce29c6ca93ceeb6775ecca2dd74b Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Sat, 10 Jan 2009 11:15:21 +0000
Subject: [PATCH] Fix for issue 3701 (The Setup is not managing properly the backends when the replication involves multiple base-dn)

---
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java            |  111 ++++++++++++++++++++++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java                  |  158 +++++++++++++++++++++++++++++--
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java   |    1 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java |    1 
 opendj-sdk/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java                             |    1 
 opendj-sdk/opends/src/messages/messages/quicksetup.properties                                    |    1 
 opendj-sdk/opends/src/ads/org/opends/admin/ads/ReplicaDescriptor.java                            |   19 +++
 7 files changed, 280 insertions(+), 12 deletions(-)

diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ReplicaDescriptor.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/ReplicaDescriptor.java
index cd96ce5..964563d 100644
--- a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ReplicaDescriptor.java
+++ b/opendj-sdk/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;
+  }
 }
diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
index 31f815a..16b72a8 100644
--- a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
+++ b/opendj-sdk/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);
diff --git a/opendj-sdk/opends/src/messages/messages/quicksetup.properties b/opendj-sdk/opends/src/messages/messages/quicksetup.properties
index ac7cf05..ea60c2f 100644
--- a/opendj-sdk/opends/src/messages/messages/quicksetup.properties
+++ b/opendj-sdk/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 \
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
index 005aebe..c468ce4 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
+++ b/opendj-sdk/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";
   }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java
index ec3a9a6..2400355 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java
+++ b/opendj-sdk/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.
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
index 2437a05..bb0275d 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
@@ -175,6 +175,7 @@
           notifyListeners(getTaskSeparator());
         }
         setCurrentProgressStep(InstallProgressStep.CONFIGURING_REPLICATION);
+        createReplicatedBackends();
         configureReplication();
         checkAbort();
       }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
index b43f6fd..5460b73 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
@@ -224,6 +224,7 @@
           notifyListeners(getTaskSeparator());
         }
         setCurrentProgressStep(InstallProgressStep.CONFIGURING_REPLICATION);
+        createReplicatedBackends();
         configureReplication();
         checkAbort();
       }

--
Gitblit v1.10.0