From 30cdaded4aa75d49c663640e5d6659228e0ca1a9 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Fri, 31 May 2013 17:25:23 +0000
Subject: [PATCH] Fix for OPENDJ-875: Use of hostnames in replication protocol causes failover problems

---
 opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServer.java       |   44 +++++++++++++++++++++++++++++++++++++-------
 opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java |   16 +++-------------
 2 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServer.java b/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
index 4076a1d..629da1c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
@@ -537,11 +537,7 @@
       dbEnv = new ReplicationDbEnv(getFileForPath(dbDirname).getAbsolutePath(),
           this);
 
-      /*
-       * Open replicationServer socket
-       */
-      String localhostname = InetAddress.getLocalHost().getHostName();
-      serverURL = localhostname + ":" + String.valueOf(replicationPort);
+      setServerURL();
       listenSocket = new ServerSocket();
       listenSocket.bind(new InetSocketAddress(replicationPort));
 
@@ -1038,8 +1034,7 @@
         stopListen = false;
 
         replicationPort = newPort;
-        String localhostname = InetAddress.getLocalHost().getHostName();
-        serverURL = localhostname + ":" + String.valueOf(replicationPort);
+        setServerURL();
         listenSocket = new ServerSocket();
         listenSocket.bind(new InetSocketAddress(replicationPort));
 
@@ -1151,6 +1146,41 @@
     return new ConfigChangeResult(ResultCode.SUCCESS, false);
   }
 
+  /*
+   * Try and set a sensible URL for this replication server. Since we are
+   * listening on all addresses there are a couple of potential candidates: 1) a
+   * matching server url in the replication server's configuration, 2) hostname
+   * local address.
+   */
+  private void setServerURL() throws UnknownHostException
+  {
+    /*
+     * First try the set of configured replication servers to see if one of them
+     * is this replication server (this should always be the case).
+     */
+    for (String rs : replicationServers)
+    {
+      /*
+       * No need validate the string format because the admin framework has
+       * already done it.
+       */
+      final int index = rs.lastIndexOf(":");
+      final String hostname = rs.substring(0, index);
+      final int port = Integer.parseInt(rs.substring(index + 1));
+      if (port == replicationPort && isLocalAddress(hostname))
+      {
+        serverURL = rs;
+        return;
+      }
+    }
+
+    /*
+     * Fall-back to the machine hostname.
+     */
+    serverURL = InetAddress.getLocalHost().getHostName() + ":"
+        + replicationPort;
+  }
+
   /**
    * Broadcast a configuration change that just happened to the whole topology
    * by sending a TopologyMsg to every entity in the topology.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java b/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java
index 88c9487..9237dbc 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java
@@ -34,7 +34,6 @@
 import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
 
 import java.io.IOException;
-import java.net.InetAddress;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
@@ -3017,18 +3016,9 @@
   @Override
   public String getMonitorInstanceName()
   {
-    String hostname = "unknown";
-    try
-    {
-      hostname = InetAddress.getLocalHost().getHostName();
-    }
-    catch (Exception e) {}
-    return "Replication Server "
-           + replicationServer.getReplicationPort() + " "
-           + hostname
-           + " " + replicationServer.getServerId()
-           + ",cn=" + baseDn.replace(',', '_').replace('=', '_')
-           + ",cn=replication";
+    return "Replication server RS(" + replicationServer.getServerId() + ") "
+        + replicationServer.getServerURL() + ",cn="
+        + baseDn.replace(',', '_').replace('=', '_') + ",cn=Replication";
   }
 
   /**

--
Gitblit v1.10.0