From 09ef01374239f7048c2db6bb9cad2b8a807d4cf8 Mon Sep 17 00:00:00 2001
From: pgamba <pgamba@localhost>
Date: Wed, 28 Oct 2009 08:38:19 +0000
Subject: [PATCH] Fix#4320 ECL Replication Server only should not support 'cn=changelog' naming context
---
opends/src/server/org/opends/server/replication/server/ReplicationServer.java | 84 ++++++++++++---------------
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java | 63 +++++++++++++++++---
opends/src/messages/messages/replication.properties | 4 +
opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java | 29 +++++++++
4 files changed, 122 insertions(+), 58 deletions(-)
diff --git a/opends/src/messages/messages/replication.properties b/opends/src/messages/messages/replication.properties
index 4e52d97..da7c3de 100644
--- a/opends/src/messages/messages/replication.properties
+++ b/opends/src/messages/messages/replication.properties
@@ -435,5 +435,7 @@
server for %s in local server id %s
SEVERE_ERR_SERVER_BADLY_DISCONNECTED_181= %s has badly disconnected from this \
replication server %s
-NOTICE_UNABLE_TO_ENABLE_ECL_VIRTUAL_ATTR_182=Error when loading a virtual \
+NOTICE_ERR_UNABLE_TO_ENABLE_ECL_VIRTUAL_ATTR_182=Error when loading a virtual \
attribute for external change log: Attribute: %s , Error: %s
+NOTICE_ERR_UNABLE_TO_ENABLE_ECL_183=Error in %s when enabling the external \
+ change log: %s
diff --git a/opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java b/opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java
index d1531e8..2668ae5 100644
--- a/opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java
+++ b/opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java
@@ -157,6 +157,7 @@
import org.opends.server.types.operation.PreOperationModifyDNOperation;
import org.opends.server.types.operation.PreOperationModifyOperation;
import org.opends.server.types.operation.PreOperationOperation;
+import org.opends.server.workflowelement.externalchangelog.ECLWorkflowElement;
import org.opends.server.workflowelement.localbackend.*;
/**
@@ -896,7 +897,7 @@
}
/**
- * Utility class to have get a sting iterator from an AtributeValue iterator.
+ * Utility class to have get a string iterator from an AtributeValue iterator.
* Assuming the attribute values are strings.
*/
public static class AttributeValueStringIterator implements Iterator<String>
@@ -4181,6 +4182,31 @@
super.sessionInitiated(
initStatus, replicationServerState,generationID, session);
+ // Now that we are connected , we can enable ECL if :
+ // 1/ RS must in the same JVM and created an ECL_WORKFLOW_ELEMENT
+ // and 2/ this domain must NOT be private
+ if (!getBackend().isPrivateBackend())
+ {
+ try
+ {
+ ECLWorkflowElement wfe = (ECLWorkflowElement)
+ DirectoryServer.getWorkflowElement(
+ ECLWorkflowElement.ECL_WORKFLOW_ELEMENT);
+ if (wfe!=null)
+ wfe.getReplicationServer().enableECL();
+ }
+ catch(DirectoryException de)
+ {
+ //FIXME:DirectoryException is raised by initializeECL => fix err msg
+ Message message =
+ NOTE_ERR_UNABLE_TO_ENABLE_ECL.get(
+ "Replication Domain on" + baseDn,
+ de.getMessage() + " " + de.getCause().getMessage());
+ logError(message);
+ // and go on
+ }
+ }
+
// Now for bad data set status if needed
if (force_bad_data_set)
{
@@ -4297,6 +4323,7 @@
e.getLocalizedMessage() + stackTraceToSingleLineString(e));
logError(message);
}
+
}
/**
diff --git a/opends/src/server/org/opends/server/replication/server/ReplicationServer.java b/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
index c0c1655..b4403da 100644
--- a/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
+++ b/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
@@ -185,8 +185,11 @@
*/
private static final DebugTracer TRACER = getTracer();
- private String externalChangeLogWorkflowID = "External Changelog Workflow ID";
+ private static String externalChangeLogWorkflowID =
+ "External Changelog Workflow ID";
ECLWorkflowElement eclwe;
+ WorkflowImpl externalChangeLogWorkflowImpl = null;
+
private static HashSet<Integer> localPorts = new HashSet<Integer>();
// used to synchronize the domain creation with the connect thread.
@@ -501,15 +504,6 @@
socket.setTcpNoDelay(true);
socket.connect(ServerAddr, 500);
- /*
- ServerHandler handler = new ServerHandler(
- replSessionSecurity.createClientSession(serverURL, socket,
- ReplSessionSecurity.HANDSHAKE_TIMEOUT),
- queueSize);
- handler.start(baseDn, serverId, this.serverURL, rcvWindow,
- sslEncryption, this);
- */
-
ReplicationServerHandler handler = new ReplicationServerHandler(
replSessionSecurity.createClientSession(remoteServerURL,
socket,
@@ -578,9 +572,14 @@
serverId , this);
listenThread.start();
- // Initialize the External Changelog
- // FIXME: how is WF creation enabed/disabled in the RS ?
- initializeECL();
+ // Creates the ECL workflow elem so that DS (LDAPReplicationDomain)
+ // can know me and really enableECL.
+ if (WorkflowImpl.getWorkflow(externalChangeLogWorkflowID) != null)
+ {
+ // Already done . Nothing to do
+ return;
+ }
+ eclwe = new ECLWorkflowElement(this);
if (debugEnabled())
TRACER.debugInfo("RS " +getMonitorInstanceName()+
@@ -609,64 +608,57 @@
{
//FIXME:DirectoryException is raised by initializeECL => fix err msg
Message message = Message.raw(Category.SYNC, Severity.SEVERE_ERROR,
- "Directory Exception raised by ECL initialization: " + e.getMessage());
+ "Directory Exception raised by ECL initialization: " + e.getMessage());
logError(message);
}
}
/**
- * Initializes the ECL access by creating a dedicated workflow element.
- * @throws DirectoryException
+ * Enable the ECL access by creating a dedicated workflow element.
+ * @throws DirectoryException when an error occurs.
*/
- private void initializeECL()
+ public void enableECL()
throws DirectoryException
{
- WorkflowImpl externalChangeLogWorkflow;
- if (WorkflowImpl.getWorkflow(externalChangeLogWorkflowID)
- !=null)
+ if (externalChangeLogWorkflowImpl!=null)
+ {
+ // do nothing if ECL is already enabled
return;
-
- ECLWorkflowElement eclwe = new ECLWorkflowElement(this);
+ }
// Create the workflow for the base DN and register the workflow with
// the server.
- externalChangeLogWorkflow = new WorkflowImpl(
+ externalChangeLogWorkflowImpl = new WorkflowImpl(
externalChangeLogWorkflowID,
DN.decode(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT),
eclwe.getWorkflowElementID(),
eclwe);
- externalChangeLogWorkflow.register();
+ externalChangeLogWorkflowImpl.register();
NetworkGroup defaultNetworkGroup = NetworkGroup.getDefaultNetworkGroup();
- defaultNetworkGroup.registerWorkflow(externalChangeLogWorkflow);
+ defaultNetworkGroup.registerWorkflow(externalChangeLogWorkflowImpl);
// FIXME:ECL should the ECL Workflow be registered in adminNetworkGroup?
NetworkGroup adminNetworkGroup = NetworkGroup.getAdminNetworkGroup();
- adminNetworkGroup.registerWorkflow(externalChangeLogWorkflow);
+ adminNetworkGroup.registerWorkflow(externalChangeLogWorkflowImpl);
// FIXME:ECL should the ECL Workflow be registered in internalNetworkGroup?
NetworkGroup internalNetworkGroup = NetworkGroup.getInternalNetworkGroup();
- internalNetworkGroup.registerWorkflow(externalChangeLogWorkflow);
+ internalNetworkGroup.registerWorkflow(externalChangeLogWorkflowImpl);
- try
- {
- enableECLVirtualAttr("lastexternalchangelogcookie",
- new LastCookieVirtualProvider());
- enableECLVirtualAttr("firstchangenumber",
- new FirstChangeNumberVirtualAttributeProvider());
- enableECLVirtualAttr("lastchangenumber",
- new LastChangeNumberVirtualAttributeProvider());
- enableECLVirtualAttr("changelog",
- new ChangelogBaseDNVirtualAttributeProvider());
- }
- catch (Exception e)
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
+ enableECLVirtualAttr("lastexternalchangelogcookie",
+ new LastCookieVirtualProvider());
+ enableECLVirtualAttr("firstchangenumber",
+ new FirstChangeNumberVirtualAttributeProvider());
+ enableECLVirtualAttr("lastchangenumber",
+ new LastChangeNumberVirtualAttributeProvider());
+ enableECLVirtualAttr("changelog",
+ new ChangelogBaseDNVirtualAttributeProvider());
}
- private void enableECLVirtualAttr(String attrName,
+ private static void enableECLVirtualAttr(String attrName,
VirtualAttributeProvider<UserDefinedVirtualAttributeCfg> provider)
+ throws DirectoryException
{
Set<DN> baseDNs = new HashSet<DN>(0);
Set<DN> groupDNs = new HashSet<DN>(0);
@@ -694,13 +686,13 @@
baseDNs, groupDNs, filters, conflictBehavior);
DirectoryServer.registerVirtualAttribute(rule);
-
}
catch (Exception e)
{
Message message =
- NOTE_UNABLE_TO_ENABLE_ECL_VIRTUAL_ATTR.get(attrName, e.toString());
- logError(message);
+ NOTE_ERR_UNABLE_TO_ENABLE_ECL_VIRTUAL_ATTR.get(attrName, e.toString());
+ throw new DirectoryException(ResultCode.OPERATIONS_ERROR,
+ message, e);
}
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java
index 9c67fb4..d43eb5d 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java
@@ -138,6 +138,7 @@
import org.opends.server.util.LDIFWriter;
import org.opends.server.util.TimeThread;
import org.opends.server.workflowelement.externalchangelog.ECLSearchOperation;
+import org.opends.server.workflowelement.externalchangelog.ECLWorkflowElement;
import org.opends.server.workflowelement.localbackend.LocalBackendModifyDNOperation;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
@@ -216,12 +217,32 @@
@Test(enabled=true)
public void ECLReplicationServerTest()
{
+ // No RSDomain created yet => RS only case => ECL is not a supported
+ ECLIsNotASupportedSuffix();
+
+ // Following test does not create RSDomain (only broker) but want to test
+ // ECL .. so let's enable ECl manually
+ // Now that we tested that ECl is not available
+ try
+ {
+ ECLWorkflowElement wfe = (ECLWorkflowElement)
+ DirectoryServer.getWorkflowElement(
+ ECLWorkflowElement.ECL_WORKFLOW_ELEMENT);
+ if (wfe!=null)
+ wfe.getReplicationServer().enableECL();
+ }
+ catch(DirectoryException de)
+ {
+ fail("Ending test " + " with exception:"
+ + stackTraceToSingleLineString(de));
+ }
+
// Test all types of ops.
ECLAllOps(); // Do not clean the db for the next test
// First and last should be ok whenever a request has been done or not
// in compat mode.
- ECLCompatTestLimits(1,4);replicationServer.clearDb();
+ ECLCompatTestLimits(1,4,true);replicationServer.clearDb();
// Test with a mix of domains, a mix of DSes
ECLTwoDomains(); replicationServer.clearDb();
@@ -259,7 +280,7 @@
// First and last should be ok whenever a request has been done or not
// in compat mode.
- ECLCompatTestLimits(1,4);replicationServer.clearDb();
+ ECLCompatTestLimits(1,4, true);replicationServer.clearDb();
// Test remote API (ECL through replication protocol) with NON empty ECL
ECLRemoteNonEmpty();replicationServer.clearDb();
@@ -319,7 +340,7 @@
ECLCompatReadFromTo(5,7);
// Test first and last draft changenumber
- ECLCompatTestLimits(1,8);
+ ECLCompatTestLimits(1,8, true);
// Test first and last draft changenumber, a dd a new change, do not
// search again the ECL, but search fro first and last
@@ -329,7 +350,7 @@
ECLPurgeDraftCNDbAfterChangelogClear();
// Test first and last are updated
- ECLCompatTestLimits(0,0);
+ ECLCompatTestLimits(0,0, true);
// Persistent search in changesOnly mode
ECLPsearch(true, true);replicationServer.clearDb();
@@ -346,6 +367,11 @@
}
+ private void ECLIsNotASupportedSuffix()
+ {
+ ECLCompatTestLimits(0,0, false);
+ }
+
//=======================================================
// Objectives
// - Test that everything id ok with no changes
@@ -1182,6 +1208,7 @@
try
{
+ // Root DSE
InternalSearchOperation searchOp =
connection.processSearch(
ByteString.valueOf(""),
@@ -3263,7 +3290,8 @@
debugInfo(tn, "Ending test with success");
}
- private void ECLCompatTestLimits(int expectedFirst, int expectedLast)
+ private void ECLCompatTestLimits(int expectedFirst, int expectedLast,
+ boolean eclEnabled)
{
String tn = "ECLCompatTestLimits";
debugInfo(tn, "Starting test\n\n");
@@ -3302,12 +3330,27 @@
i++;
debugInfo(tn, "Result entry returned:" + resultEntry.toLDIFString());
ldifWriter.writeEntry(resultEntry);
- checkValue(resultEntry,"firstchangenumber",
+ if (eclEnabled)
+ {
+ checkValue(resultEntry,"firstchangenumber",
String.valueOf(expectedFirst));
- checkValue(resultEntry,"lastchangenumber",
+ checkValue(resultEntry,"lastchangenumber",
String.valueOf(expectedLast));
- checkValue(resultEntry,"changelog",
+ checkValue(resultEntry,"changelog",
String.valueOf("cn=changelog"));
+ }
+ else
+ {
+ assertEquals(getAttributeValue(resultEntry, "firstchangenumber"),
+ null);
+ assertEquals(getAttributeValue(resultEntry, "lastchangenumber"),
+ null);
+ assertEquals(getAttributeValue(resultEntry, "changelog"),
+ null);
+ assertEquals(getAttributeValue(resultEntry, "lastExternalChangelogCookie"),
+ null);
+
+ }
}
}
}
@@ -3326,7 +3369,7 @@
debugInfo(tn, "Starting test\n\n");
try
{
- ECLCompatTestLimits(expectedFirst, expectedLast);
+ ECLCompatTestLimits(expectedFirst, expectedLast, true);
// Creates broker on o=test
ReplicationBroker server01 = openReplicationSession(
@@ -3346,7 +3389,7 @@
sleep(500);
server01.stop();
- ECLCompatTestLimits(expectedFirst, expectedLast+1);
+ ECLCompatTestLimits(expectedFirst, expectedLast+1, true);
}
catch(Exception e)
--
Gitblit v1.10.0