From 59b3651afdd66d25e0af3e4e885d422e2824ba5d Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Thu, 12 Dec 2013 13:51:35 +0000
Subject: [PATCH] Fixing a test failure in Continuous Integration. See the test failure stack trace at the bottom of this commit message. ECLReplicationServerPreTest(), the very first test of ExternalChangeLogTest, expects external changelog to be disabled. However, when GroupIdHandshakeTest was run before ExternalChangeLogTest but never removed ECL virtual attributes. This led to the "lastChangeNumber" virtual attribute having an actual value of "0" while it was expected it would not exist on the returned entry.
---
opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java | 63 +---------
opendj-sdk/opends/src/server/org/opends/server/core/VirtualAttributeConfigManager.java | 123 ++++++++++----------
opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServer.java | 127 ++++++++++----------
3 files changed, 134 insertions(+), 179 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
index 7f65dbd..8226db9 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -446,9 +446,6 @@
private List<SynchronizationProvider<SynchronizationProviderCfg>>
synchronizationProviders;
- /** The set of virtual attributes defined in the server. */
- private List<VirtualAttributeRule> virtualAttributes;
-
/**
* The set of backend initialization listeners registered with the Directory
* Server.
@@ -918,8 +915,6 @@
directoryServer.supportedFeatures = new TreeSet<String>();
directoryServer.supportedLDAPVersions =
new ConcurrentHashMap<Integer,List<ConnectionHandler>>();
- directoryServer.virtualAttributes =
- new CopyOnWriteArrayList<VirtualAttributeRule>();
directoryServer.connectionHandlers =
new CopyOnWriteArrayList<ConnectionHandler>();
directoryServer.identityMappers =
@@ -4394,9 +4389,9 @@
* @return The set of virtual attribute rules registered with the Directory
* Server.
*/
- public static List<VirtualAttributeRule> getVirtualAttributes()
+ public static Collection<VirtualAttributeRule> getVirtualAttributes()
{
- return directoryServer.virtualAttributes;
+ return directoryServer.virtualAttributeConfigManager.getVirtualAttributes();
}
@@ -4417,7 +4412,7 @@
List<VirtualAttributeRule> ruleList =
new LinkedList<VirtualAttributeRule>();
- for (VirtualAttributeRule rule : directoryServer.virtualAttributes)
+ for (VirtualAttributeRule rule : getVirtualAttributes())
{
if (rule.appliesToEntry(entry))
{
@@ -4428,68 +4423,24 @@
return ruleList;
}
-
-
/**
* Registers the provided virtual attribute rule with the Directory Server.
*
* @param rule The virtual attribute rule to be registered.
*/
- public static void registerVirtualAttribute(VirtualAttributeRule rule)
+ public static void registerVirtualAttribute(final VirtualAttributeRule rule)
{
- synchronized (directoryServer.virtualAttributes)
- {
- directoryServer.virtualAttributes.add(rule);
- }
+ getInstance().virtualAttributeConfigManager.register(rule);
}
-
-
/**
* Deregisters the provided virtual attribute rule with the Directory Server.
*
- * @param rule The virutal attribute rule to be deregistered.
+ * @param rule The virtual attribute rule to be deregistered.
*/
public static void deregisterVirtualAttribute(VirtualAttributeRule rule)
{
- synchronized (directoryServer.virtualAttributes)
- {
- directoryServer.virtualAttributes.remove(rule);
- }
- }
-
-
-
- /**
- * Replaces the specified virtual attribute rule in the set of virtual
- * attributes registered with the Directory Server. If the old rule cannot
- * be found in the list, then the set of registered virtual attributes is not
- * updated.
- *
- * @param oldRule The existing rule that should be replaced with the new
- * rule.
- * @param newRule The new rule that should be used in place of the existing
- * rule.
- *
- * @return {@code true} if the old rule was found and replaced with the new
- * version, or {@code false} if it was not.
- */
- public static boolean replaceVirtualAttribute(VirtualAttributeRule oldRule,
- VirtualAttributeRule newRule)
- {
- synchronized (directoryServer.virtualAttributes)
- {
- int pos = directoryServer.virtualAttributes.indexOf(oldRule);
- if (pos >= 0)
- {
- directoryServer.virtualAttributes.set(pos, newRule);
- return true;
- }
- else
- {
- return false;
- }
- }
+ getInstance().virtualAttributeConfigManager.deregister(rule);
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/VirtualAttributeConfigManager.java b/opendj-sdk/opends/src/server/org/opends/server/core/VirtualAttributeConfigManager.java
index 572423f..64dca8e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/VirtualAttributeConfigManager.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/VirtualAttributeConfigManager.java
@@ -27,7 +27,6 @@
*/
package org.opends.server.core;
-import java.lang.reflect.Method;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
@@ -104,8 +103,7 @@
// Get the root configuration object.
ServerManagementContext managementContext =
ServerManagementContext.getInstance();
- RootCfg rootConfiguration =
- managementContext.getRootConfiguration();
+ RootCfg rootConfiguration = managementContext.getRootConfiguration();
// Register as an add and delete listener with the root configuration so we
@@ -162,7 +160,6 @@
VirtualAttributeRule rule = createRule(cfg, provider, filters);
rules.put(cfg.dn(), rule);
- DirectoryServer.registerVirtualAttribute(rule);
}
catch (InitializationException ie)
{
@@ -185,10 +182,7 @@
cfg.getConflictBehavior());
}
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public boolean isConfigurationAddAcceptable(
VirtualAttributeCfg configuration,
@@ -242,11 +236,7 @@
return filters;
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public ConfigChangeResult applyConfigurationAdd(
VirtualAttributeCfg configuration)
@@ -296,17 +286,12 @@
{
VirtualAttributeRule rule = createRule(configuration, provider, filters);
rules.put(configuration.dn(), rule);
- DirectoryServer.registerVirtualAttribute(rule);
}
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public boolean isConfigurationDeleteAcceptable(
VirtualAttributeCfg configuration,
@@ -316,11 +301,7 @@
return true;
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public ConfigChangeResult applyConfigurationDelete(
VirtualAttributeCfg configuration)
@@ -332,18 +313,13 @@
VirtualAttributeRule rule = rules.remove(configuration.dn());
if (rule != null)
{
- DirectoryServer.deregisterVirtualAttribute(rule);
rule.getProvider().finalizeVirtualAttributeProvider();
}
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public boolean isConfigurationChangeAcceptable(
VirtualAttributeCfg configuration,
@@ -384,11 +360,7 @@
return true;
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public ConfigChangeResult applyConfigurationChange(
VirtualAttributeCfg configuration)
@@ -409,7 +381,6 @@
if (existingRule != null)
{
rules.remove(configuration.dn());
- DirectoryServer.deregisterVirtualAttribute(existingRule);
existingRule.getProvider().finalizeVirtualAttributeProvider();
}
@@ -450,15 +421,9 @@
if (resultCode == ResultCode.SUCCESS)
{
VirtualAttributeRule rule = createRule(configuration, provider, filters);
-
rules.put(configuration.dn(), rule);
- if (existingRule == null)
+ if (existingRule != null)
{
- DirectoryServer.registerVirtualAttribute(rule);
- }
- else
- {
- DirectoryServer.replaceVirtualAttribute(existingRule, rule);
existingRule.getProvider().finalizeVirtualAttributeProvider();
}
}
@@ -474,7 +439,7 @@
*
* @param className The fully-qualified name of the certificate mapper
* class to load, instantiate, and initialize.
- * @param configuration The configuration to use to initialize the
+ * @param cfg The configuration to use to initialize the
* virtual attribute provider. It must not be
* {@code null}.
* @param initialize Indicates whether the virtual attribute provider
@@ -485,8 +450,9 @@
* @throws InitializationException If a problem occurred while attempting to
* initialize the certificate mapper.
*/
+ @SuppressWarnings({ "rawtypes", "unchecked" })
private VirtualAttributeProvider<? extends VirtualAttributeCfg>
- loadProvider(String className, VirtualAttributeCfg configuration,
+ loadProvider(String className, VirtualAttributeCfg cfg,
boolean initialize)
throws InitializationException
{
@@ -499,31 +465,20 @@
Class<? extends VirtualAttributeProvider> providerClass =
propertyDefinition.loadClass(className,
VirtualAttributeProvider.class);
- VirtualAttributeProvider<? extends VirtualAttributeCfg> provider =
- providerClass.newInstance();
+ VirtualAttributeProvider provider = providerClass.newInstance();
if (initialize)
{
- Method method = provider.getClass().getMethod(
- "initializeVirtualAttributeProvider",
- configuration.configurationClass());
- method.invoke(provider, configuration);
+ provider.initializeVirtualAttributeProvider(cfg);
}
else
{
- Method method =
- provider.getClass().getMethod("isConfigurationAcceptable",
- VirtualAttributeCfg.class,
- List.class);
-
List<Message> unacceptableReasons = new ArrayList<Message>();
- Boolean acceptable = (Boolean) method.invoke(provider, configuration,
- unacceptableReasons);
- if (! acceptable)
+ if (!provider.isConfigurationAcceptable(cfg, unacceptableReasons))
{
String reasons = collectionToString(unacceptableReasons, ". ");
Message message = ERR_CONFIG_VATTR_CONFIG_NOT_ACCEPTABLE.get(
- String.valueOf(configuration.dn()), reasons);
+ String.valueOf(cfg.dn()), reasons);
throw new InitializationException(message);
}
}
@@ -533,9 +488,55 @@
catch (Exception e)
{
Message message = ERR_CONFIG_VATTR_INITIALIZATION_FAILED.
- get(className, String.valueOf(configuration.dn()),
+ get(className, String.valueOf(cfg.dn()),
stackTraceToSingleLineString(e));
throw new InitializationException(message, e);
}
}
+
+ /**
+ * Retrieves the collection of registered virtual attribute rules.
+ *
+ * @return The collection of registered virtual attribute rules.
+ */
+ public Collection<VirtualAttributeRule> getVirtualAttributes()
+ {
+ return this.rules.values();
+ }
+
+ /**
+ * Registers the provided virtual attribute rule.
+ *
+ * @param rule
+ * The virtual attribute rule to be registered.
+ */
+ public void register(VirtualAttributeRule rule)
+ {
+ rules.put(getDummyDN(rule), rule);
+ }
+
+ /**
+ * Deregisters the provided virtual attribute rule.
+ *
+ * @param rule
+ * The virtual attribute rule to be deregistered.
+ */
+ public void deregister(VirtualAttributeRule rule)
+ {
+ rules.remove(getDummyDN(rule));
+ }
+
+ private DN getDummyDN(VirtualAttributeRule rule)
+ {
+ try
+ {
+ String name = rule.getAttributeType().getNameOrOID();
+ return DN.decode("cn=" + name + ",cn=Virtual Attributes,cn=config");
+ }
+ catch (DirectoryException e)
+ {
+ // should never happen
+ throw new RuntimeException(e);
+ }
+ }
}
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 b444e40..c05d427 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
@@ -32,13 +32,13 @@
import java.net.*;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.atomic.AtomicReference;
import org.opends.messages.Category;
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import org.opends.messages.Severity;
import org.opends.server.admin.server.ConfigurationChangeListener;
-import org.opends.server.admin.std.meta.VirtualAttributeCfgDefn;
import org.opends.server.admin.std.meta.VirtualAttributeCfgDefn.*;
import org.opends.server.admin.std.server.ReplicationServerCfg;
import org.opends.server.admin.std.server.UserDefinedVirtualAttributeCfg;
@@ -111,10 +111,11 @@
*/
private static final DebugTracer TRACER = getTracer();
- private static String externalChangeLogWorkflowID =
+ private static String eclWorkflowID =
"External Changelog Workflow ID";
private ECLWorkflowElement eclwe;
- private WorkflowImpl externalChangeLogWorkflowImpl = null;
+ private AtomicReference<WorkflowImpl> eclWorkflowImpl =
+ new AtomicReference<WorkflowImpl>();
/**
* This is required for unit testing, so that we can keep track of all the
@@ -428,7 +429,7 @@
// Creates the ECL workflow elem so that DS (LDAPReplicationDomain)
// can know me and really enableECL.
- if (WorkflowImpl.getWorkflow(externalChangeLogWorkflowID) != null)
+ if (WorkflowImpl.getWorkflow(eclWorkflowID) != null)
{
// Already done. Nothing to do
return;
@@ -461,54 +462,54 @@
*/
public void enableECL() throws DirectoryException
{
- if (externalChangeLogWorkflowImpl!=null)
+ if (eclWorkflowImpl.get() != null)
{
- // do nothing if ECL is already enabled
+ // ECL is already enabled, do nothing
return;
}
- // Create the workflow for the base DN and register the workflow with
- // the server.
- externalChangeLogWorkflowImpl = new WorkflowImpl(
- externalChangeLogWorkflowID,
- DN.decode(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT),
- eclwe.getWorkflowElementID(),
- eclwe);
- externalChangeLogWorkflowImpl.register();
+ // Create the workflow for the base DN
+ // and register the workflow with the server.
+ final DN dn = DN.decode(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT);
+ final WorkflowImpl workflowImpl = new WorkflowImpl(eclWorkflowID, dn,
+ eclwe.getWorkflowElementID(), eclwe);
+ if (!eclWorkflowImpl.compareAndSet(null, workflowImpl))
+ {
+ // ECL is being enabled, do nothing
+ return;
+ }
- NetworkGroup defaultNetworkGroup = NetworkGroup.getDefaultNetworkGroup();
- defaultNetworkGroup.registerWorkflow(externalChangeLogWorkflowImpl);
+ workflowImpl.register();
- // FIXME:ECL should the ECL Workflow be registered in adminNetworkGroup?
- NetworkGroup adminNetworkGroup = NetworkGroup.getAdminNetworkGroup();
- adminNetworkGroup.registerWorkflow(externalChangeLogWorkflowImpl);
+ NetworkGroup.getDefaultNetworkGroup().registerWorkflow(workflowImpl);
- // FIXME:ECL should the ECL Workflow be registered in internalNetworkGroup?
- NetworkGroup internalNetworkGroup = NetworkGroup.getInternalNetworkGroup();
- internalNetworkGroup.registerWorkflow(externalChangeLogWorkflowImpl);
+ // FIXME:ECL should the ECL Workflow be registered in admin and internal
+ // network groups?
+ NetworkGroup.getAdminNetworkGroup().registerWorkflow(workflowImpl);
+ NetworkGroup.getInternalNetworkGroup().registerWorkflow(workflowImpl);
- enableECLVirtualAttr("lastexternalchangelogcookie",
- new LastCookieVirtualProvider());
- enableECLVirtualAttr("firstchangenumber",
- new FirstChangeNumberVirtualAttributeProvider());
- enableECLVirtualAttr("lastchangenumber",
- new LastChangeNumberVirtualAttributeProvider());
- enableECLVirtualAttr("changelog",
- new ChangelogBaseDNVirtualAttributeProvider());
+ DirectoryServer.registerVirtualAttribute(buildVirtualAttributeRule(
+ "lastexternalchangelogcookie", new LastCookieVirtualProvider()));
+ DirectoryServer.registerVirtualAttribute(buildVirtualAttributeRule(
+ "firstchangenumber", new FirstChangeNumberVirtualAttributeProvider()));
+ DirectoryServer.registerVirtualAttribute(buildVirtualAttributeRule(
+ "lastchangenumber", new LastChangeNumberVirtualAttributeProvider()));
+ DirectoryServer.registerVirtualAttribute(buildVirtualAttributeRule(
+ "changelog", new ChangelogBaseDNVirtualAttributeProvider()));
}
- private static void enableECLVirtualAttr(String attrName,
+ private static VirtualAttributeRule buildVirtualAttributeRule(String attrName,
VirtualAttributeProvider<UserDefinedVirtualAttributeCfg> provider)
- throws DirectoryException
+ throws DirectoryException
{
- Set<DN> baseDNs = new HashSet<DN>(0);
- Set<DN> groupDNs = new HashSet<DN>(0);
- Set<SearchFilter> filters = new HashSet<SearchFilter>(0);
- VirtualAttributeCfgDefn.ConflictBehavior conflictBehavior =
- ConflictBehavior.VIRTUAL_OVERRIDES_REAL;
+ ConflictBehavior conflictBehavior = ConflictBehavior.VIRTUAL_OVERRIDES_REAL;
try
{
+ Set<DN> baseDNs = Collections.singleton(DN.decode(""));
+ Set<DN> groupDNs = Collections.emptySet();
+ Set<SearchFilter> filters = Collections.singleton(
+ SearchFilter.createFilterFromString("(objectclass=*)"));
// To avoid the configuration in cn=config just
// create a rule and register it into the DirectoryServer
@@ -517,17 +518,9 @@
AttributeType attributeType = DirectoryServer.getAttributeType(
attrName, false);
- SearchFilter filter =
- SearchFilter.createFilterFromString("objectclass=*");
- filters.add(filter);
-
- baseDNs.add(DN.decode(""));
- VirtualAttributeRule rule =
- new VirtualAttributeRule(attributeType, provider,
- baseDNs, SearchScope.BASE_OBJECT,
- groupDNs, filters, conflictBehavior);
-
- DirectoryServer.registerVirtualAttribute(rule);
+ return new VirtualAttributeRule(attributeType, provider,
+ baseDNs, SearchScope.BASE_OBJECT,
+ groupDNs, filters, conflictBehavior);
}
catch (Exception e)
{
@@ -539,25 +532,35 @@
private void shutdownECL()
{
- WorkflowImpl eclwf = (WorkflowImpl) WorkflowImpl
- .getWorkflow(externalChangeLogWorkflowID);
-
+ WorkflowImpl eclwf = (WorkflowImpl) WorkflowImpl.getWorkflow(eclWorkflowID);
// do it only if not already done by another RS (unit test case)
- // if (DirectoryServer.getWorkflowElement(externalChangeLogWorkflowID)
if (eclwf != null)
{
- // FIXME:ECL should the ECL Workflow be registered in
- // internalNetworkGroup?
- NetworkGroup internalNetworkGroup = NetworkGroup
- .getInternalNetworkGroup();
- internalNetworkGroup.deregisterWorkflow(externalChangeLogWorkflowID);
+ // FIXME:ECL should the ECL Workflow be registered in admin and internal
+ // network groups?
+ NetworkGroup.getInternalNetworkGroup().deregisterWorkflow(eclWorkflowID);
+ NetworkGroup.getAdminNetworkGroup().deregisterWorkflow(eclWorkflowID);
- // FIXME:ECL should the ECL Workflow be registered in adminNetworkGroup?
- NetworkGroup adminNetworkGroup = NetworkGroup.getAdminNetworkGroup();
- adminNetworkGroup.deregisterWorkflow(externalChangeLogWorkflowID);
+ NetworkGroup.getDefaultNetworkGroup().deregisterWorkflow(eclWorkflowID);
- NetworkGroup defaultNetworkGroup = NetworkGroup.getDefaultNetworkGroup();
- defaultNetworkGroup.deregisterWorkflow(externalChangeLogWorkflowID);
+ try
+ {
+ DirectoryServer.deregisterVirtualAttribute(buildVirtualAttributeRule(
+ "lastexternalchangelogcookie", new LastCookieVirtualProvider()));
+ DirectoryServer.deregisterVirtualAttribute(buildVirtualAttributeRule(
+ "firstchangenumber",
+ new FirstChangeNumberVirtualAttributeProvider()));
+ DirectoryServer.deregisterVirtualAttribute(buildVirtualAttributeRule(
+ "lastchangenumber",
+ new LastChangeNumberVirtualAttributeProvider()));
+ DirectoryServer.deregisterVirtualAttribute(buildVirtualAttributeRule(
+ "changelog", new ChangelogBaseDNVirtualAttributeProvider()));
+ }
+ catch (DirectoryException e)
+ {
+ // Should never happen
+ throw new RuntimeException(e);
+ }
eclwf.deregister();
eclwf.finalizeWorkflow();
--
Gitblit v1.10.0