| | |
| | | </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 /> |
| | |
| | | // 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; |
| | |
| | | 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()) |
| | | { |
| | |
| | | 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 |
| | |
| | | messages.add(de.getMessageObject()); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // The workflow already exist, just notify the changes to the workflow |
| | | existingWorkflow.updateConfig(configuration); |
| | | } |
| | | |
| | | return configChangeResult; |
| | | } |
| | |
| | | |
| | | // 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(); |
| | | |
| | |
| | | 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; |
| | | |
| | | |
| | | /** |
| | |
| | | * 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. |
| | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * |
| | |
| | | * |
| | | * @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 |
| | | ) |
| | | { |
| | |
| | | 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); |
| | | } |
| | | } |
| | | |
| | |
| | | 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); |
| | | } |
| | |
| | | { |
| | | 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 = |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 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; |
| | | } |
| | | } |
| | | } |
| | |
| | | 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; |
| New file |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | * |
| | | * @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. |
| | |
| | | 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. |
| | | */ |
| | |
| | | // There is nothing to do in the constructor. |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Initializes the instance of the workflow element. |
| | | * |
| | |
| | | |
| | | |
| | | /** |
| | | * {@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. |
| | |
| | | * @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(); |
| | |
| | | { |
| | | 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) |
| | | { |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | ); |
| | | |
| | | |
| | | 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(); |
| | | } |
| | |
| | | |
| | | |
| | | // 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. |
| | |
| | | { |
| | | 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(); |
| | | } |
| | |
| | | { |
| | | 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) |
| | | { |
| | |
| | | * 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 |
| | |
| | | * @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 |
| | |
| | | { |
| | | 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(); |
| | | |
| | |
| | | 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; |
| | |
| | | // 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 |
| | |
| | | } |
| | | |
| | | |
| | | //=========================================================================== |
| | | // U T I L S using dsconfig |
| | | //=========================================================================== |
| | | |
| | | |
| | | /** |
| | | * Initializes a memory-based backend. |
| | | * |
| | |
| | | * @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 |
| | |
| | | "--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. |
| | | * |
| | |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | private static void removeMemoryBackend( |
| | | private static void dsconfigRemoveMemoryBackend( |
| | | String backendID |
| | | ) throws Exception |
| | | { |
| | |
| | | } |
| | | |
| | | |
| | | |
| | | //=========================================================================== |
| | | // T E S T C A S E S |
| | | //=========================================================================== |
| | |
| | | |
| | | // 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); |
| | | |
| | |
| | | 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(); |
| | |
| | | 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 |
| | |
| | | |
| | | // 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. |
| | |
| | | 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(); |
| | |
| | | // 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 = |
| | |
| | | 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) |
| | |
| | | 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); |
| | |
| | | { |
| | | 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); |
| | |
| | | |
| | | // 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. |
| | |
| | | // 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); |
| | |
| | | // 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); |
| | |
| | | // 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); |
| | |
| | | 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. |