/*
* 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.
*/
package org.forgerock.opendj.config.server;
import static org.fest.assertions.Assertions.assertThat;
import static org.forgerock.opendj.ldif.LDIF.makeEntry;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import org.forgerock.opendj.config.AdminTestCase;
import org.forgerock.opendj.config.TestCfg;
import org.forgerock.opendj.config.TestParentCfg;
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.config.server.spi.ConfigurationRepository;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.Entry;
import org.forgerock.opendj.server.config.server.RootCfg;
import org.mockito.ArgumentCaptor;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@SuppressWarnings({ "javadoc", "rawtypes", "unchecked" })
public class ListenerTest extends AdminTestCase {
private static final DN ROOT_CONFIG_DN = DN.valueOf("cn=config");
private static final DN TEST_PARENTS_DN = DN.valueOf("cn=test parents,cn=config");
@BeforeClass
public void setUp() throws Exception {
TestCfg.setUp();
}
@AfterClass
public void tearDown() throws Exception {
TestCfg.cleanup();
}
private Entry getTestParentEntry() throws Exception {
return makeEntry("dn: cn=test parents,cn=config", "objectclass: top", "objectclass: ds-cfg-branch",
"cn: test parents");
}
/**
* Create a mock of ConfigurationRepository with provided DNs registered.
*/
private ConfigurationRepository createConfigRepositoryWithDNs(DN... dns) throws ConfigException {
ConfigurationRepository configRepository = mock(ConfigurationRepository.class);
for (DN dn : dns) {
when(configRepository.hasEntry(dn)).thenReturn(true);
}
return configRepository;
}
/**
* Register a listener for test parent entry and return the actual
* registered listener.
*/
private ConfigAddListener registerAddListenerForTestParent(ConfigurationRepository configRepository,
ServerManagedObject<RootCfg> root, ConfigurationAddListener<TestParentCfg> parentListener) throws Exception {
root.registerAddListener(TestCfg.getTestOneToManyParentRelationDefinition(), parentListener);
ArgumentCaptor<ConfigAddListener> registered = ArgumentCaptor.forClass(ConfigAddListener.class);
verify(configRepository).registerAddListener(eq(TEST_PARENTS_DN), registered.capture());
return registered.getValue();
}
/**
* Register a listener for test parent entry in delayed scenario and return
* the actual registered listener.
*/
private DelayedConfigAddListener registerAddListenerForTestParentDelayed(
ConfigurationRepository configRepository, ServerManagedObject<RootCfg> root,
ConfigurationAddListener<TestParentCfg> parentListener) throws Exception {
root.registerAddListener(TestCfg.getTestOneToManyParentRelationDefinition(), parentListener);
ArgumentCaptor<DelayedConfigAddListener> registered = ArgumentCaptor.forClass(DelayedConfigAddListener.class);
verify(configRepository).registerAddListener(eq(ROOT_CONFIG_DN), registered.capture());
return registered.getValue();
}
@Test
public void testRegisterAddListenerWithInstantiableRelationImmediate() throws Exception {
ConfigurationRepository configRepository = createConfigRepositoryWithDNs(ROOT_CONFIG_DN, TEST_PARENTS_DN);
ServerManagementContext context =
new ServerManagementContext(configRepository);
ServerManagedObject<RootCfg> root = context.getRootConfigurationManagedObject();
root.registerAddListener(TestCfg.getTestOneToManyParentRelationDefinition(),
mock(ConfigurationAddListener.class));
verify(configRepository).registerAddListener(eq(TEST_PARENTS_DN), isA(ConfigAddListener.class));
}
@Test
public void testRegisterAddListenerWithInstantiableRelationDelayed() throws Exception {
ConfigurationRepository configRepository = createConfigRepositoryWithDNs(ROOT_CONFIG_DN);
ServerManagementContext context =
new ServerManagementContext(configRepository);
ServerManagedObject<RootCfg> root = context.getRootConfigurationManagedObject();
ConfigurationAddListener<TestParentCfg> parentListener = mock(ConfigurationAddListener.class);
root.registerAddListener(TestCfg.getTestOneToManyParentRelationDefinition(), parentListener);
ArgumentCaptor<DelayedConfigAddListener> registered = ArgumentCaptor.forClass(DelayedConfigAddListener.class);
verify(configRepository).registerAddListener(eq(ROOT_CONFIG_DN), registered.capture());
// check that actual listener is the one provided to the root
ConfigurationAddListener<?> actualListener =
((ServerManagedObjectAddListenerAdaptor<?>)
((ConfigAddListenerAdaptor<?>) registered.getValue().getDelayedAddListener()).
getServerManagedObjectAddListener()).getConfigurationAddListener();
assertThat(actualListener).isEqualTo(parentListener);
}
@Test
public void testRegisterAddListenerWithInstantiableRelationDelayedThenActualized() throws Exception {
ConfigurationRepository configRepository = createConfigRepositoryWithDNs(ROOT_CONFIG_DN);
ServerManagementContext context =
new ServerManagementContext(configRepository);
ServerManagedObject<RootCfg> root = context.getRootConfigurationManagedObject();
// register a listener to root
ConfigurationAddListener<TestParentCfg> parentListener = mock(ConfigurationAddListener.class);
root.registerAddListener(TestCfg.getTestOneToManyParentRelationDefinition(), parentListener);
// get the delayed listener registered to configuration repository
ArgumentCaptor<DelayedConfigAddListener> registered = ArgumentCaptor.forClass(DelayedConfigAddListener.class);
verify(configRepository).registerAddListener(eq(ROOT_CONFIG_DN), registered.capture());
// now simulate the add of target entry
String parentDN = "cn=test parents,cn=config";
when(configRepository.hasEntry(DN.valueOf(parentDN))).thenReturn(true);
registered.getValue().applyConfigurationAdd(getTestParentEntry());
// check that listener is added for target entry and deleted for its
// parent entry
ConfigAddListenerAdaptor listener =
(ConfigAddListenerAdaptor<?>) registered.getValue().getDelayedAddListener();
verify(configRepository).registerAddListener(DN.valueOf(parentDN), listener);
verify(configRepository).deregisterAddListener(ROOT_CONFIG_DN, registered.getValue());
}
@Test
public void testRegisterAddListenerWithOptionalRelation() throws Exception {
ConfigurationRepository configRepository = createConfigRepositoryWithDNs(ROOT_CONFIG_DN);
ServerManagementContext context =
new ServerManagementContext(configRepository);
ServerManagedObject<RootCfg> root = context.getRootConfigurationManagedObject();
root.registerAddListener(TestCfg.getTestOneToZeroOrOneParentRelationDefinition(),
mock(ConfigurationAddListener.class));
verify(configRepository).registerAddListener(eq(ROOT_CONFIG_DN), isA(ConfigAddListener.class));
}
@Test
public void testRegisterDeleteListenerWithInstantiableRelationImmediate() throws Exception {
ConfigurationRepository configRepository = createConfigRepositoryWithDNs(ROOT_CONFIG_DN, TEST_PARENTS_DN);
ServerManagementContext context =
new ServerManagementContext(configRepository);
ServerManagedObject<RootCfg> root = context.getRootConfigurationManagedObject();
root.registerDeleteListener(TestCfg.getTestOneToManyParentRelationDefinition(),
mock(ConfigurationDeleteListener.class));
verify(configRepository).registerDeleteListener(eq(TEST_PARENTS_DN), isA(ConfigDeleteListener.class));
}
@Test
public void testRegisterDeleteListenerWithInstantiableRelationDelayed() throws Exception {
ConfigurationRepository configRepository = createConfigRepositoryWithDNs(ROOT_CONFIG_DN);
ServerManagementContext context =
new ServerManagementContext(configRepository);
ServerManagedObject<RootCfg> root = context.getRootConfigurationManagedObject();
ConfigurationDeleteListener<TestParentCfg> parentListener = mock(ConfigurationDeleteListener.class);
root.registerDeleteListener(TestCfg.getTestOneToManyParentRelationDefinition(), parentListener);
ArgumentCaptor<DelayedConfigAddListener> argument = ArgumentCaptor.forClass(DelayedConfigAddListener.class);
verify(configRepository).registerAddListener(eq(ROOT_CONFIG_DN), argument.capture());
// check that actual listener is the one provided to the root
ConfigurationDeleteListener actualListener =
((ServerManagedObjectDeleteListenerAdaptor)
((ConfigDeleteListenerAdaptor) argument.getValue().getDelayedDeleteListener()).
getServerManagedObjectDeleteListener()).getConfigurationDeleteListener();
assertThat(actualListener).isEqualTo(parentListener);
}
@Test
public void testRegisterDeleteListenerWithOptionalRelation() throws Exception {
ConfigurationRepository configRepository = createConfigRepositoryWithDNs(ROOT_CONFIG_DN);
ServerManagementContext context =
new ServerManagementContext(configRepository);
ServerManagedObject<RootCfg> root = context.getRootConfigurationManagedObject();
root.registerDeleteListener(TestCfg.getTestOneToZeroOrOneParentRelationDefinition(),
mock(ConfigurationDeleteListener.class));
verify(configRepository).registerDeleteListener(eq(ROOT_CONFIG_DN), isA(ConfigDeleteListener.class));
}
@Test
public void testRegisterChangeListener() throws Exception {
ConfigurationRepository configRepository = createConfigRepositoryWithDNs(ROOT_CONFIG_DN);
ServerManagementContext context =
new ServerManagementContext(configRepository);
ServerManagedObject<RootCfg> root = context.getRootConfigurationManagedObject();
root.setConfigDN(ROOT_CONFIG_DN);
root.registerChangeListener(mock(ConfigurationChangeListener.class));
verify(configRepository).registerChangeListener(eq(ROOT_CONFIG_DN), isA(ConfigChangeListener.class));
}
@Test
public void testDeregisterAddListenerWithInstantiableRelationImmediate() throws Exception {
// arrange
ConfigurationRepository configRepository = createConfigRepositoryWithDNs(ROOT_CONFIG_DN, TEST_PARENTS_DN);
ServerManagementContext context =
new ServerManagementContext(configRepository);
ServerManagedObject<RootCfg> root = context.getRootConfigurationManagedObject();
ConfigurationAddListener<TestParentCfg> parentListener = mock(ConfigurationAddListener.class);
ConfigAddListener registeredListener =
registerAddListenerForTestParent(configRepository, root, parentListener);
when(configRepository.getAddListeners(TEST_PARENTS_DN)).thenReturn(Arrays.asList(registeredListener));
// act
root.deregisterAddListener(TestCfg.getTestOneToManyParentRelationDefinition(), parentListener);
// assert
verify(configRepository).deregisterAddListener(eq(TEST_PARENTS_DN), same(registeredListener));
}
@Test
public void testDeregisterAddListenerWithInstantiableRelationDelayed() throws Exception {
// arrange
ConfigurationRepository configRepository = createConfigRepositoryWithDNs(ROOT_CONFIG_DN);
ServerManagementContext context =
new ServerManagementContext(configRepository);
ServerManagedObject<RootCfg> root = context.getRootConfigurationManagedObject();
ConfigurationAddListener<TestParentCfg> parentListener = mock(ConfigurationAddListener.class);
ConfigAddListener registeredListener =
registerAddListenerForTestParentDelayed(configRepository, root, parentListener);
when(configRepository.getAddListeners(ROOT_CONFIG_DN)).thenReturn(Arrays.asList(registeredListener));
// act
root.deregisterAddListener(TestCfg.getTestOneToManyParentRelationDefinition(), parentListener);
// assert
verify(configRepository).deregisterAddListener(eq(ROOT_CONFIG_DN), same(registeredListener));
}
}