opendj3-server-dev/src/server/org/opends/server/core/RootDseWorkflowTopology.java
@@ -28,10 +28,13 @@ import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.SearchScope; import org.opends.server.core.networkgroups.NetworkGroupNamingContexts; import org.opends.server.types.*; import org.forgerock.opendj.ldap.ResultCode; import org.opends.server.types.CanceledOperationException; import org.opends.server.types.DN; import org.opends.server.types.Operation; import org.opends.server.types.OperationType; /** * This class implements the workflow node that handles the root DSE entry. @@ -43,9 +46,11 @@ public class RootDseWorkflowTopology extends WorkflowTopology { // The naming contexts known by the root DSE. These naming contexts // are defined in the scope of a network group. private NetworkGroupNamingContexts namingContexts = null; /** * The naming contexts known by the root DSE. These naming contexts * are defined in the scope of a network group. */ private NetworkGroupNamingContexts namingContexts; /** @@ -75,19 +80,16 @@ * be cancelled. */ @Override public void execute(Operation operation) throws CanceledOperationException { // Execute the operation. OperationType operationType = operation.getOperationType(); if (operationType != OperationType.SEARCH) public void execute(Operation operation) throws CanceledOperationException { // Execute the operation getWorkflowImpl().execute(operation); OperationType operationType = operation.getOperationType(); if (operationType == OperationType.SEARCH) { executeSearch((SearchOperation) operation); } else { // Execute the SEARCH operation executeSearch((SearchOperation) operation); getWorkflowImpl().execute(operation); } } @@ -175,13 +177,10 @@ */ public StringBuilder toString(String leftMargin) { String workflowID = getWorkflowImpl().getWorkflowId(); StringBuilder sb = new StringBuilder(); // display the identifier and baseDN String workflowID = this.getWorkflowImpl().getWorkflowId(); sb.append(leftMargin + "Workflow ID = " + workflowID + "\n"); sb.append(leftMargin + " baseDN:[ \"\" ]\n"); sb.append(leftMargin).append("Workflow ID = ").append(workflowID).append("\n"); sb.append(leftMargin).append(" baseDN:[ \"\" ]\n"); return sb; } opendj3-server-dev/src/server/org/opends/server/core/networkgroups/NetworkGroup.java
@@ -72,7 +72,7 @@ // Invalidate all NetworkGroups so they cannot accidentally be // used after a restart. defaultNetworkGroup.invalidate(); defaultNetworkGroup = new NetworkGroup("default"); defaultNetworkGroup = new NetworkGroup(DEFAULT_NETWORK_GROUP_NAME); } /** @@ -101,10 +101,7 @@ private TreeMap<String, WorkflowTopologyNode> registeredWorkflowNodes = new TreeMap<String, WorkflowTopologyNode>(); /** * A lock to protect concurrent access to the registered Workflow * nodes. */ /** A lock to protect concurrent access to the registered Workflow nodes. */ private final Object registeredWorkflowNodesLock = new Object(); /** @@ -134,13 +131,12 @@ */ public Workflow deregisterWorkflow(DN baseDN) { Workflow workflow = null; if (baseDN == null) { return workflow; return null; } Workflow workflow = null; if (baseDN.isRootDN()) { // deregister the rootDSE @@ -175,10 +171,8 @@ // group, update the reference counter of the workflow. if (workflow != null) { WorkflowImpl workflowImpl = (WorkflowImpl) workflow; workflowImpl.decrementReferenceCounter(); ((WorkflowImpl) workflow).decrementReferenceCounter(); } return workflow; } @@ -210,48 +204,34 @@ private Workflow getWorkflowCandidatePriv(DN baseDN) { // the top workflow to return Workflow workflowCandidate = null; // get the list of workflow candidates if (baseDN.isRootDN()) { // The rootDSE workflow is the candidate. workflowCandidate = rootDSEWorkflowNode; return rootDSEWorkflowNode; } else { // Search the highest workflow in the topology that can handle // the baseDN. // Search the highest workflow in the topology that can handle the baseDN. //First search the private workflows // The order is important to ensure that the admin network group // is not broken and can always find cn=config for (WorkflowTopologyNode curWorkflow : namingContexts .getPrivateNamingContexts()) for (WorkflowTopologyNode curWorkflow : namingContexts.getPrivateNamingContexts()) { workflowCandidate = curWorkflow.getWorkflowCandidate(baseDN); WorkflowTopologyNode workflowCandidate = curWorkflow.getWorkflowCandidate(baseDN); if (workflowCandidate != null) { break; } } // If not found, search the public if (workflowCandidate == null) { for (WorkflowTopologyNode curWorkflow : namingContexts .getPublicNamingContexts()) { workflowCandidate = curWorkflow.getWorkflowCandidate(baseDN); if (workflowCandidate != null) { break; } } } } return workflowCandidate; } } // Not found, search the public for (WorkflowTopologyNode curWorkflow : namingContexts.getPublicNamingContexts()) { WorkflowTopologyNode workflowCandidate = curWorkflow.getWorkflowCandidate(baseDN); if (workflowCandidate != null) { return workflowCandidate; } } return null; } /** * Checks whether the base DN of a new workflow to register is present @@ -263,7 +243,7 @@ * If the base DN of the workflow is already present in the * network group */ private void checkWorkflowBaseDN(WorkflowTopologyNode workflowNode) private void checkNotRegistered(WorkflowTopologyNode workflowNode) throws DirectoryException { String workflowID = workflowNode.getWorkflowImpl().getWorkflowId(); @@ -276,12 +256,9 @@ DN nodeBaseDN = node.getBaseDN(); if (nodeBaseDN.equals(workflowNode.getBaseDN())) { // The base DN is already registered in the network group, // we must reject the registration request LocalizableMessage message = ERR_REGISTER_WORKFLOW_BASE_DN_ALREADY_EXISTS.get( workflowID, networkGroupID, node.getWorkflowImpl() .getWorkflowId(), workflowNode.getWorkflowImpl().getBaseDN()); LocalizableMessage message = ERR_REGISTER_WORKFLOW_BASE_DN_ALREADY_EXISTS.get( workflowID, networkGroupID, node.getWorkflowImpl().getWorkflowId(), workflowNode.getWorkflowImpl().getBaseDN()); throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); } } @@ -292,38 +269,23 @@ * * @param workflow * the workflow node to deregister * @return <code>true</code> when the workflow has been successfully * deregistered */ private boolean deregisterWorkflow(Workflow workflow) private void deregisterWorkflow(Workflow workflow) { // true as soon as the workflow has been deregistered boolean deregistered = false; // Is it the rootDSE workflow? if (workflow == rootDSEWorkflowNode) { rootDSEWorkflowNode = null; deregistered = true; return; } else { // Deregister the workflow with the network group. WorkflowTopologyNode workflowNode = (WorkflowTopologyNode) workflow; deregisterWorkflowNode(workflowNode); deregistered = true; // The workflow to deregister is not the root DSE workflow. // Remove it from the workflow topology. workflowNode.remove(); // Rebuild the list of naming context handled by the network group rebuildNamingContextList(); } return deregistered; } /** @@ -368,12 +330,12 @@ // reset lists of naming contexts namingContexts.resetLists(); // a registered workflow with no parent is a naming context for (WorkflowTopologyNode workflowNode : registeredWorkflowNodes.values()) { WorkflowTopologyNode parent = workflowNode.getParent(); if (parent == null) { // a registered workflow with no parent is a naming context namingContexts.addNamingContext(workflowNode); } } @@ -394,28 +356,20 @@ */ public void registerWorkflow(WorkflowImpl workflow) throws DirectoryException { // Is it the rootDSE workflow? DN baseDN = workflow.getBaseDN(); if (baseDN.isRootDN()) { // NOTE - The rootDSE workflow is stored with the // registeredWorkflows. rootDSEWorkflowNode = new RootDseWorkflowTopology(workflow, namingContexts); // NOTE - The rootDSE workflow is stored with the registeredWorkflows. rootDSEWorkflowNode = new RootDseWorkflowTopology(workflow, namingContexts); return; } else { // This workflow is not the rootDSE workflow. Try to insert it in // the workflow topology. WorkflowTopologyNode workflowNode = new WorkflowTopologyNode(workflow); // Register the workflow node with the network group. If the // workflow ID is already existing then an exception is raised. // Try to insert it in the workflow topology. WorkflowTopologyNode workflowNode = new WorkflowTopologyNode(workflow); registerWorkflowNode(workflowNode); // Now add the workflow in the workflow topology... for (WorkflowTopologyNode curNode : registeredWorkflowNodes .values()) for (WorkflowTopologyNode curNode : registeredWorkflowNodes.values()) { if ( // Try to insert the new workflow under an existing workflow... @@ -428,16 +382,10 @@ } } // Rebuild the list of naming context handled by the network group rebuildNamingContextList(); // Now that the workflow node has been registered with the network // group, update the reference counter of the workflow, unless // the network group is either default, or administration, or // internal network group. workflow.incrementReferenceCounter(); } } @@ -459,19 +407,13 @@ synchronized (registeredWorkflowNodesLock) { // The workflow must not be already registered if (registeredWorkflowNodes.containsKey(workflowID)) { LocalizableMessage message = ERR_REGISTER_WORKFLOW_NODE_ALREADY_EXISTS.get(workflowID, networkGroupID); throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); LocalizableMessage message = ERR_REGISTER_WORKFLOW_NODE_ALREADY_EXISTS.get(workflowID, networkGroupID); throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); } // The workflow base DN should not be already present in the // network group. Bypass the check for the private workflows... checkWorkflowBaseDN(workflowNode); checkNotRegistered(workflowNode); // All is fine, let's register the workflow TreeMap<String, WorkflowTopologyNode> newRegisteredWorkflowNodes = opendj3-server-dev/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -35,6 +35,7 @@ import org.forgerock.i18n.LocalizableMessageDescriptor; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.ldap.ResultCode; import org.opends.server.api.AccessControlHandler; import org.opends.server.api.Backend; import org.opends.server.controls.LDAPPostReadRequestControl; import org.opends.server.controls.LDAPPostReadResponseControl; @@ -80,10 +81,7 @@ private static TreeMap<String, LocalBackendWorkflowElement> registeredLocalBackends = new TreeMap<String, LocalBackendWorkflowElement>(); /** * A lock to guarantee safe concurrent access to the registeredLocalBackends * variable. */ /** 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. */ @@ -124,7 +122,6 @@ */ public void finalizeWorkflowElement() { // null all fields so that any use of the finalized object will raise a NPE this.workflowElementID = null; this.workflowElementTypeInfo = null; this.backend = null; @@ -144,18 +141,14 @@ public static LocalBackendWorkflowElement createAndRegister( String workflowElementID, Backend<?> backend) { // If the requested workflow element does not exist then create one. LocalBackendWorkflowElement localBackend = registeredLocalBackends.get(workflowElementID); LocalBackendWorkflowElement localBackend = registeredLocalBackends.get(workflowElementID); if (localBackend == null) { localBackend = new LocalBackendWorkflowElement(); localBackend.initialize(workflowElementID, backend); // store the new local backend in the list of registered backends registerLocalBackend(localBackend); } return localBackend; } @@ -181,8 +174,7 @@ { synchronized (registeredLocalBackendsLock) { for (LocalBackendWorkflowElement localBackend: registeredLocalBackends.values()) for (LocalBackendWorkflowElement localBackend : registeredLocalBackends.values()) { deregisterLocalBackend(localBackend.getWorkflowElementID()); } @@ -220,8 +212,7 @@ { final Control control = iter.next(); if (!AccessControlConfigManager.getInstance().getAccessControlHandler() .isAllowed(targetDN, op, control)) if (!getAccessControlHandler().isAllowed(targetDN, op, control)) { // As per RFC 4511 4.1.11. if (control.isCritical()) @@ -278,14 +269,12 @@ Entry entry, DN entryDN, ResultCode resultCode, LocalizableMessage message, ResultCode altResultCode, LocalizableMessage altMessage) throws DirectoryException { if (AccessControlConfigManager.getInstance().getAccessControlHandler() .canDiscloseInformation(entry, entryDN, operation)) if (getAccessControlHandler().canDiscloseInformation(entry, entryDN, operation)) { return new DirectoryException(resultCode, message); } // replacement reason returned to the user final DirectoryException ex = new DirectoryException(altResultCode, altMessage); final DirectoryException ex = new DirectoryException(altResultCode, altMessage); // real underlying reason ex.setMaskedResultCode(resultCode); ex.setMaskedMessage(message); @@ -329,8 +318,7 @@ Entry entry, DN entryDN, ResultCode resultCode, LocalizableMessage message, ResultCode altResultCode, LocalizableMessage altMessage) throws DirectoryException { if (AccessControlConfigManager.getInstance().getAccessControlHandler() .canDiscloseInformation(entry, entryDN, operation)) if (getAccessControlHandler().canDiscloseInformation(entry, entryDN, operation)) { operation.setResultCode(resultCode); operation.appendErrorMessage(message); @@ -362,8 +350,7 @@ try { if (!AccessControlConfigManager.getInstance().getAccessControlHandler() .canDiscloseInformation(null, operation.getMatchedDN(), operation)) if (!getAccessControlHandler().canDiscloseInformation(null, operation.getMatchedDN(), operation)) { operation.setMatchedDN(null); } @@ -404,28 +391,19 @@ */ final Entry fullEntry = entry.duplicate(true); /* * Even though the associated update succeeded, we should still check * whether or not we should return the entry. */ final SearchResultEntry unfilteredSearchEntry = new SearchResultEntry( fullEntry, null); if (AccessControlConfigManager.getInstance().getAccessControlHandler() .maySend(operation, unfilteredSearchEntry)) // Even though the associated update succeeded, // we should still check whether or not we should return the entry. final SearchResultEntry unfilteredSearchEntry = new SearchResultEntry(fullEntry, null); if (getAccessControlHandler().maySend(operation, unfilteredSearchEntry)) { // Filter the entry based on the control's attribute list. final Entry filteredEntry = fullEntry.filterEntry( postReadRequest.getRequestedAttributes(), false, false, false); final SearchResultEntry filteredSearchEntry = new SearchResultEntry( filteredEntry, null); final Entry filteredEntry = fullEntry.filterEntry(postReadRequest.getRequestedAttributes(), false, false, false); final SearchResultEntry filteredSearchEntry = new SearchResultEntry(filteredEntry, null); // Strip out any attributes which access control denies access to. AccessControlConfigManager.getInstance().getAccessControlHandler() .filterEntry(operation, unfilteredSearchEntry, filteredSearchEntry); getAccessControlHandler().filterEntry(operation, unfilteredSearchEntry, filteredSearchEntry); final LDAPPostReadResponseControl responseControl = new LDAPPostReadResponseControl(filteredSearchEntry); operation.addResponseControl(responseControl); operation.addResponseControl(new LDAPPostReadResponseControl(filteredSearchEntry)); } } @@ -449,52 +427,42 @@ return; } /* * Even though the associated update succeeded, we should still check * whether or not we should return the entry. */ final SearchResultEntry unfilteredSearchEntry = new SearchResultEntry( entry, null); if (AccessControlConfigManager.getInstance().getAccessControlHandler() .maySend(operation, unfilteredSearchEntry)) // Even though the associated update succeeded, // we should still check whether or not we should return the entry. final SearchResultEntry unfilteredSearchEntry = new SearchResultEntry(entry, null); if (getAccessControlHandler().maySend(operation, unfilteredSearchEntry)) { // Filter the entry based on the control's attribute list. final Entry filteredEntry = entry.filterEntry( preReadRequest.getRequestedAttributes(), false, false, false); final SearchResultEntry filteredSearchEntry = new SearchResultEntry( filteredEntry, null); final Entry filteredEntry = entry.filterEntry(preReadRequest.getRequestedAttributes(), false, false, false); final SearchResultEntry filteredSearchEntry = new SearchResultEntry(filteredEntry, null); // Strip out any attributes which access control denies access to. AccessControlConfigManager.getInstance().getAccessControlHandler() .filterEntry(operation, unfilteredSearchEntry, filteredSearchEntry); getAccessControlHandler().filterEntry(operation, unfilteredSearchEntry, filteredSearchEntry); final LDAPPreReadResponseControl responseControl = new LDAPPreReadResponseControl(filteredSearchEntry); operation.addResponseControl(responseControl); operation.addResponseControl(new LDAPPreReadResponseControl(filteredSearchEntry)); } } private static AccessControlHandler<?> getAccessControlHandler() { return AccessControlConfigManager.getInstance().getAccessControlHandler(); } /** * Registers a local backend with the server. * * @param localBackend the local backend to register with the server */ private static void registerLocalBackend( LocalBackendWorkflowElement localBackend) private static void registerLocalBackend(LocalBackendWorkflowElement localBackend) { synchronized (registeredLocalBackendsLock) { String localBackendID = localBackend.getWorkflowElementID(); LocalBackendWorkflowElement existingLocalBackend = registeredLocalBackends.get(localBackendID); LocalBackendWorkflowElement existingLocalBackend = registeredLocalBackends.get(localBackendID); if (existingLocalBackend == null) { TreeMap<String, LocalBackendWorkflowElement> newLocalBackends = new TreeMap <String, LocalBackendWorkflowElement>(registeredLocalBackends); new TreeMap<String, LocalBackendWorkflowElement>(registeredLocalBackends); newLocalBackends.put(localBackendID, localBackend); registeredLocalBackends = newLocalBackends; } @@ -512,14 +480,11 @@ { synchronized (registeredLocalBackendsLock) { LocalBackendWorkflowElement existingLocalBackend = registeredLocalBackends.get(workflowElementID); LocalBackendWorkflowElement existingLocalBackend = registeredLocalBackends.get(workflowElementID); if (existingLocalBackend != null) { TreeMap<String, LocalBackendWorkflowElement> newLocalBackends = new TreeMap<String, LocalBackendWorkflowElement>( registeredLocalBackends); new TreeMap<String, LocalBackendWorkflowElement>(registeredLocalBackends); newLocalBackends.remove(workflowElementID); registeredLocalBackends = newLocalBackends; } @@ -538,45 +503,31 @@ switch (operation.getOperationType()) { case BIND: LocalBackendBindOperation bindOperation = new LocalBackendBindOperation((BindOperation) operation); bindOperation.processLocalBind(this); new LocalBackendBindOperation((BindOperation) operation).processLocalBind(this); break; case SEARCH: LocalBackendSearchOperation searchOperation = new LocalBackendSearchOperation((SearchOperation) operation); searchOperation.processLocalSearch(this); new LocalBackendSearchOperation((SearchOperation) operation).processLocalSearch(this); break; case ADD: LocalBackendAddOperation addOperation = new LocalBackendAddOperation((AddOperation) operation); addOperation.processLocalAdd(this); new LocalBackendAddOperation((AddOperation) operation).processLocalAdd(this); break; case DELETE: LocalBackendDeleteOperation deleteOperation = new LocalBackendDeleteOperation((DeleteOperation) operation); deleteOperation.processLocalDelete(this); new LocalBackendDeleteOperation((DeleteOperation) operation).processLocalDelete(this); break; case MODIFY: LocalBackendModifyOperation modifyOperation = new LocalBackendModifyOperation((ModifyOperation) operation); modifyOperation.processLocalModify(this); new LocalBackendModifyOperation((ModifyOperation) operation).processLocalModify(this); break; case MODIFY_DN: LocalBackendModifyDNOperation modifyDNOperation = new LocalBackendModifyDNOperation((ModifyDNOperation) operation); modifyDNOperation.processLocalModifyDN(this); new LocalBackendModifyDNOperation((ModifyDNOperation) operation).processLocalModifyDN(this); break; case COMPARE: LocalBackendCompareOperation compareOperation = new LocalBackendCompareOperation((CompareOperation) operation); compareOperation.processLocalCompare(this); new LocalBackendCompareOperation((CompareOperation) operation).processLocalCompare(this); break; case ABANDON: @@ -606,9 +557,7 @@ @SuppressWarnings("unchecked") static <O extends Operation, L> void attachLocalOperation(O globalOperation, L currentLocalOperation) { List<?> existingAttachment = (List<?>) globalOperation.getAttachment(Operation.LOCALBACKENDOPERATIONS); List<?> existingAttachment = (List<?>) globalOperation.getAttachment(Operation.LOCALBACKENDOPERATIONS); List<L> newAttachment = new ArrayList<L>(); if (existingAttachment != null) @@ -619,8 +568,7 @@ newAttachment.addAll ((List<L>) existingAttachment); } newAttachment.add (currentLocalOperation); globalOperation.setAttachment(Operation.LOCALBACKENDOPERATIONS, newAttachment); globalOperation.setAttachment(Operation.LOCALBACKENDOPERATIONS, newAttachment); } /** @@ -672,32 +620,23 @@ { if (!backend.isPrivateBackend()) { switch (DirectoryServer.getWritabilityMode()) checkIfWritable(DirectoryServer.getWritabilityMode(), op, serverMsg, entryDN); checkIfWritable(backend.getWritabilityMode(), op, backendMsg, entryDN); } } private static void checkIfWritable(WritabilityMode writabilityMode, Operation op, LocalizableMessageDescriptor.Arg1<Object> errorMsg, DN entryDN) throws DirectoryException { switch (writabilityMode) { case DISABLED: throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, serverMsg.get(String.valueOf(entryDN))); throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, errorMsg.get(entryDN)); case INTERNAL_ONLY: if (!(op.isInternalOperation() || op.isSynchronizationOperation())) { throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, serverMsg.get(String.valueOf(entryDN))); } } switch (backend.getWritabilityMode()) { case DISABLED: throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, backendMsg.get(String.valueOf(entryDN))); case INTERNAL_ONLY: if (!(op.isInternalOperation() || op.isSynchronizationOperation())) { throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, backendMsg.get(String.valueOf(entryDN))); } throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, errorMsg.get(entryDN)); } } } opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
@@ -60,15 +60,7 @@ */ @SuppressWarnings("javadoc") public class NetworkGroupTest extends DirectoryServerTestCase { //=========================================================================== // B E F O R E C L A S S //=========================================================================== /** * Sets up the environment for performing the tests in this suite. * * @throws Exception if the environment could not be set up. */ @BeforeClass public void setUp() throws Exception { @@ -77,10 +69,6 @@ TestCaseUtils.startServer(); } //=========================================================================== // D A T A P R O V I D E R //=========================================================================== /** * Provides information to create a network group with one workflow inside. * @@ -162,35 +150,6 @@ }; } /** * Provides information to create 2 network groups with different priorities. */ @DataProvider (name = "DNSet_4") public Object[][] initDNSet_4() throws Exception { String networkGroupID1 = "group1"; String networkGroupID2 = "group2"; DN dn1 = DN.valueOf("o=test1"); DN dn2 = DN.valueOf("o=test2"); return new Object[][] { { networkGroupID1, dn1, 1, networkGroupID2, dn2, 2 }, { networkGroupID1, dn1, 2, networkGroupID2, dn2, 1 } }; } //=========================================================================== // T E S T C A S E S //=========================================================================== /** * Tests the network group registration. * @@ -199,11 +158,7 @@ * in the network group */ @Test (dataProvider = "DNSet_0", groups = "virtual") public void testNetworkGroupRegistration( String networkGroupID, DN workflowBaseDN ) throws Exception public void testNetworkGroupRegistration(String networkGroupID, DN workflowBaseDN) throws Exception { // Create and register the network group with the server. NetworkGroup networkGroup = new NetworkGroup(networkGroupID); @@ -211,8 +166,6 @@ // Create a workflow -- the workflow ID is the string representation // of the workflow base DN. WorkflowImpl workflow = new WorkflowImpl(workflowBaseDN.toString(), workflowBaseDN, null); // Register the workflow with the network group. networkGroup.registerWorkflow(workflow); // Register again the workflow with the network group and catch the @@ -220,7 +173,7 @@ try { networkGroup.registerWorkflow(workflow); fail("DirectoryException sjhould have been thrown"); fail("DirectoryException should have been thrown"); } catch (DirectoryException de) { @@ -229,31 +182,6 @@ } } /** * Check the route process in the default network group. * * @param dnToSearch the DN of a workflow to search in the default * network group * @param dnSubordinate a subordinate DN of dnToSearch * @param exists true if we are supposed to find a workflow for * dnToSearch */ @Test (dataProvider = "DNSet_1", groups = "virtual") public void checkDefaultNetworkGroup( DN dnToSearch, DN dnSubordinate, boolean exists ) { // let's get the default network group -- it should always exist NetworkGroup defaultNG = NetworkGroup.getDefaultNetworkGroup(); assertNotNull(defaultNG); // let's check the routing through the network group doCheckNetworkGroup(defaultNG, dnToSearch, dnSubordinate, null, exists); } /** * This test checks that network groups are updated as appropriate when * backend base DNs are added or removed. When a new backend base DN is @@ -265,8 +193,7 @@ * returned. */ @Test public void testBackendBaseDNModification() throws Exception public void testBackendBaseDNModification() throws Exception { String suffix = "dc=example,dc=com"; String suffix2 = "o=networkgroup suffix"; @@ -276,8 +203,8 @@ TestCaseUtils.clearJEBackend(true, "userRoot", suffix); // Check that suffix is accessible while suffix2 is not. searchEntry(suffix, true); searchEntry(suffix2, false); 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. @@ -286,111 +213,48 @@ addBaseEntry(suffix2, "networkgroup suffix"); // Both old and new suffix should be accessible. searchEntry(suffix, true); searchEntry(suffix2, true); 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, true); searchEntry(suffix2, false); 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, false); searchEntry(suffix2, false); searchEntry(suffix, ResultCode.NO_SUCH_OBJECT); searchEntry(suffix2, ResultCode.NO_SUCH_OBJECT); // Add a base entry for the new suffix addBaseEntry(suffix2, "networkgroup suffix"); // The new suffix is accessible while the old one is not. searchEntry(suffix, false); searchEntry(suffix2, true); searchEntry(suffix, ResultCode.NO_SUCH_OBJECT); searchEntry(suffix2, ResultCode.SUCCESS); // Reset the configuration with previous suffix modifyAttribute(backendConfigDN, ModificationType.REPLACE, backendBaseDNName, suffix); } /** * Tests that routing mode changes cause the network group config * manager to be initialized, shutdown, and reinitialized correctly. * <p> * Disabled because NGs are not supported (issue OPENDJ-335). * * @see <a * href="https://opends.dev.java.net/issues/show_bug.cgi?id=3775">Issue 3775</a> * @throws Exception * If an unexpected error occurred. */ @Test(enabled=false) public void testIssue3775() throws Exception { // Switch to and from manual mode twice in order to ensure that the // config manager is initialized twice. Then register a network // group. If the initialization has worked properly the network // group should be added successfully. In the case of issue 3775, // the config add listeners ended up being added twice so adding a // network group failed because the admin framework thought it had // been added twice. // Switch to manual mode once. TestCaseUtils.dsconfig( "set-global-configuration-prop", "--set", "workflow-configuration-mode:manual"); try { // Switch back. TestCaseUtils.dsconfig( "set-global-configuration-prop", "--set", "workflow-configuration-mode:auto"); // Switch to manual mode twice. TestCaseUtils.dsconfig( "set-global-configuration-prop", "--set", "workflow-configuration-mode:manual"); // Now add network group. final String networkGroupID = "Network group issue 3775"; TestCaseUtils.dsconfig( "create-network-group", "--group-name", networkGroupID, "--set", "enabled:true", "--set", "priority:" + 123); // Remove the network group. TestCaseUtils.dsconfig("delete-network-group", "--group-name", networkGroupID); } finally { TestCaseUtils.dsconfig( "set-global-configuration-prop", "--set", "workflow-configuration-mode:auto"); } } /** * Tests the mechanism to attribute a network group to a client connection, * comparing the priority. * Create 2 network groups with different priorities. */ @Test (dataProvider = "DNSet_4", groups = "virtual") public void testNetworkGroupPriority( String ng1, DN dn1, int prio1, String ng2, DN dn2, int prio2 ) throws Exception @Test(groups = "virtual") public void testNetworkGroupPriority() throws Exception { String ng1 = "group1"; String ng2 = "group2"; DN dn1 = DN.valueOf("o=test1"); DN dn2 = DN.valueOf("o=test2"); // Create and register the network group with the server. NetworkGroup networkGroup1 = new NetworkGroup(ng1); NetworkGroup networkGroup2 = new NetworkGroup(ng2); @@ -410,8 +274,7 @@ * subordinate naming context defined in the RootDSEBackend. */ @Test public void testRootDseSubordinateNamingContext() throws Exception public void testRootDseSubordinateNamingContext() throws Exception { // Backends for the test String backend1 = "o=test-rootDSE-subordinate-naming-context-1"; @@ -419,22 +282,17 @@ String backendID1 = "test-rootDSE-subordinate-naming-context-1"; String backendID2 = "test-rootDSE-subordinate-naming-context-2"; // Clean all the backends. TestCaseUtils.clearDataBackends(); // Create a client connection for the test. InternalClientConnection connection = InternalClientConnection.getRootConnection(); // 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(connection, true, 1); searchPublicNamingContexts(ResultCode.SUCCESS, 1); // Create another test backend and check that the new backend is visible TestCaseUtils.initializeMemoryBackend(backendID2, backend2, true); searchPublicNamingContexts(connection, true, 2); 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 @@ -442,7 +300,7 @@ TestCaseUtils.dsconfig( "set-root-dse-backend-prop", "--set", "subordinate-base-dn:" + backend1); searchPublicNamingContexts(connection, true, 1); searchPublicNamingContexts(ResultCode.SUCCESS, 1); // === Cleaning @@ -451,34 +309,30 @@ TestCaseUtils.dsconfig( "set-root-dse-backend-prop", "--reset", "subordinate-base-dn"); searchPublicNamingContexts(connection, true, 2); searchPublicNamingContexts(ResultCode.SUCCESS, 2); // Clean the test backends. There is no more naming context. TestCaseUtils.clearMemoryBackend(backendID1); TestCaseUtils.clearMemoryBackend(backendID2); searchPublicNamingContexts(connection, false, 0); searchPublicNamingContexts(ResultCode.NO_SUCH_OBJECT, 0); } /** * Searches the list of naming contexts. * * @param connection the connection to use for the search request * @param shouldExist indicates whether at least one NC should be found * @param expectedRC the expected result code * @param expectedNamingContexts the number of expected naming contexts */ private void searchPublicNamingContexts( InternalClientConnection connection, boolean shouldExist, int expectedNamingContexts ) throws Exception private void searchPublicNamingContexts(ResultCode expectedRC, int expectedNamingContexts) throws Exception { InternalClientConnection conn = InternalClientConnection.getRootConnection(); SearchRequest request = newSearchRequest(DN.rootDN(), SearchScope.SINGLE_LEVEL); SearchOperation search = connection.processSearch(request); SearchOperation search = conn.processSearch(request); // Check the number of found naming context assertEquals(search.getResultCode(), shouldExist ? ResultCode.SUCCESS : ResultCode.NO_SUCH_OBJECT); if (shouldExist) assertEquals(search.getResultCode(), expectedRC); if (expectedRC == ResultCode.SUCCESS) { assertEquals(search.getEntriesSent(), expectedNamingContexts); } @@ -489,15 +343,13 @@ * Searches an entry on a given connection. * * @param baseDN the request base DN string * @param shouldExist if true the searched entry is expected to be found * @param expectedRC the expected result code */ private void searchEntry(String baseDN, boolean shouldExist) throws Exception private void searchEntry(String baseDN, ResultCode expectedRC) throws Exception { SearchRequest request = newSearchRequest(DN.valueOf(baseDN), SearchScope.BASE_OBJECT); SearchOperation search = getRootConnection().processSearch(request); // Compare the result code with the expected one assertEquals(search.getResultCode(), shouldExist ? ResultCode.SUCCESS : ResultCode.NO_SUCH_OBJECT); assertEquals(search.getResultCode(), expectedRC); } @@ -532,8 +384,7 @@ ) throws Exception { ArrayList<Modification> mods = new ArrayList<Modification>(); Attribute attributeToModify = Attributes.create(attributeName, attributeValue); 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); @@ -543,7 +394,6 @@ /** * Checks the DN routing through a network group. * * @param networkGroup the network group to use for the check * @param dnToSearch the DN of a workflow in the network group; may * be null * @param dnSubordinate a subordinate of dnToSearch @@ -552,11 +402,10 @@ * @param shouldExist true if we are supposed to find a workflow for * dnToSearch */ private void doCheckNetworkGroup( NetworkGroup networkGroup, @Test (dataProvider = "DNSet_1", groups = "virtual") public void doCheckNetworkGroup( DN dnToSearch, DN dnSubordinate, DN unrelatedDN, boolean shouldExist ) { @@ -566,7 +415,7 @@ } // Let's retrieve the workflow that maps best the dnToSearch Workflow workflow = networkGroup.getWorkflowCandidate(dnToSearch); Workflow workflow = NetworkGroup.getWorkflowCandidate(dnToSearch); if (shouldExist) { assertNotNull(workflow); @@ -580,15 +429,9 @@ // it should be the same than the one for dnToSearch if (dnSubordinate != null) { Workflow workflow2 = networkGroup.getWorkflowCandidate(dnSubordinate); Workflow workflow2 = NetworkGroup.getWorkflowCandidate(dnSubordinate); assertEquals(workflow2, workflow); } // Check that the unrelatedDN is not handled by any workflow if (unrelatedDN != null) { assertNull(networkGroup.getWorkflowCandidate(unrelatedDN)); } } }