From 13c6df397224971fb5ca3542ecb023b656e1a3c0 Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Tue, 05 Jul 2016 15:24:43 +0000
Subject: [PATCH] OPENDJ-3206 dsreplication initializeAll fails with no helpful error message if no other DS exist
---
opendj-server-legacy/src/messages/org/opends/messages/replication.properties | 4 ++
opendj-server-legacy/src/main/java/org/opends/server/replication/service/ReplicationDomain.java | 74 ++++++++++++++++++++++--------------
2 files changed, 49 insertions(+), 29 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/replication/service/ReplicationDomain.java b/opendj-server-legacy/src/main/java/org/opends/server/replication/service/ReplicationDomain.java
index d7b4d6a..0b822cd 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/replication/service/ReplicationDomain.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/replication/service/ReplicationDomain.java
@@ -16,6 +16,7 @@
*/
package org.opends.server.replication.service;
+import static org.forgerock.opendj.ldap.ResultCode.*;
import static org.opends.messages.ReplicationMessages.*;
import static org.opends.server.replication.common.AssuredMode.*;
import static org.opends.server.replication.common.StatusMachine.*;
@@ -27,6 +28,7 @@
import java.io.OutputStream;
import java.net.SocketTimeoutException;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
@@ -34,6 +36,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeoutException;
@@ -45,6 +48,7 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.config.server.ConfigException;
+import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.server.config.meta.ReplicationDomainCfgDefn.AssuredType;
import org.forgerock.opendj.server.config.server.ReplicationDomainCfg;
@@ -78,7 +82,6 @@
import org.opends.server.replication.protocol.UpdateMsg;
import org.opends.server.tasks.InitializeTargetTask;
import org.opends.server.tasks.InitializeTask;
-import org.forgerock.opendj.ldap.DN;
import org.opends.server.types.DirectoryException;
/**
@@ -1099,10 +1102,7 @@
}
}
- /**
- * This class contains the context related to an import or export launched on
- * the domain.
- */
+ /** This class contains the context related to an import or export launched on the domain. */
protected class ImportExportContext
{
/** The private task that initiated the operation. */
@@ -1153,8 +1153,7 @@
private final Set<Integer> failureList = new HashSet<>(0);
/**
- * Flow control during initialization: for each remote server, counter of
- * messages received.
+ * Flow control during initialization: Map of remote serverId to number of messages received.
*/
private final Map<Integer, Integer> ackVals = new HashMap<>();
/** ServerId of the slowest server (the one with the smallest non null counter). */
@@ -1339,15 +1338,18 @@
logger.trace("[IE] setAckVal[" + serverId + "]=" + numAck);
}
- this.ackVals.put(serverId, numAck);
+ ackVals.put(serverId, numAck);
// Recompute the server with the minAck returned,means the slowest server.
slowestServerId = serverId;
- for (Integer sid : importExportContext.get().ackVals.keySet())
+ int minMsgReceived = ackVals.get(serverId);
+ for (Entry<Integer, Integer> mapEntry : ackVals.entrySet())
{
- if (this.ackVals.get(sid) < this.ackVals.get(slowestServerId))
+ int nbMsgReceived = mapEntry.getValue();
+ if (nbMsgReceived < minMsgReceived)
{
- slowestServerId = sid;
+ slowestServerId = mapEntry.getKey();
+ minMsgReceived = nbMsgReceived;
}
}
}
@@ -1399,9 +1401,7 @@
}
catch (Exception e)
{
- ResultCode resultCode = ResultCode.OTHER;
- LocalizableMessage message = ERR_INVALID_EXPORT_TARGET.get();
- throw new DirectoryException(resultCode, message, e);
+ throw new DirectoryException(ResultCode.OTHER, ERR_INVALID_EXPORT_TARGET.get(), e);
}
}
@@ -1424,8 +1424,7 @@
* @throws DirectoryException If it was not possible to publish the
* Initialization message to the Topology.
*/
- public void initializeRemote(int target, Task initTask)
- throws DirectoryException
+ public void initializeRemote(int target, Task initTask) throws DirectoryException
{
initializeRemote(target, getServerId(), initTask, getInitWindow());
}
@@ -1460,15 +1459,21 @@
- to update the task with the server(s) where this test failed
*/
+ Map<Integer, DSInfo> replicaInfos = getReplicaInfos();
if (serverToInitialize == RoutableMsg.ALL_SERVERS)
{
+ if (replicaInfos.isEmpty())
+ {
+ throw new DirectoryException(UNWILLING_TO_PERFORM,
+ ERR_FULL_UPDATE_NO_REMOTES.get(getBaseDN(), getServerId()));
+ }
+
logger.info(NOTE_FULL_UPDATE_ENGAGED_FOR_REMOTE_START_ALL,
countEntries(), getBaseDN(), getServerId());
- ieCtx.startList.addAll(getReplicaInfos().keySet());
+ ieCtx.startList.addAll(replicaInfos.keySet());
- // We manage the list of servers with which a flow control can be enabled
- for (DSInfo dsi : getReplicaInfos().values())
+ for (DSInfo dsi : replicaInfos.values())
{
if (dsi.getProtocolVersion()>= ProtocolVersion.REPLICATION_PROTOCOL_V4)
{
@@ -1478,20 +1483,18 @@
}
else
{
+ DSInfo dsi = getDsInfoOrNull(replicaInfos.values(), serverToInitialize);
+ if (dsi == null)
+ {
+ throw new DirectoryException(UNWILLING_TO_PERFORM,
+ ERR_FULL_UPDATE_MISSING_REMOTE.get(getBaseDN(), getServerId(), serverToInitialize));
+ }
+
logger.info(NOTE_FULL_UPDATE_ENGAGED_FOR_REMOTE_START, countEntries(),
getBaseDN(), getServerId(), serverToInitialize);
ieCtx.startList.add(serverToInitialize);
-
- // We manage the list of servers with which a flow control can be enabled
- for (DSInfo dsi : getReplicaInfos().values())
- {
- if (dsi.getDsId() == serverToInitialize &&
- dsi.getProtocolVersion()>= ProtocolVersion.REPLICATION_PROTOCOL_V4)
- {
- ieCtx.setAckVal(dsi.getDsId(), 0);
- }
- }
+ ieCtx.setAckVal(dsi.getDsId(), 0);
}
DirectoryException exportRootException = null;
@@ -1653,6 +1656,19 @@
}
}
+ private DSInfo getDsInfoOrNull(Collection<DSInfo> replicaInfos, int serverToInitialize)
+ {
+ for (DSInfo dsi : replicaInfos)
+ {
+ if (dsi.getDsId() == serverToInitialize
+ && dsi.getProtocolVersion() >= ProtocolVersion.REPLICATION_PROTOCOL_V4)
+ {
+ return dsi;
+ }
+ }
+ return null;
+ }
+
/**
* For all remote servers in the start list:
* - wait it has finished the import and present the expected generationID,
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/replication.properties b/opendj-server-legacy/src/messages/org/opends/messages/replication.properties
index d8d02a4..5f652fb 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/replication.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/replication.properties
@@ -592,3 +592,7 @@
INFO_CHANGELOG_FILTER_OUT_RECORD_BREAKING_ORDER_296=Filtering out from log file '%s' the record '%s' \
because it would break ordering. Last key appended is '%s'.
ERR_UNRECOGNIZED_RECORD_VERSION_297=Cannot decode change-log record with version %x
+ERR_FULL_UPDATE_NO_REMOTES_298=Cannot start total update \
+ in domain "%s" from this directory server DS(%d): no remote directory servers exist
+ERR_FULL_UPDATE_MISSING_REMOTE_299=Cannot start total update \
+ in domain "%s" from this directory server DS(%d): the remote directory server DS(%d) is unknown
--
Gitblit v1.10.0