From 51411174542e32ef59b2b58b3bcabb3cddf5d9eb Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Fri, 19 Oct 2007 17:30:27 +0000
Subject: [PATCH] Fix for issue 2317: check servers for clock difference when configuring replication When the servers that are being replicated have a clock difference of more than 5 minutes inform the user of this.  This is done in both the graphical setup and dsreplication tools.

---
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java           |   28 ++++++++++++++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java                    |   47 +++++++++++++++++++++++
 opendj-sdk/opends/src/messages/messages/quicksetup.properties                             |    4 ++
 opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java |   16 ++++++++
 4 files changed, 95 insertions(+), 0 deletions(-)

diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java
index 793e449..b37b5cd 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java
@@ -84,6 +84,7 @@
 import org.opends.quicksetup.ReturnCode;
 import org.opends.quicksetup.event.ProgressUpdateEvent;
 import org.opends.quicksetup.event.ProgressUpdateListener;
+import org.opends.quicksetup.installer.Installer;
 import org.opends.quicksetup.installer.InstallerHelper;
 import org.opends.quicksetup.installer.PeerNotFoundException;
 import org.opends.quicksetup.installer.offline.OfflineInstaller;
@@ -2738,6 +2739,21 @@
       printErrorMessage(msg);
     }
 
+    long time1 = Utils.getServerClock(ctx1);
+    long time2 = Utils.getServerClock(ctx2);
+    if ((time1 != -1) && (time2 != -1))
+    {
+      if (Math.abs(time1 - time2) >
+      (Installer.WARNING_CLOCK_DIFFERENCE_THRESOLD_MINUTES * 60 * 1000))
+      {
+        printWarningMessage(INFO_WARNING_SERVERS_CLOCK_DIFFERENCE.get(
+            ConnectionUtils.getHostPort(ctx1),
+            ConnectionUtils.getHostPort(ctx2),
+            String.valueOf(
+                Installer.WARNING_CLOCK_DIFFERENCE_THRESOLD_MINUTES)));
+      }
+    }
+
     if (ctx1 != null)
     {
       try
diff --git a/opendj-sdk/opends/src/messages/messages/quicksetup.properties b/opendj-sdk/opends/src/messages/messages/quicksetup.properties
index e75558b..b5ae68e 100644
--- a/opendj-sdk/opends/src/messages/messages/quicksetup.properties
+++ b/opendj-sdk/opends/src/messages/messages/quicksetup.properties
@@ -651,6 +651,10 @@
 INFO_PROGRESS_CONFIGURING=Configuring Directory Server
 INFO_PROGRESS_CONFIGURING_REPLICATION=Configuring Replication
 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 \
+ be synchronized but monitoring of replication updates between servers can be \
+ difficult.
 INFO_PROGRESS_COPYING_FILE=Copying file %s to %s
 INFO_PROGRESS_CREATING_ADMINISTRATOR=Creating Global Administrator
 INFO_PROGRESS_CREATING_ADS=Creating Registration Configuration
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 99aeebe..116ddc4 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
@@ -60,6 +60,7 @@
 import org.opends.admin.ads.TopologyCache;
 import org.opends.admin.ads.TopologyCacheException;
 import org.opends.admin.ads.util.ApplicationTrustManager;
+import org.opends.admin.ads.util.ConnectionUtils;
 import org.opends.quicksetup.ui.*;
 import org.opends.quicksetup.util.Utils;
 
@@ -164,6 +165,11 @@
   /** Alias of a self-signed certificate. */
   protected static final String SELF_SIGNED_CERT_ALIAS = "server-cert";
 
+  /** The thresold in minutes used to know whether we must display a warning
+   * informing that there is a server clock difference between two servers
+   * whose contents are being replicated. */
+  public static final int WARNING_CLOCK_DIFFERENCE_THRESOLD_MINUTES = 5;
+
   /**
    * Creates a default instance.
    */
@@ -1483,6 +1489,9 @@
     replicationServers.put(Constants.SCHEMA_DN, adsServers);
 
     InitialLdapContext ctx = null;
+    long localTime = -1;
+    long localTimeMeasureTime = -1;
+    String localServerDisplay = null;
     try
     {
       ctx = createLocalContext();
@@ -1491,6 +1500,9 @@
           getUserData().getReplicationOptions().useSecureReplication(),
           getLocalHostPort(),
           knownReplicationServerIds, knownServerIds);
+      localTimeMeasureTime = System.currentTimeMillis();
+      localTime = Utils.getServerClock(ctx);
+      localServerDisplay = ConnectionUtils.getHostPort(ctx);
     }
     catch (ApplicationException ae)
     {
@@ -1583,6 +1595,22 @@
               replicationPort, enableSecureReplication,
               server.getHostPort(true), knownReplicationServerIds,
               knownServerIds);
+        long remoteTimeMeasureTime = System.currentTimeMillis();
+        long remoteTime = Utils.getServerClock(ctx);
+        if ((localTime != -1) && (remoteTime != -1))
+        {
+          if (Math.abs(localTime - remoteTime - localTimeMeasureTime +
+              remoteTimeMeasureTime) >
+          (WARNING_CLOCK_DIFFERENCE_THRESOLD_MINUTES * 60 * 1000))
+          {
+            notifyListeners(getFormattedWarning(
+                INFO_WARNING_SERVERS_CLOCK_DIFFERENCE.get(
+                    localServerDisplay, ConnectionUtils.getHostPort(ctx),
+                    String.valueOf(
+                        WARNING_CLOCK_DIFFERENCE_THRESOLD_MINUTES))));
+          }
+        }
+
         hmConfiguredRemoteReplication.put(server, repl);
 
         try
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
index 4cb0518..fed0bfe 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
@@ -39,11 +39,14 @@
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.RandomAccessFile;
+import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
+import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 import javax.naming.ldap.InitialLdapContext;
 import javax.naming.ldap.LdapName;
@@ -1388,6 +1391,50 @@
     }
     return emptyStream;
   }
+
+  /**
+   * Returns the current time of a server in milliseconds.
+   * @param ctx the connection to the server.
+   * @return the current time of a server in milliseconds.
+   */
+  public static long getServerClock(InitialLdapContext ctx)
+  {
+    long time = -1;
+    String v = null;
+    SearchControls ctls = new SearchControls();
+    ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
+    ctls.setReturningAttributes(
+        new String[] {
+            "currentTime"
+        });
+    String filter = "(objectclass=*)";
+
+    try
+    {
+      LdapName jndiName = new LdapName("cn=monitor");
+      NamingEnumeration listeners = ctx.search(jndiName, filter, ctls);
+
+      while(listeners.hasMore())
+      {
+        SearchResult sr = (SearchResult)listeners.next();
+
+        v = getFirstValue(sr, "currentTime");
+
+        TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
+
+        SimpleDateFormat formatter =
+             new SimpleDateFormat("yyyyMMddHHmmss'Z'");
+        formatter.setTimeZone(utcTimeZone);
+
+        time = formatter.parse(v).getTime();
+      }
+    }
+    catch (Throwable t)
+    {
+      LOG.log(Level.WARNING, "Error retrieving server current time: "+t, t);
+    }
+    return time;
+  }
 }
 
 /**

--
Gitblit v1.10.0