From 1501130002aa43d26224f75d6b8a7b0b9f3fe857 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Thu, 03 Jan 2008 23:50:11 +0000
Subject: [PATCH] Fix for issue 2791: dsreplication enable command assumes Administrator doesn't already exist

---
 opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java |  127 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 120 insertions(+), 7 deletions(-)

diff --git a/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java b/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java
index 398a79f..7d03420 100644
--- a/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java
+++ b/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Portions Copyright 2007 Sun Microsystems, Inc.
+ *      Portions Copyright 2007-2008 Sun Microsystems, Inc.
  */
 
 package org.opends.guitools.replicationcli;
@@ -71,6 +71,8 @@
 import org.opends.admin.ads.SuffixDescriptor;
 import org.opends.admin.ads.TopologyCache;
 import org.opends.admin.ads.TopologyCacheException;
+import org.opends.admin.ads.ADSContext.ADSPropertySyntax;
+import org.opends.admin.ads.ADSContext.AdministratorProperty;
 import org.opends.admin.ads.util.ApplicationTrustManager;
 import org.opends.admin.ads.util.ConnectionUtils;
 import org.opends.admin.ads.util.ServerLoader;
@@ -2502,6 +2504,46 @@
   }
 
   /**
+   * Tells whether there is a Global Administrator corresponding to the provided
+   * ReplicationUserData defined in the server to which the InitialLdapContext
+   * is connected.
+   * @param ctx the InitialLdapContext.
+   * @param uData the user data
+   * @return <CODE>true</CODE> if we could find an administrator and
+   * <CODE>false</CODE> otherwise.
+   */
+  private boolean hasAdministrator(InitialLdapContext ctx,
+      ReplicationUserData uData)
+  {
+    boolean isAdminDefined = false;
+    String adminUid = uData.getAdminUid();
+    try
+    {
+      ADSContext adsContext = new ADSContext(ctx);
+      Set<Map<AdministratorProperty, Object>> administrators =
+        adsContext.readAdministratorRegistry();
+      for (Map<AdministratorProperty, Object> admin : administrators)
+      {
+        String uid = (String)admin.get(AdministratorProperty.UID);
+        if (uid != null)
+        {
+          isAdminDefined = uid.equalsIgnoreCase(adminUid);
+          if (isAdminDefined)
+          {
+            break;
+          }
+        }
+      }
+    }
+    catch (Throwable t)
+    {
+      LOG.log(Level.WARNING,
+          "Unexpected error retrieving the ADS data: "+t, t);
+    }
+    return isAdminDefined;
+  }
+
+  /**
    * Helper type for the <CODE>getCommonSuffixes</CODE> method.
    */
   private enum SuffixRelationType
@@ -4094,7 +4136,7 @@
         if (registry2.size() <= 1)
         {
           // Only the server itself registered.
-          if (!hasAdministrator(adsCtx1.getDirContext()))
+          if (!hasAdministrator(adsCtx1.getDirContext(), uData))
           {
             adsCtx1.createAdministrator(getAdministratorProperties(uData));
           }
@@ -4115,7 +4157,7 @@
         else if (registry1.size() <= 1)
         {
           // Only the server itself registered.
-          if (!hasAdministrator(adsCtx2.getDirContext()))
+          if (!hasAdministrator(adsCtx2.getDirContext(), uData))
           {
             adsCtx2.createAdministrator(getAdministratorProperties(uData));
           }
@@ -4133,7 +4175,7 @@
           ctxDestination = ctx1;
           adsCtxSource = adsCtx2;
         }
-        else if (!registry1.equals(registry2))
+        else if (!areEqual(registry1, registry2))
         {
           // TO COMPLETE: we may want to merge the ADS but for the moment
           // just say this is not supported.
@@ -4153,7 +4195,7 @@
       else if (!adsCtx1.hasAdminData() && adsCtx2.hasAdminData())
       {
 //        adsCtx1.createAdministrationSuffix(null);
-        if (!hasAdministrator(adsCtx2.getDirContext()))
+        if (!hasAdministrator(adsCtx2.getDirContext(), uData))
         {
           adsCtx2.createAdministrator(getAdministratorProperties(uData));
         }
@@ -4167,7 +4209,7 @@
       else if (adsCtx1.hasAdminData() && !adsCtx2.hasAdminData())
       {
 //        adsCtx2.createAdministrationSuffix(null);
-        if (!hasAdministrator(adsCtx1.getDirContext()))
+        if (!hasAdministrator(adsCtx1.getDirContext(), uData))
         {
           adsCtx1.createAdministrator(getAdministratorProperties(uData));
         }
@@ -4181,7 +4223,12 @@
       else
       {
         adsCtx1.createAdminData(null);
-        adsCtx1.createAdministrator(getAdministratorProperties(uData));
+        if (!hasAdministrator(ctx1, uData))
+        {
+          // This could occur if the user created an administrator without
+          // registering any server.
+          adsCtx1.createAdministrator(getAdministratorProperties(uData));
+        }
         server1.updateAdsPropertiesWithServerProperties();
         adsCtx1.registerServer(server1.getAdsProperties());
         server2.updateAdsPropertiesWithServerProperties();
@@ -6824,4 +6871,70 @@
     }
     return domainId;
   }
+
+  /**
+   * Method used to compare two server registries.
+   * @param registry1 the first registry to compare.
+   * @param registry2 the second registry to compare.
+   * @return <CODE>true</CODE> if the registries are equal and
+   * <CODE>false</CODE> otherwise.
+   */
+  private boolean areEqual(
+      Set<Map<ADSContext.ServerProperty, Object>> registry1,
+      Set<Map<ADSContext.ServerProperty, Object>> registry2)
+  {
+    boolean areEqual = registry1.size() == registry2.size();
+    if (areEqual)
+    {
+      Set<ADSContext.ServerProperty> propertiesToCompare =
+        new HashSet<ADSContext.ServerProperty>();
+      ADSContext.ServerProperty[] properties =
+        ADSContext.ServerProperty.values();
+      for (int i=0; i<properties.length; i++)
+      {
+        if (properties[i].getAttributeSyntax() !=
+          ADSPropertySyntax.CERTIFICATE_BINARY)
+        {
+          propertiesToCompare.add(properties[i]);
+        }
+      }
+      for (Map<ADSContext.ServerProperty, Object> server1 : registry1)
+      {
+        boolean found = false;
+
+        for (Map<ADSContext.ServerProperty, Object> server2 : registry2)
+        {
+          found = true;
+          for (ADSContext.ServerProperty prop : propertiesToCompare)
+          {
+            Object v1 = server1.get(prop);
+            Object v2 = server2.get(prop);
+            if (v1 != null)
+            {
+              found = v1.equals(v2);
+            }
+            else if (v2 != null)
+            {
+              found = false;
+            }
+            if (!found)
+            {
+              break;
+            }
+          }
+          if (found)
+          {
+            break;
+          }
+        }
+
+        areEqual = found;
+        if (!areEqual)
+        {
+          break;
+        }
+      }
+    }
+    return areEqual;
+  }
 }

--
Gitblit v1.10.0