From 8d5e49f4af7da9e6c1311216c6bde13625defab3 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Thu, 12 Dec 2013 11:04:45 +0000
Subject: [PATCH] Checkpoint commit for OPENDJ-1235 : Migrate configuration framework
---
opendj-admin/src/main/java/org/opends/server/core/DirectoryServer.java | 11
opendj-admin/src/test/java/org/forgerock/opendj/config/ConfigurationMock.java | 217 +++++++++++++++++++++++++++++++
opendj-admin/src/test/java/org/forgerock/opendj/config/ConfigTestCase.java | 45 ++++++
opendj-admin/pom.xml | 13 +
opendj-admin/src/test/java/org/forgerock/opendj/config/ConfigurationMockTest.java | 83 +++++++++++
5 files changed, 361 insertions(+), 8 deletions(-)
diff --git a/opendj-admin/pom.xml b/opendj-admin/pom.xml
index a67d3db..ef20cf6 100644
--- a/opendj-admin/pom.xml
+++ b/opendj-admin/pom.xml
@@ -33,6 +33,13 @@
<artifactId>i18n-core</artifactId>
</dependency>
<dependency>
+ <groupId>org.forgerock.opendj</groupId>
+ <artifactId>opendj-core</artifactId>
+ <type>test-jar</type>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.forgerock.commons</groupId>
<artifactId>i18n-slf4j</artifactId>
</dependency>
@@ -145,13 +152,13 @@
</goals>
<configuration>
<outputDirectory>${project.build.directory}/generated-sources/java</outputDirectory>
- <resources>
+ <resources>
<resource>
<directory>src/main/java-templates</directory>
<filtering>true</filtering>
</resource>
- </resources>
- </configuration>
+ </resources>
+ </configuration>
</execution>
</executions>
</plugin>
diff --git a/opendj-admin/src/main/java/org/opends/server/core/DirectoryServer.java b/opendj-admin/src/main/java/org/opends/server/core/DirectoryServer.java
index 0e59e77..a33ca5f 100644
--- a/opendj-admin/src/main/java/org/opends/server/core/DirectoryServer.java
+++ b/opendj-admin/src/main/java/org/opends/server/core/DirectoryServer.java
@@ -28,16 +28,17 @@
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.ObjectClass;
+import org.forgerock.opendj.ldap.schema.Schema;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
/**
- * TODO : this is a stub
+ * TODO : this is a stub, with default or no implementation
*/
public class DirectoryServer {
public static AttributeType getAttributeType(String name, boolean b) {
- throw new RuntimeException("Not implemented");
+ return Schema.getDefaultSchema().getAttributeType(name);
}
public static String getInstanceRoot() {
@@ -48,12 +49,12 @@
throw new RuntimeException("Not implemented");
}
- public static ObjectClass getObjectClass(String lowerCase) {
- throw new RuntimeException("Not implemented");
+ public static ObjectClass getObjectClass(String name) {
+ return Schema.getDefaultSchema().getObjectClass(name);
}
public static ObjectClass getDefaultObjectClass(String name) {
- throw new RuntimeException("Not implemented");
+ return getObjectClass(name);
}
public static ConfigEntry getConfigEntry(DN dn) throws ConfigException {
diff --git a/opendj-admin/src/test/java/org/forgerock/opendj/config/ConfigTestCase.java b/opendj-admin/src/test/java/org/forgerock/opendj/config/ConfigTestCase.java
new file mode 100644
index 0000000..92a32e4
--- /dev/null
+++ b/opendj-admin/src/test/java/org/forgerock/opendj/config/ConfigTestCase.java
@@ -0,0 +1,45 @@
+/*
+ * 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 2013 ForgeRock AS.
+ */
+package org.forgerock.opendj.config;
+
+import org.forgerock.opendj.ldap.SdkTestCase;
+import org.opends.server.admin.ClassPropertyDefinition;
+import org.testng.annotations.Test;
+
+/**
+ * An abstract class that all unit tests should extend.
+ */
+@Test(groups = { "precommit", "config" })
+public abstract class ConfigTestCase extends SdkTestCase {
+
+ protected void disableClassValidationForProperties() {
+ ClassPropertyDefinition.setAllowClassValidation(false);
+ }
+
+ protected void enableClassValidationForProperties() {
+ ClassPropertyDefinition.setAllowClassValidation(true);
+ }
+}
diff --git a/opendj-admin/src/test/java/org/forgerock/opendj/config/ConfigurationMock.java b/opendj-admin/src/test/java/org/forgerock/opendj/config/ConfigurationMock.java
new file mode 100644
index 0000000..1ea2ae0
--- /dev/null
+++ b/opendj-admin/src/test/java/org/forgerock/opendj/config/ConfigurationMock.java
@@ -0,0 +1,217 @@
+/*
+ * 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 2013 ForgeRock AS.
+ */
+package org.forgerock.opendj.config;
+
+import static org.mockito.Mockito.*;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.util.Collection;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider;
+import org.opends.server.admin.AliasDefaultBehaviorProvider;
+import org.opends.server.admin.Configuration;
+import org.opends.server.admin.DefaultBehaviorProvider;
+import org.opends.server.admin.DefaultBehaviorProviderVisitor;
+import org.opends.server.admin.DefinedDefaultBehaviorProvider;
+import org.opends.server.admin.EnumPropertyDefinition;
+import org.opends.server.admin.ManagedObjectDefinition;
+import org.opends.server.admin.PropertyDefinition;
+import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider;
+import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
+
+/**
+ * Provides Mockito mocks for Configuration objects with default values
+ * corresponding to those defined in xml configuration files.
+ * <p>
+ * These mocks can be used like any other mocks, e.g, you can define stubs using
+ * {@code when} method or verify calls using {@code verify} method.
+ * <p>
+ * Example:
+ *
+ * <pre>
+ * {
+ * @code
+ * LDAPConnectionHandlerCfg mockCfg = mockCfg(LDAPConnectionHandlerCfg.class);
+ * assertThat(mockCfg.getMaxRequestSize()).isEqualTo(5 * 1000 * 1000);
+ * }
+ * </pre>
+ */
+public final class ConfigurationMock {
+
+ private static final ConfigAnswer configAnswer = new ConfigAnswer();
+
+ /**
+ * Returns a mock for the provided configuration class.
+ * <p>
+ * If a setting has a default value, the mock automatically returns the
+ * default value when the getter is called on the setting.
+ * <p>
+ * It is possible to override this default behavior with the usual methods
+ * calls with Mockito (e.g, {@code when} method).
+ *
+ * @param <T>
+ * The type of configuration.
+ * @param configClass
+ * The configuration class.
+ * @return a mock
+ */
+ public static <T extends Configuration> T mockCfg(Class<T> configClass) {
+ return mock(configClass, configAnswer);
+ }
+
+ /**
+ * A stubbed answer for Configuration objects, allowing to return default
+ * value for settings when available.
+ */
+ private static class ConfigAnswer implements org.mockito.stubbing.Answer<Object> {
+
+ /** {@inheritDoc} */
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ String definitionClassName = toDefinitionClassName(invocation.getMethod().getDeclaringClass()
+ .getName());
+ Class<?> definitionClass = Class.forName(definitionClassName);
+ ManagedObjectDefinition<?, ?> definition = (ManagedObjectDefinition<?, ?>) definitionClass.getMethod(
+ "getInstance").invoke(null);
+ Method getPropertyDefMethod =
+ definitionClass.getMethod(invocation.getMethod().getName() + "PropertyDefinition");
+ Class<?> propertyReturnType = getPropertyReturnType(getPropertyDefMethod);
+ return getDefaultValue(definition, getPropertyDefMethod, propertyReturnType);
+ }
+
+ /**
+ * Returns the type of values returned by the property.
+ */
+ private Class<?> getPropertyReturnType(Method getPropertyDefMethod) {
+ Class<?> returnClass = getPropertyDefMethod.getReturnType();
+ return ((ParameterizedType) returnClass.getGenericSuperclass())
+ .getActualTypeArguments()[0].getClass();
+ }
+
+ /**
+ * Retrieve class name of definition from class name of configuration.
+ * <p>
+ * Convert class name "[package].admin.server.FooCfg" to
+ * "[package].admin.meta.FooCfgDef"
+ */
+ private String toDefinitionClassName(String configClassName) {
+ return configClassName.replaceAll("\\.admin\\.server", ".admin.meta") + "Defn";
+ }
+
+ /**
+ * Returns the default value corresponding to the provided property
+ * definition getter method from the provided managed object definition.
+ *
+ * @param <T>
+ * The data type of values provided by the property
+ * definition.
+ * @param definition
+ * The definition of the managed object.
+ * @param getPropertyDefMethod
+ * The method to retrieve the property definition from the
+ * definition.
+ * @param propertyReturnClass
+ * The class of values provided by the property definition.
+ * @return the default value of property definition, or
+ * {@code null} if there is no default value.
+ * @throws Exception
+ * If an error occurs.
+ */
+ @SuppressWarnings({ "unchecked", "unused" })
+ private <T> Object getDefaultValue(ManagedObjectDefinition<?, ?> definition,
+ Method getPropertyDefMethod, Class<T> propertyReturnClass) throws Exception {
+ PropertyDefinition<T> propertyDefinition = (PropertyDefinition<T>) getPropertyDefMethod.invoke(definition);
+ DefaultBehaviorProvider<T> defaultBehaviorProvider = (DefaultBehaviorProvider<T>) propertyDefinition
+ .getClass().getMethod("getDefaultBehaviorProvider").invoke(propertyDefinition);
+ MockProviderVisitor<T> visitor = new MockProviderVisitor<T>(propertyDefinition);
+ Collection<T> values = defaultBehaviorProvider.accept(visitor, null);
+
+ if (propertyDefinition instanceof EnumPropertyDefinition) {
+ // enum values returned as a sorted set
+ return values;
+ } else {
+ // single value returned
+ return values.iterator().next();
+ }
+ }
+
+ }
+
+ /** Visitor used to retrieve the default value. */
+ private static class MockProviderVisitor<T> implements DefaultBehaviorProviderVisitor<T, Collection<T>, Void> {
+
+ /** The property definition used to decode the values. */
+ private PropertyDefinition<T> propertyDef;
+
+ MockProviderVisitor(PropertyDefinition<T> propertyDef) {
+ this.propertyDef = propertyDef;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Collection<T> visitAbsoluteInherited(AbsoluteInheritedDefaultBehaviorProvider<T> provider, Void p) {
+ // not handled
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Collection<T> visitAlias(AliasDefaultBehaviorProvider<T> provider, Void p) {
+ // not handled
+ return null;
+ }
+
+ /**
+ * Returns the default value for the property as a collection.
+ */
+ @Override
+ public Collection<T> visitDefined(DefinedDefaultBehaviorProvider<T> provider, Void p) {
+ SortedSet<T> values = new TreeSet<T>();
+ for (String stringValue : provider.getDefaultValues()) {
+ values.add(propertyDef.decodeValue(stringValue));
+ }
+ return values;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Collection<T> visitRelativeInherited(RelativeInheritedDefaultBehaviorProvider<T> d, Void p) {
+ // not handled
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Collection<T> visitUndefined(UndefinedDefaultBehaviorProvider<T> d, Void p) {
+ // not handled
+ return null;
+ }
+ }
+}
diff --git a/opendj-admin/src/test/java/org/forgerock/opendj/config/ConfigurationMockTest.java b/opendj-admin/src/test/java/org/forgerock/opendj/config/ConfigurationMockTest.java
new file mode 100644
index 0000000..6673939
--- /dev/null
+++ b/opendj-admin/src/test/java/org/forgerock/opendj/config/ConfigurationMockTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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 2013 ForgeRock AS.
+ */
+package org.forgerock.opendj.config;
+
+import static org.fest.assertions.Assertions.*;
+import static org.forgerock.opendj.config.ConfigurationMock.*;
+
+import org.forgerock.opendj.admin.meta.PluginCfgDefn.PluginType;
+import org.forgerock.opendj.admin.server.AttributeCleanupPluginCfg;
+import org.forgerock.opendj.admin.server.CollectiveAttributeSubentriesVirtualAttributeCfg;
+import org.forgerock.opendj.admin.server.GoverningStructureRuleVirtualAttributeCfg;
+import org.forgerock.opendj.admin.server.LDAPConnectionHandlerCfg;
+import org.forgerock.opendj.ldap.schema.Schema;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Test case to ensure that ConfigurationMock class is correct.
+ */
+@SuppressWarnings("javadoc")
+public class ConfigurationMockTest extends ConfigTestCase {
+
+ @BeforeClass
+ void setup() {
+ disableClassValidationForProperties();
+ }
+
+ @AfterClass
+ void cleanup() {
+ enableClassValidationForProperties();
+ }
+
+ @Test
+ public void testPropertyWithStringReturnValue() {
+ GoverningStructureRuleVirtualAttributeCfg mock = mockCfg(GoverningStructureRuleVirtualAttributeCfg.class);
+ assertThat(mock.getJavaClass()).
+ isEqualTo("org.opends.server.extensions.GoverningSturctureRuleVirtualAttributeProvider");
+ }
+
+ @Test
+ public void testPropertyWithLongReturnValue() throws Exception {
+ LDAPConnectionHandlerCfg mock = mockCfg(LDAPConnectionHandlerCfg.class);
+ assertThat(mock.getMaxRequestSize()).isEqualTo(5 * 1000 * 1000);
+ }
+
+ @Test
+ public void testPropertyWithEnumReturnValue() throws Exception {
+ AttributeCleanupPluginCfg mock = mockCfg(AttributeCleanupPluginCfg.class);
+ assertThat(mock.getPluginType()).containsOnly(PluginType.PREPARSEADD, PluginType.PREPARSEMODIFY);
+ }
+
+ @Test
+ public void testPropertyWithAttributeTypeReturnValue() throws Exception {
+ CollectiveAttributeSubentriesVirtualAttributeCfg mock =
+ mockCfg(CollectiveAttributeSubentriesVirtualAttributeCfg.class);
+ assertThat(mock.getAttributeType()).isEqualTo(
+ Schema.getDefaultSchema().getAttributeType("collectiveAttributeSubentries"));
+ }
+}
--
Gitblit v1.10.0