/* * 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 2014-2015 ForgeRock AS. */ package org.opends.server.core; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import static org.opends.server.ServerContextBuilder.*; import static org.testng.Assert.*; import java.io.File; import java.util.Arrays; import java.util.Set; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.opendj.config.server.ConfigChangeResult; import org.forgerock.opendj.config.server.spi.ConfigAddListener; import org.forgerock.opendj.config.server.spi.ConfigChangeListener; import org.forgerock.opendj.config.server.spi.ConfigDeleteListener; import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.ldap.Entry; import org.forgerock.opendj.ldap.LinkedHashMapEntry; import org.forgerock.opendj.ldap.ResultCode; import org.opends.server.TestCaseUtils; import org.opends.server.config.ConfigConstants; import org.opends.server.types.DirectoryException; import org.opends.server.types.InitializationException; import org.testng.annotations.Test; @SuppressWarnings("javadoc") public class ConfigurationHandlerTestCase extends CoreTestCase { private static final DN DN_CONFIG = DN.valueOf(ConfigConstants.DN_CONFIG_ROOT); private static final DN DN_SCHEMA_PROVIDERS = DN.valueOf("cn=Schema Providers,cn=config"); private static final DN DN_CORE_SCHEMA = DN.valueOf("cn=Core Schema,cn=Schema Providers,cn=config"); /** Returns the configuration handler fully initialized from configuration file. */ private ConfigurationHandler getConfigurationHandler() throws InitializationException { final ServerContext context = aServerContext(). schemaDirectory(new File(TestCaseUtils.getBuildRoot(), "resource/schema")). configFile(TestCaseUtils.getTestResource("config-small.ldif")). build(); final ConfigurationHandler configHandler = new ConfigurationHandler(context); configHandler.initialize(); return configHandler; } @Test public void testInitializeConfiguration() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); assertTrue(configHandler.hasEntry(DN_CONFIG)); } @Test public void testGetEntry() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); Entry entry = configHandler.getEntry(DN_SCHEMA_PROVIDERS); assertTrue(entry.containsAttribute("objectclass", "top", "ds-cfg-branch")); } @Test public void testGetChildren() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); Set<DN> dns = configHandler.getChildren(DN_SCHEMA_PROVIDERS); assertTrue(dns.contains(DN_CORE_SCHEMA)); } @Test public void testNumSubordinates() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); long numSubordinates = configHandler.numSubordinates(DN_SCHEMA_PROVIDERS, false); assertEquals(numSubordinates, 1); numSubordinates = configHandler.numSubordinates(DN_CONFIG, true); assertEquals(numSubordinates, 2); } @Test public void testRegisterChangeListener() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); ConfigChangeListener listener1 = mock(ConfigChangeListener.class); ConfigChangeListener listener2 = mock(ConfigChangeListener.class); configHandler.registerChangeListener(DN_SCHEMA_PROVIDERS, listener1); configHandler.registerChangeListener(DN_SCHEMA_PROVIDERS, listener2); assertEquals(configHandler.getChangeListeners(DN_SCHEMA_PROVIDERS), Arrays.asList(listener1 ,listener2)); } @Test public void testRegisterDeregisterChangeListener() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); ConfigChangeListener listener1 = mock(ConfigChangeListener.class); ConfigChangeListener listener2 = mock(ConfigChangeListener.class); configHandler.registerChangeListener(DN_SCHEMA_PROVIDERS, listener1); configHandler.registerChangeListener(DN_SCHEMA_PROVIDERS, listener2); configHandler.deregisterChangeListener(DN_SCHEMA_PROVIDERS, listener1); assertEquals(configHandler.getChangeListeners(DN_SCHEMA_PROVIDERS), Arrays.asList(listener2)); } @Test public void testRegisterAddListener() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); ConfigAddListener listener1 = mock(ConfigAddListener.class); ConfigAddListener listener2 = mock(ConfigAddListener.class); configHandler.registerAddListener(DN_SCHEMA_PROVIDERS, listener1); configHandler.registerAddListener(DN_SCHEMA_PROVIDERS, listener2); assertEquals(configHandler.getAddListeners(DN_SCHEMA_PROVIDERS), Arrays.asList(listener1 ,listener2)); } @Test public void testRegisterDeleteListener() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); ConfigDeleteListener listener1 = mock(ConfigDeleteListener.class); ConfigDeleteListener listener2 = mock(ConfigDeleteListener.class); configHandler.registerDeleteListener(DN_SCHEMA_PROVIDERS, listener1); configHandler.registerDeleteListener(DN_SCHEMA_PROVIDERS, listener2); assertEquals(configHandler.getDeleteListeners(DN_SCHEMA_PROVIDERS), Arrays.asList(listener1 ,listener2)); } @Test public void testAddEntry() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); String dn = "cn=New schema provider,cn=Schema Providers,cn=config"; configHandler.addEntry(new LinkedHashMapEntry(dn)); assertTrue(configHandler.hasEntry(DN.valueOf(dn))); } @Test(expectedExceptions=DirectoryException.class) public void testAddEntryExistingEntry() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); configHandler.addEntry(new LinkedHashMapEntry(DN_CORE_SCHEMA)); } /** TODO : disabled because fail when converting to server DN. Re-enable once migrated to SDK DN. */ @Test(enabled=false, expectedExceptions=DirectoryException.class) public void testAddEntryParentUnknown() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); configHandler.addEntry(new LinkedHashMapEntry("cn=Core Schema,cn=Schema Providers,cn=Providers,cn=config")); } @Test(expectedExceptions=DirectoryException.class) public void testAddEntryNoParent() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); configHandler.addEntry(new LinkedHashMapEntry(DN.rootDN())); } @Test public void testAddListenerWithAddEntry() throws Exception { String dn = "cn=New schema provider,cn=Schema Providers,cn=config"; ConfigurationHandler configHandler = getConfigurationHandler(); ConfigAddListener listener = mock(ConfigAddListener.class); configHandler.registerAddListener(DN_SCHEMA_PROVIDERS, listener); when(listener.configAddIsAcceptable(any(Entry.class), any(LocalizableMessageBuilder.class))). thenReturn(true); when(listener.applyConfigurationAdd(any(Entry.class))). thenReturn(new ConfigChangeResult()); configHandler.addEntry(new LinkedHashMapEntry(dn)); // ensure apply is called for listener verify(listener).applyConfigurationAdd(configHandler.getEntry(DN.valueOf(dn))); } @Test(expectedExceptions=DirectoryException.class) public void testAddListenerWithAddEntryWhenConfigNotAcceptable() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); ConfigAddListener listener = mock(ConfigAddListener.class); configHandler.registerAddListener(DN_SCHEMA_PROVIDERS, listener); when(listener.configAddIsAcceptable(any(Entry.class), any(LocalizableMessageBuilder.class))). thenReturn(false); configHandler.addEntry(new LinkedHashMapEntry("cn=New schema provider,cn=Schema Providers,cn=config")); } @Test(expectedExceptions=DirectoryException.class) public void testAddListenerWithAddEntryWhenFailureApplyingConfig() throws Exception { final ConfigChangeResult ccr = new ConfigChangeResult(); ccr.setResultCode(ResultCode.OTHER); ConfigurationHandler configHandler = getConfigurationHandler(); ConfigAddListener listener = mock(ConfigAddListener.class); configHandler.registerAddListener(DN_SCHEMA_PROVIDERS, listener); when(listener.configAddIsAcceptable(any(Entry.class), any(LocalizableMessageBuilder.class))). thenReturn(true); when(listener.applyConfigurationAdd(any(Entry.class))). thenReturn(ccr); configHandler.addEntry(new LinkedHashMapEntry("cn=New schema provider,cn=Schema Providers,cn=config")); } @Test public void testDeleteEntry() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); configHandler.deleteEntry(DN_CORE_SCHEMA); assertFalse(configHandler.hasEntry(DN_CORE_SCHEMA)); } /** TODO : disabled because fail when converting to server DN. Re-enable once migrated to SDK DN. */ @Test(enabled=false, expectedExceptions=DirectoryException.class) public void testDeleteEntryUnexistingEntry() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); configHandler.deleteEntry(DN.valueOf("cn=Unexisting provider,cn=Schema Providers,cn=config")); } @Test(enabled=false, expectedExceptions=DirectoryException.class) public void testDeleteEntryWithChildren() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); configHandler.deleteEntry(DN_SCHEMA_PROVIDERS); } /** TODO : disabled because fail when converting to server DN. Re-enable once migrated to SDK DN. */ @Test(enabled=false, expectedExceptions=DirectoryException.class) public void testDeleteEntryUnknownParent() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); configHandler.deleteEntry(DN.valueOf("cn=Core Schema,cn=Schema Providers,cn=Providers,cn=config")); } @Test public void testDeleteListenerWithDeleteEntry() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); ConfigDeleteListener listener = mock(ConfigDeleteListener.class); configHandler.registerDeleteListener(DN_SCHEMA_PROVIDERS, listener); Entry entryToDelete = configHandler.getEntry(DN_CORE_SCHEMA); when(listener.configDeleteIsAcceptable(any(Entry.class), any(LocalizableMessageBuilder.class))). thenReturn(true); when(listener.applyConfigurationDelete(any(Entry.class))). thenReturn(new ConfigChangeResult()); configHandler.deleteEntry(DN_CORE_SCHEMA); // ensure apply is called for listener verify(listener).applyConfigurationDelete(entryToDelete); } @Test(expectedExceptions=DirectoryException.class) public void testDeleteListenerWithDeleteEntryWhenConfigNotAcceptable() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); ConfigDeleteListener listener = mock(ConfigDeleteListener.class); configHandler.registerDeleteListener(DN_SCHEMA_PROVIDERS, listener); when(listener.configDeleteIsAcceptable(any(Entry.class), any(LocalizableMessageBuilder.class))). thenReturn(false); configHandler.deleteEntry(DN_CORE_SCHEMA); } @Test(expectedExceptions=DirectoryException.class) public void testDeleteListenerWithDeleteEntryWhenFailureApplyingConfig() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); final ConfigChangeResult ccr = new ConfigChangeResult(); ccr.setResultCode(ResultCode.OTHER); ConfigDeleteListener listener = mock(ConfigDeleteListener.class); configHandler.registerDeleteListener(DN_SCHEMA_PROVIDERS, listener); when(listener.configDeleteIsAcceptable(any(Entry.class), any(LocalizableMessageBuilder.class))). thenReturn(true); when(listener.applyConfigurationDelete(any(Entry.class))). thenReturn(ccr); configHandler.deleteEntry(DN_CORE_SCHEMA); } @Test public void testReplaceEntry() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); String dn = DN_CORE_SCHEMA.toString(); configHandler.replaceEntry( new LinkedHashMapEntry("dn: " + dn, "objectclass: ds-cfg-schema-provider", "ds-cfg-enabled: true"), new LinkedHashMapEntry("dn: " + dn, "objectclass: ds-cfg-schema-provider", "ds-cfg-enabled: false")); assertTrue(configHandler.hasEntry(DN_CORE_SCHEMA)); assertEquals(configHandler.getEntry(DN_CORE_SCHEMA).getAttribute("ds-cfg-enabled").firstValueAsString(), "false"); } @Test public void testChangeListenerWithReplaceEntry() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); ConfigChangeListener listener = mock(ConfigChangeListener.class); configHandler.registerChangeListener(DN_CORE_SCHEMA, listener); when(listener.configChangeIsAcceptable(any(Entry.class), any(LocalizableMessageBuilder.class))). thenReturn(true); when(listener.applyConfigurationChange(any(Entry.class))). thenReturn(new ConfigChangeResult()); Entry oldEntry = configHandler.getEntry(DN_CORE_SCHEMA); configHandler.replaceEntry(oldEntry, new LinkedHashMapEntry("dn: " + DN_CORE_SCHEMA, "objectclass: ds-cfg-schema-provider", "ds-cfg-enabled: false")); // ensure apply is called for listener verify(listener).applyConfigurationChange(configHandler.getEntry(DN_CORE_SCHEMA)); } @Test(expectedExceptions=DirectoryException.class) public void testChangeListenerWithReplaceEntryWhenConfigNotAcceptable() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); ConfigChangeListener listener = mock(ConfigChangeListener.class); configHandler.registerChangeListener(DN_CORE_SCHEMA, listener); when(listener.configChangeIsAcceptable(any(Entry.class), any(LocalizableMessageBuilder.class))). thenReturn(false); Entry oldEntry = configHandler.getEntry(DN_CORE_SCHEMA); configHandler.replaceEntry(oldEntry, new LinkedHashMapEntry("dn: " + DN_CORE_SCHEMA, "objectclass: ds-cfg-schema-provider", "ds-cfg-enabled: false")); } @Test(expectedExceptions=DirectoryException.class) public void testChangeListenerWithReplaceEntryWhenFailureApplyingConfig() throws Exception { ConfigurationHandler configHandler = getConfigurationHandler(); final ConfigChangeResult ccr = new ConfigChangeResult(); ccr.setResultCode(ResultCode.OTHER); ConfigChangeListener listener = mock(ConfigChangeListener.class); configHandler.registerChangeListener(DN_CORE_SCHEMA, listener); when(listener.configChangeIsAcceptable(any(Entry.class), any(LocalizableMessageBuilder.class))). thenReturn(true); when(listener.applyConfigurationChange(any(Entry.class))). thenReturn(ccr); Entry oldEntry = configHandler.getEntry(DN_CORE_SCHEMA); configHandler.replaceEntry(oldEntry, new LinkedHashMapEntry("dn: " + DN_CORE_SCHEMA, "objectclass: ds-cfg-schema-provider", "ds-cfg-enabled: false")); } }