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

Jean-Noel Rouvignac
06.03.2013 990c9f58e0e277fb0086b57eb3a6ff74cfb6cddf
OPENDJ-66 (CR-1368) DS does not failover between replication servers in different groups when configured explicitly for one of the groups 

ReplicationBroker.java:
In connectAsDataServer(), removed following useless if statement (root cause for the bug):
// Really no other server with our group id ?
if ((tmpRsGroupId == groupId) || (!someServersWithSameGroupId))

Extracted method connectToReplicationServer() in connectAsDataServer().
Removed hasSomeServerWithSameGroupId().
7 files modified
280 ■■■■■ changed files
opends/src/messages/messages/replication.properties 5 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/replication_de.properties 3 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/replication_es.properties 3 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/replication_fr.properties 3 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/replication_ja.properties 3 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/replication_zh_CN.properties 3 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/service/ReplicationBroker.java 260 ●●●●● patch | view | raw | blame | history
opends/src/messages/messages/replication.properties
@@ -21,7 +21,7 @@
# CDDL HEADER END
#
#      Copyright 2006-2010 Sun Microsystems, Inc.
#      Portions copyright 2011-2012 ForgeRock AS
#      Portions copyright 2011-2013 ForgeRock AS
#
#
# This file contains the primary Directory Server configuration.  It must not
@@ -257,9 +257,6 @@
any replication server. You should \
check in the configuration that the domain is enabled and that there is one \
replication server up and running
NOTICE_NEW_SERVER_WITH_SAME_GROUP_ID_120=Disconnecting from replication server \
 as a new one with our group id (%s) just arrived in topology. This is for \
 domain %s and we have server id %s
SEVERE_ERR_RS_DN_DOES_NOT_MATCH_121=DN sent by remote replication server: %s does \
 not match local replication server one: %s
SEVERE_ERR_DS_DN_DOES_NOT_MATCH_122=DN sent by replication server: %s does \
opends/src/messages/messages/replication_de.properties
@@ -21,7 +21,7 @@
# CDDL HEADER END
#
#      Copyright 2006-2010 Sun Microsystems, Inc.
#      Portions copyright 2011 ForgeRock AS
#      Portions copyright 2011-2013 ForgeRock AS
#
#
# This file contains the primary Directory Server configuration.  It must not
@@ -147,7 +147,6 @@
SEVERE_ERR_COMPUTING_FAKE_OPS_115=Aufgefangene Ausnahme berechnet Scheinvorg\u00e4nge f\u00fcr Dom\u00e4ne %s f\u00fcr Replikationsserver %s : %s
NOTICE_SERVER_STATE_RECOVERY_117=ServerState-Wiederherstellung f\u00fcr Dom\u00e4ne %s, aktualisiert mit changeNumber %s
SEVERE_ERR_RESET_GENERATION_CONN_ERR_ID_118=F\u00fcr die replizierte Dom\u00e4ne %s auf dem Server mit der Server-ID=%s konnte die Generations-ID nicht auf den Wert "%s" in der \u00fcbrigen Topologie gesetzt werden, weil der Server NICHT mit einem Replikationsserver verbunden ist. \u00dcberpr\u00fcfen Sie in der Konfiguration, dass die Dom\u00e4ne aktiviert und ein Replikationsserver eingerichtet und aktiv ist
NOTICE_NEW_SERVER_WITH_SAME_GROUP_ID_120=Verbindung zum Replikationsserver wird getrennt, da ein neuer mit unserer Gruppen-ID (%s) gerade in die Topologie gelangte. Dies gilt f\u00fcr Dom\u00e4ne %s, und wir haben Server-ID %s
SEVERE_ERR_RS_DN_DOES_NOT_MATCH_121=Der von Remote-Replikationsserver: %s gesendete DN stimmt nicht mit dem lokalen Replikationsserver eins \u00fcbereinn: %s
SEVERE_ERR_DS_DN_DOES_NOT_MATCH_122=Der von Replikationsserver: %s gesendete DN stimmt nicht mit dem lokalen Directory-Server eins \u00fcbereinn: %s
SEVERE_ERR_EXCEPTION_FORWARDING_RESET_GEN_ID_123=E/A-Ausnahme w\u00e4hrend der Weiterleitung von ResetGenerationIdMsg an die Peer-Replikationsserver f\u00fcr Dom\u00e4ne %s : %s aufgefangen
opends/src/messages/messages/replication_es.properties
@@ -21,7 +21,7 @@
# CDDL HEADER END
#
#      Copyright 2006-2010 Sun Microsystems, Inc.
#      Portions copyright 2011 ForgeRock AS
#      Portions copyright 2011-2013 ForgeRock AS
#
#
# This file contains the primary Directory Server configuration.  It must not
@@ -147,7 +147,6 @@
SEVERE_ERR_COMPUTING_FAKE_OPS_115=Se ha detectado una excepci\u00f3n al calcular operaciones falsas para el dominio %s para el servidor de repetici\u00f3n %s: %s
NOTICE_SERVER_STATE_RECOVERY_117=Recuperaci\u00f3n del estado de servidor para el dominio %s actualizada con el n\u00famero de cambio %s
SEVERE_ERR_RESET_GENERATION_CONN_ERR_ID_118=Para el dominio repetido %s, en el servidor con ID. de servidor=%s, el Id. de generaci\u00f3n no se pudo configurar con el valor %s en el resto de la topolog\u00eda porque este servidor NO est\u00e1 conectado con ning\u00fan servidor de repetici\u00f3n. Debe comprobar en la configuraci\u00f3n que el dominio est\u00e9 habilitado y que est\u00e9 funcionando un servidor de repetici\u00f3n
NOTICE_NEW_SERVER_WITH_SAME_GROUP_ID_120=Desconectando del servidor de repetici\u00f3n ya que acaba de llegar en topolog\u00eda uno nuevo con nuestro Id. de grupo (%s). Esto es para el dominio %s; nuestro Id. de servidor es %s
SEVERE_ERR_RS_DN_DOES_NOT_MATCH_121=El ND enviado por el servidor de repetici\u00f3n remoto: %s no coincide con el del servidor de repetici\u00f3n local: %s
SEVERE_ERR_DS_DN_DOES_NOT_MATCH_122=El ND enviado por el servidor de repetici\u00f3n: %s no coincide con el del servidor de directorios local: %s
SEVERE_ERR_EXCEPTION_FORWARDING_RESET_GEN_ID_123=Se ha detectado una excepci\u00f3n IOException al reenviar ResetGenerationIdMsg a los servidores de repetici\u00f3n del mismo nivel para el dominio %s: %s
opends/src/messages/messages/replication_fr.properties
@@ -21,7 +21,7 @@
# CDDL HEADER END
#
#      Copyright 2006-2010 Sun Microsystems, Inc.
#      Portions copyright 2011 ForgeRock AS
#      Portions copyright 2011-2013 ForgeRock AS
#
#
# This file contains the primary Directory Server configuration.  It must not
@@ -147,7 +147,6 @@
SEVERE_ERR_COMPUTING_FAKE_OPS_115=Exception d\u00e9tect\u00e9e lors du traitement d'op\u00e9rations factices pour le domaine %s pour le serveur de r\u00e9plication %s\u00a0: %s
NOTICE_SERVER_STATE_RECOVERY_117=R\u00e9cup\u00e9ration ServerState pour le domaine %s, mis \u00e0 jour avec changeNumber %s
SEVERE_ERR_RESET_GENERATION_CONN_ERR_ID_118=Pour le domaine r\u00e9pliqu\u00e9 %s, dans le serveur muni de l'identifiant serverId=%s, l'identifiant de g\u00e9n\u00e9ration n'a pas pu \u00eatre d\u00e9fini sur la valeur %s dans la reste de la topologie, car ce serveur n'est PAS connect\u00e9 \u00e0 un serveur de r\u00e9plication. Vous devez v\u00e9rifier dans la configuration si le domaine est bien activ\u00e9 et qu'un serveur de r\u00e9plication est bien en cours d'ex\u00e9cution
NOTICE_NEW_SERVER_WITH_SAME_GROUP_ID_120=D\u00e9connexion du serveur de r\u00e9plication comme en tant que nouveau avec notre ID de groupe (%s) venant d'arriver dans la topologie. Ceci s'applique au domaine %s et nous avons l'ID %s du serveur
SEVERE_ERR_RS_DN_DOES_NOT_MATCH_121=Le DN envoy\u00e9 par le serveur de r\u00e9plication distant\u00a0: %s ne correspond pas \u00e0 celui du serveur de r\u00e9plication local\u00a0: %s
SEVERE_ERR_DS_DN_DOES_NOT_MATCH_122=Le DN envoy\u00e9 par le serveur de r\u00e9plication\u00a0: %s ne correspond pas au DN Directory Server local\u00a0: %s
SEVERE_ERR_EXCEPTION_FORWARDING_RESET_GEN_ID_123=Exception IOException d\u00e9tect\u00e9e lors du transfert de ResetGenerationIdMsg aux serveurs de r\u00e9plication pairs pour le domaine %s\u00a0: %s
opends/src/messages/messages/replication_ja.properties
@@ -21,7 +21,7 @@
# CDDL HEADER END
#
#      Copyright 2006-2010 Sun Microsystems, Inc.
#      Portions copyright 2011 ForgeRock AS
#      Portions copyright 2011-2013 ForgeRock AS
#
#
# This file contains the primary Directory Server configuration.  It must not
@@ -147,7 +147,6 @@
SEVERE_ERR_COMPUTING_FAKE_OPS_115=\u30ec\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b5\u30fc\u30d0\u30fc %2$s \u306e\u30c9\u30e1\u30a4\u30f3 %1$s \u306b\u5bfe\u3059\u308b\u7591\u4f3c\u64cd\u4f5c\u3092\u8a08\u7b97\u4e2d\u306b\u4f8b\u5916\u304c\u30ad\u30e3\u30c3\u30c1\u3055\u308c\u307e\u3057\u305f: %3$s
NOTICE_SERVER_STATE_RECOVERY_117=\u30c9\u30e1\u30a4\u30f3 %s \u306e ServerState \u306e\u5fa9\u5143\u304c\u3001changeNumber %s \u3067\u66f4\u65b0\u3055\u308c\u307e\u3057\u305f
SEVERE_ERR_RESET_GENERATION_CONN_ERR_ID_118=\u30ec\u30d7\u30ea\u30b1\u30fc\u30c8\u3055\u308c\u305f\u30c9\u30e1\u30a4\u30f3 %s \u306e serverId=%s \u306e\u30b5\u30fc\u30d0\u30fc\u3067\u3001\u30c8\u30dd\u30ed\u30b8\u306e\u6b8b\u308a\u306e\u90e8\u5206\u306e\u751f\u6210 ID \u3092\u5024 %s \u306b\u8a2d\u5b9a\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u3053\u306e\u30b5\u30fc\u30d0\u30fc\u306f\u3069\u306e\u30ec\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b5\u30fc\u30d0\u30fc\u306b\u3082\u63a5\u7d9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u8a2d\u5b9a\u3067\u3001\u30c9\u30e1\u30a4\u30f3\u304c\u6709\u52b9\u3067\u3042\u308b\u3053\u3068\u304a\u3088\u3073 1 \u3064\u306e\u30ec\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b5\u30fc\u30d0\u30fc\u304c\u8d77\u52d5\u3057\u3001\u7a3c\u50cd\u4e2d\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044
NOTICE_NEW_SERVER_WITH_SAME_GROUP_ID_120=\u5f53\u30b0\u30eb\u30fc\u30d7\u306e ID (%s) \u3092\u6301\u3064\u65b0\u898f\u306e\u30b5\u30fc\u30d0\u30fc\u304c\u30c8\u30dd\u30ed\u30b8\u306b\u5c0e\u5165\u3055\u308c\u305f\u305f\u3081\u3001\u30ec\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b5\u30fc\u30d0\u30fc\u304b\u3089\u5207\u65ad\u3057\u3066\u3044\u307e\u3059\u3002\u3053\u308c\u306e\u5bfe\u8c61\u306f\u30c9\u30e1\u30a4\u30f3 %s \u3067\u3001\u30b5\u30fc\u30d0\u30fc ID \u306f %s \u3067\u3059
SEVERE_ERR_RS_DN_DOES_NOT_MATCH_121=\u30ea\u30e2\u30fc\u30c8\u30ec\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b5\u30fc\u30d0\u30fc\u306b\u3088\u3063\u3066\u9001\u4fe1\u3055\u308c\u305f DN: %s \u304c\u3001\u30ed\u30fc\u30ab\u30eb\u30ec\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b5\u30fc\u30d0\u30fc\u306e\u3082\u306e: %s \u3068\u4e00\u81f4\u3057\u307e\u305b\u3093
SEVERE_ERR_DS_DN_DOES_NOT_MATCH_122=\u30ec\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b5\u30fc\u30d0\u30fc\u306b\u3088\u3063\u3066\u9001\u4fe1\u3055\u308c\u305f DN: %s \u304c\u3001\u30ed\u30fc\u30ab\u30eb\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30b5\u30fc\u30d0\u30fc\u306e\u3082\u306e: %s \u3068\u4e00\u81f4\u3057\u307e\u305b\u3093
SEVERE_ERR_EXCEPTION_FORWARDING_RESET_GEN_ID_123=\u30c9\u30e1\u30a4\u30f3 %s \u306e\u30d4\u30a2\u30ec\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b5\u30fc\u30d0\u30fc\u306b ResetGenerationIdMsg \u3092\u8ee2\u9001\u4e2d\u306b IOException \u304c\u30ad\u30e3\u30c3\u30c1\u3055\u308c\u307e\u3057\u305f: %s
opends/src/messages/messages/replication_zh_CN.properties
@@ -21,7 +21,7 @@
# CDDL HEADER END
#
#      Copyright 2006-2010 Sun Microsystems, Inc.
#      Portions copyright 2011 ForgeRock AS
#      Portions copyright 2011-2013 ForgeRock AS
#
#
# This file contains the primary Directory Server configuration.  It must not
@@ -147,7 +147,6 @@
SEVERE_ERR_COMPUTING_FAKE_OPS_115=\u8ba1\u7b97\u590d\u5236\u670d\u52a1\u5668 %2$s \u7684\u57df %1$s \u7684\u865a\u5047\u64cd\u4f5c\u65f6\u6355\u83b7\u5230\u5f02\u5e38: %3$s
NOTICE_SERVER_STATE_RECOVERY_117=\u57df %s \u7684\u670d\u52a1\u5668\u72b6\u6001\u6062\u590d\uff0c\u4f7f\u7528\u66f4\u6539\u53f7 %s \u8fdb\u884c\u4e86\u66f4\u65b0
SEVERE_ERR_RESET_GENERATION_CONN_ERR_ID_118=\u5bf9\u4e8e\u590d\u5236\u7684\u57df %s\uff0c\u5728\u670d\u52a1\u5668 ID \u4e3a %s \u7684\u670d\u52a1\u5668\u4e2d\uff0c\u65e0\u6cd5\u5728\u5269\u4f59\u7684\u62d3\u6251\u4e2d\u5c06\u751f\u6210 ID \u8bbe\u7f6e\u4e3a\u503c %s\uff0c\u56e0\u4e3a\u8be5\u670d\u52a1\u5668\u672a\u8fde\u63a5\u5230\u4efb\u4f55\u590d\u5236\u670d\u52a1\u5668\u3002\u60a8\u5e94\u7b7e\u5165\u5df2\u542f\u7528\u57df\u4e14\u6709\u4e00\u4e2a\u590d\u5236\u670d\u52a1\u5668\u5df2\u5f00\u542f\u5e76\u6b63\u5728\u8fd0\u884c\u7684\u914d\u7f6e
NOTICE_NEW_SERVER_WITH_SAME_GROUP_ID_120=\u6b63\u5728\u4ece\u590d\u5236\u670d\u52a1\u5668\u65ad\u5f00\u8fde\u63a5\uff0c\u56e0\u4e3a\u5177\u6709\u6211\u4eec\u7ec4 ID (%s) \u7684\u65b0\u590d\u5236\u670d\u52a1\u5668\u521a\u521a\u5230\u8fbe\u62d3\u6251\u4e2d\u3002\u8be5\u670d\u52a1\u5668\u7528\u4e8e\u57df %s \u5e76\u4e14\u6211\u4eec\u5177\u6709\u670d\u52a1\u5668 ID %s
SEVERE_ERR_RS_DN_DOES_NOT_MATCH_121=\u8fdc\u7a0b\u590d\u5236\u670d\u52a1\u5668\u53d1\u9001\u7684 DN %s \u4e0e\u672c\u5730\u590d\u5236\u670d\u52a1\u5668\u4e0a\u7684 %s \u4e0d\u5339\u914d
SEVERE_ERR_DS_DN_DOES_NOT_MATCH_122=\u590d\u5236\u670d\u52a1\u5668\u53d1\u9001\u7684 DN %s \u4e0e\u672c\u5730\u76ee\u5f55\u670d\u52a1\u5668\u4e0a\u7684 %s \u4e0d\u5339\u914d
SEVERE_ERR_EXCEPTION_FORWARDING_RESET_GEN_ID_123=\u5c06 ResetGenerationIdMsg \u8f6c\u53d1\u5230\u57df %s \u7684\u5bf9\u7b49\u590d\u5236\u670d\u52a1\u5668\u65f6\u6355\u83b7\u5230 IOException: %s
opends/src/server/org/opends/server/replication/service/ReplicationBroker.java
@@ -874,7 +874,6 @@
    stopChangeTimeHeartBeatPublishing();
    mustRunBestServerCheckingAlgorithm = 0;
    boolean newServerWithSameGroupId = false;
    synchronized (connectPhaseLock)
    {
      /*
@@ -889,164 +888,45 @@
      // Get info from every available replication servers
      replicationServerInfos = collectReplicationServersInfo();
      ReplicationServerInfo replicationServerInfo = null;
      ReplicationServerInfo electedRsInfo = null;
      if (replicationServerInfos.size() > 0)
      {
        // At least one server answered, find the best one.
        replicationServerInfo = computeBestReplicationServer(true, -1, state,
          replicationServerInfos, serverId, baseDn, groupId,
          this.getGenerationID());
        electedRsInfo = computeBestReplicationServer(true, -1, state,
          replicationServerInfos, serverId, baseDn, groupId, getGenerationID());
        // Best found, now initialize connection to this one (handshake phase 1)
        if (debugEnabled())
          debugInfo("serverId: " + serverId +
            " phase 2 : will perform PhaseOneH with the preferred RS="
              + replicationServerInfo);
        replicationServerInfo = performPhaseOneHandshake(
          replicationServerInfo.getServerURL(), true, false);
              + electedRsInfo);
        electedRsInfo = performPhaseOneHandshake(
          electedRsInfo.getServerURL(), true, false);
        if (replicationServerInfo != null)
        if (electedRsInfo != null)
        {
          // Update replication server info with potentially more up to date
          // data (server state for instance may have changed)
          replicationServerInfos.put(replicationServerInfo.getServerId(),
              replicationServerInfo);
          replicationServerInfos
              .put(electedRsInfo.getServerId(), electedRsInfo);
          // Handshake phase 1 exchange went well
          // Compute in which status we are starting the session to tell the RS
          ServerStatus initStatus =
            computeInitialServerStatus(replicationServerInfo.getGenerationId(),
            replicationServerInfo.getServerState(),
            replicationServerInfo.getDegradedStatusThreshold(),
            this.getGenerationID());
            computeInitialServerStatus(electedRsInfo.getGenerationId(),
            electedRsInfo.getServerState(),
            electedRsInfo.getDegradedStatusThreshold(),
            getGenerationID());
          // Perform session start (handshake phase 2)
          TopologyMsg topologyMsg = performPhaseTwoHandshake(
            replicationServerInfo.getServerURL(), initStatus);
            electedRsInfo.getServerURL(), initStatus);
          if (topologyMsg != null) // Handshake phase 2 exchange went well
          {
            try
            {
              /*
               * If we just connected to a RS with a different group id than us
               * (because for instance a RS with our group id was unreachable
               * while connecting to each RS) but the just received TopologyMsg
               * shows that in the same time a RS with our group id connected,
               * we must give up the connection to force reconnection that will
               * certainly go back to a server with our group id as server with
               * our group id have a greater priority for connection (in
               * computeBestReplicationServer). In other words, we disconnect to
               * connect to a server with our group id. If a server with our
               * group id comes back later in the topology, we will be advised
               * upon reception of a new TopologyMsg message and we will force
               * reconnection at that time to retrieve a server with our group
               * id.
               */
              byte tmpRsGroupId = replicationServerInfo.getGroupId();
              boolean someServersWithSameGroupId =
                hasSomeServerWithSameGroupId(topologyMsg.getRsList());
              // Really no other server with our group id ?
              if ((tmpRsGroupId == groupId) || (!someServersWithSameGroupId))
              {
                replicationServer = session.getReadableRemoteAddress();
                maxSendWindow = replicationServerInfo.getWindowSize();
                rsGroupId = replicationServerInfo.getGroupId();
                rsServerId = replicationServerInfo.getServerId();
                rsServerUrl = replicationServerInfo.getServerURL();
                receiveTopo(topologyMsg);
                // Log a message to let the administrator know that the failure
                // was resolved.
                // Wakeup all the thread that were waiting on the window
                // on the previous connection.
                connectionError = false;
                if (sendWindow != null)
                {
                  /*
                   * Fix (hack) for OPENDJ-401: we want to ensure that no
                   * threads holding this semaphore will get blocked when they
                   * acquire it. However, we also need to make sure that we
                   * don't overflow the semaphore by releasing too many permits.
                   */
                  final int MAX_PERMITS = (Integer.MAX_VALUE >>> 2);
                  if (sendWindow.availablePermits() < MAX_PERMITS)
                  {
                    /*
                     * At least 2^29 acquisitions would need to occur for this
                     * to be insufficient. In addition, at least 2^30 releases
                     * would need to occur for this to potentially overflow.
                     * Hopefully this is unlikely to happen.
                     */
                    sendWindow.release(MAX_PERMITS);
                  }
                }
                sendWindow = new Semaphore(maxSendWindow);
                rcvWindow = maxRcvWindow;
                connected = true;
                // May have created a broker with null replication domain for
                // unit test purpose.
                if (domain != null)
                {
                  domain.sessionInitiated(
                    initStatus, replicationServerInfo.getServerState(),
                    replicationServerInfo.getGenerationId(),
                    session);
                }
                if (getRsGroupId() != groupId)
                {
                  // Connected to replication server with wrong group id:
                  // warn user and start poller to recover when a server with
                  // right group id arrives...
                  Message message =
                    WARN_CONNECTED_TO_SERVER_WITH_WRONG_GROUP_ID.get(
                    Byte.toString(groupId), Integer.toString(rsServerId),
                    replicationServerInfo.getServerURL(),
                    Byte.toString(getRsGroupId()),
                    baseDn, Integer.toString(serverId));
                  logError(message);
                }
                startRSHeartBeatMonitoring();
                if (replicationServerInfo.getProtocolVersion() >=
                  ProtocolVersion.REPLICATION_PROTOCOL_V3)
                {
                  startChangeTimeHeartBeatPublishing();
                }
              } else
              {
                // Detected new RS with our group id: log disconnection to
                // inform administrator
                Message message = NOTE_NEW_SERVER_WITH_SAME_GROUP_ID.get(
                  Byte.toString(groupId), baseDn.toString(),
                  Integer.toString(serverId));
                logError(message);
                // Do not log connection error
                newServerWithSameGroupId = true;
              }
            } catch (Exception e)
            {
              Message message = ERR_COMPUTING_FAKE_OPS.get(
                baseDn, replicationServerInfo.getServerURL(),
                e.getLocalizedMessage() + stackTraceToSingleLineString(e));
              logError(message);
            } finally
            {
              if (connected == false)
              {
                ProtocolSession localSession = session;
                if (localSession != null)
                {
                  localSession.close();
                  session = null;
                }
              }
            }
            connectToReplicationServer(electedRsInfo, initStatus, topologyMsg);
          } // Could perform handshake phase 2 with best
        } // Could perform handshake phase 1 with best
@@ -1057,9 +937,8 @@
      {
        connectPhaseLock.notify();
        if ((replicationServerInfo.getGenerationId() ==
          this.getGenerationID()) ||
          (replicationServerInfo.getGenerationId() == -1))
        if ((electedRsInfo.getGenerationId() == getGenerationID())
            || (electedRsInfo.getGenerationId() == -1))
        {
          Message message = NOTE_NOW_FOUND_SAME_GENERATION_CHANGELOG
              .get(serverId, rsServerId, baseDn,
@@ -1072,7 +951,7 @@
              .get(serverId, rsServerId, baseDn,
                  session.getReadableRemoteAddress(),
                  getGenerationID(),
                  replicationServerInfo.getGenerationId());
                  electedRsInfo.getGenerationId());
          logError(message);
        }
      } else
@@ -1081,7 +960,7 @@
         * This server could not find any replicationServer. It's going to start
         * in degraded mode. Log a message.
         */
        if (!connectionError && !newServerWithSameGroupId)
        if (!connectionError)
        {
          connectionError = true;
          connectPhaseLock.notify();
@@ -1107,17 +986,104 @@
  }
  /**
   * Has the passed RS info list some servers with our group id ?
   * @return true if at least one server has the same group id
   * Connects to a replication server.
   *
   * @param rsInfo
   *          the Replication Server to connect to
   * @param initStatus
   *          The status to enter the state machine with
   * @param topologyMsg
   *          the message containing the topology information
   */
  private boolean hasSomeServerWithSameGroupId(List<RSInfo> rsInfos)
  private void connectToReplicationServer(ReplicationServerInfo rsInfo,
      ServerStatus initStatus, TopologyMsg topologyMsg)
  {
    for (RSInfo rsInfo : rsInfos)
    try
    {
      if (rsInfo.getGroupId() == this.groupId)
        return true;
      replicationServer = session.getReadableRemoteAddress();
      maxSendWindow = rsInfo.getWindowSize();
      rsGroupId = rsInfo.getGroupId();
      rsServerId = rsInfo.getServerId();
      rsServerUrl = rsInfo.getServerURL();
      receiveTopo(topologyMsg);
      // Log a message to let the administrator know that the failure
      // was resolved.
      // Wakeup all the thread that were waiting on the window
      // on the previous connection.
      connectionError = false;
      if (sendWindow != null)
      {
        /*
         * Fix (hack) for OPENDJ-401: we want to ensure that no threads holding
         * this semaphore will get blocked when they acquire it. However, we
         * also need to make sure that we don't overflow the semaphore by
         * releasing too many permits.
         */
        final int MAX_PERMITS = (Integer.MAX_VALUE >>> 2);
        if (sendWindow.availablePermits() < MAX_PERMITS)
        {
          /*
           * At least 2^29 acquisitions would need to occur for this to be
           * insufficient. In addition, at least 2^30 releases would need to
           * occur for this to potentially overflow. Hopefully this is unlikely
           * to happen.
           */
          sendWindow.release(MAX_PERMITS);
        }
      }
      sendWindow = new Semaphore(maxSendWindow);
      rcvWindow = maxRcvWindow;
      connected = true;
      // May have created a broker with null replication domain for
      // unit test purpose.
      if (domain != null)
      {
        domain.sessionInitiated(initStatus, rsInfo.getServerState(), rsInfo
            .getGenerationId(), session);
      }
      if (getRsGroupId() != groupId)
      {
        // Connected to replication server with wrong group id:
        // warn user and start poller to recover when a server with
        // right group id arrives...
        Message message =
            WARN_CONNECTED_TO_SERVER_WITH_WRONG_GROUP_ID.get(Byte
                .toString(groupId), Integer.toString(rsServerId), rsInfo
                .getServerURL(), Byte.toString(getRsGroupId()), baseDn, Integer
                .toString(serverId));
        logError(message);
      }
      startRSHeartBeatMonitoring();
      if (rsInfo.getProtocolVersion() >=
        ProtocolVersion.REPLICATION_PROTOCOL_V3)
      {
        startChangeTimeHeartBeatPublishing();
      }
    }
    return false;
    catch (Exception e)
    {
      Message message =
          ERR_COMPUTING_FAKE_OPS.get(baseDn, rsInfo.getServerURL(), e
              .getLocalizedMessage()
              + stackTraceToSingleLineString(e));
      logError(message);
    }
    finally
    {
      if (connected == false)
      {
        ProtocolSession localSession = session;
        if (localSession != null)
        {
          localSession.close();
          session = null;
        }
      }
    }
  }
  /**