/* * 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 2007-2008 Sun Microsystems, Inc. * Portions copyright 2013 ForgeRock AS */ package org.opends.server.admin.server; import java.util.Collection; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import javax.naming.ldap.LdapName; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.opendj.admin.client.ConnectionHandlerCfgClient; import org.forgerock.opendj.admin.client.LDAPConnectionHandlerCfgClient; import org.forgerock.opendj.admin.client.RootCfgClient; import org.forgerock.opendj.admin.meta.LDAPConnectionHandlerCfgDefn; import org.forgerock.opendj.admin.server.ConnectionHandlerCfg; import org.forgerock.opendj.admin.server.RootCfg; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.TestCaseUtils; import org.opends.server.admin.AdminTestCase; import org.opends.server.admin.AdministratorAction; import org.opends.server.admin.AggregationPropertyDefinition; import org.opends.server.admin.IllegalPropertyValueStringException; import org.opends.server.admin.ManagedObjectNotFoundException; import org.opends.server.admin.PropertyException; import org.opends.server.admin.PropertyOption; import org.opends.server.admin.TestCfg; import org.opends.server.admin.TestChildCfg; import org.opends.server.admin.TestChildCfgDefn; import org.opends.server.admin.TestParentCfg; import org.opends.server.admin.UndefinedDefaultBehaviorProvider; import org.opends.server.admin.client.OperationRejectedException; import org.opends.server.admin.condition.Conditions; import org.opends.server.config.ConfigException; import org.opends.server.core.DirectoryServer; import org.opends.server.types.ConfigChangeResult; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; /** * Test cases for aggregations on the server-side. */ @Test(singleThreaded = true) public final class AggregationServerTest extends AdminTestCase { /** * Dummy change listener for triggering change constraint call-backs. */ private static final class DummyChangeListener implements ConfigurationChangeListener { /** * {@inheritDoc} */ @Override public ConfigChangeResult applyConfigurationChange(TestChildCfg configuration) { return new ConfigChangeResult(ResultCode.SUCCESS, false); } /** * {@inheritDoc} */ @Override public boolean isConfigurationChangeAcceptable(TestChildCfg configuration, List unacceptableReasons) { return true; } } /** * Dummy delete listener for triggering delete constraint call-backs. */ private static final class DummyDeleteListener implements ConfigurationDeleteListener { /** * {@inheritDoc} */ @Override public ConfigChangeResult applyConfigurationDelete(TestChildCfg configuration) { return new ConfigChangeResult(ResultCode.SUCCESS, false); } /** * {@inheritDoc} */ @Override public boolean isConfigurationDeleteAcceptable(TestChildCfg configuration, List unacceptableReasons) { return true; } } private static final String TEST_CHILD_7_DN = "cn=test child 7,cn=test children,cn=test parent 1,cn=test parents,cn=config"; private static final String TEST_CHILD_6_DN = "cn=test child 6,cn=test children,cn=test parent 1,cn=test parents,cn=config"; /** The name of the test connection handler. */ private static final String TEST_CONNECTION_HANDLER_NAME = "Test Connection Handler"; /** Test child 1 LDIF. */ private static final String[] TEST_CHILD_1 = new String[] { "dn: cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config", "objectclass: top", "objectclass: ds-cfg-test-child-dummy", "cn: test child 1", "ds-cfg-enabled: true", "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", "ds-cfg-attribute-type: description", "ds-cfg-conflict-behavior: virtual-overrides-real" }; /** Test child 2 LDIF. */ private static final String[] TEST_CHILD_2 = new String[] { "dn: cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config", "objectclass: top", "objectclass: ds-cfg-test-child-dummy", "cn: test child 2", "ds-cfg-enabled: true", "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", "ds-cfg-attribute-type: description", "ds-cfg-conflict-behavior: virtual-overrides-real", "ds-cfg-rotation-policy: cn=LDAP Connection Handler, cn=connection handlers, cn=config" }; /** Test child 3 LDIF (invalid reference). */ private static final String[] TEST_CHILD_3 = new String[] { "dn: cn=test child 3,cn=test children,cn=test parent 1,cn=test parents,cn=config", "objectclass: top", "objectclass: ds-cfg-test-child-dummy", "cn: test child 3", "ds-cfg-enabled: true", "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", "ds-cfg-attribute-type: description", "ds-cfg-conflict-behavior: virtual-overrides-real", "ds-cfg-rotation-policy: cn=LDAP Connection Handler, cn=bad rdn, cn=config" }; /** Test child 4 LDIF. */ private static final String[] TEST_CHILD_4 = new String[] { "dn: cn=test child 4,cn=test children,cn=test parent 1,cn=test parents,cn=config", "objectclass: top", "objectclass: ds-cfg-test-child-dummy", "cn: test child 4", "ds-cfg-enabled: true", "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", "ds-cfg-attribute-type: description", "ds-cfg-conflict-behavior: virtual-overrides-real", "ds-cfg-rotation-policy: cn=LDAP Connection Handler, cn=connection handlers, cn=config", "ds-cfg-rotation-policy: cn=LDAPS Connection Handler, cn=connection handlers, cn=config" }; /** Test child 5 LDIF. */ private static final String[] TEST_CHILD_5 = new String[] { "dn: cn=test child 5,cn=test children,cn=test parent 1,cn=test parents,cn=config", "objectclass: top", "objectclass: ds-cfg-test-child-dummy", "cn: test child 5", "ds-cfg-enabled: true", "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", "ds-cfg-attribute-type: description", "ds-cfg-conflict-behavior: virtual-overrides-real", "ds-cfg-rotation-policy: cn=BAD Connection Handler 1, cn=connection handlers, cn=config", "ds-cfg-rotation-policy: cn=BAD Connection Handler 2, cn=connection handlers, cn=config", "ds-cfg-rotation-policy: cn=LDAP Connection Handler, cn=connection handlers, cn=config" }; /** Test child 6 LDIF. */ private static final String[] TEST_CHILD_6 = new String[] { "dn: cn=test child 6,cn=test children,cn=test parent 1,cn=test parents,cn=config", "objectclass: top", "objectclass: ds-cfg-test-child-dummy", "cn: test child 6", "ds-cfg-enabled: true", "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", "ds-cfg-attribute-type: description", "ds-cfg-conflict-behavior: virtual-overrides-real", "ds-cfg-rotation-policy: cn=" + TEST_CONNECTION_HANDLER_NAME + ", cn=connection handlers, cn=config" }; /** Test child 7 LDIF. */ private static final String[] TEST_CHILD_7 = new String[] { "dn: cn=test child 7,cn=test children,cn=test parent 1,cn=test parents,cn=config", "objectclass: top", "objectclass: ds-cfg-test-child-dummy", "cn: test child 7", "ds-cfg-enabled: false", "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", "ds-cfg-attribute-type: description", "ds-cfg-conflict-behavior: virtual-overrides-real", "ds-cfg-rotation-policy: cn=" + TEST_CONNECTION_HANDLER_NAME + ", cn=connection handlers, cn=config" }; /** Test LDIF. */ private static final String[] TEST_LDIF = new String[] { // Base entries. "dn: cn=test parents,cn=config", "objectclass: top", "objectclass: ds-cfg-branch", "cn: test parents", "", // Parent 1. "dn: cn=test parent 1,cn=test parents,cn=config", "objectclass: top", "objectclass: ds-cfg-test-parent-dummy", "cn: test parent 1", "ds-cfg-enabled: true", "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", "ds-cfg-attribute-type: description", "ds-cfg-conflict-behavior: virtual-overrides-real", "", // Child base entries. "dn:cn=test children,cn=test parent 1,cn=test parents,cn=config", "objectclass: top", "objectclass: ds-cfg-branch", "cn: test children", "" }; /** * The saved test child configuration "aggregation-property" property * definition. */ private AggregationPropertyDefinition aggregationPropertyDefinitionDefault = null; /** * An aggregation where the target must be enabled if the source is enabled. */ private AggregationPropertyDefinition aggregationPropertyDefinitionTargetAndSourceMustBeEnabled = null; /** An aggregation where the target must be enabled. */ private AggregationPropertyDefinition aggregationPropertyDefinitionTargetMustBeEnabled = null; /** * Sets up tests * * @throws Exception * If the server could not be initialized. */ @BeforeClass public void setUp() throws Exception { TestCfg.setUp(); // Add test managed objects. TestCaseUtils.addEntries(TEST_LDIF); // Save the aggregation property definition so that it can be // replaced and restored later. aggregationPropertyDefinitionDefault = TestChildCfgDefn.getInstance() .getAggregationPropertyPropertyDefinition(); // Create the two test aggregation properties. AggregationPropertyDefinition.Builder builder; TestChildCfgDefn d = TestChildCfgDefn.getInstance(); builder = AggregationPropertyDefinition.createBuilder(d, "aggregation-property"); builder.setOption(PropertyOption.MULTI_VALUED); builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, d, "aggregation-property")); builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider()); builder.setParentPath("/"); builder.setRelationDefinition("connection-handler"); builder.setTargetIsEnabledCondition(Conditions.contains("enabled", "true")); aggregationPropertyDefinitionTargetMustBeEnabled = builder.getInstance(); TestCfg.initializePropertyDefinition(aggregationPropertyDefinitionTargetMustBeEnabled); builder = AggregationPropertyDefinition.createBuilder(d, "aggregation-property"); builder.setOption(PropertyOption.MULTI_VALUED); builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, d, "aggregation-property")); builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider()); builder.setParentPath("/"); builder.setRelationDefinition("connection-handler"); builder.setTargetIsEnabledCondition(Conditions.contains("enabled", "true")); builder.setTargetNeedsEnablingCondition(Conditions.contains("mandatory-boolean-property", "true")); aggregationPropertyDefinitionTargetAndSourceMustBeEnabled = builder.getInstance(); TestCfg.initializePropertyDefinition(aggregationPropertyDefinitionTargetAndSourceMustBeEnabled); } /** * Tears down test environment. * * @throws Exception * If the test entries could not be removed. */ @AfterClass public void tearDown() throws Exception { TestCfg.cleanup(); // Restore the test child aggregation definition. TestCfg.addPropertyDefinition(aggregationPropertyDefinitionDefault); // Remove test entries. deleteSubtree("cn=test parents,cn=config"); } /** * Tests that aggregation is rejected when the LDAP DN contains a valid RDN * but an invalid parent DN. * * @throws Exception * If the test unexpectedly fails. */ @Test public void testAggregationBadBaseDN() throws Exception { // Add the entry. TestCaseUtils.addEntry(TEST_CHILD_3); try { TestParentCfg parent = getParent("test parent 1"); parent.getTestChild("test child 3"); Assert.fail("Unexpectedly added test child 3 when it had a bad aggregation value"); } catch (ConfigException e) { // Check that we have a decoding exception as the cause and // there was only one cause the illegal property value. Throwable cause = e.getCause(); if (cause instanceof ServerManagedObjectDecodingException) { ServerManagedObjectDecodingException de = (ServerManagedObjectDecodingException) cause; Collection causes = de.getCauses(); Assert.assertEquals(causes.size(), 1); cause = causes.iterator().next(); if (cause instanceof IllegalPropertyValueStringException) { IllegalPropertyValueStringException pe = (IllegalPropertyValueStringException) cause; Assert.assertEquals(pe.getPropertyDefinition(), TestChildCfgDefn.getInstance() .getAggregationPropertyPropertyDefinition()); Assert.assertEquals(pe.getIllegalValueString(), "cn=LDAP Connection Handler, cn=bad rdn, cn=config"); } else { // Got an unexpected cause. throw e; } } else { // Got an unexpected cause. throw e; } } finally { deleteSubtree("cn=test child 3,cn=test children,cn=test parent 1,cn=test parents,cn=config"); } } /** * Tests that aggregation is rejected by a constraint violation when the DN * values are dangling. * * @throws Exception * If the test unexpectedly fails. */ @Test public void testAggregationDanglingReference() throws Exception { // Add the entry. TestCaseUtils.addEntry(TEST_CHILD_5); try { TestParentCfg parent = getParent("test parent 1"); parent.getTestChild("test child 5"); Assert.fail("Unexpectedly added test child 5 when it had a dangling reference"); } catch (ConfigException e) { // Check that we have a constraint violation as the cause. Throwable cause = e.getCause(); if (cause instanceof ConstraintViolationException) { ConstraintViolationException cve = (ConstraintViolationException) cause; Collection causes = cve.getMessages(); Assert.assertEquals(causes.size(), 2); } else { // Got an unexpected cause. throw e; } } finally { deleteSubtree("cn=test child 5,cn=test children,cn=test parent 1,cn=test parents,cn=config"); } } /** * Tests that aggregation is rejected by a constraint violation when an * enabled component references a disabled component and the referenced * component must always be enabled. * * @throws Exception * If the test unexpectedly fails. */ @Test public void testAggregationDisabledReference1() throws Exception { // Add the entry and the connection handler. TestCaseUtils.addEntry(TEST_CHILD_6); try { createConnectionHandler(false); } catch (Exception e) { deleteSubtree(TEST_CHILD_6_DN); throw e; } // Register the temporary aggregation definition. TestCfg.removeConstraint(aggregationPropertyDefinitionDefault.getSourceConstraint()); TestCfg.addPropertyDefinition(aggregationPropertyDefinitionTargetMustBeEnabled); TestCfg.addConstraint(aggregationPropertyDefinitionTargetMustBeEnabled.getSourceConstraint()); try { TestParentCfg parent = getParent("test parent 1"); parent.getTestChild("test child 6"); Assert.fail("Unexpectedly added test child 6 when it had a disabled reference"); } catch (ConfigException e) { // Check that we have a constraint violation as the cause. Throwable cause = e.getCause(); if (cause instanceof ConstraintViolationException) { ConstraintViolationException cve = (ConstraintViolationException) cause; Collection causes = cve.getMessages(); Assert.assertEquals(causes.size(), 1); } else { // Got an unexpected cause. throw e; } } finally { // Put back the default aggregation definition. TestCfg.removeConstraint(aggregationPropertyDefinitionTargetMustBeEnabled.getSourceConstraint()); TestCfg.addPropertyDefinition(aggregationPropertyDefinitionDefault); TestCfg.addConstraint(aggregationPropertyDefinitionDefault.getSourceConstraint()); try { deleteSubtree(TEST_CHILD_6_DN); } finally { deleteConnectionHandler(); } } } /** * Tests that aggregation is rejected by a constraint violation when a * disabled component references a disabled component and the referenced * component must always be enabled. * * @throws Exception * If the test unexpectedly fails. */ @Test public void testAggregationDisabledReference2() throws Exception { // Add the entry. TestCaseUtils.addEntry(TEST_CHILD_7); try { createConnectionHandler(false); } catch (Exception e) { deleteSubtree(TEST_CHILD_7_DN); throw e; } // Register the temporary aggregation definition. TestCfg.removeConstraint(aggregationPropertyDefinitionDefault.getSourceConstraint()); TestCfg.addPropertyDefinition(aggregationPropertyDefinitionTargetMustBeEnabled); TestCfg.addConstraint(aggregationPropertyDefinitionTargetMustBeEnabled.getSourceConstraint()); try { TestParentCfg parent = getParent("test parent 1"); parent.getTestChild("test child 7"); Assert.fail("Unexpectedly added test child 7 when it had a disabled reference"); } catch (ConfigException e) { // Check that we have a constraint violation as the cause. Throwable cause = e.getCause(); if (cause instanceof ConstraintViolationException) { ConstraintViolationException cve = (ConstraintViolationException) cause; Collection causes = cve.getMessages(); Assert.assertEquals(causes.size(), 1); } else { // Got an unexpected cause. throw e; } } finally { // Put back the default aggregation definition. TestCfg.removeConstraint(aggregationPropertyDefinitionTargetMustBeEnabled.getSourceConstraint()); TestCfg.addPropertyDefinition(aggregationPropertyDefinitionDefault); TestCfg.addConstraint(aggregationPropertyDefinitionDefault.getSourceConstraint()); try { deleteSubtree(TEST_CHILD_7_DN); } finally { deleteConnectionHandler(); } } } /** * Tests that aggregation is rejected by a constraint violation when an * enabled component references a disabled component and the referenced * component must always be enabled when the referencing component is * enabled. * * @throws Exception * If the test unexpectedly fails. */ @Test public void testAggregationDisabledReference3() throws Exception { // Add the entry. TestCaseUtils.addEntry(TEST_CHILD_6); try { createConnectionHandler(false); } catch (Exception e) { deleteSubtree(TEST_CHILD_6_DN); throw e; } // Register the temporary aggregation definition. TestCfg.removeConstraint(aggregationPropertyDefinitionDefault.getSourceConstraint()); TestCfg.addPropertyDefinition(aggregationPropertyDefinitionTargetAndSourceMustBeEnabled); TestCfg.addConstraint(aggregationPropertyDefinitionTargetAndSourceMustBeEnabled.getSourceConstraint()); try { TestParentCfg parent = getParent("test parent 1"); parent.getTestChild("test child 6"); Assert.fail("Unexpectedly added test child 6 when it had a disabled reference"); } catch (ConfigException e) { // Check that we have a constraint violation as the cause. Throwable cause = e.getCause(); if (cause instanceof ConstraintViolationException) { ConstraintViolationException cve = (ConstraintViolationException) cause; Collection causes = cve.getMessages(); Assert.assertEquals(causes.size(), 1); } else { // Got an unexpected cause. throw e; } } finally { // Put back the default aggregation definition. TestCfg.removeConstraint(aggregationPropertyDefinitionTargetAndSourceMustBeEnabled.getSourceConstraint()); TestCfg.addPropertyDefinition(aggregationPropertyDefinitionDefault); TestCfg.addConstraint(aggregationPropertyDefinitionDefault.getSourceConstraint()); try { deleteSubtree(TEST_CHILD_6_DN); } finally { deleteConnectionHandler(); } } } /** * Tests that aggregation is allowed when a disabled component references a * disabled component and the referenced component must always be enabled * when the referencing component is enabled. * * @throws Exception * If the test unexpectedly fails. */ @Test public void testAggregationDisabledReference4() throws Exception { // Add the entry. TestCaseUtils.addEntry(TEST_CHILD_7); try { createConnectionHandler(false); } catch (Exception e) { deleteSubtree(TEST_CHILD_7_DN); throw e; } // Register the temporary aggregation definition. TestCfg.removeConstraint(aggregationPropertyDefinitionDefault.getSourceConstraint()); TestCfg.addPropertyDefinition(aggregationPropertyDefinitionTargetAndSourceMustBeEnabled); TestCfg.addConstraint(aggregationPropertyDefinitionTargetAndSourceMustBeEnabled.getSourceConstraint()); try { TestParentCfg parent = getParent("test parent 1"); parent.getTestChild("test child 7"); } finally { // Put back the default aggregation definition. TestCfg.removeConstraint(aggregationPropertyDefinitionTargetAndSourceMustBeEnabled.getSourceConstraint()); TestCfg.addPropertyDefinition(aggregationPropertyDefinitionDefault); TestCfg.addConstraint(aggregationPropertyDefinitionDefault.getSourceConstraint()); try { deleteSubtree(TEST_CHILD_7_DN); } finally { deleteConnectionHandler(); } } } /** * Tests that aggregation contains no values when it contains does not * contain any DN attribute values. * * @throws Exception * If the test unexpectedly fails. */ @Test public void testAggregationEmpty() throws Exception { // Add the entry. TestCaseUtils.addEntry(TEST_CHILD_1); try { TestParentCfg parent = getParent("test parent 1"); assertChild1(parent.getTestChild("test child 1")); } finally { deleteSubtree("cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config"); } } /** * Tests that aggregation contains multiple valid values when it contains a * multiple valid DN attribute values. * * @throws Exception * If the test unexpectedly fails. */ @Test public void testAggregationMultipleValues() throws Exception { // Add the entry. TestCaseUtils.addEntry(TEST_CHILD_4); try { TestParentCfg parent = getParent("test parent 1"); assertChild4(parent.getTestChild("test child 4")); } finally { deleteSubtree("cn=test child 4,cn=test children,cn=test parent 1,cn=test parents,cn=config"); } } /** * Tests that aggregation contains single valid value when it contains a * single valid DN attribute values. * * @throws Exception * If the test unexpectedly fails. */ @Test public void testAggregationSingle() throws Exception { // Add the entry. TestCaseUtils.addEntry(TEST_CHILD_2); try { TestParentCfg parent = getParent("test parent 1"); assertChild2(parent.getTestChild("test child 2")); } finally { deleteSubtree("cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config"); } } /** * Tests that it is impossible to delete a referenced component when the * referenced component must always exist regardless of whether the * referencing component is enabled or not. * * @throws Exception * If the test unexpectedly fails. */ @Test public void testCannotDeleteReferencedComponent() throws Exception { // Add the entry. TestCaseUtils.addEntry(TEST_CHILD_7); try { createConnectionHandler(true); } catch (Exception e) { deleteSubtree(TEST_CHILD_7_DN); throw e; } // Register the temporary aggregation definition. TestCfg.removeConstraint(aggregationPropertyDefinitionDefault.getSourceConstraint()); TestCfg.addPropertyDefinition(aggregationPropertyDefinitionTargetMustBeEnabled); TestCfg.addConstraint(aggregationPropertyDefinitionTargetMustBeEnabled.getSourceConstraint()); ConfigurationDeleteListener dl = new DummyDeleteListener(); ConfigurationChangeListener cl = new DummyChangeListener(); try { // Retrieve the parent and child managed objects and register // delete and change listeners respectively in order to trigger // the constraint call-backs. TestParentCfg parent = getParent("test parent 1"); parent.addTestChildDeleteListener(dl); TestChildCfg child = parent.getTestChild("test child 7"); child.addChangeListener(cl); // Now attempt to delete the referenced connection handler. // This should fail. try { deleteConnectionHandler(); Assert.fail("Successfully deleted a referenced component"); } catch (OperationRejectedException e) { // This is the expected exception - do nothing. } } finally { try { deleteSubtree(TEST_CHILD_7_DN); } finally { try { deleteConnectionHandler(); } catch (ManagedObjectNotFoundException e) { // Ignore as it may have been deleted already. } finally { // Remove the temporary delete listener. TestParentCfg parent = getParent("test parent 1"); parent.removeTestChildDeleteListener(dl); // Put back the default aggregation definition. TestCfg.removeConstraint(aggregationPropertyDefinitionTargetMustBeEnabled.getSourceConstraint()); TestCfg.addPropertyDefinition(aggregationPropertyDefinitionDefault); TestCfg.addConstraint(aggregationPropertyDefinitionDefault.getSourceConstraint()); } } } } /** * Tests that it is impossible to disable a referenced component when the * referenced component must always be enabled regardless of whether the * referencing component is enabled or not. * * @throws Exception * If the test unexpectedly fails. */ @Test public void testCannotDisableReferencedComponent() throws Exception { // Add the entry. TestCaseUtils.addEntry(TEST_CHILD_7); try { createConnectionHandler(true); } catch (Exception e) { deleteSubtree(TEST_CHILD_7_DN); throw e; } // Register the temporary aggregation definition. TestCfg.removeConstraint(aggregationPropertyDefinitionDefault.getSourceConstraint()); TestCfg.addPropertyDefinition(aggregationPropertyDefinitionTargetMustBeEnabled); TestCfg.addConstraint(aggregationPropertyDefinitionTargetMustBeEnabled.getSourceConstraint()); ConfigurationDeleteListener dl = new DummyDeleteListener(); ConfigurationChangeListener cl = new DummyChangeListener(); try { // Retrieve the parent and child managed objects and register // delete and change listeners respectively in order to trigger // the constraint call-backs. TestParentCfg parent = getParent("test parent 1"); parent.addTestChildDeleteListener(dl); TestChildCfg child = parent.getTestChild("test child 7"); child.addChangeListener(cl); // Now attempt to disable the referenced connection handler. // This should fail. try { RootCfgClient root = TestCaseUtils.getRootConfiguration(); ConnectionHandlerCfgClient client = root.getConnectionHandler(TEST_CONNECTION_HANDLER_NAME); client.setEnabled(false); client.commit(); Assert.fail("Successfully disabled a referenced component"); } catch (OperationRejectedException e) { // This is the expected exception - do nothing. } } finally { try { deleteSubtree(TEST_CHILD_7_DN); } finally { try { deleteConnectionHandler(); } finally { // Remove the temporary delete listener. TestParentCfg parent = getParent("test parent 1"); parent.removeTestChildDeleteListener(dl); // Put back the default aggregation definition. TestCfg.removeConstraint(aggregationPropertyDefinitionTargetMustBeEnabled.getSourceConstraint()); TestCfg.addPropertyDefinition(aggregationPropertyDefinitionDefault); TestCfg.addConstraint(aggregationPropertyDefinitionDefault.getSourceConstraint()); } } } } /** Assert that the values of child 1 are correct. */ private void assertChild1(TestChildCfg child) { Assert.assertEquals(child.getMandatoryClassProperty(), "org.opends.server.extensions.UserDefinedVirtualAttributeProvider"); Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(), DirectoryServer.getAttributeType("description")); assertSetEquals(child.getAggregationProperty(), new String[0]); } /** Assert that the values of child 2 are correct. */ private void assertChild2(TestChildCfg child) { Assert.assertEquals(child.getMandatoryClassProperty(), "org.opends.server.extensions.UserDefinedVirtualAttributeProvider"); Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(), DirectoryServer.getAttributeType("description")); // Test normalization. assertSetEquals(child.getAggregationProperty(), "LDAP Connection Handler"); assertSetEquals(child.getAggregationProperty(), " LDAP Connection Handler "); assertSetEquals(child.getAggregationProperty(), " ldap connection HANDLER "); } /** Assert that the values of child 4 are correct. */ private void assertChild4(TestChildCfg child) { Assert.assertEquals(child.getMandatoryClassProperty(), "org.opends.server.extensions.UserDefinedVirtualAttributeProvider"); Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(), DirectoryServer.getAttributeType("description")); assertSetEquals(child.getAggregationProperty(), "LDAPS Connection Handler", "LDAP Connection Handler"); } /** Asserts that the actual set of DNs contains the expected values. */ private void assertSetEquals(SortedSet actual, String... expected) { SortedSet values = new TreeSet(TestChildCfgDefn.getInstance() .getAggregationPropertyPropertyDefinition()); if (expected != null) { for (String value : expected) { values.add(value); } } Assert.assertEquals((Object) actual, (Object) values); } /** Creates a test connection handler for testing. */ private void createConnectionHandler(boolean enabled) throws Exception { RootCfgClient root = TestCaseUtils.getRootConfiguration(); LDAPConnectionHandlerCfgClient client = root.createConnectionHandler( LDAPConnectionHandlerCfgDefn.getInstance(), TEST_CONNECTION_HANDLER_NAME, null); client.setEnabled(enabled); client.setListenPort(1000); client.commit(); } /** Deletes the test connection handler after testing. */ private void deleteConnectionHandler() throws Exception { RootCfgClient root = TestCaseUtils.getRootConfiguration(); root.removeConnectionHandler(TEST_CONNECTION_HANDLER_NAME); } /** Gets the named parent configuration. */ private TestParentCfg getParent(String name) throws IllegalArgumentException, ConfigException { ServerManagedObject root = serverContext.getRootConfigurationManagedObject(); return root.getChild(TestCfg.getTestOneToManyParentRelationDefinition(), name).getConfiguration(); } }