From a59bc5309dcfaa674d5f1a0257af8bb298c8002b Mon Sep 17 00:00:00 2001
From: mmarie <mmarie@localhost>
Date: Thu, 22 May 2008 08:59:31 +0000
Subject: [PATCH] 3264 : Workflow element creation ordering may lead to failure
---
opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java | 112 +++++++++++++++++++++-
opendj-sdk/opends/src/server/org/opends/server/core/WorkflowConfigManager.java | 2
opendj-sdk/opends/src/messages/messages/core.properties | 3
opendj-sdk/opends/src/server/org/opends/server/workflowelement/WorkflowElementConfigManager.java | 69 +++++++------
opendj-sdk/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java | 93 ------------------
5 files changed, 149 insertions(+), 130 deletions(-)
diff --git a/opendj-sdk/opends/src/messages/messages/core.properties b/opendj-sdk/opends/src/messages/messages/core.properties
index 17e171d..a4fcb1f 100644
--- a/opendj-sdk/opends/src/messages/messages/core.properties
+++ b/opendj-sdk/opends/src/messages/messages/core.properties
@@ -1771,3 +1771,6 @@
MILD_ERR_MODDN_NEW_SUPERIOR_IN_SUBTREE_702=The modify DN operation \
for entry %s cannot be performed because the new superior entry %s is equal \
to or a subordinate of the entry to be moved
+SEVERE_ERR_REGISTER_WORKFLOW_ELEMENT_ALREADY_EXISTS_703=Unable to register \
+ workflow element %s with the Directory Server because another workflow \
+ element with the same ID is already registered
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 5a2f5b3..8002d69 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
@@ -170,13 +170,21 @@
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.util.Validator.ensureNotNull;
-import org.opends.server.util.*;
+import org.opends.server.util.MultiOutputStream;
+import org.opends.server.util.RuntimeInformation;
+import org.opends.server.util.SetupUtils;
+import org.opends.server.util.StaticUtils;
+import org.opends.server.util.TimeThread;
+import org.opends.server.util.Validator;
+import org.opends.server.util.VersionCompatibilityIssue;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.ArgumentParser;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.StringArgument;
-import org.opends.server.workflowelement.*;
-import org.opends.server.workflowelement.localbackend.*;
+import org.opends.server.workflowelement.WorkflowElement;
+import org.opends.server.workflowelement.WorkflowElementConfigManager;
+import
+ org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement;
import org.opends.server.protocols.internal.InternalConnectionHandler;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.crypto.CryptoManagerSync;
@@ -700,6 +708,11 @@
// The writability mode for the Directory Server.
private WritabilityMode writabilityMode;
+ // The mappings between the names and WorkflowElements
+ // registered with the Directory Server
+ private ConcurrentHashMap<String, WorkflowElement> workflowElements =
+ new ConcurrentHashMap<String, WorkflowElement>();
+
// The workflow configuration mode (auto or manual).
private WorkflowConfigurationMode workflowConfigurationMode;
@@ -2788,7 +2801,7 @@
// First of all re-initialize the current workflow configuration
NetworkGroup.resetConfig();
WorkflowImpl.resetConfig();
- WorkflowElement.resetConfig();
+ directoryServer.workflowElements.clear();
// Then configure the workflows
workflowElementConfigManager = new WorkflowElementConfigManager();
@@ -2818,7 +2831,7 @@
// First of all re-initialize the current workflow configuration
NetworkGroup.resetConfig();
WorkflowImpl.resetConfig();
- WorkflowElement.resetConfig();
+ directoryServer.workflowElements.clear();
// For each base DN in a backend create a workflow and register
// the workflow with the default network group
@@ -9819,8 +9832,6 @@
return isAuto;
}
-
-
/**
* Retrieves the workflow configuration mode.
*
@@ -9831,7 +9842,94 @@
return directoryServer.workflowConfigurationMode;
}
+ /**
+ * Return the WorkflowElement associated with a name.
+ *
+ * @param workflowElementID the name of the requested workflow element
+ * @return the associated workflow element or null
+ */
+ public static WorkflowElement getWorkflowElement(String workflowElementID) {
+ return(directoryServer.workflowElements.get(workflowElementID));
+ }
+ /**
+ * Return the WorkflowElement associated with a name and try to
+ * create it if it does not exists yet.
+ *
+ * @param workflowElementID the name of the requested workflow element
+ * @return the associated workflow element
+ * @throws ConfigException if the configuration is invalid
+ * @throws InitializationException if the initialization failed
+ */
+ public static WorkflowElement getOrCreateWorkflowElement(
+ String workflowElementID)
+ throws ConfigException, InitializationException {
+
+ WorkflowElement we = directoryServer.workflowElements.get(
+ workflowElementID);
+
+ if (we == null) {
+ we = directoryServer.workflowElementConfigManager.
+ loadAndRegisterWorkflowElement(workflowElementID);
+ }
+
+ return (we);
+ }
+
+ /**
+ * Registers the provided workflow element from the Directory Server.
+ *
+ * @param we The workflow element to register. It must not be
+ * {@code null}.
+ * @throws DirectoryException If the workflow element ID for the
+ * provided workflow element conflicts with the ID of
+ * an existing workflow element.
+ */
+ public static void registerWorkflowElement(WorkflowElement we)
+ throws DirectoryException {
+ ensureNotNull(we);
+
+ String workflowElementID = we.getWorkflowElementID();
+ ensureNotNull(workflowElementID);
+
+ synchronized (directoryServer)
+ {
+ if (directoryServer.workflowElements.containsKey(workflowElementID)) {
+ Message message = ERR_REGISTER_WORKFLOW_ELEMENT_ALREADY_EXISTS.get(
+ workflowElementID);
+ } else {
+ directoryServer.workflowElements.put(workflowElementID, we);
+ }
+ }
+ }
+
+ /**
+ * Deregisters the provided workflow element from the Directory Server.
+ *
+ * @param we The workflow element to deregister. It must not be
+ * {@code null}.
+ */
+ public static void deregisterWorkflowElement(WorkflowElement we) {
+ ensureNotNull(we);
+
+ String workflowElementID = we.getWorkflowElementID();
+ ensureNotNull(workflowElementID);
+
+ synchronized (directoryServer)
+ {
+ directoryServer.workflowElements.remove(workflowElementID);
+ }
+ }
+
+ /**
+ * Verifies if the provided workflow element ID is already registered.
+ *
+ * @param workflowElementID workflow element identifier
+ * @return boolean indicating if workflow element is already registered
+ */
+ public static boolean isWorkflowElementRegistered(String workflowElementID) {
+ return (directoryServer.workflowElements.containsKey(workflowElementID));
+ }
/**
* Print messages for start-ds "-F" option (full version information).
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/WorkflowConfigManager.java b/opendj-sdk/opends/src/server/org/opends/server/core/WorkflowConfigManager.java
index 2faf2da..8ea5280 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/WorkflowConfigManager.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/WorkflowConfigManager.java
@@ -294,7 +294,7 @@
// Create the root workflow element to associate with the workflow
String rootWorkflowElementID = workflowCfg.getWorkflowElement();
WorkflowElement rootWorkflowElement =
- WorkflowElement.getWorkflowElement(rootWorkflowElementID);
+ DirectoryServer.getWorkflowElement(rootWorkflowElementID);
// Get the base DN targeted by the workflow
DN baseDN = workflowCfg.getBaseDN();
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java
index 21c7194..9911ff7 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java
@@ -26,15 +26,10 @@
*/
package org.opends.server.workflowelement;
-import static org.opends.server.util.Validator.ensureNotNull;
import static org.opends.messages.ConfigMessages.*;
import java.util.List;
-import java.util.TreeMap;
-
-import org.opends.messages.Message;
import org.opends.server.admin.std.server.WorkflowElementCfg;
-import org.opends.server.config.ConfigException;
import org.opends.server.types.Operation;
import org.opends.server.types.CanceledOperationException;
@@ -61,17 +56,6 @@
// The workflow element identifier.
private String workflowElementID = null;
-
- // The set of workflow elements registered with the server.
- // The workflow element identifier is used as a key in the map.
- private static TreeMap<String, WorkflowElement> registeredWorkflowElements =
- new TreeMap<String, WorkflowElement>();
-
-
- // A lock to protect access to the registered workflow elements.
- private static Object registeredWorkflowElementsLock = new Object();
-
-
// The parent of the workflow element (null if the workflow element is
// the root of the processing tree).
private WorkflowElement<?> parent = null;
@@ -85,7 +69,6 @@
// There is nothing to do in the constructor.
}
-
/**
* Initializes the instance of the workflow element.
*
@@ -123,7 +106,7 @@
* for this workflow element, or {@code false} if not.
*/
public boolean isConfigurationAcceptable(
- WorkflowElementCfg configuration,
+ T configuration,
List<String> unacceptableReasons)
{
// This default implementation does not perform any special
@@ -143,7 +126,6 @@
// No action is required by default.
}
-
/**
* Executes the workflow element for an operation.
*
@@ -191,78 +173,5 @@
{
return workflowElementID;
}
-
-
- /**
- * Registers the workflow element (this) with the server.
- *
- * @throws ConfigException If the workflow element ID for the provided
- * workflow element conflicts with the workflow
- * element ID of an existing workflow element.
- */
- public void register()
- throws ConfigException
- {
- ensureNotNull(workflowElementID);
-
- synchronized (registeredWorkflowElementsLock)
- {
- // the workflow element must not be already registered
- if (registeredWorkflowElements.containsKey(workflowElementID))
- {
- Message message = ERR_CONFIG_WORKFLOW_ELEMENT_ALREADY_REGISTERED.get(
- workflowElementID);
- throw new ConfigException(message);
- }
-
- TreeMap<String, WorkflowElement> newWorkflowElements =
- new TreeMap<String, WorkflowElement>(registeredWorkflowElements);
- newWorkflowElements.put(workflowElementID, this);
- registeredWorkflowElements = newWorkflowElements;
- }
- }
-
-
- /**
- * Deregisters the workflow element (this) with the server.
- */
- public void deregister()
- {
- ensureNotNull(workflowElementID);
-
- synchronized (registeredWorkflowElementsLock)
- {
- TreeMap<String, WorkflowElement> newWorkflowElements =
- new TreeMap<String, WorkflowElement>(registeredWorkflowElements);
- newWorkflowElements.remove(workflowElementID);
- registeredWorkflowElements = newWorkflowElements;
- }
- }
-
-
- /**
- * Gets a workflow element that was registered with the server.
- *
- * @param workflowElementID the ID of the workflow element to get
- * @return the requested workflow element
- */
- public static WorkflowElement getWorkflowElement(
- String workflowElementID)
- {
- return registeredWorkflowElements.get(workflowElementID);
- }
-
-
- /**
- * Resets all the registered workflows.
- */
- public static void resetConfig()
- {
- synchronized (registeredWorkflowElementsLock)
- {
- registeredWorkflowElements = new TreeMap<String, WorkflowElement>();
- }
- }
-
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/WorkflowElementConfigManager.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/WorkflowElementConfigManager.java
index 113defa..411a4e7 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/WorkflowElementConfigManager.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/WorkflowElementConfigManager.java
@@ -35,7 +35,6 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
import org.opends.messages.Message;
import org.opends.server.admin.ClassPropertyDefinition;
@@ -49,7 +48,7 @@
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
@@ -67,18 +66,12 @@
ConfigurationDeleteListener<WorkflowElementCfg>
{
- // A mapping between the DNs of the config entries and the associated
- // workflow elements.
- private ConcurrentHashMap<DN, WorkflowElement> workflowElements;
-
-
/**
* Creates a new instance of this workflow config manager.
*/
public WorkflowElementConfigManager()
{
- workflowElements = new ConcurrentHashMap<DN, WorkflowElement>();
}
@@ -113,18 +106,38 @@
//Initialize the existing workflows.
for (String workflowName : rootConfiguration.listWorkflowElements())
{
- WorkflowElementCfg workflowConfiguration =
- rootConfiguration.getWorkflowElement(workflowName);
- workflowConfiguration.addChangeListener(this);
-
- if (workflowConfiguration.isEnabled())
- {
- loadAndRegisterWorkflowElement(workflowConfiguration);
- }
+ loadAndRegisterWorkflowElement(workflowName);
}
}
+ /**
+ * Return the associated workflowElement is enabled if the
+ * workflow is enabled.
+ *
+ * @param workflowName workflow identifier
+ * @return workflowelement associated with the workflowName of null
+ * @throws org.opends.server.config.ConfigException Exception will reading
+ * the config
+ * @throws org.opends.server.types.InitializationException Exception while
+ * initializing the workflow element
+ */
+ public WorkflowElement loadAndRegisterWorkflowElement(String workflowName)
+ throws ConfigException, InitializationException {
+ ServerManagementContext managementContext =
+ ServerManagementContext.getInstance();
+ RootCfg rootConfiguration =
+ managementContext.getRootConfiguration();
+ WorkflowElementCfg workflowConfiguration =
+ rootConfiguration.getWorkflowElement(workflowName);
+ workflowConfiguration.addChangeListener(this);
+ if (workflowConfiguration.isEnabled())
+ {
+ return (loadAndRegisterWorkflowElement(workflowConfiguration));
+ }
+
+ return (null);
+ }
/**
* {@inheritDoc}
@@ -220,10 +233,10 @@
WorkflowElement workflowElement =
- workflowElements.remove(configuration.dn());
+ DirectoryServer.getWorkflowElement(configuration.dn().toString());
if (workflowElement != null)
{
- workflowElement.deregister();
+ DirectoryServer.deregisterWorkflowElement(workflowElement);
workflowElement.finalizeWorkflowElement();
}
@@ -278,7 +291,7 @@
// Get the existing workflow element if it's already enabled.
WorkflowElement existingWorkflowElement =
- workflowElements.get(configuration.dn());
+ DirectoryServer.getWorkflowElement(configuration.dn().toString());
// If the new configuration has the workflow element disabled,
// then disable it if it is enabled, or do nothing if it's already disabled.
@@ -286,8 +299,7 @@
{
if (existingWorkflowElement != null)
{
- workflowElements.remove(configuration.dn());
- existingWorkflowElement.deregister();
+ DirectoryServer.deregisterWorkflowElement(existingWorkflowElement);
existingWorkflowElement.finalizeWorkflowElement();
}
@@ -320,8 +332,8 @@
* Loads a class and instanciates it as a workflow element. The workflow
* element is initialized and registered with the server.
*
- * @param workflowCfg the workflow element configuration
- *
+ * @param workflowElementCfg the workflow element configuration
+ * @return WorkflowElement
* @throws InitializationException If a problem occurs while trying to
* decode a provided string as a DN or if
* the workflow element ID for a provided
@@ -329,7 +341,7 @@
* ID of an existing workflow during workflow
* registration.
*/
- private void loadAndRegisterWorkflowElement(
+ WorkflowElement loadAndRegisterWorkflowElement(
WorkflowElementCfg workflowElementCfg
) throws InitializationException
{
@@ -341,16 +353,13 @@
try
{
// register the workflow element
- workflowElement.register();
-
- // keep the workflow element in the list of configured workflow
- // elements
- workflowElements.put(workflowElementCfg.dn(), workflowElement);
+ DirectoryServer.registerWorkflowElement(workflowElement);
}
- catch (ConfigException de)
+ catch (DirectoryException de)
{
throw new InitializationException(de.getMessageObject());
}
+ return (workflowElement);
}
--
Gitblit v1.10.0