OPENDJ-1545 Remove Workflow, NetworkGroups and related attempts at building a proxy
ObservableWorkflowElementState.java: REMOVED
2 files deleted
7 files modified
| | |
| | | |
| | | // Create the workflow for the base DN and register the workflow with |
| | | // the server. |
| | | WorkflowImpl workflowImpl = new WorkflowImpl( |
| | | workflowID, |
| | | baseDN, |
| | | rootWE.getWorkflowElementID(), |
| | | rootWE); |
| | | WorkflowImpl workflowImpl = new WorkflowImpl(workflowID, baseDN, rootWE); |
| | | workflowImpl.register(); |
| | | |
| | | return workflowImpl; |
| | | } |
| | | |
| | |
| | | */ |
| | | package org.opends.server.core; |
| | | |
| | | import java.util.Observable; |
| | | import java.util.Observer; |
| | | import java.util.TreeMap; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessageBuilder; |
| | |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.Operation; |
| | | import org.opends.server.workflowelement.ObservableWorkflowElementState; |
| | | import org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement; |
| | | |
| | | import static org.forgerock.util.Reject.*; |
| | |
| | | * task in turn will execute its subordinate nodes and synchronizes them |
| | | * as needed. |
| | | */ |
| | | public class WorkflowImpl implements Workflow, Observer |
| | | public class WorkflowImpl implements Workflow |
| | | { |
| | | /** The workflow identifier used by the configuration. */ |
| | | private final String workflowID; |
| | |
| | | /** The root of the workflow task tree. */ |
| | | private LocalBackendWorkflowElement rootWorkflowElement; |
| | | |
| | | /** The root workflow element identifier. */ |
| | | private final String rootWorkflowElementID; |
| | | |
| | | /** The base DN of the data handled by the workflow. */ |
| | | private final DN baseDN; |
| | | |
| | |
| | | * |
| | | * @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, |
| | | LocalBackendWorkflowElement rootWorkflowElement |
| | | public WorkflowImpl(String workflowId, DN baseDN, LocalBackendWorkflowElement rootWorkflowElement |
| | | ) |
| | | { |
| | | this.workflowID = workflowId; |
| | |
| | | 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. |
| | | LocalBackendWorkflowElement.registerForStateUpdate(rootWorkflowElement, null, this); |
| | | } |
| | | else |
| | | { |
| | | this.isPrivate = false; |
| | | this.rootWorkflowElementID = null; |
| | | |
| | | // 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. |
| | | LocalBackendWorkflowElement.registerForStateUpdate(null, rootWorkflowElementID, this); |
| | | } |
| | | } |
| | | |
| | |
| | | * conflicts with the workflow ID of an existing |
| | | * workflow. |
| | | */ |
| | | public void register() |
| | | throws DirectoryException |
| | | void register() throws DirectoryException |
| | | { |
| | | ifNull(workflowID); |
| | | |
| | |
| | | /** |
| | | * Deregisters the current workflow (this) with the server. |
| | | */ |
| | | public void deregister() |
| | | void deregister() |
| | | { |
| | | ifNull(workflowID); |
| | | |
| | | // Deregister the workflow with the list of objects to notify when |
| | | // a workflow element is created or deleted. |
| | | LocalBackendWorkflowElement.deregisterForStateUpdate(null, rootWorkflowElementID, this); |
| | | |
| | | // Deregister the workflow with the list of registered workflows. |
| | | synchronized (registeredWorkflowsLock) |
| | | { |
| | |
| | | * Deregisters all Workflows that have been registered. This should be |
| | | * called when the server is shutting down. |
| | | */ |
| | | public static void deregisterAllOnShutdown() |
| | | static void deregisterAllOnShutdown() |
| | | { |
| | | synchronized (registeredWorkflowsLock) |
| | | { |
| | | registeredWorkflows = |
| | | new TreeMap<String, Workflow>(); |
| | | registeredWorkflows = new TreeMap<String, Workflow>(); |
| | | } |
| | | } |
| | | |
| | |
| | | * @param workflowID the ID of the workflow to get |
| | | * @return the requested workflow |
| | | */ |
| | | public static Workflow getWorkflow( |
| | | String workflowID) |
| | | static Workflow getWorkflow(String workflowID) |
| | | { |
| | | return registeredWorkflows.get(workflowID); |
| | | } |
| | |
| | | return rootWorkflowElement; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | 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. |
| | |
| | | return "Workflow " + workflowID; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | LocalBackendWorkflowElement we = weState.getObservedWorkflowElement(); |
| | | String newWorkflowElementID = we.getWorkflowElementID(); |
| | | if (! rootWorkflowElementID.equalsIgnoreCase(newWorkflowElementID)) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | // The workflow element maps the root workflow element |
| | | // don't forget to register the workflow with the list of objects to notify |
| | | // when the root workflow element is disabled... |
| | | rootWorkflowElement = weState.getObservedWorkflowElement(); |
| | | LocalBackendWorkflowElement.registerForStateUpdate(rootWorkflowElement, null, this); |
| | | LocalBackendWorkflowElement.deregisterForStateUpdate(null, rootWorkflowElementID, this); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Increments the workflow reference counter. |
| | | * <p> |
| | |
| | | |
| | | |
| | | // The list of subordinate nodes of the current workflow node. |
| | | private ArrayList<WorkflowTopologyNode> subordinates = |
| | | new ArrayList<WorkflowTopologyNode>(); |
| | | private final ArrayList<WorkflowTopologyNode> subordinates = new ArrayList<WorkflowTopologyNode>(); |
| | | |
| | | |
| | | /** |
| | |
| | | * @return the base DN which is the parent of the <code>dn</code>, |
| | | * <code>null</code> if no parent DN was found |
| | | */ |
| | | public DN getParentBaseDN(DN dn) |
| | | DN getParentBaseDN(DN dn) |
| | | { |
| | | if (dn == null) |
| | | { |
| | |
| | | * |
| | | * @param subordinate the subordinate to remove from the subordinate list |
| | | */ |
| | | public void removeSubordinate( |
| | | WorkflowTopologyNode subordinate |
| | | ) |
| | | private void removeSubordinate(WorkflowTopologyNode subordinate) |
| | | { |
| | | subordinates.remove(subordinate); |
| | | } |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.Iterator; |
| | | import java.util.List; |
| | | import java.util.Observable; |
| | | import java.util.Observer; |
| | | import java.util.TreeMap; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.ConcurrentMap; |
| | | import java.util.concurrent.CopyOnWriteArrayList; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.LocalizableMessageDescriptor; |
| | |
| | | import org.opends.server.controls.LDAPPreReadResponseControl; |
| | | import org.opends.server.core.*; |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.workflowelement.ObservableWorkflowElementState; |
| | | |
| | | import static org.opends.messages.CoreMessages.*; |
| | | |
| | |
| | | * This class defines a local backend workflow element; e-g an entity that |
| | | * handle the processing of an operation against a local backend. |
| | | */ |
| | | public class LocalBackendWorkflowElement implements Observer |
| | | public class LocalBackendWorkflowElement |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | |
| | | private Backend<?> backend; |
| | | |
| | | /** the set of local backend workflow elements registered with the server. */ |
| | | private static TreeMap<String, LocalBackendWorkflowElement> |
| | | registeredLocalBackends = |
| | | new TreeMap<String, LocalBackendWorkflowElement>(); |
| | | private static TreeMap<String, LocalBackendWorkflowElement> registeredLocalBackends = |
| | | new TreeMap<String, LocalBackendWorkflowElement>(); |
| | | |
| | | /** |
| | | * A lock to guarantee safe concurrent access to the registeredLocalBackends |
| | |
| | | */ |
| | | private static final Object registeredLocalBackendsLock = new Object(); |
| | | |
| | | |
| | | /** A string indicating the type of the workflow element. */ |
| | | private static final String BACKEND_WORKFLOW_ELEMENT = "Backend"; |
| | | |
| | | |
| | | /** 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>>(); |
| | | |
| | | /** |
| | | * 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 |
| | | */ |
| | | // TODO JNR rename |
| | | public static void registerForStateUpdate(LocalBackendWorkflowElement 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) |
| | | { |
| | | we.observableState.addObserver(observer); |
| | | } |
| | | else |
| | | { |
| | | if (weid == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | List<Observer> observers = newWorkflowElementNotificationList.get(weid); |
| | | if (observers == null) |
| | | { |
| | | // create the list of observers |
| | | observers = new CopyOnWriteArrayList<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 deregisterForStateUpdate(LocalBackendWorkflowElement 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) |
| | | { |
| | | we.observableState.deleteObserver(observer); |
| | | } |
| | | |
| | | if (weid != null) |
| | | { |
| | | List<Observer> observers = newWorkflowElementNotificationList.get(weid); |
| | | if (observers != null) |
| | | { |
| | | observers.remove(observer); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public final void update(Observable o, Object arg) |
| | | { |
| | | // By default, do nothing when notification hits the workflow element. |
| | | } |
| | | |
| | | /** |
| | | * Initializes a new instance of the local backend workflow element. |
| | | * This method is intended to be called by DirectoryServer when |
| | |
| | | |
| | | // Create a workflow and register it with the server |
| | | String workflowID = baseDN + "#" + backendID; |
| | | WorkflowImpl workflowImpl = new WorkflowImpl( |
| | | workflowID, DN.valueOf(baseDN), workflowElementID, workflowElement); |
| | | WorkflowImpl workflowImpl = new WorkflowImpl(workflowID, DN.valueOf(baseDN), workflowElement); |
| | | workflowImpl.register(); |
| | | |
| | | // Register the workflow with the internal network group |
| | | NetworkGroup.getInternalNetworkGroup().registerWorkflow(workflowImpl); |
| | | |
| | | return workflowImpl; |
| | | } |
| | | |
| | |
| | | * is created, we check that the route operation returns the best workflow |
| | | * candidate for a given request base DN. |
| | | */ |
| | | @SuppressWarnings("javadoc") |
| | | public class WorkflowTopologyTest extends UtilTestCase |
| | | { |
| | | //=========================================================================== |
| | |
| | | DN dummyDN |
| | | ) |
| | | { |
| | | WorkflowImpl workflow = new WorkflowImpl(baseDN.toString(), baseDN, null, null); |
| | | WorkflowImpl workflow = new WorkflowImpl(baseDN.toString(), baseDN, null); |
| | | |
| | | // Create a worflow with the dit, no pre/post-workflow element. |
| | | WorkflowTopologyNode workflowNode = new WorkflowTopologyNode(workflow); |
| | |
| | | readBaseDN = workflowNode.getParentBaseDN (dummyDN); |
| | | assertNull (readBaseDN); |
| | | } |
| | | |
| | | } // createWorkflow_basic |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Create a topology with 2 workflows. The test case contains creation |
| | |
| | | // Create one DIT set for baseDN and one DIT set for subordinateDN |
| | | // (no workflow element in any DIT). Create a dummy DIT as well using |
| | | // the unrelatedDN. |
| | | WorkflowImpl workflow = null; |
| | | WorkflowImpl subWorkflow = null; |
| | | WorkflowImpl workflow = new WorkflowImpl(baseDN.toString(), baseDN, null); |
| | | WorkflowImpl subWorkflow = new WorkflowImpl(subordinateDN.toString(), subordinateDN, null); |
| | | WorkflowImpl unrelatedWorkflow = null; |
| | | if (unrelatedDN != null) |
| | | { |
| | | workflow = new WorkflowImpl(baseDN.toString(), baseDN, null, null); |
| | | subWorkflow = new WorkflowImpl(subordinateDN.toString(), subordinateDN, null, null); |
| | | if (unrelatedDN != null) |
| | | { |
| | | unrelatedWorkflow = new WorkflowImpl(unrelatedDN.toString(), unrelatedDN, null, null); |
| | | } |
| | | unrelatedWorkflow = new WorkflowImpl(unrelatedDN.toString(), unrelatedDN, null); |
| | | } |
| | | |
| | | // Create a worflow for each dit, no pre/post-workflow element |
| | |
| | | ) |
| | | { |
| | | // Create a worflow for each baseDN, no pre/post-workflow element |
| | | WorkflowTopologyNode w1; |
| | | WorkflowTopologyNode w2; |
| | | WorkflowTopologyNode w3; |
| | | { |
| | | // create DITs with the given baseDNs with no workflow element. |
| | | WorkflowImpl workflow1; |
| | | WorkflowImpl workflow2; |
| | | WorkflowImpl workflow3; |
| | | { |
| | | workflow1 = new WorkflowImpl(baseDN1.toString(), baseDN1, null, null); |
| | | workflow2 = new WorkflowImpl(baseDN2.toString(), baseDN2, null, null); |
| | | workflow3 = new WorkflowImpl(baseDN3.toString(), baseDN3, null, null); |
| | | } |
| | | |
| | | w1 = new WorkflowTopologyNode(workflow1); |
| | | w2 = new WorkflowTopologyNode(workflow2); |
| | | w3 = new WorkflowTopologyNode(workflow3); |
| | | } |
| | | WorkflowTopologyNode w1 = new WorkflowTopologyNode(new WorkflowImpl(baseDN1.toString(), baseDN1, null)); |
| | | WorkflowTopologyNode w2 = new WorkflowTopologyNode(new WorkflowImpl(baseDN2.toString(), baseDN2, null)); |
| | | WorkflowTopologyNode w3 = new WorkflowTopologyNode(new WorkflowImpl(baseDN3.toString(), baseDN3, null)); |
| | | |
| | | // insert status |
| | | boolean insert; |
| | |
| | | ) |
| | | { |
| | | // Create a worflow for each baseDN, no pre/post-workflow element |
| | | WorkflowTopologyNode w1; |
| | | WorkflowTopologyNode w2; |
| | | WorkflowTopologyNode w3; |
| | | { |
| | | // create DITs with the given baseDNs with no workflow element. |
| | | WorkflowImpl workflow1; |
| | | WorkflowImpl workflow2; |
| | | WorkflowImpl workflow3; |
| | | { |
| | | workflow1 = new WorkflowImpl(baseDN1.toString(), baseDN1, null, null); |
| | | workflow2 = new WorkflowImpl(baseDN2.toString(), baseDN2, null, null); |
| | | workflow3 = new WorkflowImpl(baseDN3.toString(), baseDN3, null, null); |
| | | } |
| | | |
| | | w1 = new WorkflowTopologyNode(workflow1); |
| | | w2 = new WorkflowTopologyNode(workflow2); |
| | | w3 = new WorkflowTopologyNode(workflow3); |
| | | } |
| | | WorkflowTopologyNode w1 = new WorkflowTopologyNode(new WorkflowImpl(baseDN1.toString(), baseDN1, null)); |
| | | WorkflowTopologyNode w2 = new WorkflowTopologyNode(new WorkflowImpl(baseDN2.toString(), baseDN2, null)); |
| | | WorkflowTopologyNode w3 = new WorkflowTopologyNode(new WorkflowImpl(baseDN3.toString(), baseDN3, null)); |
| | | |
| | | // Put all the workflows in a pool |
| | | WorkflowTopologyNode[] workflowPool = {w1, w2, w3}; |
| | |
| | | // dump the topology |
| | | StringBuilder sb = w1.toString (""); |
| | | System.out.println (sb); |
| | | |
| | | } // createWorkflow_complexTopology1 |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Test the elaboration of the global result code by the workflow. |
| | |
| | | throws DirectoryException |
| | | { |
| | | // Create a workflow to handle the baseDN with no workflow element |
| | | WorkflowImpl workflow = new WorkflowImpl(baseDN.toString(), baseDN, null, null); |
| | | WorkflowImpl workflow = new WorkflowImpl(baseDN.toString(), baseDN, null); |
| | | |
| | | // Register the workflow with the server. Don't catch the |
| | | // DirectoryException that could be thrown by the register() method. |
| | |
| | | |
| | | // Create a workflow -- the workflow ID is the string representation |
| | | // of the workflow base DN. |
| | | WorkflowImpl workflow = new WorkflowImpl(workflowBaseDN.toString(), workflowBaseDN, null, null); |
| | | WorkflowImpl workflow = new WorkflowImpl(workflowBaseDN.toString(), workflowBaseDN, null); |
| | | |
| | | // Register the workflow with the network group. |
| | | networkGroup.registerWorkflow(workflow); |
| | |
| | | |
| | | // Create a workflow -- the workflow ID is the string representation |
| | | // of the workflow base DN. |
| | | WorkflowImpl workflow1 = new WorkflowImpl(dn1.toString(), dn1, null, null); |
| | | WorkflowImpl workflow2 = new WorkflowImpl(dn2.toString(), dn2, null, null); |
| | | WorkflowImpl workflow1 = new WorkflowImpl(dn1.toString(), dn1, null); |
| | | WorkflowImpl workflow2 = new WorkflowImpl(dn2.toString(), dn2, null); |
| | | |
| | | // Register the workflow with the network group. |
| | | networkGroup1.registerWorkflow(workflow1); |
| | |
| | | |
| | | // Create a workflow with no task inside. The workflow identifier |
| | | // is the a string representation of the workflow base DN. |
| | | WorkflowImpl workflow = new WorkflowImpl(workflowBaseDN.toString(), workflowBaseDN, null, null); |
| | | WorkflowImpl workflow = new WorkflowImpl(workflowBaseDN.toString(), workflowBaseDN, null); |
| | | assertNotNull(workflow); |
| | | |
| | | // Register the workflow with the network group. |