opendj3-server-dev/src/server/org/opends/server/backends/RootDSEBackend.java
@@ -31,7 +31,6 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -59,8 +58,6 @@ import org.opends.server.core.ModifyDNOperation; import org.opends.server.core.ModifyOperation; import org.opends.server.core.SearchOperation; import org.opends.server.core.WorkflowTopologyNode; import org.opends.server.core.networkgroups.NetworkGroup; import org.opends.server.types.*; import org.opends.server.util.BuildVersion; import org.opends.server.util.LDIFWriter; @@ -459,29 +456,13 @@ { HashMap<AttributeType,List<Attribute>> dseUserAttrs = new HashMap<AttributeType,List<Attribute>>(); HashMap<AttributeType,List<Attribute>> dseOperationalAttrs = new HashMap<AttributeType,List<Attribute>>(); // Add the "namingContexts" attribute. final Collection<DN> namingContexts; if (connection == null) { namingContexts = DirectoryServer.getPublicNamingContexts().keySet(); } else { namingContexts = new LinkedList<DN>(); for (WorkflowTopologyNode node : NetworkGroup.getDefaultNetworkGroup() .getNamingContexts().getPublicNamingContexts()) { namingContexts.add(node.getBaseDN()); } } Attribute publicNamingContextAttr = createDNAttribute(ATTR_NAMING_CONTEXTS, ATTR_NAMING_CONTEXTS_LC, namingContexts); Attribute publicNamingContextAttr = createDNAttribute( ATTR_NAMING_CONTEXTS, ATTR_NAMING_CONTEXTS_LC, DirectoryServer.getPublicNamingContexts().keySet()); addAttribute(publicNamingContextAttr, dseUserAttrs, dseOperationalAttrs); @@ -680,45 +661,6 @@ } /** * Determines the workflow nodes which handle subordinate naming contexts. * A workflow node is handling a subordinate naming context if the workflow * base DN is in the list of the RootDSE subordinate naming contexts. * * @param nodes * The list from which we search the workflow nodes which * are handling subordinate naming contexts * * @return The list of workflow nodes that are handling subordinate * naming contexts */ public Iterable<WorkflowTopologyNode> getSubordinateNamingContexts( Iterable<WorkflowTopologyNode> nodes) { // If the list of subordinate naming contexts is null // then return the whole list of workflow nodes. if (subordinateBaseDNs == null) { return nodes; } // The returned list of subordinate naming contexts List<WorkflowTopologyNode> subNC = new ArrayList<WorkflowTopologyNode>(); // Determine which workflow node is handling a subordinate naming context. for (WorkflowTopologyNode node : nodes) { DN dn = node.getBaseDN(); if (subordinateBaseDNs.containsKey(dn)) { subNC.add(node); } } return subNC; } /** * Creates an attribute for the root DSE meant to hold a set of DNs. * * @param name The name for the attribute. @@ -945,8 +887,13 @@ } } /** * Returns the subordinate base DNs of the root DSE. * * @return the subordinate base DNs of the root DSE */ @SuppressWarnings({ "unchecked", "rawtypes" }) private Map<DN, Backend<?>> getSubordinateBaseDNs() public Map<DN, Backend<?>> getSubordinateBaseDNs() { if (subordinateBaseDNs != null) { opendj3-server-dev/src/server/org/opends/server/core/AddOperationBasis.java
@@ -26,11 +26,6 @@ */ package org.opends.server.core; import static org.opends.messages.CoreMessages.*; import static org.opends.server.config.ConfigConstants.*; import static org.opends.server.loggers.AccessLogger.*; import static org.opends.server.util.StaticUtils.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -41,7 +36,6 @@ import org.forgerock.opendj.ldap.ResultCode; import org.opends.server.api.ClientConnection; import org.opends.server.api.plugin.PluginResult; import org.opends.server.core.networkgroups.NetworkGroup; import org.opends.server.protocols.ldap.LDAPAttribute; import org.opends.server.protocols.ldap.LDAPResultCode; import org.opends.server.types.*; @@ -49,6 +43,12 @@ import org.opends.server.types.operation.PreParseAddOperation; import org.opends.server.workflowelement.localbackend.LocalBackendAddOperation; import static org.opends.messages.CoreMessages.*; import static org.opends.server.config.ConfigConstants.*; import static org.opends.server.loggers.AccessLogger.*; import static org.opends.server.util.StaticUtils.*; import static org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement.*; /** * This class defines an operation that may be used to add a new entry to the * Directory Server. @@ -570,19 +570,7 @@ return; } // Retrieve the network group attached to the client connection // and get a workflow to process the operation. Workflow workflow = NetworkGroup.getWorkflowCandidate(entryDN); if (workflow == null) { // We have found no workflow for the requested base DN, just return // a no such entry result code and stop the processing. updateOperationErrMsgAndResCode(); return; } workflow.execute(this); workflowExecuted = true; workflowExecuted = execute(this, entryDN); } catch(CanceledOperationException coe) { @@ -633,8 +621,7 @@ * elements of the workflow, otherwise invoke the post response plugins * that have been registered with the current operation. * * @param workflowExecuted <code>true</code> if a workflow has been * executed * @param workflowExecuted <code>true</code> if a workflow has been executed */ @SuppressWarnings({ "unchecked", "rawtypes" }) private void invokePostResponsePlugins(boolean workflowExecuted) @@ -667,15 +654,9 @@ } } /** * Updates the error message and the result code of the operation. * * This method is called because no workflows were found to process * the operation. */ private void updateOperationErrMsgAndResCode() /** {@inheritDoc} */ @Override public void updateOperationErrMsgAndResCode() { DN entryDN = getEntryDN(); DN parentDN = entryDN.getParentDNInSuffix(); opendj3-server-dev/src/server/org/opends/server/core/BindOperationBasis.java
@@ -35,7 +35,6 @@ import org.forgerock.opendj.ldap.ResultCode; import org.opends.server.api.ClientConnection; import org.opends.server.api.plugin.PluginResult; import org.opends.server.core.networkgroups.NetworkGroup; import org.opends.server.types.*; import org.opends.server.types.operation.PreParseBindOperation; import org.opends.server.workflowelement.localbackend.LocalBackendBindOperation; @@ -44,6 +43,7 @@ import static org.opends.messages.CoreMessages.*; import static org.opends.server.core.DirectoryServer.*; import static org.opends.server.loggers.AccessLogger.*; import static org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement.*; /** * This class defines an operation that may be used to authenticate a user to @@ -557,16 +557,7 @@ } } Workflow workflow = NetworkGroup.getWorkflowCandidate(bindDN); if (workflow == null) { // We have found no workflow for the requested base DN, just return // a no such entry result code and stop the processing. updateOperationErrMsgAndResCode(); return; } workflow.execute(this); workflowExecuted = true; workflowExecuted = execute(this, bindDN); } catch(CanceledOperationException coe) { @@ -636,14 +627,9 @@ } } /** * Updates the error message and the result code of the operation. * * This method is called because no workflows were found to process * the operation. */ private void updateOperationErrMsgAndResCode() /** {@inheritDoc} */ @Override public void updateOperationErrMsgAndResCode() { LocalizableMessage message = ERR_BIND_OPERATION_UNKNOWN_USER.get(); setResultCode(ResultCode.INVALID_CREDENTIALS); opendj3-server-dev/src/server/org/opends/server/core/CompareOperationBasis.java
@@ -26,10 +26,6 @@ */ package org.opends.server.core; import static org.opends.messages.CoreMessages.*; import static org.opends.server.loggers.AccessLogger.*; import static org.opends.server.util.StaticUtils.*; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -40,12 +36,16 @@ import org.forgerock.opendj.ldap.ResultCode; import org.opends.server.api.ClientConnection; import org.opends.server.api.plugin.PluginResult; import org.opends.server.core.networkgroups.NetworkGroup; import org.opends.server.types.*; import org.opends.server.types.operation.PostResponseCompareOperation; import org.opends.server.types.operation.PreParseCompareOperation; import org.opends.server.workflowelement.localbackend.LocalBackendCompareOperation; import static org.opends.messages.CoreMessages.*; import static org.opends.server.loggers.AccessLogger.*; import static org.opends.server.util.StaticUtils.*; import static org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement.*; /** * This class defines an operation that may be used to determine whether a * specified entry in the Directory Server contains a given attribute-value @@ -156,22 +156,14 @@ attributeOptions = new HashSet<String>(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public final ByteString getRawEntryDN() { return rawEntryDN; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public final void setRawEntryDN(ByteString rawEntryDN) { @@ -180,11 +172,7 @@ entryDN = null; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public final DN getEntryDN() { @@ -204,22 +192,14 @@ return entryDN; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public final String getRawAttributeType() { return rawAttributeType; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public final void setRawAttributeType(String rawAttributeType) { @@ -229,8 +209,6 @@ attributeOptions = null; } private void getAttributeTypeAndOptions() { String baseName; int semicolonPos = rawAttributeType.indexOf(';'); @@ -257,9 +235,7 @@ attributeType = DirectoryServer.getAttributeType(baseName, true); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public final AttributeType getAttributeType() { @@ -269,22 +245,14 @@ return attributeType; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void setAttributeType(AttributeType attributeType) { this.attributeType = attributeType; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public Set<String> getAttributeOptions() { @@ -294,43 +262,29 @@ return attributeOptions; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void setAttributeOptions(Set<String> attributeOptions) { this.attributeOptions = attributeOptions; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public final ByteString getAssertionValue() { return assertionValue; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public final void setAssertionValue(ByteString assertionValue) { this.assertionValue = assertionValue; } /** * {@inheritDoc} */ @Override() /** {@inheritDoc} */ @Override public final OperationType getOperationType() { // Note that no debugging will be done in this method because it is a likely @@ -354,45 +308,29 @@ return proxiedAuthorizationDN; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN) { this.proxiedAuthorizationDN = proxiedAuthorizationDN; } /** * {@inheritDoc} */ @Override() /** {@inheritDoc} */ @Override public final List<Control> getResponseControls() { return responseControls; } /** * {@inheritDoc} */ @Override() /** {@inheritDoc} */ @Override public final void addResponseControl(Control control) { responseControls.add(control); } /** * {@inheritDoc} */ @Override() /** {@inheritDoc} */ @Override public final void removeResponseControl(Control control) { responseControls.remove(control); @@ -466,19 +404,7 @@ return; } // Retrieve the network group registered with the client connection // and get a workflow to process the operation. Workflow workflow = NetworkGroup.getWorkflowCandidate(entryDN); if (workflow == null) { // We have found no workflow for the requested base DN, just return // a no such entry result code and stop the processing. updateOperationErrMsgAndResCode(); return; } workflow.execute(this); workflowExecuted = true; workflowExecuted = execute(this, entryDN); } catch(CanceledOperationException coe) { @@ -520,11 +446,10 @@ /** * Invokes the post response plugins. If a workflow has been executed * then invoke the post response plugins provided by the workflow * elements of the worklfow, otherwise invoke the post reponse plugins * elements of the workflow, otherwise invoke the post response plugins * that have been registered with the current operation. * * @param workflowExecuted <code>true</code> if a workflow has been * executed * @param workflowExecuted <code>true</code> if a workflow has been executed */ private void invokePostResponsePlugins(boolean workflowExecuted) { @@ -563,18 +488,15 @@ * This method is called because no workflow was found to process * the operation. */ private void updateOperationErrMsgAndResCode() @Override public void updateOperationErrMsgAndResCode() { setResultCode(ResultCode.NO_SUCH_OBJECT); appendErrorMessage(ERR_COMPARE_NO_SUCH_ENTRY.get(getEntryDN())); } /** * {@inheritDoc} */ @Override() /** {@inheritDoc} */ @Override public final void toString(StringBuilder buffer) { buffer.append("CompareOperation(connID="); opendj3-server-dev/src/server/org/opends/server/core/DeleteOperationBasis.java
@@ -26,8 +26,6 @@ */ package org.opends.server.core; import static org.opends.messages.CoreMessages.*; import static org.opends.server.loggers.AccessLogger.*; import java.util.ArrayList; import java.util.List; @@ -36,12 +34,15 @@ import org.forgerock.opendj.ldap.ResultCode; import org.opends.server.api.ClientConnection; import org.opends.server.api.plugin.PluginResult; import org.opends.server.core.networkgroups.NetworkGroup; import org.opends.server.types.*; import org.opends.server.types.operation.PostResponseDeleteOperation; import org.opends.server.types.operation.PreParseDeleteOperation; import org.opends.server.workflowelement.localbackend.LocalBackendDeleteOperation; import static org.opends.messages.CoreMessages.*; import static org.opends.server.loggers.AccessLogger.*; import static org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement.*; /** * This class defines an operation that may be used to remove an entry from the * Directory Server. @@ -263,19 +264,7 @@ return; } // Retrieve the network group attached to the client connection // and get a workflow to process the operation. Workflow workflow = NetworkGroup.getWorkflowCandidate(entryDN); if (workflow == null) { // We have found no workflow for the requested base DN, just return // a no such entry result code and stop the processing. updateOperationErrMsgAndResCode(); return; } workflow.execute(this); workflowExecuted = true; workflowExecuted = execute(this, entryDN); } catch(CanceledOperationException coe) { @@ -323,11 +312,10 @@ /** * Invokes the post response plugins. If a workflow has been executed * then invoke the post response plugins provided by the workflow * elements of the worklfow, otherwise invoke the post reponse plugins * elements of the workflow, otherwise invoke the post response plugins * that have been registered with the current operation. * * @param workflowExecuted <code>true</code> if a workflow has been * executed * @param workflowExecuted <code>true</code> if a workflow has been executed */ private void invokePostResponsePlugins(boolean workflowExecuted) { @@ -359,14 +347,9 @@ } } /** * Updates the error message and the result code of the operation. * * This method is called because no workflows were found to process * the operation. */ private void updateOperationErrMsgAndResCode() /** {@inheritDoc} */ @Override public void updateOperationErrMsgAndResCode() { setResultCode(ResultCode.NO_SUCH_OBJECT); appendErrorMessage(ERR_DELETE_NO_SUCH_ENTRY.get(getEntryDN())); @@ -384,4 +367,3 @@ } } opendj3-server-dev/src/server/org/opends/server/core/DirectoryServer.java
@@ -125,7 +125,6 @@ import org.opends.server.config.JMXMBean; import org.opends.server.controls.PasswordPolicyErrorType; import org.opends.server.controls.PasswordPolicyResponseControl; import org.opends.server.core.networkgroups.NetworkGroup; import org.opends.server.crypto.CryptoManagerImpl; import org.opends.server.crypto.CryptoManagerSync; import org.opends.server.extensions.ConfigFileHandler; @@ -229,7 +228,6 @@ import static org.opends.server.util.DynamicConstants.*; import static org.opends.server.util.ServerConstants.*; import static org.opends.server.util.StaticUtils.*; import static org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement.*; /** * This class defines the core of the Directory Server. It manages the startup @@ -2162,12 +2160,7 @@ */ private static void createWorkflow(DN baseDN, Backend<?> backend) throws DirectoryException { // Create a root workflow element to encapsulate the backend final String backendID = backend.getBackendID(); LocalBackendWorkflowElement rootWE = createAndRegister(backendID, backend); // Create the workflow for the base DN and register the workflow with the server NetworkGroup.getDefaultNetworkGroup().registerWorkflow(backendID, baseDN, rootWE); LocalBackendWorkflowElement.createAndRegister(baseDN, backend); } /** @@ -5190,7 +5183,10 @@ directoryServer.backends = newBackends; // Don't need anymore the local backend workflow element so we can remove it LocalBackendWorkflowElement.remove(backend.getBackendID()); for (DN baseDN : backend.getBaseDNs()) { LocalBackendWorkflowElement.remove(baseDN); } BackendMonitor monitor = backend.getBackendMonitor(); @@ -5391,7 +5387,7 @@ // Now we need to deregister the workflow that was associated with the base DN if (!baseDN.equals(DN.valueOf("cn=config"))) { NetworkGroup.getDefaultNetworkGroup().deregisterWorkflow(baseDN); LocalBackendWorkflowElement.remove(baseDN); } } } @@ -7147,9 +7143,6 @@ logger.traceException(e); } // Deregister all workflows and network group configuration. NetworkGroup.deregisterAllOnShutdown(); // Force a new InternalClientConnection to be created on restart. InternalConnectionHandler.clearRootClientConnectionAtShutdown(); opendj3-server-dev/src/server/org/opends/server/core/ModifyDNOperationBasis.java
@@ -34,7 +34,6 @@ import org.forgerock.opendj.ldap.ResultCode; import org.opends.server.api.ClientConnection; import org.opends.server.api.plugin.PluginResult; import org.opends.server.core.networkgroups.NetworkGroup; import org.opends.server.types.*; import org.opends.server.types.operation.PostResponseModifyDNOperation; import org.opends.server.types.operation.PreParseModifyDNOperation; @@ -42,6 +41,7 @@ import static org.opends.messages.CoreMessages.*; import static org.opends.server.loggers.AccessLogger.*; import static org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement.*; /** * This class defines an operation that may be used to alter the DN of an entry @@ -449,18 +449,7 @@ return; } // Retrieve the network group attached to the client connection // and get a workflow to process the operation. Workflow workflow = NetworkGroup.getWorkflowCandidate(entryDN); if (workflow == null) { // We have found no workflow for the requested base DN, just return // a no such entry result code and stop the processing. updateOperationErrMsgAndResCode(); return; } workflow.execute(this); workflowExecuted = true; workflowExecuted = execute(this, entryDN); } catch(CanceledOperationException coe) { @@ -507,11 +496,10 @@ /** * Invokes the post response plugins. If a workflow has been executed * then invoke the post response plugins provided by the workflow * elements of the worklfow, otherwise invoke the post reponse plugins * elements of the workflow, otherwise invoke the post response plugins * that have been registered with the current operation. * * @param workflowExecuted <code>true</code> if a workflow has been * executed * @param workflowExecuted <code>true</code> if a workflow has been executed */ private void invokePostResponsePlugins(boolean workflowExecuted) { @@ -545,14 +533,9 @@ } } /** * Updates the error message and the result code of the operation. * * This method is called because no workflows were found to process * the operation. */ private void updateOperationErrMsgAndResCode() /** {@inheritDoc} */ @Override public void updateOperationErrMsgAndResCode() { setResultCode(ResultCode.NO_SUCH_OBJECT); appendErrorMessage(ERR_MODDN_NO_BACKEND_FOR_CURRENT_ENTRY.get(entryDN)); opendj3-server-dev/src/server/org/opends/server/core/ModifyOperationBasis.java
@@ -34,7 +34,6 @@ import org.forgerock.opendj.ldap.ResultCode; import org.opends.server.api.ClientConnection; import org.opends.server.api.plugin.PluginResult; import org.opends.server.core.networkgroups.NetworkGroup; import org.opends.server.protocols.ldap.LDAPAttribute; import org.opends.server.protocols.ldap.LDAPModification; import org.opends.server.protocols.ldap.LDAPResultCode; @@ -45,6 +44,7 @@ import static org.opends.messages.CoreMessages.*; import static org.opends.server.loggers.AccessLogger.*; import static org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement.*; /** * This class defines an operation that may be used to modify an entry in the @@ -69,10 +69,7 @@ /** The set of response controls for this modify operation. */ private List<Control> responseControls; /** * The raw, unprocessed set of modifications as included in the client * request. */ /** The raw, unprocessed set of modifications as included in the client request. */ private List<RawModification> rawModifications; /** The set of modifications for this modify operation. */ @@ -368,19 +365,7 @@ return; } // Retrieve the network group attached to the client connection // and get a workflow to process the operation. Workflow workflow = NetworkGroup.getWorkflowCandidate(entryDN); if (workflow == null) { // We have found no workflow for the requested base DN, just return // a no such entry result code and stop the processing. updateOperationErrMsgAndResCode(); return; } workflow.execute(this); workflowExecuted = true; workflowExecuted = execute(this, entryDN); } catch(CanceledOperationException coe) { @@ -427,11 +412,10 @@ /** * Invokes the post response plugins. If a workflow has been executed * then invoke the post response plugins provided by the workflow * elements of the worklfow, otherwise invoke the post reponse plugins * elements of the workflow, otherwise invoke the post response plugins * that have been registered with the current operation. * * @param workflowExecuted <code>true</code> if a workflow has been * executed * @param workflowExecuted <code>true</code> if a workflow has been executed */ private void invokePostResponsePlugins(boolean workflowExecuted) { @@ -464,15 +448,9 @@ } } /** * Updates the error message and the result code of the operation. * * This method is called because no workflows were found to process * the operation. */ private void updateOperationErrMsgAndResCode() /** {@inheritDoc} */ @Override public void updateOperationErrMsgAndResCode() { setResultCode(ResultCode.NO_SUCH_OBJECT); appendErrorMessage(ERR_MODIFY_NO_SUCH_ENTRY.get(getEntryDN())); opendj3-server-dev/src/server/org/opends/server/core/RootDseWorkflowTopology.java
File was deleted opendj3-server-dev/src/server/org/opends/server/core/SearchOperationBasis.java
@@ -46,7 +46,6 @@ import org.opends.server.api.plugin.PluginResult; import org.opends.server.controls.AccountUsableResponseControl; import org.opends.server.controls.MatchedValuesControl; import org.opends.server.core.networkgroups.NetworkGroup; import org.opends.server.protocols.ldap.LDAPFilter; import org.opends.server.types.AbstractOperation; import org.opends.server.types.Attribute; @@ -74,6 +73,7 @@ import static org.opends.server.loggers.AccessLogger.*; import static org.opends.server.util.ServerConstants.*; import static org.opends.server.util.StaticUtils.*; import static org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement.*; /** * This class defines an operation that may be used to locate entries in the @@ -889,9 +889,9 @@ buffer.append(", baseDN="); buffer.append(rawBaseDN); buffer.append(", scope="); buffer.append(scope.toString()); buffer.append(scope); buffer.append(", filter="); buffer.append(rawFilter.toString()); buffer.append(rawFilter); buffer.append(")"); } @@ -1089,17 +1089,7 @@ return; } // Retrieve the network group attached to the client connection // and get a workflow to process the operation. Workflow workflow = NetworkGroup.getWorkflowCandidate(baseDN); if (workflow == null) { // We have found no workflow for the requested base DN, just return // a no such entry result code and stop the processing. updateOperationErrMsgAndResCode(); return; } workflow.execute(this); execute(this, baseDN); } catch(CanceledOperationException coe) { @@ -1162,14 +1152,9 @@ pluginConfigManager.invokePostResponseSearchPlugins(this); } /** * Updates the error message and the result code of the operation. * * This method is called because no workflows were found to process * the operation. */ private void updateOperationErrMsgAndResCode() /** {@inheritDoc} */ @Override public void updateOperationErrMsgAndResCode() { setResultCode(ResultCode.NO_SUCH_OBJECT); appendErrorMessage(ERR_SEARCH_BASE_DOESNT_EXIST.get(getBaseDN())); opendj3-server-dev/src/server/org/opends/server/core/Workflow.java
File was deleted opendj3-server-dev/src/server/org/opends/server/core/WorkflowResultCode.java
@@ -34,7 +34,7 @@ * This class implements the workflow result code. The workflow result code * contains an LDAP result code along with an LDAP error message. */ class WorkflowResultCode public class WorkflowResultCode { /** The global result code. */ private ResultCode resultCode = ResultCode.UNDEFINED; @@ -58,7 +58,7 @@ * @param resultCode the initial value for the result code * @param errorMessage the initial value for the error message */ WorkflowResultCode(ResultCode resultCode, LocalizableMessageBuilder errorMessage) public WorkflowResultCode(ResultCode resultCode, LocalizableMessageBuilder errorMessage) { this.resultCode = resultCode; this.errorMessage = errorMessage; @@ -106,7 +106,7 @@ * @param newErrorMessage the new error message associated to the new error code * @return <code>true</code> if a referral result code must be turned into a reference entry */ boolean elaborateGlobalResultCode(ResultCode newResultCode, LocalizableMessageBuilder newErrorMessage) public boolean elaborateGlobalResultCode(ResultCode newResultCode, LocalizableMessageBuilder newErrorMessage) { // if global result code has not been set yet then just take the new // result code as is @@ -181,7 +181,7 @@ * * @return the global result code. */ ResultCode resultCode() public ResultCode resultCode() { return resultCode; } @@ -191,7 +191,7 @@ * * @return the global error message. */ LocalizableMessageBuilder errorMessage() public LocalizableMessageBuilder errorMessage() { return errorMessage; } opendj3-server-dev/src/server/org/opends/server/core/WorkflowTopology.java
File was deleted opendj3-server-dev/src/server/org/opends/server/core/WorkflowTopologyNode.java
File was deleted opendj3-server-dev/src/server/org/opends/server/core/networkgroups/NetworkGroup.java
File was deleted opendj3-server-dev/src/server/org/opends/server/core/networkgroups/NetworkGroupNamingContexts.java
File was deleted opendj3-server-dev/src/server/org/opends/server/core/networkgroups/package-info.java
File was deleted opendj3-server-dev/src/server/org/opends/server/types/AbstractOperation.java
@@ -72,35 +72,22 @@ protected static final List<Control> NO_RESPONSE_CONTROLS = new ArrayList<Control>(0); /** * The client connection with which this operation is associated. */ /** The client connection with which this operation is associated. */ protected final ClientConnection clientConnection; /** * The message ID for this operation. */ /** The message ID for this operation. */ protected final int messageID; /** * The operation ID for this operation. */ /** The operation ID for this operation. */ protected final long operationID; /** * Whether nanotime was used for this operation. */ /** Whether nanotime was used for this operation. */ protected final boolean useNanoTime; /** * The cancel request for this operation. */ /** The cancel request for this operation. */ protected CancelRequest cancelRequest; /** * The cancel result for this operation. */ /** The cancel result for this operation. */ protected CancelResult cancelResult; /** @@ -762,7 +749,6 @@ { return true; } if (obj instanceof Operation) { Operation other = (Operation) obj; @@ -771,7 +757,6 @@ return other.getOperationID() == operationID; } } return false; } @@ -799,5 +784,13 @@ } } } } /** * Updates the error message and the result code of the operation. This method * is called because no workflows were found to process the operation. */ public void updateOperationErrMsgAndResCode() { // do nothing by default } } opendj3-server-dev/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -27,16 +27,20 @@ package org.opends.server.workflowelement.localbackend; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.TreeMap; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.i18n.LocalizableMessageDescriptor; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.SearchScope; import org.opends.server.api.AccessControlHandler; import org.opends.server.api.Backend; import org.opends.server.backends.RootDSEBackend; import org.opends.server.controls.LDAPPostReadRequestControl; import org.opends.server.controls.LDAPPostReadResponseControl; import org.opends.server.controls.LDAPPreReadRequestControl; @@ -47,17 +51,6 @@ import static org.opends.messages.CoreMessages.*; /** * This class defines a workflow element, i.e. a task in a workflow. * * [outdated] * A workflow element can wrap a physical * repository such as a local backend, a remote LDAP server or a local LDIF * file. A workflow element can also be used to route operations. * This is the case for load balancing and distribution. * And workflow element can be used in a virtual environment to transform data * (DN and attribute renaming, attribute value renaming...). * [/outdated] * * This class defines a local backend workflow element; e-g an entity that * handle the processing of an operation against a local backend. */ @@ -65,42 +58,30 @@ { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); /** * An information indicating the type of the current workflow element. This * information is for debug and tooling purpose only. */ private String workflowElementTypeInfo = "not defined"; /** The workflow element identifier. */ private String workflowElementID; /** The backend's baseDN mapped by this object. */ private DN baseDN; /** the backend associated with the local workflow element. */ 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<DN, LocalBackendWorkflowElement> registeredLocalBackends = new TreeMap<DN, LocalBackendWorkflowElement>(); /** A lock to guarantee safe concurrent access to the registeredLocalBackends variable. */ private static final Object registeredLocalBackendsLock = new Object(); /** A string indicating the type of the workflow element. */ private static final String BACKEND_WORKFLOW_ELEMENT = "Backend"; /** * Initializes a new instance of the local backend workflow element. * This method is intended to be called by DirectoryServer when * workflow configuration mode is auto as opposed to * initializeWorkflowElement which is invoked when workflow * configuration mode is manual. * * @param workflowElementID the workflow element identifier * @param backend the backend associated to that workflow element * @param baseDN * the backend's baseDN mapped by this object * @param backend * the backend associated to that workflow element */ private void initialize(String workflowElementID, Backend<?> backend) private void initialize(DN baseDN, Backend<?> backend) { this.workflowElementID = workflowElementID; this.workflowElementTypeInfo = BACKEND_WORKFLOW_ELEMENT; this.baseDN = baseDN; this.backend = backend; } @@ -122,30 +103,27 @@ */ public void finalizeWorkflowElement() { this.workflowElementID = null; this.workflowElementTypeInfo = null; this.baseDN = null; this.backend = null; } /** * Creates and registers a local backend with the server. * * @param workflowElementID the identifier of the workflow element to create * @param backend the backend to associate with the local backend * workflow element * * @return the existing local backend workflow element if it was * already created or a newly created local backend workflow * element. * @param baseDN * the backend's baseDN mapped by this object * @param backend * the backend to associate with the local backend workflow element * @return the existing local backend workflow element if it was already * created or a newly created local backend workflow element. */ public static LocalBackendWorkflowElement createAndRegister( String workflowElementID, Backend<?> backend) public static LocalBackendWorkflowElement createAndRegister(DN baseDN, Backend<?> backend) { LocalBackendWorkflowElement localBackend = registeredLocalBackends.get(workflowElementID); LocalBackendWorkflowElement localBackend = registeredLocalBackends.get(baseDN); if (localBackend == null) { localBackend = new LocalBackendWorkflowElement(); localBackend.initialize(workflowElementID, backend); localBackend.initialize(baseDN, backend); registerLocalBackend(localBackend); } @@ -157,11 +135,12 @@ /** * Removes a local backend that was registered with the server. * * @param workflowElementID the identifier of the workflow element to remove * @param baseDN * the identifier of the workflow to remove */ public static void remove(String workflowElementID) public static void remove(DN baseDN) { deregisterLocalBackend(workflowElementID); deregisterLocalBackend(baseDN); } @@ -176,7 +155,7 @@ { for (LocalBackendWorkflowElement localBackend : registeredLocalBackends.values()) { deregisterLocalBackend(localBackend.getWorkflowElementID()); deregisterLocalBackend(localBackend.getBaseDN()); } } } @@ -457,13 +436,13 @@ { synchronized (registeredLocalBackendsLock) { String localBackendID = localBackend.getWorkflowElementID(); LocalBackendWorkflowElement existingLocalBackend = registeredLocalBackends.get(localBackendID); DN baseDN = localBackend.getBaseDN(); LocalBackendWorkflowElement existingLocalBackend = registeredLocalBackends.get(baseDN); if (existingLocalBackend == null) { TreeMap<String, LocalBackendWorkflowElement> newLocalBackends = new TreeMap<String, LocalBackendWorkflowElement>(registeredLocalBackends); newLocalBackends.put(localBackendID, localBackend); TreeMap<DN, LocalBackendWorkflowElement> newLocalBackends = new TreeMap<DN, LocalBackendWorkflowElement>(registeredLocalBackends); newLocalBackends.put(baseDN, localBackend); registeredLocalBackends = newLocalBackends; } } @@ -474,25 +453,26 @@ /** * Deregisters a local backend with the server. * * @param workflowElementID the identifier of the workflow element to remove * @param baseDN * the identifier of the local backend to remove */ private static void deregisterLocalBackend(String workflowElementID) private static void deregisterLocalBackend(DN baseDN) { synchronized (registeredLocalBackendsLock) { LocalBackendWorkflowElement existingLocalBackend = registeredLocalBackends.get(workflowElementID); LocalBackendWorkflowElement existingLocalBackend = registeredLocalBackends.get(baseDN); if (existingLocalBackend != null) { TreeMap<String, LocalBackendWorkflowElement> newLocalBackends = new TreeMap<String, LocalBackendWorkflowElement>(registeredLocalBackends); newLocalBackends.remove(workflowElementID); TreeMap<DN, LocalBackendWorkflowElement> newLocalBackends = new TreeMap<DN, LocalBackendWorkflowElement>(registeredLocalBackends); newLocalBackends.remove(baseDN); registeredLocalBackends = newLocalBackends; } } } /** * Executes the workflow element for an operation. * Executes the workflow for an operation. * * @param operation * the operation to execute @@ -576,9 +556,9 @@ * * @return the workflow element identifier */ public String getWorkflowElementID() public DN getBaseDN() { return workflowElementID; return baseDN; } /** @@ -641,13 +621,299 @@ } } /** * Executes the supplied operation. * * @param operation * the operation to execute * @param entryDN * the entry DN whose backend will be used * @return true if the operation successfully executed, false otherwise * @throws CanceledOperationException * if this operation should be cancelled. */ public static boolean execute(Operation operation, DN entryDN) throws CanceledOperationException { LocalBackendWorkflowElement workflow = getLocalBackendWorkflowElement(entryDN); if (workflow == null) { // We have found no backend for the requested base DN, // just return a no such entry result code and stop the processing. if (operation instanceof AbstractOperation) { ((AbstractOperation) operation).updateOperationErrMsgAndResCode(); } return false; } if (workflow.getBaseDN().isRootDN()) { executeOnRootDSE(operation, workflow); } else { executeOnNonRootDSE(operation, workflow); } return true; } private static LocalBackendWorkflowElement getLocalBackendWorkflowElement(DN entryDN) { while (entryDN != null) { final LocalBackendWorkflowElement workflow = registeredLocalBackends.get(entryDN); if (workflow != null) { return workflow; } entryDN = entryDN.parent(); } return null; } /** * Executes an operation on the root DSE entry. * * @param operation * the operation to execute * @param workflow * the workflow where to execute the operation * @throws CanceledOperationException * if this operation should be cancelled. */ private static void executeOnRootDSE(Operation operation, LocalBackendWorkflowElement workflow) throws CanceledOperationException { OperationType operationType = operation.getOperationType(); if (operationType == OperationType.SEARCH) { executeSearch((SearchOperation) operation, workflow); } else { workflow.execute(operation); } } /** * Executes a search operation on the the root DSE entry. * * @param searchOp * the operation to execute * @param workflow * the workflow where to execute the operation * @throws CanceledOperationException * if this operation should be cancelled. */ private static void executeSearch(SearchOperation searchOp, LocalBackendWorkflowElement workflow) throws CanceledOperationException { // Keep a the original search scope because we will alter it in the operation SearchScope originalScope = searchOp.getScope(); // Search base? // The root DSE entry itself is never returned unless the operation // is a search base on the null suffix. if (originalScope == SearchScope.BASE_OBJECT) { workflow.execute(searchOp); return; } // Create a workflow result code in case we need to perform search in // subordinate workflows. WorkflowResultCode workflowResultCode = new WorkflowResultCode(searchOp.getResultCode(), searchOp.getErrorMessage()); // The search scope is not 'base', so let's do a search on all the public // naming contexts with appropriate new search scope and new base DN. SearchScope newScope = elaborateScopeForSearchInSubordinates(originalScope); searchOp.setScope(newScope); DN originalBaseDN = searchOp.getBaseDN(); for (LocalBackendWorkflowElement subordinate : getRootDSESubordinates()) { // We have to change the operation request base DN to match the // subordinate workflow base DN. Otherwise the workflow will // return a no such entry result code as the operation request // base DN is a superior of the workflow base DN! DN ncDN = subordinate.getBaseDN(); // Set the new request base DN then do execute the operation // in the naming context workflow. searchOp.setBaseDN(ncDN); execute(searchOp, ncDN); boolean sendReferenceEntry = workflowResultCode.elaborateGlobalResultCode( searchOp.getResultCode(), searchOp.getErrorMessage()); if (sendReferenceEntry) { // TODO jdemendi - turn a referral result code into a reference entry // and send the reference entry to the client application } } // Now restore the original request base DN and original search scope searchOp.setBaseDN(originalBaseDN); searchOp.setScope(originalScope); // If the result code is still uninitialized (ie no naming context), // we should return NO_SUCH_OBJECT workflowResultCode.elaborateGlobalResultCode( ResultCode.NO_SUCH_OBJECT, new LocalizableMessageBuilder(LocalizableMessage.EMPTY)); // Set the operation result code and error message searchOp.setResultCode(workflowResultCode.resultCode()); searchOp.setErrorMessage(workflowResultCode.errorMessage()); } private static Collection<LocalBackendWorkflowElement> getRootDSESubordinates() { final RootDSEBackend rootDSEBackend = DirectoryServer.getRootDSEBackend(); final List<LocalBackendWorkflowElement> results = new ArrayList<LocalBackendWorkflowElement>(); for (DN subordinateBaseDN : rootDSEBackend.getSubordinateBaseDNs().keySet()) { results.add(registeredLocalBackends.get(subordinateBaseDN)); } return results; } private static void executeOnNonRootDSE(Operation operation, LocalBackendWorkflowElement workflow) throws CanceledOperationException { workflow.execute(operation); // For subtree search operation we need to go through the subordinate nodes. if (operation.getOperationType() == OperationType.SEARCH) { executeSearchOnSubordinates((SearchOperation) operation, workflow); } } /** * Executes a search operation on the subordinate workflows. * * @param searchOp * the search operation to execute * @param workflow * the workflow element * @throws CanceledOperationException * if this operation should be canceled. */ private static void executeSearchOnSubordinates(SearchOperation searchOp, LocalBackendWorkflowElement workflow) throws CanceledOperationException { // If the scope of the search is 'base' then it's useless to search // in the subordinate workflows. SearchScope originalScope = searchOp.getScope(); if (originalScope == SearchScope.BASE_OBJECT) { return; } // Elaborate the new search scope before executing the search operation // in the subordinate workflows. SearchScope newScope = elaborateScopeForSearchInSubordinates(originalScope); searchOp.setScope(newScope); // Let's search in the subordinate workflows. WorkflowResultCode workflowResultCode = new WorkflowResultCode( searchOp.getResultCode(), searchOp.getErrorMessage()); DN originalBaseDN = searchOp.getBaseDN(); for (LocalBackendWorkflowElement subordinate : getSubordinates(workflow)) { // We have to change the operation request base DN to match the // subordinate workflow base DN. Otherwise the workflow will // return a no such entry result code as the operation request // base DN is a superior of the subordinate workflow base DN. DN subordinateDN = subordinate.getBaseDN(); // If the new search scope is 'base' and the search base DN does not // map the subordinate workflow then skip the subordinate workflow. if (newScope == SearchScope.BASE_OBJECT && !subordinateDN.parent().equals(originalBaseDN)) { continue; } // If the request base DN is not a subordinate of the subordinate // workflow base DN then do not search in the subordinate workflow. if (!originalBaseDN.isAncestorOf(subordinateDN)) { continue; } // Set the new request base DN and do execute the // operation in the subordinate workflow. searchOp.setBaseDN(subordinateDN); execute(searchOp, subordinateDN); boolean sendReferenceEntry = workflowResultCode.elaborateGlobalResultCode(searchOp.getResultCode(), searchOp.getErrorMessage()); if (sendReferenceEntry) { // TODO jdemendi - turn a referral result code into a reference entry // and send the reference entry to the client application } } // Now we are done with the operation, let's restore the original // base DN and search scope in the operation. searchOp.setBaseDN(originalBaseDN); searchOp.setScope(originalScope); // Update the operation result code and error message searchOp.setResultCode(workflowResultCode.resultCode()); searchOp.setErrorMessage(workflowResultCode.errorMessage()); } private static Collection<LocalBackendWorkflowElement> getSubordinates(LocalBackendWorkflowElement workflow) { final DN baseDN = workflow.getBaseDN(); final Backend<?> backend = workflow.getBackend(); final ArrayList<LocalBackendWorkflowElement> results = new ArrayList<LocalBackendWorkflowElement>(); for (Backend<?> subordinate : backend.getSubordinateBackends()) { for (DN subordinateDN : subordinate.getBaseDNs()) { if (subordinateDN.isDescendantOf(baseDN)) { results.add(registeredLocalBackends.get(subordinateDN)); } } } return results; } /** * Elaborates a new search scope according to the current search scope. The * new scope is intended to be used for searches on subordinate workflows. * * @param currentScope * the current search scope * @return the new scope to use for searches on subordinate workflows, * <code>null</code> when current scope is 'base' */ private static SearchScope elaborateScopeForSearchInSubordinates(SearchScope currentScope) { switch (currentScope.asEnum()) { case BASE_OBJECT: return null; case SINGLE_LEVEL: return SearchScope.BASE_OBJECT; case SUBORDINATES: case WHOLE_SUBTREE: return SearchScope.WHOLE_SUBTREE; default: return currentScope; } } /** {@inheritDoc} */ @Override public String toString() { return getClass().getSimpleName() + " backend=" + backend + " workflowElementID=" + this.workflowElementID + " workflowElementTypeInfo=" + this.workflowElementTypeInfo; + " backend=" + this.backend + " baseDN=" + this.baseDN; } } opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowTopologyTest.java
File was deleted opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
File was deleted opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElementTest.java
New file @@ -0,0 +1,281 @@ /* * 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 legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * 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 legal-notices/CDDLv1_0.txt. * 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 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2014 ForgeRock AS. */ package org.opends.server.workflowelement.localbackend; import java.util.ArrayList; import org.forgerock.opendj.ldap.ModificationType; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.SearchScope; import org.opends.server.DirectoryServerTestCase; import org.opends.server.TestCaseUtils; import org.opends.server.core.ModifyOperation; import org.opends.server.core.SearchOperation; import org.opends.server.protocols.internal.SearchRequest; import org.opends.server.types.Attribute; import org.opends.server.types.Attributes; import org.opends.server.types.DN; import org.opends.server.types.DirectoryException; import org.opends.server.types.Modification; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import static org.opends.server.config.ConfigConstants.*; import static org.opends.server.protocols.internal.InternalClientConnection.*; import static org.opends.server.protocols.internal.Requests.*; import static org.testng.Assert.*; /** * This set of tests test the LocalBackendWorkflowElement. */ @SuppressWarnings("javadoc") public class LocalBackendWorkflowElementTest extends DirectoryServerTestCase { @BeforeClass public void setUp() throws Exception { TestCaseUtils.startServer(); } /** * This test checks that workflows are updated as appropriate when backend * base DNs are added or removed. * <p> * When a new backend base DN is added, the new suffix should be accessible * for the route process - ie. a workflow should be created and be a potential * candidate for the route process. * <p> * Similarly, when a backend base DN is removed its associated workflow should * be removed; subsequently, any request targeting the removed suffix should * be rejected and a no such entry status code be returned. */ @Test public void testBackendBaseDNModification() throws Exception { String suffix = "dc=example,dc=com"; String suffix2 = "o=workflow suffix"; String backendBaseDNName = "ds-cfg-base-dn"; // Initialize a backend with a base entry. TestCaseUtils.clearJEBackend(true, "userRoot", suffix); // Check that suffix is accessible while suffix2 is not. searchEntry(suffix, ResultCode.SUCCESS); searchEntry(suffix2, ResultCode.NO_SUCH_OBJECT); // Add a new suffix in the backend and create a base entry for the new suffix String backendConfigDN = "ds-cfg-backend-id=userRoot," + DN_BACKEND_BASE; modifyAttribute(backendConfigDN, ModificationType.ADD, backendBaseDNName, suffix2); addBaseEntry(suffix2, "workflow suffix"); // Both old and new suffix should be accessible. searchEntry(suffix, ResultCode.SUCCESS); searchEntry(suffix2, ResultCode.SUCCESS); // Remove the new suffix... modifyAttribute(backendConfigDN, ModificationType.DELETE, backendBaseDNName, suffix2); // ...and check that the removed suffix is no more accessible. searchEntry(suffix, ResultCode.SUCCESS); searchEntry(suffix2, ResultCode.NO_SUCH_OBJECT); // Replace the suffix with suffix2 in the backend modifyAttribute(backendConfigDN, ModificationType.REPLACE, backendBaseDNName, suffix2); // Now none of the suffixes are accessible: this means the entries // under the old suffix are not moved to the new suffix. searchEntry(suffix, ResultCode.NO_SUCH_OBJECT); searchEntry(suffix2, ResultCode.NO_SUCH_OBJECT); // Add a base entry for the new suffix addBaseEntry(suffix2, "workflow suffix"); // The new suffix is accessible while the old one is not. searchEntry(suffix, ResultCode.NO_SUCH_OBJECT); searchEntry(suffix2, ResultCode.SUCCESS); // Reset the configuration with previous suffix modifyAttribute(backendConfigDN, ModificationType.REPLACE, backendBaseDNName, suffix); } /** * This test checks that the workflow takes into account the subordinate * naming context defined in the RootDSEBackend. */ @Test public void testNonRootDseSubordinateNamingContext() throws Exception { // Backends for the test String backendID1 = "test-dc-example-dc-com-subordinate1,dc=example,dc=com"; String backendID2 = "test-dc-example-dc-com-subordinate2,dc=example,dc=com"; String backend1 = "o=" + backendID1; String backend2 = "o=" + backendID2; try { TestCaseUtils.clearDataBackends(); // At this point, the list of subordinate naming context is not defined // yet (null): any public backend should be visible. Create a backend // with a base entry and check that the test naming context is visible. TestCaseUtils.initializeMemoryBackend(backendID1, backend1, true); searchEntries("dc=example,dc=com", ResultCode.SUCCESS, 1); // Create another test backend and check that the new backend is visible TestCaseUtils.initializeMemoryBackend(backendID2, backend2, true); searchEntries("dc=example,dc=com", ResultCode.SUCCESS, 2); } finally { // Clean the test backends. There is no more naming context. TestCaseUtils.clearMemoryBackend(backendID1); TestCaseUtils.clearMemoryBackend(backendID2); searchEntries("dc=example,dc=com", ResultCode.NO_SUCH_OBJECT, 0); } } /** * This test checks that the workflow takes into account the subordinate * naming context defined in the RootDSEBackend. */ @Test public void testRootDseSubordinateNamingContext() throws Exception { // Backends for the test String backend1 = "o=test-rootDSE-subordinate-naming-context-1"; String backend2 = "o=test-rootDSE-subordinate-naming-context-2"; String backendID1 = "test-rootDSE-subordinate-naming-context-1"; String backendID2 = "test-rootDSE-subordinate-naming-context-2"; try { TestCaseUtils.clearDataBackends(); // At this point, the list of subordinate naming context is not defined // yet (null): any public backend should be visible. Create a backend // with a base entry and check that the test naming context is visible. TestCaseUtils.initializeMemoryBackend(backendID1, backend1, true); searchPublicNamingContexts(ResultCode.SUCCESS, 1); // Create another test backend and check that the new backend is visible TestCaseUtils.initializeMemoryBackend(backendID2, backend2, true); searchPublicNamingContexts(ResultCode.SUCCESS, 2); // Now put in the list of subordinate naming context the backend1 naming context. // This white list will prevent the backend2 to be visible. TestCaseUtils.dsconfig( "set-root-dse-backend-prop", "--set", "subordinate-base-dn:" + backend1); searchPublicNamingContexts(ResultCode.SUCCESS, 1); // === Cleaning // Reset the subordinate naming context list. // Both naming context should be visible again. TestCaseUtils.dsconfig( "set-root-dse-backend-prop", "--reset", "subordinate-base-dn"); searchPublicNamingContexts(ResultCode.SUCCESS, 2); } finally { // Clean the test backends. There is no more naming context. TestCaseUtils.clearMemoryBackend(backendID1); TestCaseUtils.clearMemoryBackend(backendID2); searchPublicNamingContexts(ResultCode.NO_SUCH_OBJECT, 0); } } /** * Searches the list of naming contexts. * * @param expectedRC the expected result code * @param expectedNamingContexts the number of expected naming contexts */ private void searchPublicNamingContexts(ResultCode expectedRC, int expectedNamingContexts) throws Exception { searchEntries("", expectedRC, expectedNamingContexts); } private void searchEntries(String baseDN, ResultCode expectedRC, int expectedNbEntries) throws DirectoryException { SearchRequest request = newSearchRequest(DN.valueOf(baseDN), SearchScope.SINGLE_LEVEL); SearchOperation search = getRootConnection().processSearch(request); assertEquals(search.getResultCode(), expectedRC); if (expectedRC == ResultCode.SUCCESS) { assertEquals(search.getEntriesSent(), expectedNbEntries); } } /** * Searches an entry on a given connection. * * @param baseDN the request base DN string * @param expectedRC the expected result code */ private void searchEntry(String baseDN, ResultCode expectedRC) throws Exception { SearchRequest request = newSearchRequest(DN.valueOf(baseDN), SearchScope.BASE_OBJECT); SearchOperation search = getRootConnection().processSearch(request); assertEquals(search.getResultCode(), expectedRC); } /** * Creates a base entry for the given suffix. * * @param suffix the suffix for which the base entry is to be created */ private void addBaseEntry(String suffix, String namingAttribute) throws Exception { TestCaseUtils.addEntry( "dn: " + suffix, "objectClass: top", "objectClass: organization", "o: " + namingAttribute); } /** * Adds/Deletes/Replaces an attribute in a given entry. * * @param baseDN the request base DN string * @param modType the modification type (add/delete/replace) * @param attributeName the name of the attribute to add/delete/replace * @param attributeValue the value of the attribute to add/delete/replace */ private void modifyAttribute(String baseDN, ModificationType modType, String attributeName, String attributeValue) throws Exception { ArrayList<Modification> mods = new ArrayList<Modification>(); Attribute attributeToModify = Attributes.create(attributeName, attributeValue); mods.add(new Modification(modType, attributeToModify)); ModifyOperation modifyOperation = getRootConnection().processModify(DN.valueOf(baseDN), mods); assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS); } }