From 7d9f9ebbdd79002266e85efa0f7f19aeb7339e9b Mon Sep 17 00:00:00 2001
From: jdemendi <jdemendi@localhost>
Date: Fri, 31 Oct 2008 11:12:52 +0000
Subject: [PATCH] fix 35353, Workflows are not notified when their root workflow elements are disabled
---
opendj-sdk/opends/src/server/org/opends/server/core/WorkflowResultCode.java | 11
opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java | 7
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowConfigurationTest.java | 39 ++-
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowTopologyTest.java | 30 +-
opendj-sdk/opends/src/server/org/opends/server/core/WorkflowConfigManager.java | 14
opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/WorkflowConfiguration.xml | 2
opendj-sdk/opends/src/server/org/opends/server/workflowelement/WorkflowElementConfigManager.java | 52 +++-
opendj-sdk/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java | 184 ++++++++++++++++
opendj-sdk/opends/src/server/org/opends/server/core/WorkflowImpl.java | 167 ++++++++++++++
opendj-sdk/opends/src/server/org/opends/server/workflowelement/ObservableWorkflowElementState.java | 99 +++++++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java | 10
11 files changed, 542 insertions(+), 73 deletions(-)
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/WorkflowConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/WorkflowConfiguration.xml
index adef53f..35f8a24 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/WorkflowConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/WorkflowConfiguration.xml
@@ -107,7 +107,7 @@
</ldap:attribute>
</adm:profile>
</adm:property>
- <adm:property name="base-dn" mandatory="true">
+ <adm:property name="base-dn" mandatory="true" read-only="true">
<adm:synopsis>
Specifies the base DN of the data targeted by the
<adm:user-friendly-name />
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 2e69d06..5d5c9ff 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
@@ -2735,10 +2735,13 @@
// backendID and baseDN should be ok.
String workflowID = backend.getBackendID() + "#" + baseDN.toString();
- // Create the worklfow for the base DN and register the workflow with
+ // Create the workflow for the base DN and register the workflow with
// the server.
WorkflowImpl workflowImpl = new WorkflowImpl(
- workflowID, baseDN, (WorkflowElement) rootWE);
+ workflowID,
+ baseDN,
+ rootWE.getWorkflowElementID(),
+ (WorkflowElement) rootWE);
workflowImpl.register();
return workflowImpl;
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 b51ce36..a0d79a6 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
@@ -234,10 +234,10 @@
new ConfigChangeResult(resultCode, adminActionRequired, messages);
- // Get the existing network group if it's already enabled.
+ // Get the existing workflow if it's already enabled.
WorkflowImpl existingWorkflow = workflows.get(configuration.dn());
- // If the new configuration has the validator disabled, then disable it if
+ // If the new configuration has the workflow disabled, then disable it if
// it is enabled, or do nothing if it's already disabled.
if (! configuration.isEnabled())
{
@@ -251,7 +251,7 @@
return configChangeResult;
}
- // If the network group is disabled then create and register it.
+ // If the workflow is disabled then create and register it.
if (existingWorkflow == null)
{
try
@@ -268,6 +268,11 @@
messages.add(de.getMessageObject());
}
}
+ else
+ {
+ // The workflow already exist, just notify the changes to the workflow
+ existingWorkflow.updateConfig(configuration);
+ }
return configChangeResult;
}
@@ -302,7 +307,8 @@
// Create the workflow and register it with the server
WorkflowImpl workflowImpl =
- new WorkflowImpl(workflowId, baseDN, rootWorkflowElement);
+ new WorkflowImpl(
+ workflowId, baseDN, rootWorkflowElementID, rootWorkflowElement);
workflows.put(workflowCfg.dn(), workflowImpl);
workflowImpl.register();
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/WorkflowImpl.java b/opendj-sdk/opends/src/server/org/opends/server/core/WorkflowImpl.java
index 10208e0..ca8ce53 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/WorkflowImpl.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/WorkflowImpl.java
@@ -27,16 +27,19 @@
package org.opends.server.core;
import static org.opends.messages.CoreMessages.*;
-import org.opends.messages.Message;
-import org.opends.messages.MessageBuilder;
-
import static org.opends.server.util.Validator.ensureNotNull;
import java.util.Collection;
+import java.util.Observable;
+import java.util.Observer;
import java.util.TreeMap;
+import org.opends.messages.Message;
+import org.opends.messages.MessageBuilder;
+import org.opends.server.admin.std.server.WorkflowCfg;
import org.opends.server.types.*;
import org.opends.server.workflowelement.WorkflowElement;
+import org.opends.server.workflowelement.ObservableWorkflowElementState;
/**
@@ -48,16 +51,19 @@
* task in turn will execute its subordinate nodes and synchronizes them
* as needed.
*/
-public class WorkflowImpl implements Workflow
+public class WorkflowImpl implements Workflow, Observer
{
// The workflow identifier used by the configuration.
- private String workflowID = null;
+ private final String workflowID;
// The root of the workflow task tree.
private WorkflowElement<?> rootWorkflowElement = null;
+ // The root workflow element identifier.
+ private String rootWorkflowElementID = null;
+
// The base DN of the data handled by the workflow.
- private DN baseDN = null;
+ private final DN baseDN;
// Flag indicating whether the workflow root node of the task tree is
// handling a private local backend.
@@ -81,7 +87,7 @@
/**
- * Creates a new instance of a workflow implementation. To define a worfklow
+ * Creates a new instance of a workflow implementation. To define a workflow
* one needs to provide a task tree root node (the rootWorkflowElement) and
* a base DN to identify the data set upon which the tasks can be applied.
*
@@ -89,11 +95,13 @@
*
* @param workflowId workflow internal identifier
* @param baseDN identifies the data handled by the workflow
+ * @param rootWorkflowElementID the identifier of the root workflow element
* @param rootWorkflowElement the root node of the workflow task tree
*/
public WorkflowImpl(
String workflowId,
DN baseDN,
+ String rootWorkflowElementID,
WorkflowElement<?> rootWorkflowElement
)
{
@@ -103,6 +111,20 @@
if (this.rootWorkflowElement != null)
{
this.isPrivate = rootWorkflowElement.isPrivate();
+ this.rootWorkflowElementID = rootWorkflowElementID;
+
+ // The workflow wants to be notified when the workflow element state
+ // is changing from enabled to disabled and vice versa.
+ WorkflowElement.registereForStateUpdate(
+ rootWorkflowElement, null, this);
+ }
+ else
+ {
+ // The root workflow element has not been loaded, let's register
+ // the workflow with the list of objects that want to be notify
+ // when the workflow element is created.
+ WorkflowElement.registereForStateUpdate(
+ null, rootWorkflowElementID, this);
}
}
@@ -198,7 +220,7 @@
if (registeredWorkflows.containsKey(workflowID))
{
Message message =
- ERR_REGISTER_WORKFLOW_ALREADY_EXISTS.get(workflowID);
+ ERR_REGISTER_WORKFLOW_ALREADY_EXISTS.get(workflowID);
throw new DirectoryException(
ResultCode.UNWILLING_TO_PERFORM, message);
}
@@ -218,6 +240,12 @@
{
ensureNotNull(workflowID);
+ // Deregister the workflow with the list of objects to notify when
+ // a workflow element is created or deleted.
+ WorkflowElement.deregistereForStateUpdate(
+ null, rootWorkflowElementID, this);
+
+ // Deregister the workflow with the list of registered workflows.
synchronized (registeredWorkflowsLock)
{
TreeMap<String, Workflow> newWorkflows =
@@ -315,4 +343,127 @@
}
}
+
+ /**
+ * Updates the workflow configuration. This method should be invoked
+ * whenever an existing workflow is modified.
+ *
+ * @param configuration the new workflow configuration
+ */
+ public void updateConfig(WorkflowCfg configuration)
+ {
+ // The only parameter that can be changed is the root workflow element.
+ String rootWorkflowElementID = configuration.getWorkflowElement();
+ WorkflowElement<?> rootWorkflowElement =
+ DirectoryServer.getWorkflowElement(rootWorkflowElementID);
+
+ // Update the ID of the new root workflow element
+ // and deregister the workflow with the list of objects to notify
+ // when the former root workflow element is created
+ String previousRootWorkflowElement = this.rootWorkflowElementID;
+ WorkflowElement.deregistereForStateUpdate(
+ null, previousRootWorkflowElement, this);
+ this.rootWorkflowElementID = rootWorkflowElementID;
+
+ // Does the new root workflow element exist?
+ if (rootWorkflowElement == null)
+ {
+ // The new root workflow element does not exist yet then do nothing
+ // but register with the list of object to notify when the workflow
+ // element is created (and deregister first in case the workflow
+ // was already registered)
+ WorkflowElement.registereForStateUpdate(
+ null, rootWorkflowElementID, this);
+ rootWorkflowElement = null;
+ }
+ else
+ {
+ // The new root workflow element exists, let's use it and don't forget
+ // to register with the list of objects to notify when the workflow
+ // element is deleted.
+ this.rootWorkflowElement = rootWorkflowElement;
+ WorkflowElement.registereForStateUpdate(
+ rootWorkflowElement, null, this);
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void update(Observable observable, Object arg)
+ {
+ if (observable instanceof ObservableWorkflowElementState)
+ {
+ ObservableWorkflowElementState weState =
+ (ObservableWorkflowElementState) observable;
+ updateRootWorkflowElementState(weState);
+ }
+ }
+
+
+ /**
+ * Display the workflow object.
+ * @return a string identifying the workflow.
+ */
+ public String toString()
+ {
+ String id = "Workflow " + workflowID;
+ return id;
+ }
+
+
+ /**
+ * Takes into account an update of the root workflow element.
+ * <p>
+ * This method is called when a workflow element is created or
+ * deleted. If the workflow element is the root workflow element
+ * then the workflow processes it as follow:
+ * <br>
+ * If the workflow element is disabled then the workflow reset
+ * its root workflow element (ie. the workflow has no more workflow
+ * element, hence the workflow cannot process requests anymore).
+ * <br>
+ * If the workflow element is enabled then the workflow adopts the
+ * workflow element as its new root workflow element. The workflow
+ * then can process requests again.
+ *
+ * @param weState the new state of the root workflow element
+ */
+ private void updateRootWorkflowElementState(
+ ObservableWorkflowElementState weState)
+ {
+ // Check that the workflow element maps the root workflow element.
+ // If not then ignore the workflow element.
+ WorkflowElement<?> we = weState.getObservedWorkflowElement();
+ String newWorkflowElementID = we.getWorkflowElementID();
+ if (! rootWorkflowElementID.equalsIgnoreCase(newWorkflowElementID))
+ {
+ return;
+ }
+
+ // The workflow element maps the root workflow element, let's process it.
+ if (weState.workflowElementIsEnabled())
+ {
+ // The root workflow element is enabled, let's use it
+ // and don't forget to register the workflow with the list
+ // of objects to notify when the root workflow element
+ // is disabled...
+ rootWorkflowElement = weState.getObservedWorkflowElement();
+ WorkflowElement.registereForStateUpdate(
+ rootWorkflowElement, null, this);
+ WorkflowElement.deregistereForStateUpdate(
+ null, rootWorkflowElementID, this);
+ }
+ else
+ {
+ // The root workflow element has been disabled. Reset the current
+ // reference to the root workflow element and register the workflow
+ // with the list of objects to notify when new workflow elements
+ // are created.
+ WorkflowElement.registereForStateUpdate(
+ null, rootWorkflowElement.getWorkflowElementID(), this);
+ rootWorkflowElement = null;
+ }
+ }
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/WorkflowResultCode.java b/opendj-sdk/opends/src/server/org/opends/server/core/WorkflowResultCode.java
index 5b54e3b..9a9ec53 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/WorkflowResultCode.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/WorkflowResultCode.java
@@ -207,16 +207,7 @@
errorMessage = new MessageBuilder (newErrorMessage);
break;
default:
- // global resultCode remains the same but append the new
- // error message into the current error message
- if (errorMessage == null)
- {
- errorMessage = new MessageBuilder (newErrorMessage);
- }
- else
- {
- errorMessage.append(newErrorMessage);
- }
+ // Do nothing (we don't want to override the first error)
break;
}
break;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/ObservableWorkflowElementState.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/ObservableWorkflowElementState.java
new file mode 100644
index 0000000..6ba7914
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/ObservableWorkflowElementState.java
@@ -0,0 +1,99 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.workflowelement;
+
+import java.util.Observable;
+
+
+/**
+ * This class implements an observable workflow element state.
+ * The observable workflow element state notifies observers when the
+ * state of the workflow element has changed. Typically, observers are
+ * notified when a workflow element is enabled or disabled.
+ */
+public class ObservableWorkflowElementState extends Observable
+{
+ // The observed workflow element
+ private final WorkflowElement<?> observedWorkflowElement;
+
+
+ // The "enabled" state of the observed workflow element.
+ // By default, a workflow element is enabled (otherwise this
+ // instance of workflow element state would not exist).
+ private boolean enabled = true;
+
+
+ /**
+ * Creates an instance of an observable object for a given workflow
+ * element.
+ *
+ * @param observedWorkflowElement the workflow element to observe
+ */
+ public ObservableWorkflowElementState(
+ WorkflowElement<?> observedWorkflowElement)
+ {
+ this.observedWorkflowElement = observedWorkflowElement;
+ }
+
+
+ /**
+ * Gets the observed workflow element.
+ * @return the observed workflow element.
+ */
+ public WorkflowElement<?> getObservedWorkflowElement()
+ {
+ return observedWorkflowElement;
+ }
+
+
+ /**
+ * Allows the observed workflow element to indicate its new state
+ * (enabled or disabled).
+ *
+ * @param enabled the new "enabled" state of the observed workflow element
+ */
+ public void setWorkflowElementEnabled(
+ boolean enabled)
+ {
+ if (this.enabled != enabled)
+ {
+ setChanged();
+ this.enabled = enabled;
+ }
+ }
+
+
+ /**
+ * Indicates whether the observed workflow element is enabled or not.
+ *
+ * @return <code>true</code> if the observed workflow element is enabled.
+ */
+ public boolean workflowElementIsEnabled()
+ {
+ return enabled;
+ }
+}
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 7b8a29b..80eaff5 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
@@ -27,7 +27,13 @@
package org.opends.server.workflowelement;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
import org.opends.server.admin.std.server.WorkflowElementCfg;
import org.opends.server.types.Operation;
import org.opends.server.types.CanceledOperationException;
@@ -44,8 +50,8 @@
*
* @param <T> The type of configuration handled by this workflow element.
*/
-public abstract class WorkflowElement
- <T extends WorkflowElementCfg>
+public abstract class WorkflowElement <T extends WorkflowElementCfg>
+ implements Observer
{
// Indicates whether the workflow element encapsulates a private local
// backend.
@@ -61,6 +67,170 @@
private String workflowElementID = null;
+ // The observable state of the workflow element.
+ private ObservableWorkflowElementState observableState =
+ new ObservableWorkflowElementState(this);
+
+
+ // The list of observers who want to be notified when a workflow element
+ // required by the observer is created. The key of the map is a string
+ // that identifies the newly created workflow element.
+ private static ConcurrentMap<String, List<Observer>>
+ newWorkflowElementNotificationList =
+ new ConcurrentHashMap<String, List<Observer>>();
+
+
+ /**
+ * Provides the observable state of the workflow element.
+ * This method is intended to be called by the WorkflowElementConfigManager
+ * that wants to notify observers that the workflow element state has
+ * changed (in particular when a workflow element has been disabled).
+ *
+ * @return the observable state of the workflow element
+ */
+ protected ObservableWorkflowElementState getObservableState()
+ {
+ return observableState;
+ }
+
+
+ /**
+ * Registers with a specific workflow element to be notified when the
+ * workflow element state has changed. This notification system is
+ * mainly used to be warned when a workflow element is enabled or
+ * disabled.
+ * <p>
+ * If the workflow element <code>we</code> is not <code>null</code>
+ * then the <code>observer</code> is registered with the list of objects
+ * to notify when <code>we</code> has changed.
+ * <p>
+ * If the workflow element <code>we</code> is <code>null</code> then
+ * the <code>observer</code> is registered with a static list of objects
+ * to notify when a workflow element named <code>weid</code> is created.
+ *
+ * @param we the workflow element. If <code>null</code> then observer
+ * is registered with a list of workflow element
+ * identifiers.
+ * @param weid the identifier of the workflow element. This parameter
+ * is useless when <code>we</code> is not <code>null</code>
+ * @param observer the observer to notify when the workflow element state
+ * has been modified
+ */
+ public static void registereForStateUpdate(
+ WorkflowElement<?> we,
+ String weid,
+ Observer observer
+ )
+ {
+ // If the workflow element "we" exists then register the observer with "we"
+ // else register the observer with a static list of workflow element
+ // identifiers
+ if (we != null)
+ {
+ ObservableWorkflowElementState westate = we.getObservableState();
+ westate.addObserver(observer);
+ }
+ else
+ {
+ if (weid == null)
+ {
+ return;
+ }
+
+ List<Observer> observers = newWorkflowElementNotificationList.get(weid);
+ if (observers == null)
+ {
+ // create the list of observers
+ observers = new ArrayList<Observer>();
+ observers.add(observer);
+ newWorkflowElementNotificationList.put(weid, observers);
+ }
+ else
+ {
+ // update the observer list
+ observers.add(observer);
+ }
+ }
+ }
+
+
+ /**
+ * Deregisters an observer that was registered with a specific workflow
+ * element.
+ * <p>
+ * If the workflow element <code>we</code> is not <code>null</code>
+ * then the <code>observer</code> is deregistered with the list of objects
+ * to notify when <code>we</code> has changed.
+ * <p>
+ * If the workflow element <code>we</code> is <code>null</code> then
+ * the <code>observer</code> is deregistered with a static list of objects
+ * to notify when a workflow element named <code>weid</code> is created.
+ *
+ * @param we the workflow element. If <code>null</code> then observer
+ * is deregistered with a list of workflow element
+ * identifiers.
+ * @param weid the identifier of the workflow element. This parameter
+ * is useless when <code>we</code> is not <code>null</code>
+ * @param observer the observer to deregister
+ */
+ public static void deregistereForStateUpdate(
+ WorkflowElement<?> we,
+ String weid,
+ Observer observer
+ )
+ {
+ // If the workflow element "we" exists then deregister the observer
+ // with "we" else deregister the observer with a static list of
+ // workflow element identifiers
+ if (we != null)
+ {
+ ObservableWorkflowElementState westate = we.getObservableState();
+ westate.deleteObserver(observer);
+ }
+ else
+ {
+ List<Observer> observers = newWorkflowElementNotificationList.get(weid);
+ if (observers != null)
+ {
+ observers.remove(observer);
+ }
+ }
+ }
+
+
+ /**
+ * Notifies all the observers who want to be warn when a workflow element
+ * is created.
+ *
+ * @param workflowElement the newly created workflow element
+ */
+ public static void notifyStateUpdate(
+ WorkflowElement<?> workflowElement)
+ {
+ // Go through the list of observers and notify them all
+ String weID = workflowElement.getWorkflowElementID();
+
+ List<Observer> observers = newWorkflowElementNotificationList.get(weID);
+ if (observers != null)
+ {
+ for (Observer observer: observers)
+ {
+ // The update might fail because an observer could have been
+ // terminated. In this case, just ignore the failure and remove
+ // the observer from the list of objects to notify.
+ try
+ {
+ observer.update(workflowElement.getObservableState(), null);
+ }
+ catch(Exception e)
+ {
+ observers.remove(observer);
+ }
+ }
+ }
+ }
+
+
/**
* Creates a new instance of the workflow element.
*/
@@ -69,6 +239,7 @@
// There is nothing to do in the constructor.
}
+
/**
* Initializes the instance of the workflow element.
*
@@ -89,6 +260,15 @@
/**
+ * {@inheritDoc}
+ */
+ public void update(Observable o, Object arg)
+ {
+ // By default, do nothing when notification hits the workflow element.
+ }
+
+
+ /**
* Get the type of the workflow element. The type is a string information
* indicating which type is the current workflow element. This information
* is intended to be used by tools for trace and debug purpose.
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 2d43211..95e62bd 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
@@ -121,7 +121,7 @@
* @throws org.opends.server.types.InitializationException Exception while
* initializing the workflow element
*/
- public WorkflowElement loadAndRegisterWorkflowElement(String workflowName)
+ public WorkflowElement<?> loadAndRegisterWorkflowElement(String workflowName)
throws ConfigException, InitializationException {
ServerManagementContext managementContext =
ServerManagementContext.getInstance();
@@ -188,7 +188,11 @@
{
try
{
- loadAndRegisterWorkflowElement(configuration);
+ WorkflowElement<?> we = loadAndRegisterWorkflowElement(configuration);
+
+ // Notify observers who want to be notify when new workflow elements
+ // are created.
+ WorkflowElement.notifyStateUpdate(we);
}
catch (InitializationException de)
{
@@ -214,7 +218,7 @@
List<Message> unacceptableReasons)
{
// FIXME -- We should try to perform some check to determine whether the
- // worklfow element is in use.
+ // workflow element is in use.
return true;
}
@@ -232,11 +236,18 @@
);
- WorkflowElement workflowElement =
+ WorkflowElement<?> workflowElement =
DirectoryServer.getWorkflowElement(
configuration.getWorkflowElementId());
if (workflowElement != null)
{
+ // Notify to observers that the workflow element is now disabled
+ ObservableWorkflowElementState observableState =
+ workflowElement.getObservableState();
+ observableState.setWorkflowElementEnabled(false);
+ observableState.notifyObservers();
+
+ // Remove the workflow element
DirectoryServer.deregisterWorkflowElement(workflowElement);
workflowElement.finalizeWorkflowElement();
}
@@ -291,9 +302,8 @@
// Get the existing workflow element if it's already enabled.
- WorkflowElement existingWorkflowElement =
- DirectoryServer.getWorkflowElement(
- configuration.getWorkflowElementId());
+ WorkflowElement<?> existingWorkflowElement =
+ DirectoryServer.getWorkflowElement(configuration.getWorkflowElementId());
// If the new configuration has the workflow element disabled,
// then disable it if it is enabled, or do nothing if it's already disabled.
@@ -301,6 +311,13 @@
{
if (existingWorkflowElement != null)
{
+ // Notify to observers that the workflow element is now disabled
+ ObservableWorkflowElementState observableState =
+ existingWorkflowElement.getObservableState();
+ observableState.setWorkflowElementEnabled(false);
+ observableState.notifyObservers();
+
+ // Remove the workflow element
DirectoryServer.deregisterWorkflowElement(existingWorkflowElement);
existingWorkflowElement.finalizeWorkflowElement();
}
@@ -313,7 +330,11 @@
{
try
{
- loadAndRegisterWorkflowElement(configuration);
+ WorkflowElement<?> we = loadAndRegisterWorkflowElement(configuration);
+
+ // Notify observers who want to be notify when new workflow elements
+ // are created.
+ WorkflowElement.notifyStateUpdate(we);
}
catch (InitializationException de)
{
@@ -343,13 +364,13 @@
* ID of an existing workflow during workflow
* registration.
*/
- WorkflowElement loadAndRegisterWorkflowElement(
+ WorkflowElement<?> loadAndRegisterWorkflowElement(
WorkflowElementCfg workflowElementCfg
) throws InitializationException
{
// Load the workflow element class
String className = workflowElementCfg.getJavaClass();
- WorkflowElement workflowElement =
+ WorkflowElement<?> workflowElement =
loadWorkflowElement(className, workflowElementCfg, true);
try
@@ -381,7 +402,7 @@
* @throws InitializationException If a problem occurred while attempting
* to initialize the workflow element.
*/
- private WorkflowElement loadWorkflowElement(
+ private WorkflowElement<?> loadWorkflowElement(
String className,
WorkflowElementCfg configuration,
boolean initialize
@@ -391,15 +412,20 @@
{
WorkflowElementCfgDefn definition;
ClassPropertyDefinition propertyDefinition;
+ // I cannot use the parameterized type WorflowElement<?>
+ // because it would break the line WorkflowElement.class below.
+ // Use SuppressWarning because we know the cast is safe.
+ @SuppressWarnings("unchecked")
Class<? extends WorkflowElement> workflowElementClass;
- WorkflowElement<? extends WorkflowElementCfg> workflowElement;
definition = WorkflowElementCfgDefn.getInstance();
propertyDefinition =
definition.getJavaClassPropertyDefinition();
workflowElementClass =
propertyDefinition.loadClass(className, WorkflowElement.class);
- workflowElement =
+ // Again, use SuppressWarning because we know the cast is safe
+ @SuppressWarnings("unchecked")
+ WorkflowElement<? extends WorkflowElementCfg> workflowElement =
(WorkflowElement<? extends WorkflowElementCfg>)
workflowElementClass.newInstance();
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowConfigurationTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowConfigurationTest.java
index deb1328..243c76f 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowConfigurationTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowConfigurationTest.java
@@ -54,6 +54,7 @@
import org.opends.server.types.SearchScope;
import org.opends.server.util.StaticUtils;
import org.opends.server.util.UtilTestCase;
+import org.opends.server.workflowelement.WorkflowElement;
import org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -307,7 +308,7 @@
// Create a workflow and register it with the server
String workflowID = baseDN + "#" + backendID;
WorkflowImpl workflowImpl = new WorkflowImpl(
- workflowID, DN.decode(baseDN), workflowElement);
+ workflowID, DN.decode(baseDN), workflowElementID, workflowElement);
workflowImpl.register();
// Register the workflow with the internal network group
@@ -431,6 +432,11 @@
}
+ //===========================================================================
+ // U T I L S using dsconfig
+ //===========================================================================
+
+
/**
* Initializes a memory-based backend.
*
@@ -439,9 +445,10 @@
* @param createBaseEntry indicate whether to automatically create the base
* entry and add it to the backend.
*
+ * @return the newly created backend
* @throws Exception If an unexpected problem occurs.
*/
- private static void createBackend(
+ private static Backend dsconfigCreateMemoryBackend(
String backendID,
String baseDN,
boolean createBaseEntry
@@ -455,15 +462,16 @@
"--set", "writability-mode:enabled",
"--set", "enabled:true");
+ Backend backend = DirectoryServer.getBackend(backendID);
if (createBaseEntry)
{
- Backend backend = DirectoryServer.getBackend(backendID);
Entry e = createEntry(DN.decode(baseDN));
backend.addEntry(e, null);
}
+ return backend;
}
-
+
/**
* Remove a backend.
*
@@ -471,7 +479,7 @@
*
* @throws Exception If an unexpected problem occurs.
*/
- private static void removeMemoryBackend(
+ private static void dsconfigRemoveMemoryBackend(
String backendID
) throws Exception
{
@@ -481,7 +489,6 @@
}
-
//===========================================================================
// T E S T C A S E S
//===========================================================================
@@ -536,7 +543,7 @@
// Set the workflow configuration mode to manual. In this mode
// no there is no workflow by default (but the config and rootDSE
- // workflows) so seaarches on the test backend should fail.
+ // workflows) so searches on the test backend should fail.
setModeManual();
checkBackendIsNotAccessible(testBaseDN);
@@ -545,6 +552,10 @@
createWorkflow(testBaseDN, testBackendID);
checkBackendIsAccessible(testBaseDN);
+ // Remove the workflow and check that searches are failing.
+ removeWorkflow(testBaseDN, testBackendID);
+ checkBackendIsNotAccessible(testBaseDN);
+
// Change workflow configuration mode back to auto and check that
// test backend is still accessible
setModeAuto();
@@ -624,11 +635,11 @@
checkBackendIsNotAccessible(baseDN1);
// Create a backend and check that the base entry is accessible.
- createBackend(backendID1, baseDN1, true);
+ dsconfigCreateMemoryBackend(backendID1, baseDN1, true);
checkBackendIsAccessible(baseDN1);
// Remove the backend and check that the suffix is no more accessible.
- removeMemoryBackend(backendID1);
+ dsconfigRemoveMemoryBackend(backendID1);
checkBackendIsNotAccessible(baseDN1);
// Now move to the manual mode
@@ -637,21 +648,21 @@
// Create a backend and create a workflow to route operations to that
// new backend. Then check that the base entry is accessible.
- createBackend(backendID2, baseDN2, true);
+ dsconfigCreateMemoryBackend(backendID2, baseDN2, true);
createWorkflow(baseDN2, backendID2);
checkBackendIsAccessible(baseDN2);
// Remove the workflow and the backend and check that the base entry
// is no more accessible.
removeWorkflow(baseDN2, backendID2);
- removeMemoryBackend(backendID2);
+ dsconfigRemoveMemoryBackend(backendID2);
checkBackendIsNotAccessible(baseDN2);
// Back to the original configuration mode
setModeAuto();
}
-
-
+
+
/**
* This test checks the creation and utilization of network group
* in the route process.
@@ -688,7 +699,7 @@
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
- // Put back the internal network group in the client conenction
+ // Put back the internal network group in the client connection
// and check that searches are still working.
clientConnection.setNetworkGroup(NetworkGroup.getInternalNetworkGroup());
searchOperation.run();
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowTopologyTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowTopologyTest.java
index 4d5d083..20113c8 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowTopologyTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowTopologyTest.java
@@ -440,7 +440,7 @@
// create a DIT set with the baseDN (no workflow element in the DIT).
WorkflowElement nullWE = null;
WorkflowImpl workflow =
- new WorkflowImpl (baseDN.toString(), baseDN, nullWE);
+ new WorkflowImpl (baseDN.toString(), baseDN, null, nullWE);
// Create a worflow with the dit, no pre/post-workflow element.
WorkflowTopologyNode workflowNode =
@@ -503,18 +503,20 @@
WorkflowImpl unrelatedWorkflow = null;
{
WorkflowElement nullWE = null;
- workflow = new WorkflowImpl (baseDN.toString(), baseDN, nullWE);
- subWorkflow = new WorkflowImpl (subordinateDN.toString(), subordinateDN, nullWE);
+ workflow = new WorkflowImpl (baseDN.toString(), baseDN, null, nullWE);
+ subWorkflow = new WorkflowImpl (
+ subordinateDN.toString(), subordinateDN, null, nullWE);
if (unrelatedDN != null)
{
- unrelatedWorkflow = new WorkflowImpl (unrelatedDN.toString(), unrelatedDN, nullWE);
+ unrelatedWorkflow = new WorkflowImpl (
+ unrelatedDN.toString(), unrelatedDN, null, nullWE);
}
}
// Create a worflow for each dit, no pre/post-workflow element
- WorkflowTopologyNode w1 = new WorkflowTopologyNode (workflow, null, null);
- WorkflowTopologyNode w1bis = new WorkflowTopologyNode (workflow, null, null);
- WorkflowTopologyNode w2 = new WorkflowTopologyNode (subWorkflow, null, null);
+ WorkflowTopologyNode w1 = new WorkflowTopologyNode(workflow, null, null);
+ WorkflowTopologyNode w1bis = new WorkflowTopologyNode(workflow, null, null);
+ WorkflowTopologyNode w2 = new WorkflowTopologyNode(subWorkflow, null, null);
WorkflowTopologyNode w3 = null;
if (unrelatedWorkflow != null)
@@ -648,9 +650,9 @@
WorkflowImpl workflow3;
{
WorkflowElement nullWE = null;
- workflow1 = new WorkflowImpl (baseDN1.toString(), baseDN1, nullWE);
- workflow2 = new WorkflowImpl (baseDN2.toString(), baseDN2, nullWE);
- workflow3 = new WorkflowImpl (baseDN3.toString(), baseDN3, nullWE);
+ workflow1 = new WorkflowImpl(baseDN1.toString(), baseDN1, null, nullWE);
+ workflow2 = new WorkflowImpl(baseDN2.toString(), baseDN2, null, nullWE);
+ workflow3 = new WorkflowImpl(baseDN3.toString(), baseDN3, null, nullWE);
}
w1 = new WorkflowTopologyNode (workflow1, null, null);
@@ -830,9 +832,9 @@
{
WorkflowElement nullWE = null;
- workflow1 = new WorkflowImpl (baseDN1.toString(), baseDN1, nullWE);
- workflow2 = new WorkflowImpl (baseDN2.toString(), baseDN2, nullWE);
- workflow3 = new WorkflowImpl (baseDN3.toString(), baseDN3, nullWE);
+ workflow1 = new WorkflowImpl(baseDN1.toString(), baseDN1, null, nullWE);
+ workflow2 = new WorkflowImpl(baseDN2.toString(), baseDN2, null, nullWE);
+ workflow3 = new WorkflowImpl(baseDN3.toString(), baseDN3, null, nullWE);
}
w1 = new WorkflowTopologyNode (workflow1, null, null);
@@ -957,7 +959,7 @@
// Create a workflow to handle the baseDN with no workflow element
WorkflowImpl workflow = new WorkflowImpl(
- baseDN.toString(), baseDN, nullWE);
+ baseDN.toString(), baseDN, null, nullWE);
// Register the workflow with the server. Don't catch the
// DirectoryException that could be thrown by the register() method.
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
index 65b607e..b79c3ec 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
@@ -486,7 +486,7 @@
// of the workflow base DN.
WorkflowElement nullWE = null;
WorkflowImpl workflow = new WorkflowImpl(
- workflowBaseDN.toString(), workflowBaseDN, nullWE);
+ workflowBaseDN.toString(), workflowBaseDN, null, nullWE);
// Register the workflow with the network group.
networkGroup.registerWorkflow(workflow);
@@ -779,7 +779,7 @@
// of the workflow base DN.
WorkflowElement nullWE = null;
WorkflowImpl workflow = new WorkflowImpl(
- workflowBaseDN.toString(), workflowBaseDN, nullWE);
+ workflowBaseDN.toString(), workflowBaseDN, null, nullWE);
// Register the workflow with the network group.
networkGroup.registerWorkflow(workflow);
@@ -835,9 +835,9 @@
// of the workflow base DN.
WorkflowElement nullWE = null;
WorkflowImpl workflow1 = new WorkflowImpl(
- dn1.toString(), dn1, nullWE);
+ dn1.toString(), dn1, null, nullWE);
WorkflowImpl workflow2 = new WorkflowImpl(
- dn2.toString(), dn2, nullWE);
+ dn2.toString(), dn2, null, nullWE);
// Register the workflow with the network group.
networkGroup1.registerWorkflow(workflow1);
@@ -1210,7 +1210,7 @@
WorkflowElement rootWE = null;
String workflowId = workflowBaseDN.toString();
WorkflowImpl workflow = new WorkflowImpl(
- workflowId, workflowBaseDN, rootWE);
+ workflowId, workflowBaseDN, null, rootWE);
assertNotNull(workflow);
// Register the workflow with the network group.
--
Gitblit v1.10.0