Partial fix for issue 1449: administration framework aggregation support
This change adds support for "aggregation" properties, which are properties which reference other managed objects (see issue 1449 for more details). Subsequent changes will add server-side and client-side referential integrity support, as well as migrating components over to using them (this will be post MS1.0).
8 files added
23 files modified
| | |
| | | <path refid="quickSetup.classpath" /> |
| | | </classpath> |
| | | </javac> |
| | | |
| | | <copy todir="${unittest.classes.dir}"> |
| | | <fileset dir="${unittest.testng.src.dir}" |
| | | includes="**/*.properties" /> |
| | | </copy> |
| | | |
| | | <!-- Prep the TestNG XML file --> |
| | | |
| | |
| | | type="tns:description-type"> |
| | | <xsd:annotation> |
| | | <xsd:documentation> |
| | | The user friendly plural name of this managed object. This element |
| | | is optional and by default the user friendly plural name is derived |
| | | from the definition's plural-name attribute. |
| | | The user friendly plural name of this managed object. This |
| | | element is optional and by default the user friendly plural |
| | | name is derived from the definition's plural-name attribute. |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | </xsd:element> |
| | |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | </xsd:attribute> |
| | | <xsd:attribute name="aggregation" type="tns:path-type" |
| | | use="optional"> |
| | | <xsd:annotation> |
| | | <xsd:documentation> |
| | | For aggregation relations, the path locating the relation |
| | | beneath which the referenced (aggregated) managed objects can |
| | | be found. If this attribute is not specified, the relation is |
| | | a composition by default. |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | </xsd:attribute> |
| | | <xsd:attribute name="managed-object-name" type="tns:name-type" |
| | | use="optional"> |
| | | <xsd:annotation> |
| | |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | <xsd:choice> |
| | | <xsd:element name="aggregation"> |
| | | <xsd:annotation> |
| | | <xsd:documentation> |
| | | An aggregation property names one or more managed objects |
| | | which are required by the managed object associated with |
| | | this property. An aggregation property definition takes care |
| | | to perform referential integrity checks: referenced managed |
| | | objects cannot be deleted. Nor can an aggregation reference |
| | | non-existent managed objects. Referential integrity checks |
| | | are not performed during value validation. Instead they are |
| | | performed when changes to the managed object are committed. |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | <xsd:complexType> |
| | | <xsd:attribute name="parent-path" type="tns:path-type" |
| | | use="required"> |
| | | <xsd:annotation> |
| | | <xsd:documentation> |
| | | The name of the managed object which is the parent of |
| | | the aggregated managed objects. |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | </xsd:attribute> |
| | | <xsd:attribute name="relation-name" type="tns:name-type" |
| | | use="required"> |
| | | <xsd:annotation> |
| | | <xsd:documentation> |
| | | The relation in the parent managed object which contains |
| | | the aggregated managed objects. |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | </xsd:attribute> |
| | | <xsd:attribute name="managed-object-name" type="tns:name-type" |
| | | use="optional"> |
| | | <xsd:annotation> |
| | | <xsd:documentation> |
| | | The type of managed object referenced by this |
| | | aggregation if different from this relation's name. |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | </xsd:attribute> |
| | | <xsd:attribute name="managed-object-package" |
| | | type="tns:package-type" use="optional"> |
| | | <xsd:annotation> |
| | | <xsd:documentation> |
| | | The package containing the referenced managed object |
| | | definition if it is not the same as this managed |
| | | object's package. |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | </xsd:attribute> |
| | | <xsd:attribute name="source-enabled-property-name" |
| | | type="tns:name-type" use="optional"> |
| | | <xsd:annotation> |
| | | <xsd:documentation> |
| | | The optional boolean "enabled" property in the |
| | | aggregating managed object. When this property is true, |
| | | the "target-enabled-property-name" in the aggregated |
| | | managed objects must also be true. The |
| | | "target-enabled-property-name" attribute must be |
| | | specified when this attribute is defined. |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | </xsd:attribute> |
| | | <xsd:attribute name="target-enabled-property-name" |
| | | type="tns:name-type" use="optional"> |
| | | <xsd:annotation> |
| | | <xsd:documentation> |
| | | The optional boolean "enabled" property in the |
| | | aggregated managed objects. This property must not be |
| | | false while the aggregated managed object is referenced. |
| | | This attribute must be defined when the |
| | | "source-enabled-property-name" attribute is specified. |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | </xsd:attribute> |
| | | </xsd:complexType> |
| | | </xsd:element> |
| | | <xsd:element name="attribute-type"> |
| | | <xsd:annotation> |
| | | <xsd:documentation> |
| | |
| | | |
| | | |
| | | --> |
| | | <xsl:include href="property-types/aggregation.xsl" /> |
| | | <xsl:include href="property-types/attribute-type.xsl" /> |
| | | <xsl:include href="property-types/boolean.xsl" /> |
| | | <xsl:include href="property-types/dn.xsl" /> |
| New file |
| | |
| | | <!-- |
| | | ! 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 |
| | | ! trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | ! or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | ! 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 |
| | | ! trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 |
| | | ! |
| | | ! |
| | | ! Portions Copyright 2007 Sun Microsystems, Inc. |
| | | ! --> |
| | | <xsl:stylesheet version="1.0" xmlns:adm="http://www.opends.org/admin" |
| | | xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
| | | <!-- |
| | | Templates for processing aggregation properties. |
| | | --> |
| | | <xsl:template match="adm:aggregation" mode="java-definition-imports"> |
| | | <xsl:element name="import"> |
| | | <xsl:call-template name="get-definition-package" /> |
| | | <xsl:value-of select="'.client.'" /> |
| | | <xsl:call-template name="get-client-type" /> |
| | | </xsl:element> |
| | | <xsl:element name="import"> |
| | | <xsl:call-template name="get-definition-package" /> |
| | | <xsl:value-of select="'.server.'" /> |
| | | <xsl:call-template name="get-server-type" /> |
| | | </xsl:element> |
| | | <xsl:element name="import"> |
| | | <xsl:call-template name="get-definition-package" /> |
| | | <xsl:value-of select="'.meta.'" /> |
| | | <xsl:call-template name="get-definition-type" /> |
| | | </xsl:element> |
| | | <import>org.opends.server.admin.ManagedObjectPath</import> |
| | | </xsl:template> |
| | | <xsl:template match="adm:aggregation" mode="java-value-type"> |
| | | <xsl:value-of select="'String'" /> |
| | | </xsl:template> |
| | | <xsl:template match="adm:aggregation" mode="java-definition-type"> |
| | | <xsl:value-of select="'AggregationPropertyDefinition'" /> |
| | | </xsl:template> |
| | | <xsl:template match="adm:aggregation" |
| | | mode="java-definition-generic-type"> |
| | | <xsl:call-template name="get-client-type" /> |
| | | <xsl:value-of select="', '" /> |
| | | <xsl:call-template name="get-server-type" /> |
| | | </xsl:template> |
| | | <xsl:template match="adm:aggregation" mode="java-definition-ctor"> |
| | | <xsl:if test="not(@parent-path)"> |
| | | <xsl:message terminate="yes"> |
| | | <xsl:value-of |
| | | select="concat('No parent-path defined for aggregation property ', ../../@name)" /> |
| | | </xsl:message> |
| | | </xsl:if> |
| | | <xsl:if test="not(@relation-name)"> |
| | | <xsl:message terminate="yes"> |
| | | <xsl:value-of |
| | | select="concat('No relation-name defined for aggregation property ', ../../@name)" /> |
| | | </xsl:message> |
| | | </xsl:if> |
| | | <xsl:if |
| | | test="@source-enabled-property-name and not(@target-enabled-property-name)"> |
| | | <xsl:message terminate="yes"> |
| | | <xsl:value-of |
| | | select="concat('source-enabled-property-name defined but target-enabled-property-name undefined in aggregation property ', ../../@name)" /> |
| | | </xsl:message> |
| | | </xsl:if> |
| | | <xsl:value-of |
| | | select="concat(' builder.setParentPath(ManagedObjectPath.valueOf("', |
| | | normalize-space(@parent-path), '"));
')" /> |
| | | <xsl:value-of |
| | | select="concat(' builder.setRelationDefinition("', |
| | | normalize-space(@relation-name), '");
')" /> |
| | | <xsl:value-of select="' builder.setManagedObjectDefinition('" /> |
| | | <xsl:call-template name="get-definition-type" /> |
| | | <xsl:value-of select="'.getInstance());
'" /> |
| | | <xsl:if test="@source-enabled-property-name"> |
| | | <xsl:value-of |
| | | select="concat(' builder.setSourceEnabledPropertyName("', |
| | | normalize-space(@source-enabled-property-name), '");
')" /> |
| | | </xsl:if> |
| | | <xsl:if test="@target-enabled-property-name"> |
| | | <xsl:value-of |
| | | select="concat(' builder.setTargetEnabledPropertyName("', |
| | | normalize-space(@target-enabled-property-name), '");
')" /> |
| | | </xsl:if> |
| | | </xsl:template> |
| | | <!-- |
| | | Gets the Java client configuration interface for the referenced type. |
| | | --> |
| | | <xsl:template name="get-client-type"> |
| | | <xsl:call-template name="get-reference-type" /> |
| | | <xsl:value-of select="'CfgClient'" /> |
| | | </xsl:template> |
| | | <!-- |
| | | Gets the Java server configuration interface for the referenced type. |
| | | --> |
| | | <xsl:template name="get-server-type"> |
| | | <xsl:call-template name="get-reference-type" /> |
| | | <xsl:value-of select="'Cfg'" /> |
| | | </xsl:template> |
| | | <!-- |
| | | Gets the Java definition configuration interface for the referenced type. |
| | | --> |
| | | <xsl:template name="get-definition-type"> |
| | | <xsl:call-template name="get-reference-type" /> |
| | | <xsl:value-of select="'CfgDefn'" /> |
| | | </xsl:template> |
| | | <!-- |
| | | Gets the Java definition configuration package. |
| | | --> |
| | | <xsl:template name="get-definition-package"> |
| | | <xsl:choose> |
| | | <xsl:when test="@managed-object-package"> |
| | | <xsl:value-of select="@managed-object-package" /> |
| | | </xsl:when> |
| | | <xsl:otherwise> |
| | | <xsl:value-of select="$this-package" /> |
| | | </xsl:otherwise> |
| | | </xsl:choose> |
| | | </xsl:template> |
| | | <!-- |
| | | Gets the Java name for the referenced type. |
| | | --> |
| | | <xsl:template name="get-reference-type"> |
| | | <xsl:choose> |
| | | <xsl:when test="@managed-object-name"> |
| | | <xsl:call-template name="name-to-java"> |
| | | <xsl:with-param name="value" select="@managed-object-name" /> |
| | | </xsl:call-template> |
| | | </xsl:when> |
| | | <xsl:otherwise> |
| | | <xsl:call-template name="name-to-java"> |
| | | <xsl:with-param name="value" select="@relation-name" /> |
| | | </xsl:call-template> |
| | | </xsl:otherwise> |
| | | </xsl:choose> |
| | | </xsl:template> |
| | | </xsl:stylesheet> |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * 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 |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.admin; |
| | | |
| | | |
| | | |
| | | import static org.opends.server.util.Validator.*; |
| | | |
| | | import java.util.EnumSet; |
| | | |
| | | import org.opends.server.types.DN; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Aggregation property definition. |
| | | * <p> |
| | | * An aggregation property names one or more managed objects which are |
| | | * required by the managed object associated with this property. An |
| | | * aggregation property definition takes care to perform referential |
| | | * integrity checks: referenced managed objects cannot be deleted. Nor |
| | | * can an aggregation reference non-existent managed objects. |
| | | * Referential integrity checks are <b>not</b> performed during value |
| | | * validation. Instead they are performed when changes to the managed |
| | | * object are committed. |
| | | * <p> |
| | | * An aggregation property definition can optionally identify two |
| | | * properties: |
| | | * <ul> |
| | | * <li>an <code>enabled</code> property in the aggregated managed |
| | | * object - the property must be a {@link BooleanPropertyDefinition} |
| | | * and indicate whether the aggregated managed object is enabled or |
| | | * not. If specified, the administration framework will prevent the |
| | | * aggregated managed object from being disabled while it is |
| | | * referenced |
| | | * <li>an <code>enabled</code> property in this property's managed |
| | | * object - the property must be a {@link BooleanPropertyDefinition} |
| | | * and indicate whether this property's managed object is enabled or |
| | | * not. If specified, and as long as there is an equivalent |
| | | * <code>enabled</code> property defined for the aggregated managed |
| | | * object, the <code>enabled</code> property in the aggregated |
| | | * managed object will only be checked when this property is true. |
| | | * </ul> |
| | | * In other words, these properties can be used to make sure that |
| | | * referenced managed objects are not disabled while they are |
| | | * referenced. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * aggregation property definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * aggregation property definition refers to. |
| | | */ |
| | | public final class AggregationPropertyDefinition |
| | | <C extends ConfigurationClient, S extends Configuration> |
| | | extends PropertyDefinition<String> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing aggregation property |
| | | * definitions. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that |
| | | * this aggregation property definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that |
| | | * this aggregation property definition refers to. |
| | | */ |
| | | public static class Builder |
| | | <C extends ConfigurationClient, S extends Configuration> |
| | | extends AbstractBuilder<String, AggregationPropertyDefinition<C, S>> { |
| | | |
| | | // The name of the managed object which is the parent of the |
| | | // aggregated managed objects. |
| | | private ManagedObjectPath<?, ?> p = null; |
| | | |
| | | // The name of a relation in the parent managed object which |
| | | // contains the aggregated managed objects. |
| | | private String rdName = null; |
| | | |
| | | // The type of referenced managed objects. |
| | | private AbstractManagedObjectDefinition<?, ?> cd = null; |
| | | |
| | | // The optional name of a boolean "enabled" property in this |
| | | // managed object. When this property is true, the enabled |
| | | // property in the aggregated managed object must also be true. |
| | | private String sourceEnabledPropertyName = null; |
| | | |
| | | // The optional name of a boolean "enabled" property in the |
| | | // aggregated managed object. This property must not be false |
| | | // while the aggregated managed object is referenced. |
| | | private String targetEnabledPropertyName = null; |
| | | |
| | | |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, |
| | | String propertyName) { |
| | | super(d, propertyName); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the name of the managed object which is the parent of the |
| | | * aggregated managed objects. |
| | | * <p> |
| | | * This must be defined before the property definition can be |
| | | * built. |
| | | * |
| | | * @param p |
| | | * The name of the managed object which is the parent of |
| | | * the aggregated managed objects. |
| | | */ |
| | | public final void setParentPath(ManagedObjectPath<?, ?> p) { |
| | | this.p = p; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the relation in the parent managed object which contains |
| | | * the aggregated managed objects. |
| | | * <p> |
| | | * This must be defined before the property definition can be |
| | | * built. |
| | | * |
| | | * @param rdName |
| | | * The name of a relation in the parent managed object |
| | | * which contains the aggregated managed objects. |
| | | */ |
| | | public final void setRelationDefinition(String rdName) { |
| | | this.rdName = rdName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the definition of the type of referenced managed objects. |
| | | * <p> |
| | | * This must be defined before the property definition can be |
| | | * built. |
| | | * |
| | | * @param d |
| | | * The definition of the type of referenced managed |
| | | * objects. |
| | | */ |
| | | public final void setManagedObjectDefinition( |
| | | AbstractManagedObjectDefinition<C, S> d) { |
| | | this.cd = d; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the optional boolean "enabled" property in this managed |
| | | * object. When this property is true, the enabled property in the |
| | | * aggregated managed object must also be true. |
| | | * <p> |
| | | * By default no source property is defined. When it is defined, |
| | | * the target property must also be defined. |
| | | * |
| | | * @param sourceEnabledPropertyName |
| | | * The optional boolean "enabled" property in this |
| | | * managed object. |
| | | */ |
| | | public final void setSourceEnabledPropertyName( |
| | | String sourceEnabledPropertyName) { |
| | | this.sourceEnabledPropertyName = sourceEnabledPropertyName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the optional boolean "enabled" property in the aggregated |
| | | * managed object. This property must not be false while the |
| | | * aggregated managed object is referenced. |
| | | * <p> |
| | | * By default no target property is defined. It must be defined, |
| | | * if the source property is defined. |
| | | * |
| | | * @param targetEnabledPropertyName |
| | | * The optional boolean "enabled" property in the |
| | | * aggregated managed object. |
| | | */ |
| | | public final void setTargetEnabledPropertyName( |
| | | String targetEnabledPropertyName) { |
| | | this.targetEnabledPropertyName = targetEnabledPropertyName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | @Override |
| | | protected AggregationPropertyDefinition<C, S> buildInstance( |
| | | AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<String> defaultBehavior) { |
| | | // Make sure that the parent path has been defined. |
| | | if (p == null) { |
| | | throw new IllegalStateException("Parent path undefined"); |
| | | } |
| | | |
| | | // Make sure that the relation definition has been defined. |
| | | if (rdName == null) { |
| | | throw new IllegalStateException("Relation definition undefined"); |
| | | } |
| | | |
| | | // Make sure that the managed object definition has been |
| | | // defined. |
| | | if (cd == null) { |
| | | throw new IllegalStateException("Managed object definition undefined"); |
| | | } |
| | | |
| | | // Make sure that the relation definition is a member of the |
| | | // parent path's definition. |
| | | AbstractManagedObjectDefinition<?, ?> parent = p |
| | | .getManagedObjectDefinition(); |
| | | RelationDefinition<?, ?> rd = parent.getRelationDefinition(rdName); |
| | | |
| | | // Make sure the relation refers to the child type. |
| | | AbstractManagedObjectDefinition<?, ?> dTmp = rd.getChildDefinition(); |
| | | if (dTmp != cd) { |
| | | throw new IllegalStateException("Relation definition \"" + rd.getName() |
| | | + "\" does not refer to definition " + d.getName()); |
| | | } |
| | | |
| | | // Force the relation to the correct type. |
| | | InstantiableRelationDefinition<C, S> relation = |
| | | (InstantiableRelationDefinition<C, S>) rd; |
| | | |
| | | // Make sure that if a source property is specified then a |
| | | // target property is also specified. |
| | | if (sourceEnabledPropertyName != null |
| | | && targetEnabledPropertyName == null) { |
| | | throw new IllegalStateException( |
| | | "Source property defined but target property is undefined"); |
| | | } |
| | | |
| | | return new AggregationPropertyDefinition<C, S>(d, propertyName, options, |
| | | adminAction, defaultBehavior, p, relation, sourceEnabledPropertyName, |
| | | targetEnabledPropertyName); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates an aggregation property definition builder. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that |
| | | * this aggregation property definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that |
| | | * this aggregation property definition refers to. |
| | | * @param d |
| | | * The managed object definition associated with this |
| | | * property definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new aggregation property definition builder. |
| | | */ |
| | | public static <C extends ConfigurationClient, S extends Configuration> |
| | | Builder<C, S> createBuilder( |
| | | AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder<C, S>(d, propertyName); |
| | | } |
| | | |
| | | // The name of the managed object which is the parent of the |
| | | // aggregated managed objects. |
| | | private final ManagedObjectPath<?, ?> parentPath; |
| | | |
| | | // The relation in the parent managed object which contains the |
| | | // aggregated managed objects. |
| | | private final InstantiableRelationDefinition<C, S> relationDefinition; |
| | | |
| | | // The optional name of a boolean "enabled" property in this managed |
| | | // object. When this property is true, the enabled property in the |
| | | // aggregated managed object must also be true. |
| | | private final String sourceEnabledPropertyName; |
| | | |
| | | // The optional name of a boolean "enabled" property in the |
| | | // aggregated managed object. This property must not be false while |
| | | // the aggregated managed object is referenced. |
| | | private final String targetEnabledPropertyName; |
| | | |
| | | |
| | | |
| | | // Private constructor. |
| | | private AggregationPropertyDefinition( |
| | | AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<String> defaultBehavior, |
| | | ManagedObjectPath<?, ?> parentPath, |
| | | InstantiableRelationDefinition<C, S> relationDefinition, |
| | | String sourceEnabledPropertyName, String targetEnabledPropertyName) { |
| | | super(d, String.class, propertyName, options, adminAction, defaultBehavior); |
| | | |
| | | this.parentPath = parentPath; |
| | | this.relationDefinition = relationDefinition; |
| | | this.sourceEnabledPropertyName = sourceEnabledPropertyName; |
| | | this.targetEnabledPropertyName = targetEnabledPropertyName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitAggregation(this, p); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, String value, P p) { |
| | | return v.visitAggregation(this, value, p); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String decodeValue(String value) |
| | | throws IllegalPropertyValueStringException { |
| | | ensureNotNull(value); |
| | | |
| | | try { |
| | | validateValue(value); |
| | | return value; |
| | | } catch (IllegalPropertyValueException e) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Constructs a DN for a referenced managed object having the |
| | | * provided name. This method is implemented by first calling |
| | | * {@link #getChildPath(String)} and then invoking |
| | | * {@link ManagedObjectPath#toDN()} on the returned path. |
| | | * |
| | | * @param name |
| | | * The name of the child managed object. |
| | | * @return Returns a DN for a referenced managed object having the |
| | | * provided name. |
| | | */ |
| | | public final DN getChildDN(String name) { |
| | | return getChildPath(name).toDN(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Constructs a managed object path for a referenced managed object |
| | | * having the provided name. |
| | | * |
| | | * @param name |
| | | * The name of the child managed object. |
| | | * @return Returns a managed object path for a referenced managed |
| | | * object having the provided name. |
| | | */ |
| | | public final ManagedObjectPath<C, S> getChildPath(String name) { |
| | | return parentPath.child(relationDefinition, name); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the name of the managed object which is the parent of the |
| | | * aggregated managed objects. |
| | | * |
| | | * @return Returns the name of the managed object which is the |
| | | * parent of the aggregated managed objects. |
| | | */ |
| | | public final ManagedObjectPath<?, ?> getParentPath() { |
| | | return parentPath; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the relation in the parent managed object which contains the |
| | | * aggregated managed objects. |
| | | * |
| | | * @return Returns the relation in the parent managed object which |
| | | * contains the aggregated managed objects. |
| | | */ |
| | | public final InstantiableRelationDefinition<C, S> getRelationDefinition() { |
| | | return relationDefinition; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the optional boolean "enabled" property in this managed |
| | | * object. When this property is true, the enabled property in the |
| | | * aggregated managed object must also be true. |
| | | * |
| | | * @return Returns the optional boolean "enabled" property in this |
| | | * managed object, or <code>null</code> if none is |
| | | * defined. |
| | | * @throws IllegalArgumentException |
| | | * If the named property does not exist in this property's |
| | | * associated managed object definition. |
| | | * @throws ClassCastException |
| | | * If the named property does exist but is not a |
| | | * {@link BooleanPropertyDefinition}. |
| | | */ |
| | | public final BooleanPropertyDefinition getSourceEnabledPropertyDefinition() |
| | | throws IllegalArgumentException, ClassCastException { |
| | | if (sourceEnabledPropertyName == null) { |
| | | return null; |
| | | } |
| | | |
| | | AbstractManagedObjectDefinition<?, ?> d = getManagedObjectDefinition(); |
| | | |
| | | PropertyDefinition<?> pd; |
| | | pd = d.getPropertyDefinition(sourceEnabledPropertyName); |
| | | |
| | | return (BooleanPropertyDefinition) pd; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the optional boolean "enabled" property in the aggregated |
| | | * managed object. This property must not be false while the |
| | | * aggregated managed object is referenced. |
| | | * |
| | | * @return Returns the optional boolean "enabled" property in the |
| | | * aggregated managed object, or <code>null</code> if none |
| | | * is defined. |
| | | * @throws IllegalArgumentException |
| | | * If the named property does not exist in the aggregated |
| | | * managed object's definition. |
| | | * @throws ClassCastException |
| | | * If the named property does exist but is not a |
| | | * {@link BooleanPropertyDefinition}. |
| | | */ |
| | | public final BooleanPropertyDefinition getTargetEnabledPropertyDefinition() |
| | | throws IllegalArgumentException, ClassCastException { |
| | | if (targetEnabledPropertyName == null) { |
| | | return null; |
| | | } |
| | | |
| | | AbstractManagedObjectDefinition<?, ?> d; |
| | | PropertyDefinition<?> pd; |
| | | |
| | | d = relationDefinition.getChildDefinition(); |
| | | pd = d.getPropertyDefinition(targetEnabledPropertyName); |
| | | |
| | | return (BooleanPropertyDefinition) pd; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String normalizeValue(String value) |
| | | throws IllegalPropertyValueException { |
| | | try { |
| | | Reference<C, S> reference = Reference.parseName(parentPath, |
| | | relationDefinition, value); |
| | | return reference.getNormalizedName(); |
| | | } catch (IllegalArgumentException e) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void toString(StringBuilder builder) { |
| | | super.toString(builder); |
| | | |
| | | builder.append(" parentPath="); |
| | | builder.append(parentPath); |
| | | |
| | | builder.append(" relationDefinition="); |
| | | builder.append(relationDefinition.getName()); |
| | | |
| | | if (sourceEnabledPropertyName != null) { |
| | | builder.append(" sourceEnabledPropertyName="); |
| | | builder.append(sourceEnabledPropertyName); |
| | | } |
| | | |
| | | if (targetEnabledPropertyName != null) { |
| | | builder.append(" targetEnabledPropertyName="); |
| | | builder.append(targetEnabledPropertyName); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(String value) throws IllegalPropertyValueException { |
| | | try { |
| | | Reference.parseName(parentPath, relationDefinition, value); |
| | | } catch (IllegalArgumentException e) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Forcefully removes any resource bundles associated with the |
| | | * provided definition and using the default locale. |
| | | * <p> |
| | | * This method is intended for internal testing only. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | */ |
| | | synchronized void removeResourceBundle( |
| | | AbstractManagedObjectDefinition<?, ?> d) { |
| | | removeResourceBundle(d, Locale.getDefault()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Forcefully removes any resource bundles associated with the |
| | | * provided definition and locale. |
| | | * <p> |
| | | * This method is intended for internal testing only. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param locale |
| | | * The locale. |
| | | */ |
| | | synchronized void removeResourceBundle( |
| | | AbstractManagedObjectDefinition<?, ?> d, Locale locale) { |
| | | // Get the locale resource mapping. |
| | | Map<Locale, ResourceBundle> map = resources.get(d); |
| | | if (map != null) { |
| | | map.remove(locale); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Forcefully adds the provided resource bundle to this I18N |
| | | * resource for the default locale. |
| | | * <p> |
| | | * This method is intended for internal testing only. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param resoureBundle |
| | | * The resource bundle to be used. |
| | | */ |
| | | synchronized void setResourceBundle(AbstractManagedObjectDefinition<?, ?> d, |
| | | ResourceBundle resoureBundle) { |
| | | setResourceBundle(d, Locale.getDefault(), resoureBundle); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Forcefully adds the provided resource bundle to this I18N |
| | | * resource. |
| | | * <p> |
| | | * This method is intended for internal testing only. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param locale |
| | | * The locale. |
| | | * @param resoureBundle |
| | | * The resource bundle to be used. |
| | | */ |
| | | synchronized void setResourceBundle(AbstractManagedObjectDefinition<?, ?> d, |
| | | Locale locale, ResourceBundle resoureBundle) { |
| | | // First get the locale-resource mapping, creating it if |
| | | // necessary. |
| | | Map<Locale, ResourceBundle> map = resources.get(d); |
| | | if (map == null) { |
| | | map = new HashMap<Locale, ResourceBundle>(); |
| | | resources.put(d, map); |
| | | } |
| | | |
| | | // Add the resource bundle. |
| | | map.put(locale, resoureBundle); |
| | | } |
| | | |
| | | |
| | | |
| | | // Retrieve the resource bundle associated with a managed object and |
| | | // locale, lazily loading it if necessary. |
| | | private synchronized ResourceBundle getResourceBundle( |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> |
| | | Message visitAggregation(AggregationPropertyDefinition<C, S> d, Void p) { |
| | | return Message.raw("NAME"); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Message visitAttributeType(AttributeTypePropertyDefinition d, |
| | | Void p) { |
| | | return Message.raw("OID"); |
| | |
| | | |
| | | |
| | | /** |
| | | * Visit an aggregation property definition. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that |
| | | * this aggregation property definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that |
| | | * this aggregation property definition refers to. |
| | | * @param d |
| | | * The aggregation property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> |
| | | R visitAggregation(AggregationPropertyDefinition<C, S> d, P p) { |
| | | return visitUnknown(d, p); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Visit an attribute type property definition. |
| | | * |
| | | * @param d |
| | |
| | | |
| | | |
| | | /** |
| | | * Visit an aggregation property value. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that |
| | | * this aggregation property definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that |
| | | * this aggregation property definition refers to. |
| | | * @param d |
| | | * The aggregation property definition to visit. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> |
| | | R visitAggregation( |
| | | AggregationPropertyDefinition<C, S> d, String v, P p) { |
| | | return visitUnknown(d, v, p); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Visit an attribute type. |
| | | * |
| | | * @param d |
| | |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public <E extends Enum<E>> R visitEnum( |
| | | EnumPropertyDefinition<E> d, E v, P p) { |
| | | public <E extends Enum<E>> |
| | | R visitEnum(EnumPropertyDefinition<E> d, E v, P p) { |
| | | return visitUnknown(d, v, p); |
| | | } |
| | | |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * 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 |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.admin; |
| | | |
| | | |
| | | |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.RDN; |
| | | import org.opends.server.util.StaticUtils; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A reference to another managed object. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * reference refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * reference refers to. |
| | | */ |
| | | public final class Reference<C extends ConfigurationClient, |
| | | S extends Configuration> { |
| | | |
| | | /** |
| | | * Parses a DN string value as a reference using the provided |
| | | * managed object path and relation definition. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that |
| | | * this reference refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that |
| | | * this reference refers to. |
| | | * @param p |
| | | * The path of the referenced managed object's parent. |
| | | * @param rd |
| | | * The instantiable relation in the parent which contains |
| | | * the referenced managed object. |
| | | * @param s |
| | | * The DN string value. |
| | | * @return Returns the new reference based on the provided DN string |
| | | * value. |
| | | * @throws IllegalArgumentException |
| | | * If the DN string value could not be decoded as a DN or |
| | | * if the provided DN did not correspond to the provided |
| | | * path and relation. |
| | | */ |
| | | public static <C extends ConfigurationClient, S extends Configuration> |
| | | Reference<C, S> parseDN( |
| | | ManagedObjectPath<?, ?> p, InstantiableRelationDefinition<C, S> rd, |
| | | String s) throws IllegalArgumentException { |
| | | AbstractManagedObjectDefinition<?, ?> d = p.getManagedObjectDefinition(); |
| | | RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName()); |
| | | if (tmp != rd) { |
| | | throw new IllegalArgumentException("The relation \"" + rd.getName() |
| | | + "\" is not associated with the definition \"" + d.getName() + "\""); |
| | | } |
| | | |
| | | DN dn; |
| | | try { |
| | | dn = DN.decode(s); |
| | | } catch (DirectoryException e) { |
| | | throw new IllegalArgumentException("Unabled to decode the DN string: \"" |
| | | + s + "\""); |
| | | } |
| | | |
| | | RDN rdn = dn.getRDN(); |
| | | if (rdn == null) { |
| | | throw new IllegalArgumentException("Unabled to decode the DN string: \"" |
| | | + s + "\""); |
| | | } |
| | | |
| | | AttributeValue av = rdn.getAttributeValue(0); |
| | | if (av == null) { |
| | | throw new IllegalArgumentException("Unabled to decode the DN string: \"" |
| | | + s + "\""); |
| | | } |
| | | |
| | | String name = av.getStringValue(); |
| | | |
| | | // Check that the DN was valid. |
| | | DN expected = p.child(rd, name).toDN(); |
| | | if (!dn.equals(expected)) { |
| | | throw new IllegalArgumentException("Unabled to decode the DN string: \"" |
| | | + s + "\""); |
| | | } |
| | | |
| | | return new Reference<C, S>(p, rd, name); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses a name as a reference using the provided managed object |
| | | * path and relation definition. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that |
| | | * this reference refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that |
| | | * this reference refers to. |
| | | * @param p |
| | | * The path of the referenced managed object's parent. |
| | | * @param rd |
| | | * The instantiable relation in the parent which contains |
| | | * the referenced managed object. |
| | | * @param s |
| | | * The name of the referenced managed object. |
| | | * @return Returns the new reference based on the provided name. |
| | | * @throws IllegalArgumentException |
| | | * If the relation is not associated with the provided |
| | | * parent's definition, or if the provided name is empty. |
| | | */ |
| | | public static <C extends ConfigurationClient, S extends Configuration> |
| | | Reference<C, S> parseName( |
| | | ManagedObjectPath<?, ?> p, InstantiableRelationDefinition<C, S> rd, |
| | | String s) throws IllegalArgumentException { |
| | | // Sanity checks. |
| | | AbstractManagedObjectDefinition<?, ?> d = p.getManagedObjectDefinition(); |
| | | RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName()); |
| | | if (tmp != rd) { |
| | | throw new IllegalArgumentException("The relation \"" + rd.getName() |
| | | + "\" is not associated with the definition \"" + d.getName() + "\""); |
| | | } |
| | | |
| | | if (s.trim().length() == 0) { |
| | | throw new IllegalArgumentException("Empty names are not allowed"); |
| | | } |
| | | |
| | | return new Reference<C, S>(p, rd, s); |
| | | } |
| | | |
| | | // The name of the referenced managed object. |
| | | private final String name; |
| | | |
| | | // The path of the referenced managed object. |
| | | private final ManagedObjectPath<C, S> path; |
| | | |
| | | // The instantiable relation in the parent which contains the |
| | | // referenced managed object. |
| | | private final InstantiableRelationDefinition<C, S> relation; |
| | | |
| | | |
| | | |
| | | // Private constructor. |
| | | private Reference(ManagedObjectPath<?, ?> parent, |
| | | InstantiableRelationDefinition<C, S> relation, String name) |
| | | throws IllegalArgumentException { |
| | | this.relation = relation; |
| | | this.name = name; |
| | | this.path = parent.child(relation, name); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the name of the referenced managed object. |
| | | * |
| | | * @return Returns the name of the referenced managed object. |
| | | */ |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the normalized name of the referenced managed object. |
| | | * |
| | | * @return Returns the normalized name of the referenced managed |
| | | * object. |
| | | */ |
| | | public String getNormalizedName() { |
| | | PropertyDefinition<?> pd = relation.getNamingPropertyDefinition(); |
| | | return normalizeName(pd); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the DN of the referenced managed object. |
| | | * |
| | | * @return Returns the DN of the referenced managed object. |
| | | */ |
| | | public DN toDN() { |
| | | return path.toDN(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String toString() { |
| | | return name; |
| | | } |
| | | |
| | | |
| | | |
| | | // Normalize a value using the specified naming property definition |
| | | // if defined. |
| | | private <T> String normalizeName(PropertyDefinition<T> pd) { |
| | | if (pd != null) { |
| | | try { |
| | | T tvalue = pd.decodeValue(name); |
| | | return pd.normalizeValue(tvalue); |
| | | } catch (IllegalPropertyValueStringException e) { |
| | | // Fall through to default normalization. |
| | | } |
| | | } |
| | | |
| | | // FIXME: should really use directory string normalizer. |
| | | String s = name.trim().replaceAll(" +", " "); |
| | | return StaticUtils.toLowerCase(s); |
| | | } |
| | | } |
| | |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.AbstractManagedObjectDefinition; |
| | | import org.opends.server.admin.AggregationPropertyDefinition; |
| | | import org.opends.server.admin.Configuration; |
| | | import org.opends.server.admin.ConfigurationClient; |
| | | import org.opends.server.admin.DefaultBehaviorException; |
| | |
| | | import org.opends.server.admin.ManagedObjectNotFoundException; |
| | | import org.opends.server.admin.ManagedObjectPath; |
| | | import org.opends.server.admin.PropertyDefinition; |
| | | import org.opends.server.admin.PropertyDefinitionVisitor; |
| | | import org.opends.server.admin.PropertyException; |
| | | import org.opends.server.admin.PropertyIsMandatoryException; |
| | | import org.opends.server.admin.PropertyIsSingleValuedException; |
| | | import org.opends.server.admin.PropertyOption; |
| | | import org.opends.server.admin.Reference; |
| | | import org.opends.server.admin.RelationDefinition; |
| | | import org.opends.server.admin.UnknownPropertyDefinitionException; |
| | | import org.opends.server.admin.DefinitionDecodingException.Reason; |
| | | import org.opends.server.admin.client.AuthorizationException; |
| | | import org.opends.server.admin.client.CommunicationException; |
| | |
| | | */ |
| | | final class LDAPDriver extends Driver { |
| | | |
| | | /** |
| | | * A visitor which is used to decode property LDAP values. |
| | | */ |
| | | private static final class ValueDecoder extends |
| | | PropertyDefinitionVisitor<Object, String> { |
| | | |
| | | /** |
| | | * Decodes the provided property LDAP value. |
| | | * |
| | | * @param <PD> |
| | | * The type of the property. |
| | | * @param pd |
| | | * The property definition. |
| | | * @param value |
| | | * The LDAP string representation. |
| | | * @return Returns the decoded LDAP value. |
| | | * @throws IllegalPropertyValueStringException |
| | | * If the property value could not be decoded because it |
| | | * was invalid. |
| | | */ |
| | | public static <PD> PD decode(PropertyDefinition<PD> pd, Object value) |
| | | throws IllegalPropertyValueStringException { |
| | | String s = String.valueOf(value); |
| | | return pd.castValue(pd.accept(new ValueDecoder(), s)); |
| | | } |
| | | |
| | | |
| | | |
| | | // Prevent instantiation. |
| | | private ValueDecoder() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> |
| | | Object visitAggregation(AggregationPropertyDefinition<C, S> d, String p) { |
| | | // Aggregations values are stored as full DNs in LDAP, but |
| | | // just their common name is exposed in the admin framework. |
| | | try { |
| | | Reference<C, S> reference = Reference.parseDN(d.getParentPath(), d |
| | | .getRelationDefinition(), p); |
| | | return reference.getName(); |
| | | } catch (IllegalArgumentException e) { |
| | | throw new IllegalPropertyValueStringException(d, p); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <T> Object visitUnknown(PropertyDefinition<T> d, String p) |
| | | throws UnknownPropertyDefinitionException { |
| | | // By default the property definition's decoder will do. |
| | | return d.decodeValue(p); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // The LDAP connection. |
| | | private final LDAPConnection connection; |
| | | |
| | |
| | | for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) { |
| | | String attrID = profile.getAttributeName(mod, pd); |
| | | Attribute attribute = attributes.get(attrID); |
| | | List<String> values = new LinkedList<String>(); |
| | | |
| | | if (attribute != null && attribute.size() != 0) { |
| | | NamingEnumeration<?> ldapValues = attribute.getAll(); |
| | | while (ldapValues.hasMore()) { |
| | | Object obj = ldapValues.next(); |
| | | if (obj != null) { |
| | | values.add(obj.toString()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | try { |
| | | decodeProperty(newProperties, path, pd, values); |
| | | decodeProperty(newProperties, path, pd, attribute); |
| | | } catch (PropertyException e) { |
| | | exceptions.add(e); |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | @Override |
| | | public <PD> SortedSet<PD> getPropertyValues(ManagedObjectPath<?, ?> path, |
| | | public <C extends ConfigurationClient, S extends Configuration, PD> |
| | | SortedSet<PD> getPropertyValues(ManagedObjectPath<C, S> path, |
| | | PropertyDefinition<PD> pd) throws IllegalArgumentException, |
| | | DefinitionDecodingException, AuthorizationException, |
| | | ManagedObjectNotFoundException, CommunicationException, |
| | | PropertyException { |
| | | // Check that the requested property is from the definition |
| | | // associated with the path. |
| | | AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition(); |
| | | PropertyDefinition<?> tmp = d.getPropertyDefinition(pd.getName()); |
| | | if (tmp != pd) { |
| | | throw new IllegalArgumentException("The property " + pd.getName() |
| | | + " is not associated with a " + d.getName()); |
| | | } |
| | | |
| | | if (!managedObjectExists(path)) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | |
| | | try { |
| | | // Read the entry associated with the managed object. |
| | | LdapName dn = LDAPNameBuilder.create(path, profile); |
| | | AbstractManagedObjectDefinition<?, ?> d = path |
| | | .getManagedObjectDefinition(); |
| | | ManagedObjectDefinition<?, ?> mod = getEntryDefinition(d, dn); |
| | | ManagedObjectDefinition<? extends C, ? extends S> mod; |
| | | mod = getEntryDefinition(d, dn); |
| | | |
| | | // Make sure we use the correct property definition, the |
| | | // provided one might have been overridden in the resolved |
| | | // definition. |
| | | pd = (PropertyDefinition<PD>) mod.getPropertyDefinition(pd.getName()); |
| | | |
| | | String attrID = profile.getAttributeName(mod, pd); |
| | | Attributes attributes = connection.readEntry(dn, Collections |
| | | .singleton(attrID)); |
| | | Attribute attribute = attributes.get(attrID); |
| | | |
| | | // Decode the values. |
| | | SortedSet<PD> values = new TreeSet<PD>(pd); |
| | | if (attribute == null || attribute.size() == 0) { |
| | | // Use the property's default values. |
| | | values.addAll(findDefaultValues(path, pd, false)); |
| | | } else { |
| | | // Decode the values. |
| | | if (attribute != null) { |
| | | NamingEnumeration<?> ldapValues = attribute.getAll(); |
| | | while (ldapValues.hasMore()) { |
| | | Object obj = ldapValues.next(); |
| | | if (obj != null) { |
| | | PD value = pd.decodeValue(obj.toString()); |
| | | PD value = ValueDecoder.decode(pd, obj); |
| | | values.add(value); |
| | | } |
| | | } |
| | |
| | | throw new PropertyIsMandatoryException(pd); |
| | | } |
| | | |
| | | if (values.isEmpty()) { |
| | | // Use the property's default values. |
| | | values.addAll(findDefaultValues(path.asSubType(mod), pd, false)); |
| | | } |
| | | |
| | | return values; |
| | | } catch (NameNotFoundException e) { |
| | | throw new ManagedObjectNotFoundException(); |
| | |
| | | |
| | | // Create a property using the provided string values. |
| | | private <PD> void decodeProperty(PropertySet newProperties, |
| | | ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd, List<String> values) |
| | | throws PropertyException { |
| | | ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd, |
| | | Attribute attribute) throws PropertyException, |
| | | NamingException { |
| | | PropertyException exception = null; |
| | | |
| | | // Get the property's active values. |
| | | Collection<PD> activeValues = new ArrayList<PD>(values.size()); |
| | | for (String value : values) { |
| | | try { |
| | | activeValues.add(pd.decodeValue(value)); |
| | | } catch (IllegalPropertyValueStringException e) { |
| | | exception = e; |
| | | SortedSet<PD> activeValues = new TreeSet<PD>(pd); |
| | | if (attribute != null) { |
| | | NamingEnumeration<?> ldapValues = attribute.getAll(); |
| | | while (ldapValues.hasMore()) { |
| | | Object obj = ldapValues.next(); |
| | | if (obj != null) { |
| | | PD value = ValueDecoder.decode(pd, obj); |
| | | activeValues.add(value); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (activeValues.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) { |
| | | // This exception takes precedence over previous exceptions. |
| | | exception = new PropertyIsSingleValuedException(pd); |
| | | PD value = activeValues.iterator().next(); |
| | | PD value = activeValues.first(); |
| | | activeValues.clear(); |
| | | activeValues.add(value); |
| | | } |
| | |
| | | import javax.naming.ldap.Rdn; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.AggregationPropertyDefinition; |
| | | import org.opends.server.admin.Configuration; |
| | | import org.opends.server.admin.ConfigurationClient; |
| | | import org.opends.server.admin.InstantiableRelationDefinition; |
| | |
| | | import org.opends.server.admin.ManagedObjectPath; |
| | | import org.opends.server.admin.PropertyDefinition; |
| | | import org.opends.server.admin.PropertyOption; |
| | | import org.opends.server.admin.PropertyValueVisitor; |
| | | import org.opends.server.admin.Reference; |
| | | import org.opends.server.admin.RelationDefinition; |
| | | import org.opends.server.admin.UnknownPropertyDefinitionException; |
| | | import org.opends.server.admin.client.AuthorizationException; |
| | | import org.opends.server.admin.client.CommunicationException; |
| | | import org.opends.server.admin.client.ConcurrentModificationException; |
| | |
| | | final class LDAPManagedObject<T extends ConfigurationClient> extends |
| | | AbstractManagedObject<T> { |
| | | |
| | | /** |
| | | * A visitor which is used to encode property LDAP values. |
| | | */ |
| | | private static final class ValueEncoder extends |
| | | PropertyValueVisitor<Object, Void> { |
| | | |
| | | // Prevent instantiation. |
| | | private ValueEncoder() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> |
| | | Object visitAggregation( |
| | | AggregationPropertyDefinition<C, S> d, String v, Void p) { |
| | | // Aggregations values are stored as full DNs in LDAP, but |
| | | // just their common name is exposed in the admin framework. |
| | | Reference<C, S> reference = Reference.parseName(d.getParentPath(), d |
| | | .getRelationDefinition(), v); |
| | | return reference.toDN().toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <PD> Object visitUnknown(PropertyDefinition<PD> d, PD v, Void p) |
| | | throws UnknownPropertyDefinitionException { |
| | | return d.encodeValue(v); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // The LDAP management driver associated with this managed object. |
| | | private final LDAPDriver driver; |
| | | |
| | |
| | | // Encode a property into LDAP string values. |
| | | private <PD> void encodeProperty(Attribute attribute, |
| | | PropertyDefinition<PD> pd) { |
| | | PropertyValueVisitor<Object, Void> visitor = new ValueEncoder(); |
| | | Property<PD> p = getProperty(pd); |
| | | if (pd.hasOption(PropertyOption.MANDATORY)) { |
| | | // For mandatory properties we fall-back to the default values |
| | | // if defined which can sometimes be the case e.g when a |
| | | // mandatory property is overridden. |
| | | for (PD value : p.getEffectiveValues()) { |
| | | attribute.add(pd.encodeValue(value)); |
| | | attribute.add(pd.accept(visitor, value, null)); |
| | | } |
| | | } else { |
| | | for (PD value : p.getPendingValues()) { |
| | | attribute.add(pd.encodeValue(value)); |
| | | attribute.add(pd.accept(visitor, value, null)); |
| | | } |
| | | } |
| | | } |
| | |
| | | * Gets the effective value of a property in the named managed |
| | | * object. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that the |
| | | * path definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that the |
| | | * path definition refers to. |
| | | * @param <PD> |
| | | * The type of the property to be retrieved. |
| | | * @param path |
| | |
| | | * If the client cannot contact the server due to an |
| | | * underlying communication problem. |
| | | */ |
| | | public final <PD> PD getPropertyValue(ManagedObjectPath<?, ?> path, |
| | | public final <C extends ConfigurationClient, S extends Configuration, PD> |
| | | PD getPropertyValue(ManagedObjectPath<C, S> path, |
| | | PropertyDefinition<PD> pd) throws IllegalArgumentException, |
| | | DefinitionDecodingException, AuthorizationException, |
| | | ManagedObjectNotFoundException, CommunicationException, |
| | |
| | | * managed object contains a property which inherits default values |
| | | * from another property in the same managed object. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that the |
| | | * path definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that the |
| | | * path definition refers to. |
| | | * @param <PD> |
| | | * The type of the property to be retrieved. |
| | | * @param path |
| | |
| | | * If the client cannot contact the server due to an |
| | | * underlying communication problem. |
| | | */ |
| | | public abstract <PD> SortedSet<PD> getPropertyValues( |
| | | ManagedObjectPath<?, ?> path, PropertyDefinition<PD> pd) |
| | | public abstract <C extends ConfigurationClient, S extends Configuration, PD> |
| | | SortedSet<PD> getPropertyValues( |
| | | ManagedObjectPath<C, S> path, PropertyDefinition<PD> pd) |
| | | throws IllegalArgumentException, DefinitionDecodingException, |
| | | AuthorizationException, ManagedObjectNotFoundException, |
| | | CommunicationException, PropertyException; |
| | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.AbstractManagedObjectDefinition; |
| | | import org.opends.server.admin.AggregationPropertyDefinition; |
| | | import org.opends.server.admin.AliasDefaultBehaviorProvider; |
| | | import org.opends.server.admin.Configuration; |
| | | import org.opends.server.admin.ConfigurationClient; |
| | |
| | | import org.opends.server.admin.ManagedObjectDefinition; |
| | | import org.opends.server.admin.ManagedObjectPath; |
| | | import org.opends.server.admin.PropertyDefinition; |
| | | import org.opends.server.admin.PropertyDefinitionVisitor; |
| | | import org.opends.server.admin.PropertyException; |
| | | import org.opends.server.admin.PropertyIsMandatoryException; |
| | | import org.opends.server.admin.PropertyIsSingleValuedException; |
| | | import org.opends.server.admin.PropertyNotFoundException; |
| | | import org.opends.server.admin.PropertyOption; |
| | | import org.opends.server.admin.Reference; |
| | | import org.opends.server.admin.RelationDefinition; |
| | | import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.UndefinedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.UnknownPropertyDefinitionException; |
| | | import org.opends.server.admin.DefinitionDecodingException.Reason; |
| | | import org.opends.server.admin.std.meta.RootCfgDefn; |
| | | import org.opends.server.admin.std.server.RootCfg; |
| | |
| | | throw new PropertyNotFoundException(propertyName); |
| | | } |
| | | |
| | | List<String> stringValues = getAttribute(mod, pd2, configEntry); |
| | | if (stringValues.isEmpty()) { |
| | | List<AttributeValue> values = getAttribute(mod, pd2, configEntry); |
| | | if (values.isEmpty()) { |
| | | // Recursively retrieve this property's default values. |
| | | Collection<T> tmp = find(target, pd2); |
| | | Collection<T> values = new ArrayList<T>(tmp.size()); |
| | | Collection<T> pvalues = new ArrayList<T>(tmp.size()); |
| | | for (T value : tmp) { |
| | | pd1.validateValue(value); |
| | | values.add(value); |
| | | pvalues.add(value); |
| | | } |
| | | return values; |
| | | return pvalues; |
| | | } else { |
| | | Collection<T> values = new ArrayList<T>(stringValues.size()); |
| | | for (String s : stringValues) { |
| | | values.add(pd1.decodeValue(s)); |
| | | Collection<T> pvalues = new ArrayList<T>(values.size()); |
| | | for (AttributeValue value : values) { |
| | | pvalues.add(ValueDecoder.decode(pd1, value)); |
| | | } |
| | | return values; |
| | | return pvalues; |
| | | } |
| | | } catch (DefinitionDecodingException e) { |
| | | throw new DefaultBehaviorException(pd1, e); |
| | |
| | | String oc = LDAPProfile.getInstance().getObjectClass(d); |
| | | return entry.hasObjectClass(oc); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * A visitor which is used to decode property LDAP values. |
| | | */ |
| | | private static final class ValueDecoder extends |
| | | PropertyDefinitionVisitor<Object, String> { |
| | | |
| | | /** |
| | | * Decodes the provided property LDAP value. |
| | | * |
| | | * @param <PD> |
| | | * The type of the property. |
| | | * @param pd |
| | | * The property definition. |
| | | * @param value |
| | | * The LDAP string representation. |
| | | * @return Returns the decoded LDAP value. |
| | | * @throws IllegalPropertyValueStringException |
| | | * If the property value could not be decoded because it |
| | | * was invalid. |
| | | */ |
| | | public static <PD> PD decode(PropertyDefinition<PD> pd, |
| | | AttributeValue value) throws IllegalPropertyValueStringException { |
| | | String s = value.getStringValue(); |
| | | return pd.castValue(pd.accept(new ValueDecoder(), s)); |
| | | } |
| | | |
| | | |
| | | |
| | | // Prevent instantiation. |
| | | private ValueDecoder() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> |
| | | Object visitAggregation(AggregationPropertyDefinition<C, S> d, String p) { |
| | | // Aggregations values are stored as full DNs in LDAP, but |
| | | // just their common name is exposed in the admin framework. |
| | | try { |
| | | Reference<C, S> reference = Reference.parseDN(d.getParentPath(), d |
| | | .getRelationDefinition(), p); |
| | | return reference.getName(); |
| | | } catch (IllegalArgumentException e) { |
| | | throw new IllegalPropertyValueStringException(d, p); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <T> Object visitUnknown(PropertyDefinition<T> d, String p) |
| | | throws UnknownPropertyDefinitionException { |
| | | // By default the property definition's decoder will do. |
| | | return d.decodeValue(p); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // Singleton instance. |
| | | private final static ServerManagementContext INSTANCE = |
| | |
| | | * Gets the effective value of a property in the named managed |
| | | * object. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that the |
| | | * path definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that the |
| | | * path definition refers to. |
| | | * @param <PD> |
| | | * The type of the property to be retrieved. |
| | | * @param path |
| | |
| | | * If the named managed object could not be found or if it |
| | | * could not be decoded. |
| | | */ |
| | | public <PD> PD getPropertyValue(ManagedObjectPath<?, ?> path, |
| | | public <C extends ConfigurationClient, S extends Configuration, PD> |
| | | PD getPropertyValue(ManagedObjectPath<C, S> path, |
| | | PropertyDefinition<PD> pd) throws IllegalArgumentException, |
| | | ConfigException, PropertyException { |
| | | SortedSet<PD> values = getPropertyValues(path, pd); |
| | |
| | | * Gets the effective values of a property in the named managed |
| | | * object. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that the |
| | | * path definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that the |
| | | * path definition refers to. |
| | | * @param <PD> |
| | | * The type of the property to be retrieved. |
| | | * @param path |
| | |
| | | * If the named managed object could not be found or if it |
| | | * could not be decoded. |
| | | */ |
| | | public <PD> SortedSet<PD> getPropertyValues(ManagedObjectPath<?, ?> path, |
| | | @SuppressWarnings("unchecked") |
| | | public <C extends ConfigurationClient, S extends Configuration, PD> |
| | | SortedSet<PD> getPropertyValues(ManagedObjectPath<C, S> path, |
| | | PropertyDefinition<PD> pd) throws IllegalArgumentException, |
| | | ConfigException, PropertyException { |
| | | // Check that the requested property is from the definition |
| | | // associated with the path. |
| | | AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition(); |
| | | PropertyDefinition<?> tmp = d.getPropertyDefinition(pd.getName()); |
| | | if (tmp != pd) { |
| | | throw new IllegalArgumentException("The property " + pd.getName() |
| | | + " is not associated with a " + d.getName()); |
| | | } |
| | | |
| | | // Determine the exact type of managed object referenced by the |
| | | // path. |
| | | DN dn = DNBuilder.create(path); |
| | | ConfigEntry configEntry = getManagedObjectConfigEntry(dn); |
| | | |
| | | DefinitionResolver resolver = new MyDefinitionResolver(configEntry); |
| | | AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition(); |
| | | ManagedObjectDefinition<?, ?> mod; |
| | | ManagedObjectDefinition<? extends C, ? extends S> mod; |
| | | |
| | | try { |
| | | mod = d.resolveManagedObjectDefinition(resolver); |
| | |
| | | .createDecodingExceptionAdaptor(dn, e); |
| | | } |
| | | |
| | | List<String> values = getAttribute(mod, pd, configEntry); |
| | | return decodeProperty(path, pd, values, null); |
| | | // Make sure we use the correct property definition, the |
| | | // provided one might have been overridden in the resolved |
| | | // definition. |
| | | pd = (PropertyDefinition<PD>) mod.getPropertyDefinition(pd.getName()); |
| | | |
| | | List<AttributeValue> values = getAttribute(mod, pd, configEntry); |
| | | return decodeProperty(path.asSubType(mod), pd, values, null); |
| | | } |
| | | |
| | | |
| | |
| | | Map<PropertyDefinition<?>, SortedSet<?>> properties = |
| | | new HashMap<PropertyDefinition<?>, SortedSet<?>>(); |
| | | for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) { |
| | | List<String> values = getAttribute(mod, pd, configEntry); |
| | | List<AttributeValue> values = getAttribute(mod, pd, configEntry); |
| | | try { |
| | | SortedSet<?> pvalues = decodeProperty(path, pd, values, newConfigEntry); |
| | | properties.put(pd, pvalues); |
| | |
| | | |
| | | // Create a property using the provided string values. |
| | | private <T> SortedSet<T> decodeProperty(ManagedObjectPath<?, ?> path, |
| | | PropertyDefinition<T> pd, List<String> stringValues, |
| | | PropertyDefinition<T> pd, List<AttributeValue> values, |
| | | ConfigEntry newConfigEntry) throws PropertyException { |
| | | PropertyException exception = null; |
| | | SortedSet<T> values = new TreeSet<T>(pd); |
| | | SortedSet<T> pvalues = new TreeSet<T>(pd); |
| | | |
| | | if (!stringValues.isEmpty()) { |
| | | if (!values.isEmpty()) { |
| | | // The property has values defined for it. |
| | | for (String value : stringValues) { |
| | | for (AttributeValue value : values) { |
| | | try { |
| | | values.add(pd.decodeValue(value)); |
| | | pvalues.add(ValueDecoder.decode(pd, value)); |
| | | } catch (IllegalPropertyValueStringException e) { |
| | | exception = e; |
| | | } |
| | |
| | | } else { |
| | | // No values defined so get the defaults. |
| | | try { |
| | | values.addAll(getDefaultValues(path, pd, newConfigEntry)); |
| | | pvalues.addAll(getDefaultValues(path, pd, newConfigEntry)); |
| | | } catch (DefaultBehaviorException e) { |
| | | exception = e; |
| | | } |
| | | } |
| | | |
| | | if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) { |
| | | if (pvalues.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) { |
| | | // This exception takes precedence over previous exceptions. |
| | | exception = new PropertyIsSingleValuedException(pd); |
| | | T value = values.first(); |
| | | values.clear(); |
| | | values.add(value); |
| | | T value = pvalues.first(); |
| | | pvalues.clear(); |
| | | pvalues.add(value); |
| | | } |
| | | |
| | | if (values.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) { |
| | | if (pvalues.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) { |
| | | // The values maybe empty because of a previous exception. |
| | | if (exception == null) { |
| | | exception = new PropertyIsMandatoryException(pd); |
| | |
| | | if (exception != null) { |
| | | throw exception; |
| | | } else { |
| | | return values; |
| | | return pvalues; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // Gets the attribute associated with a property from a ConfigEntry. |
| | | private List<String> getAttribute(ManagedObjectDefinition<?, ?> d, |
| | | private List<AttributeValue> getAttribute(ManagedObjectDefinition<?, ?> d, |
| | | PropertyDefinition<?> pd, ConfigEntry configEntry) { |
| | | // TODO: we create a default attribute type if it is |
| | | // undefined. We should log a warning here if this is the case |
| | | // since the attribute should have been defined. |
| | | String attrID = LDAPProfile.getInstance().getAttributeName(d, pd); |
| | | AttributeType type = DirectoryServer.getAttributeType(attrID, true); |
| | | AttributeValueDecoder<String> decoder = |
| | | new AttributeValueDecoder<String>() { |
| | | AttributeValueDecoder<AttributeValue> decoder = |
| | | new AttributeValueDecoder<AttributeValue>() { |
| | | |
| | | public String decode(AttributeValue value) throws DirectoryException { |
| | | return value.getStringValue(); |
| | | public AttributeValue decode(AttributeValue value) |
| | | throws DirectoryException { |
| | | return value; |
| | | } |
| | | }; |
| | | |
| | | List<String> values = new LinkedList<String>(); |
| | | List<AttributeValue> values = new LinkedList<AttributeValue>(); |
| | | try { |
| | | configEntry.getEntry().getAttributeValues(type, decoder, values); |
| | | } catch (DirectoryException e) { |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * 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 |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.opends.server.admin; |
| | | |
| | | |
| | | |
| | | import org.opends.server.DirectoryServerTestCase; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.types.DN; |
| | | import org.testng.Assert; |
| | | import org.testng.annotations.AfterClass; |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.Test; |
| | | |
| | | |
| | | |
| | | /** |
| | | * AggregationPropertyDefinition Tester. |
| | | */ |
| | | @Test(sequential = true) |
| | | public class AggregationPropertyDefinitionTest extends DirectoryServerTestCase { |
| | | |
| | | /** |
| | | * Sets up tests |
| | | * |
| | | * @throws Exception |
| | | * If the server could not be initialized. |
| | | */ |
| | | @BeforeClass |
| | | public void setUp() throws Exception { |
| | | // This test suite depends on having the schema available, so |
| | | // we'll start the server. |
| | | TestCaseUtils.startServer(); |
| | | TestCfg.setUp(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tears down test environment. |
| | | */ |
| | | @AfterClass |
| | | public void tearDown() { |
| | | TestCfg.cleanup(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests that the |
| | | * {@link AggregationPropertyDefinition#normalizeValue(String)} |
| | | * works. |
| | | * |
| | | * @throws Exception |
| | | * If the test unexpectedly fails. |
| | | */ |
| | | @Test |
| | | public void testNormalizeValue() throws Exception { |
| | | TestChildCfgDefn d = TestChildCfgDefn.getInstance(); |
| | | AggregationPropertyDefinition<?, ?> pd = d |
| | | .getAggregationPropertyPropertyDefinition(); |
| | | String nvalue = pd.normalizeValue(" LDAP connection handler "); |
| | | Assert.assertEquals(nvalue, "ldap connection handler"); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests that the |
| | | * {@link AggregationPropertyDefinition#getChildDN(String)} works. |
| | | * |
| | | * @throws Exception |
| | | * If the test unexpectedly fails. |
| | | */ |
| | | @Test |
| | | public void testGetChildDN() throws Exception { |
| | | TestChildCfgDefn d = TestChildCfgDefn.getInstance(); |
| | | AggregationPropertyDefinition<?, ?> pd = d |
| | | .getAggregationPropertyPropertyDefinition(); |
| | | DN expected = DN |
| | | .decode("cn=ldap connection handler, cn=connection handlers, cn=config"); |
| | | DN actual = pd.getChildDN(" LDAP connection handler "); |
| | | Assert.assertEquals(actual, expected); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests that the |
| | | * {@link AggregationPropertyDefinition#getChildPath(String)} works. |
| | | * |
| | | * @throws Exception |
| | | * If the test unexpectedly fails. |
| | | */ |
| | | @Test |
| | | public void testGetChildPath() throws Exception { |
| | | TestChildCfgDefn d = TestChildCfgDefn.getInstance(); |
| | | AggregationPropertyDefinition<?, ?> pd = d |
| | | .getAggregationPropertyPropertyDefinition(); |
| | | ManagedObjectPath<?, ?> path = pd.getChildPath("LDAP connection handler"); |
| | | |
| | | Assert.assertSame(path.getManagedObjectDefinition(), pd |
| | | .getRelationDefinition().getChildDefinition()); |
| | | Assert.assertSame(path.getRelationDefinition(), pd.getRelationDefinition()); |
| | | } |
| | | |
| | | } |
| | |
| | | return "ds-cfg-virtual-attribute-base-dn"; |
| | | } else if (pd == (PropertyDefinition<?>)td.getOptionalMultiValuedDNProperty2PropertyDefinition()) { |
| | | return "ds-cfg-virtual-attribute-group-dn"; |
| | | } else if (pd == (PropertyDefinition<?>)td.getAggregationPropertyPropertyDefinition()) { |
| | | return "ds-cfg-backend-base-dn"; |
| | | } else { |
| | | throw new RuntimeException("Unexpected test-child property" |
| | | + pd.getName()); |
| | |
| | | public String getObjectClass(AbstractManagedObjectDefinition<?, ?> d) { |
| | | // These casts throughout are required to work around a bug in JDK versions prior to 1.5.0_08. |
| | | if (d == (AbstractManagedObjectDefinition<?, ?>)TestParentCfgDefn.getInstance()) { |
| | | return "ds-cfg-virtual-attribute"; |
| | | return "ds-cfg-test-parent-dummy"; |
| | | } else if (d == (AbstractManagedObjectDefinition<?, ?>)TestChildCfgDefn.getInstance()) { |
| | | return "ds-cfg-virtual-attribute"; |
| | | return "ds-cfg-test-child-dummy"; |
| | | } else { |
| | | // Not known. |
| | | return null; |
| | |
| | | |
| | | |
| | | |
| | | import java.util.ResourceBundle; |
| | | |
| | | import org.opends.server.admin.std.meta.RootCfgDefn; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.schema.ObjectClassSyntax; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ByteStringFactory; |
| | | import org.opends.server.types.ObjectClass; |
| | | |
| | | |
| | | |
| | |
| | | |
| | | // Create a one-to-many relation for test-parent components. |
| | | static { |
| | | InstantiableRelationDefinition.Builder<TestParentCfgClient, TestParentCfg> builder = |
| | | new InstantiableRelationDefinition.Builder<TestParentCfgClient, TestParentCfg>( |
| | | InstantiableRelationDefinition.Builder<TestParentCfgClient, TestParentCfg> builder = new InstantiableRelationDefinition.Builder<TestParentCfgClient, TestParentCfg>( |
| | | RootCfgDefn.getInstance(), "test-one-to-many-parent", |
| | | "test-one-to-many-parents", TestParentCfgDefn.getInstance()); |
| | | RD_TEST_ONE_TO_MANY_PARENT = builder.getInstance(); |
| | |
| | | |
| | | // Create a one-to-many relation for test-parent components. |
| | | static { |
| | | OptionalRelationDefinition.Builder<TestParentCfgClient, TestParentCfg> builder = |
| | | new OptionalRelationDefinition.Builder<TestParentCfgClient, TestParentCfg>( |
| | | OptionalRelationDefinition.Builder<TestParentCfgClient, TestParentCfg> builder = new OptionalRelationDefinition.Builder<TestParentCfgClient, TestParentCfg>( |
| | | RootCfgDefn.getInstance(), "test-one-to-zero-or-one-parent", |
| | | TestParentCfgDefn.getInstance()); |
| | | RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT = builder.getInstance(); |
| | | } |
| | | |
| | | // Test parent object class definition. |
| | | private static ObjectClass TEST_PARENT_OCD = null; |
| | | |
| | | // Test child object class definition. |
| | | private static ObjectClass TEST_CHILD_OCD = null; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Registers test parent and child object class definitions and any |
| | | * required resource bundles. |
| | | * <p> |
| | | * Unit tests which call this method <b>must</b> call |
| | | * {@link #cleanup()} on completion. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | public synchronized static void setUp() throws Exception { |
| | | if (TEST_PARENT_OCD == null) { |
| | | String ocd = "( 1.3.6.1.4.1.26027.1.2.4455114401 " |
| | | + "NAME 'ds-cfg-test-parent-dummy' " |
| | | + "SUP top STRUCTURAL " |
| | | + "MUST ( cn $ ds-cfg-virtual-attribute-class $ " |
| | | + "ds-cfg-virtual-attribute-enabled $ ds-cfg-virtual-attribute-type ) " |
| | | + "MAY ( ds-cfg-virtual-attribute-base-dn $ ds-cfg-virtual-attribute-group-dn $ " |
| | | + "ds-cfg-virtual-attribute-filter $ ds-cfg-virtual-attribute-conflict-behavior ) " |
| | | + "X-ORIGIN 'OpenDS Directory Server' )"; |
| | | ByteString b = ByteStringFactory.create(ocd); |
| | | |
| | | TEST_PARENT_OCD = ObjectClassSyntax.decodeObjectClass(b, DirectoryServer |
| | | .getSchema(), false); |
| | | } |
| | | |
| | | if (TEST_CHILD_OCD == null) { |
| | | String ocd = "( 1.3.6.1.4.1.26027.1.2.4455114402 " |
| | | + "NAME 'ds-cfg-test-child-dummy' " |
| | | + "SUP top STRUCTURAL " |
| | | + "MUST ( cn $ ds-cfg-virtual-attribute-class $ " |
| | | + "ds-cfg-virtual-attribute-enabled $ ds-cfg-virtual-attribute-type ) " |
| | | + "MAY ( ds-cfg-virtual-attribute-base-dn $ ds-cfg-virtual-attribute-group-dn $ " |
| | | + "ds-cfg-virtual-attribute-filter $ ds-cfg-virtual-attribute-conflict-behavior $" |
| | | + "ds-cfg-backend-base-dn) " + "X-ORIGIN 'OpenDS Directory Server' )"; |
| | | ByteString b = ByteStringFactory.create(ocd); |
| | | |
| | | TEST_CHILD_OCD = ObjectClassSyntax.decodeObjectClass(b, DirectoryServer |
| | | .getSchema(), false); |
| | | } |
| | | |
| | | { |
| | | // Register the test parent object class. |
| | | DirectoryServer.registerObjectClass(TEST_PARENT_OCD, true); |
| | | |
| | | // Register the test parent resource bundle. |
| | | TestParentCfgDefn d = TestParentCfgDefn.getInstance(); |
| | | String baseName = d.getClass().getName(); |
| | | ResourceBundle resourceBundle = ResourceBundle.getBundle(baseName); |
| | | ManagedObjectDefinitionI18NResource.getInstance().setResourceBundle(d, |
| | | resourceBundle); |
| | | } |
| | | |
| | | { |
| | | // Register the test child object class. |
| | | DirectoryServer.registerObjectClass(TEST_CHILD_OCD, true); |
| | | |
| | | // Register the test child resource bundle. |
| | | TestChildCfgDefn d = TestChildCfgDefn.getInstance(); |
| | | String baseName = d.getClass().getName(); |
| | | ResourceBundle resourceBundle = ResourceBundle.getBundle(baseName); |
| | | ManagedObjectDefinitionI18NResource.getInstance().setResourceBundle(d, |
| | | resourceBundle); |
| | | } |
| | | |
| | | // Ensure that the relations are registered (do this after things |
| | | // that can fail and leave tests in a bad state). |
| | | RootCfgDefn.getInstance().registerRelationDefinition( |
| | | RD_TEST_ONE_TO_MANY_PARENT); |
| | | RootCfgDefn.getInstance().registerRelationDefinition( |
| | | RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT); |
| | | LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | |
| | | * framework. |
| | | */ |
| | | public static void cleanup() { |
| | | RootCfgDefn.getInstance().deregisterRelationDefinition( |
| | | RD_TEST_ONE_TO_MANY_PARENT); |
| | | RootCfgDefn.getInstance().deregisterRelationDefinition( |
| | | RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT); |
| | | LDAPProfile.getInstance().popWrapper(); |
| | | |
| | | { |
| | | RootCfgDefn.getInstance().deregisterRelationDefinition( |
| | | RD_TEST_ONE_TO_MANY_PARENT); |
| | | RootCfgDefn.getInstance().deregisterRelationDefinition( |
| | | RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT); |
| | | DirectoryServer.deregisterObjectClass(TEST_PARENT_OCD); |
| | | TestParentCfgDefn d = TestParentCfgDefn.getInstance(); |
| | | ManagedObjectDefinitionI18NResource.getInstance().removeResourceBundle(d); |
| | | } |
| | | |
| | | { |
| | | DirectoryServer.deregisterObjectClass(TEST_CHILD_OCD); |
| | | TestChildCfgDefn d = TestChildCfgDefn.getInstance(); |
| | | ManagedObjectDefinitionI18NResource.getInstance().removeResourceBundle(d); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | |
| | | * Gets the one-to-many relation between the root and test-parent |
| | | * components. |
| | | * <p> |
| | | * Unit tests which call this method <b>must</b> call |
| | | * {@link #cleanup()} on completion. |
| | | * Unit tests which call this method <b>must</b> have already |
| | | * called {@link #setUp()}. |
| | | * |
| | | * @return Returns the one-to-many relation between the root and |
| | | * test-parent components. |
| | | */ |
| | | public static InstantiableRelationDefinition<TestParentCfgClient, TestParentCfg> getTestOneToManyParentRelationDefinition() { |
| | | // Ensure that the relation is registered. |
| | | RootCfgDefn.getInstance().registerRelationDefinition( |
| | | RD_TEST_ONE_TO_MANY_PARENT); |
| | | return RD_TEST_ONE_TO_MANY_PARENT; |
| | | } |
| | | |
| | |
| | | * Gets the one-to-zero-or-one relation between the root and a |
| | | * test-parent component. |
| | | * <p> |
| | | * Unit tests which call this method <b>must</b> call |
| | | * {@link #cleanup()} on completion. |
| | | * Unit tests which call this method <b>must</b> have already |
| | | * called {@link #setUp()}. |
| | | * |
| | | * @return Returns the one-to-zero-or-one relation between the root |
| | | * and a test-parent component. |
| | | */ |
| | | public static OptionalRelationDefinition<TestParentCfgClient, TestParentCfg> getTestOneToZeroOrOneParentRelationDefinition() { |
| | | // Ensure that the relation is registered. |
| | | RootCfgDefn.getInstance().registerRelationDefinition( |
| | | RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT); |
| | | return RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds a constraint temporarily with test child definition. |
| | | * |
| | | * @param constraint |
| | | * The constraint. |
| | | */ |
| | | public static void addConstraint(Constraint constraint) { |
| | | TestChildCfgDefn.getInstance().registerConstraint(constraint); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Removes a constraint from the test child definition. |
| | | * |
| | | * @param constraint |
| | | * The constraint. |
| | | */ |
| | | public static void removeConstraint(Constraint constraint) { |
| | | TestChildCfgDefn.getInstance().deregisterConstraint(constraint); |
| | | } |
| | | |
| | | |
| | | |
| | | // Prevent instantiation. |
| | | private TestCfg() { |
| | | // No implementation required. |
| | |
| | | import org.opends.server.admin.Configuration; |
| | | import org.opends.server.admin.ManagedObjectDefinition; |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import org.opends.server.admin.TestChildCfgClient; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.DN; |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * Get the "aggregation-property" property. |
| | | * <p> |
| | | * An aggregation property which references connection handlers. |
| | | * |
| | | * @return Returns the values of the "aggregation-property" property. |
| | | */ |
| | | SortedSet<String> getAggregationProperty(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get the "mandatory-boolean-property" property. |
| | | * <p> |
| | | * A mandatory boolean property. |
| | |
| | | import org.opends.server.admin.IllegalPropertyValueException; |
| | | import org.opends.server.admin.ManagedObjectDefinition; |
| | | import org.opends.server.admin.PropertyIsReadOnlyException; |
| | | import org.opends.server.admin.TestChildCfg; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.DN; |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * Get the "aggregation-property" property. |
| | | * <p> |
| | | * An aggregation property which references connection handlers. |
| | | * |
| | | * @return Returns the values of the "aggregation-property" property. |
| | | */ |
| | | SortedSet<String> getAggregationProperty(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Set the "aggregation-property" property. |
| | | * <p> |
| | | * An aggregation property which references connection handlers. |
| | | * |
| | | * @param values The values of the "aggregation-property" property. |
| | | * @throws IllegalPropertyValueException |
| | | * If one or more of the new values are invalid. |
| | | */ |
| | | void setAggregationProperty(Collection<String> values) throws IllegalPropertyValueException; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get the "mandatory-boolean-property" property. |
| | | * <p> |
| | | * A mandatory boolean property. |
| | |
| | | import org.opends.server.admin.AttributeTypePropertyDefinition; |
| | | import org.opends.server.admin.BooleanPropertyDefinition; |
| | | import org.opends.server.admin.ClassPropertyDefinition; |
| | | import org.opends.server.admin.DNPropertyDefinition; |
| | | import org.opends.server.admin.DefaultBehaviorProvider; |
| | | import org.opends.server.admin.DefinedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.ManagedObjectAlreadyExistsException; |
| | | import org.opends.server.admin.ManagedObjectDefinition; |
| | | import org.opends.server.admin.ManagedObjectPath; |
| | | import org.opends.server.admin.PropertyIsReadOnlyException; |
| | | import org.opends.server.admin.PropertyOption; |
| | | import org.opends.server.admin.PropertyProvider; |
| | | import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.UndefinedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.client.AuthorizationException; |
| | | import org.opends.server.admin.client.CommunicationException; |
| | | import org.opends.server.admin.client.ConcurrentModificationException; |
| | | import org.opends.server.admin.client.ManagedObject; |
| | | import org.opends.server.admin.client.MissingMandatoryPropertiesException; |
| | | import org.opends.server.admin.client.OperationRejectedException; |
| | | import org.opends.server.admin.DefaultBehaviorProvider; |
| | | import org.opends.server.admin.DefinedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.DNPropertyDefinition; |
| | | import org.opends.server.admin.ManagedObjectAlreadyExistsException; |
| | | import org.opends.server.admin.ManagedObjectDefinition; |
| | | import org.opends.server.admin.PropertyIsReadOnlyException; |
| | | import org.opends.server.admin.PropertyOption; |
| | | import org.opends.server.admin.PropertyProvider; |
| | | import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import org.opends.server.admin.server.ServerManagedObject; |
| | | import org.opends.server.admin.UndefinedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.std.client.ConnectionHandlerCfgClient; |
| | | import org.opends.server.admin.TestChildCfgClient; |
| | | import org.opends.server.admin.std.meta.ConnectionHandlerCfgDefn; |
| | | import org.opends.server.admin.std.server.ConnectionHandlerCfg; |
| | | import org.opends.server.admin.TestChildCfg; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.DN; |
| | | |
| | |
| | | |
| | | |
| | | |
| | | // The "aggregation-property" property definition. |
| | | private static final AggregationPropertyDefinition<ConnectionHandlerCfgClient, ConnectionHandlerCfg> PD_AGGREGATION_PROPERTY; |
| | | |
| | | |
| | | |
| | | // The "mandatory-boolean-property" property definition. |
| | | private static final BooleanPropertyDefinition PD_MANDATORY_BOOLEAN_PROPERTY; |
| | | |
| | |
| | | |
| | | |
| | | |
| | | // Build the "aggregation-property" property definition. |
| | | static { |
| | | AggregationPropertyDefinition.Builder<ConnectionHandlerCfgClient, ConnectionHandlerCfg> builder = AggregationPropertyDefinition.createBuilder(INSTANCE, "aggregation-property"); |
| | | builder.setOption(PropertyOption.MULTI_VALUED); |
| | | builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "aggregation-property")); |
| | | builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>()); |
| | | builder.setParentPath(ManagedObjectPath.valueOf("/")); |
| | | builder.setRelationDefinition("connection-handler"); |
| | | builder.setManagedObjectDefinition(ConnectionHandlerCfgDefn.getInstance()); |
| | | PD_AGGREGATION_PROPERTY = builder.getInstance(); |
| | | INSTANCE.registerPropertyDefinition(PD_AGGREGATION_PROPERTY); |
| | | } |
| | | |
| | | |
| | | |
| | | // Build the "mandatory-boolean-property" property definition. |
| | | static { |
| | | BooleanPropertyDefinition.Builder builder = BooleanPropertyDefinition.createBuilder(INSTANCE, "mandatory-boolean-property"); |
| | |
| | | private TestChildCfgDefn() { |
| | | super("test-child", null); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds a constraint temporarily with this test definition. |
| | | * |
| | | * @param constraint The constraint. |
| | | */ |
| | | public void addConstraint(Constraint constraint) { |
| | | registerConstraint(constraint); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Removes a constraint from this test definition. |
| | | * |
| | | * @param constraint The constraint. |
| | | */ |
| | | public void removeConstraint(Constraint constraint) { |
| | | deregisterConstraint(constraint); |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * Get the "aggregation-property" property definition. |
| | | * <p> |
| | | * An aggregation property which references connection handlers. |
| | | * |
| | | * @return Returns the "aggregation-property" property definition. |
| | | */ |
| | | public AggregationPropertyDefinition<ConnectionHandlerCfgClient, ConnectionHandlerCfg> getAggregationPropertyPropertyDefinition() { |
| | | return PD_AGGREGATION_PROPERTY; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get the "mandatory-boolean-property" property definition. |
| | | * <p> |
| | | * A mandatory boolean property. |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public SortedSet<String> getAggregationProperty() { |
| | | return impl.getPropertyValues(INSTANCE.getAggregationPropertyPropertyDefinition()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void setAggregationProperty(Collection<String> values) { |
| | | impl.setPropertyValues(INSTANCE.getAggregationPropertyPropertyDefinition(), values); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Boolean isMandatoryBooleanProperty() { |
| | | return impl.getPropertyValue(INSTANCE.getMandatoryBooleanPropertyPropertyDefinition()); |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public SortedSet<String> getAggregationProperty() { |
| | | return impl.getPropertyValues(INSTANCE.getAggregationPropertyPropertyDefinition()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isMandatoryBooleanProperty() { |
| | | return impl.getPropertyValue(INSTANCE.getMandatoryBooleanPropertyPropertyDefinition()); |
| | | } |
| New file |
| | |
| | | user-friendly-name=Test Child |
| | | user-friendly-plural-name=Test Children |
| | | synopsis=A configuration for testing components that are subordinate to a parent component. It re-uses the virtual-attribute configuration LDAP profile. |
| | | property.aggregation-property.synopsis=An aggregation property which references connection handlers. |
| | | property.mandatory-boolean-property.synopsis=A mandatory boolean property. |
| | | property.mandatory-class-property.synopsis=A mandatory Java-class property requiring a component restart. |
| | | property.mandatory-read-only-attribute-type-property.synopsis=A mandatory read-only attribute type property. |
| | | property.optional-multi-valued-dn-property1.synopsis=An optional multi-valued DN property which inherits its values from optional-multi-valued-dn-property in the parent. |
| | | property.optional-multi-valued-dn-property2.synopsis=An optional multi-valued DN property which inherits its values from optional-multi-valued-dn-property1. |
| | |
| | | ! Portions Copyright 2007 Sun Microsystems, Inc. |
| | | ! --> |
| | | <adm:managed-object name="test-child" plural-name="test-children" |
| | | package="org.opends.server.admin.std" |
| | | package="org.opends.server.admin" |
| | | xmlns:adm="http://www.opends.org/admin" |
| | | xmlns:ldap="http://www.opends.org/admin-ldap"> |
| | | <adm:synopsis> |
| | |
| | | </adm:synopsis> |
| | | <adm:profile name="ldap"> |
| | | <ldap:object-class> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.2.91</ldap:oid> |
| | | <ldap:name>ds-cfg-virtual-attribute</ldap:name> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.2.4455114402</ldap:oid> |
| | | <ldap:name>ds-cfg-test-child-dummy</ldap:name> |
| | | <ldap:superior>top</ldap:superior> |
| | | </ldap:object-class> |
| | | </adm:profile> |
| | |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | <adm:property name="aggregation-property" multi-valued="true"> |
| | | <adm:synopsis> |
| | | An aggregation property which references connection handlers. |
| | | </adm:synopsis> |
| | | <adm:default-behavior> |
| | | <adm:undefined /> |
| | | </adm:default-behavior> |
| | | <adm:syntax> |
| | | <adm:aggregation parent-path="/" |
| | | relation-name="connection-handler" /> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.1.332</ldap:oid> |
| | | <ldap:name>ds-task-initialize-domain-dn</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | </adm:managed-object> |
| New file |
| | |
| | | user-friendly-name=Test Parent |
| | | user-friendly-plural-name=Test Parents |
| | | synopsis=A configuration for testing components that have child components. It re-uses the virtual-attribute configuration LDAP profile. |
| | | property.mandatory-boolean-property.synopsis=A mandatory boolean property. |
| | | property.mandatory-class-property.synopsis=A mandatory Java-class property requiring a component restart. |
| | | property.mandatory-read-only-attribute-type-property.synopsis=A mandatory read-only attribute type property. |
| | | property.optional-multi-valued-dn-property.synopsis=An optional multi-valued DN property with a defined default behavior. |
| | | relation.optional-test-child.user-friendly-name=Optional Test Child |
| | | relation.optional-test-child.synopsis=A configuration for testing components that are subordinate to a parent component. It re-uses the virtual-attribute configuration LDAP profile. |
| | | relation.test-child.user-friendly-name=Test Child |
| | | relation.test-child.user-friendly-plural-name=Test Children |
| | | relation.test-child.synopsis=A configuration for testing components that are subordinate to a parent component. It re-uses the virtual-attribute configuration LDAP profile. |
| | |
| | | ! Portions Copyright 2007 Sun Microsystems, Inc. |
| | | ! --> |
| | | <adm:managed-object name="test-parent" plural-name="test-parents" |
| | | package="org.opends.server.admin.std" |
| | | package="org.opends.server.admin" |
| | | xmlns:adm="http://www.opends.org/admin" |
| | | xmlns:ldap="http://www.opends.org/admin-ldap"> |
| | | <adm:synopsis> |
| | |
| | | </adm:synopsis> |
| | | <adm:profile name="ldap"> |
| | | <ldap:object-class> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.2.91</ldap:oid> |
| | | <ldap:name>ds-cfg-virtual-attribute</ldap:name> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.2.4455114401</ldap:oid> |
| | | <ldap:name>ds-cfg-test-parent-dummy</ldap:name> |
| | | <ldap:superior>top</ldap:superior> |
| | | </ldap:object-class> |
| | | </adm:profile> |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * 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 |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.admin.client.ldap; |
| | | |
| | | |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.AdminTestCase; |
| | | import org.opends.server.admin.DefinitionDecodingException; |
| | | import org.opends.server.admin.IllegalPropertyValueStringException; |
| | | import org.opends.server.admin.ManagedObjectNotFoundException; |
| | | import org.opends.server.admin.PropertyException; |
| | | import org.opends.server.admin.TestCfg; |
| | | import org.opends.server.admin.TestChildCfgClient; |
| | | import org.opends.server.admin.TestChildCfgDefn; |
| | | import org.opends.server.admin.TestParentCfgClient; |
| | | import org.opends.server.admin.client.AuthorizationException; |
| | | import org.opends.server.admin.client.CommunicationException; |
| | | import org.opends.server.admin.client.ConcurrentModificationException; |
| | | import org.opends.server.admin.client.ManagedObject; |
| | | import org.opends.server.admin.client.ManagedObjectDecodingException; |
| | | import org.opends.server.admin.client.ManagementContext; |
| | | import org.opends.server.admin.std.client.RootCfgClient; |
| | | import org.opends.server.core.DirectoryServer; |
| | | 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 client-side. |
| | | */ |
| | | @Test(sequential = true) |
| | | public class AggregationTest extends AdminTestCase { |
| | | |
| | | // Test LDIF. |
| | | private static final String[] TEST_LDIF = new String[] { |
| | | // Base entries. |
| | | "dn: cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-branch", |
| | | "cn: config", |
| | | "", |
| | | "dn: cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-branch", |
| | | "cn: test-parents", |
| | | "", |
| | | // Parent 1 - uses default values for |
| | | // optional-multi-valued-dn-property. |
| | | "dn: cn=test parent 1,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-test-parent-dummy", |
| | | "cn: test parent 1", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | | "ds-cfg-virtual-attribute-type: description", |
| | | "", |
| | | // Child base entry. |
| | | "dn:cn=test children,cn=test parent 1,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-branch", |
| | | "cn: multiple children", |
| | | "", |
| | | // Child 1 has no references. |
| | | "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-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | | "ds-cfg-virtual-attribute-type: description", |
| | | "", |
| | | // Child 2 has a single valid reference. |
| | | "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-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | | "ds-cfg-virtual-attribute-type: description", |
| | | "ds-cfg-backend-base-dn: cn=LDAP Connection Handler, cn=connection handlers, cn=config", |
| | | "", |
| | | // Child 3 has a multiple valid references. |
| | | "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-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | | "ds-cfg-virtual-attribute-type: description", |
| | | "ds-cfg-backend-base-dn: cn=LDAP Connection Handler, cn=connection handlers, cn=config", |
| | | "ds-cfg-backend-base-dn: cn=LDAPS Connection Handler, cn=connection handlers, cn=config", |
| | | "", |
| | | // Child 4 has a single bad reference. |
| | | "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-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | | "ds-cfg-virtual-attribute-type: description", |
| | | "ds-cfg-backend-base-dn: cn=LDAP Connection Handler, cn=bad rdn, cn=config", |
| | | "", |
| | | }; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets up tests |
| | | * |
| | | * @throws Exception |
| | | * If the server could not be initialized. |
| | | */ |
| | | @BeforeClass |
| | | public void setUp() throws Exception { |
| | | // This test suite depends on having the schema available, so |
| | | // we'll start the server. |
| | | TestCaseUtils.startServer(); |
| | | TestCfg.setUp(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tears down test environment. |
| | | */ |
| | | @AfterClass |
| | | public void tearDown() { |
| | | TestCfg.cleanup(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 { |
| | | MockLDAPConnection c = new MockLDAPConnection(); |
| | | c.importLDIF(TEST_LDIF); |
| | | ManagementContext ctx = LDAPManagementContext.createFromContext(c); |
| | | TestParentCfgClient parent = getTestParent(ctx, "test parent 1"); |
| | | TestChildCfgClient child = parent.getTestChild("test child 1"); |
| | | assertSetEquals(child.getAggregationProperty(), new String[0]); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 { |
| | | MockLDAPConnection c = new MockLDAPConnection(); |
| | | c.importLDIF(TEST_LDIF); |
| | | ManagementContext ctx = LDAPManagementContext.createFromContext(c); |
| | | TestParentCfgClient parent = getTestParent(ctx, "test parent 1"); |
| | | TestChildCfgClient child = parent.getTestChild("test child 2"); |
| | | |
| | | // Test normalization. |
| | | assertSetEquals(child.getAggregationProperty(), "LDAP Connection Handler"); |
| | | assertSetEquals(child.getAggregationProperty(), |
| | | " LDAP Connection Handler "); |
| | | assertSetEquals(child.getAggregationProperty(), |
| | | " ldap connection HANDLER "); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 testAggregationMultiple() throws Exception { |
| | | MockLDAPConnection c = new MockLDAPConnection(); |
| | | c.importLDIF(TEST_LDIF); |
| | | ManagementContext ctx = LDAPManagementContext.createFromContext(c); |
| | | TestParentCfgClient parent = getTestParent(ctx, "test parent 1"); |
| | | TestChildCfgClient child = parent.getTestChild("test child 3"); |
| | | assertSetEquals(child.getAggregationProperty(), "LDAPS Connection Handler", |
| | | "LDAP Connection Handler"); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 { |
| | | MockLDAPConnection c = new MockLDAPConnection(); |
| | | c.importLDIF(TEST_LDIF); |
| | | ManagementContext ctx = LDAPManagementContext.createFromContext(c); |
| | | TestParentCfgClient parent = getTestParent(ctx, "test parent 1"); |
| | | |
| | | try { |
| | | parent.getTestChild("test child 4"); |
| | | Assert.fail("Unexpectedly retrieved test child 4" |
| | | + " when it had a bad aggregation value"); |
| | | } catch (ManagedObjectDecodingException e) { |
| | | Collection<PropertyException> causes = e.getCauses(); |
| | | Assert.assertEquals(causes.size(), 1); |
| | | |
| | | Throwable 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; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests creation of a child managed object with a single reference. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test |
| | | public void testCreateChildManagedObject() throws Exception { |
| | | CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection( |
| | | "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | c.addExpectedAttribute("cn", "test child new"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child-dummy"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-class", |
| | | "org.opends.server.extensions.UserDefinedVirtualAttributeProvider"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-type", "description"); |
| | | c.addExpectedAttribute("ds-cfg-backend-base-dn", |
| | | "cn=LDAP Connection Handler,cn=connection handlers,cn=config"); |
| | | |
| | | ManagementContext ctx = LDAPManagementContext.createFromContext(c); |
| | | TestParentCfgClient parent = getTestParent(ctx, "test parent 1"); |
| | | TestChildCfgClient child = parent.createTestChild(TestChildCfgDefn |
| | | .getInstance(), "test child new", null); |
| | | child.setMandatoryBooleanProperty(true); |
| | | child.setMandatoryReadOnlyAttributeTypeProperty(DirectoryServer |
| | | .getAttributeType("description")); |
| | | child.setAggregationProperty(Collections |
| | | .singleton("LDAP Connection Handler")); |
| | | child.commit(); |
| | | |
| | | c.assertEntryIsCreated(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests modification of a child managed object so that it has a |
| | | * different reference. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test |
| | | public void testModifyChildManagedObject() throws Exception { |
| | | ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection( |
| | | "cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | c.addExpectedModification("ds-cfg-backend-base-dn", |
| | | "cn=LDAPS Connection Handler,cn=connection handlers,cn=config", |
| | | "cn=JMX Connection Handler,cn=connection handlers,cn=config"); |
| | | ManagementContext ctx = LDAPManagementContext.createFromContext(c); |
| | | TestParentCfgClient parent = getTestParent(ctx, "test parent 1"); |
| | | TestChildCfgClient child = parent.getTestChild("test child 2"); |
| | | child.setAggregationProperty(Arrays.asList("LDAPS Connection Handler", |
| | | "JMX Connection Handler")); |
| | | child.commit(); |
| | | Assert.assertTrue(c.isEntryModified()); |
| | | } |
| | | |
| | | |
| | | |
| | | // Retrieve the named test parent managed object. |
| | | private TestParentCfgClient getTestParent(ManagementContext context, |
| | | String name) throws DefinitionDecodingException, |
| | | ManagedObjectDecodingException, AuthorizationException, |
| | | ManagedObjectNotFoundException, ConcurrentModificationException, |
| | | CommunicationException { |
| | | ManagedObject<RootCfgClient> root = context |
| | | .getRootConfigurationManagedObject(); |
| | | return root.getChild(TestCfg.getTestOneToManyParentRelationDefinition(), |
| | | name).getConfiguration(); |
| | | } |
| | | |
| | | |
| | | |
| | | // Asserts that the actual set of DNs contains the expected values. |
| | | private void assertSetEquals(SortedSet<String> actual, String... expected) { |
| | | SortedSet<String> values = new TreeSet<String>(TestChildCfgDefn |
| | | .getInstance().getAggregationPropertyPropertyDefinition()); |
| | | if (expected != null) { |
| | | for (String value : expected) { |
| | | values.add(value); |
| | | } |
| | | } |
| | | Assert.assertEquals((Object) actual, (Object) values); |
| | | } |
| | | |
| | | } |
| | |
| | | import org.opends.server.admin.AdminTestCase; |
| | | import org.opends.server.admin.Constraint; |
| | | import org.opends.server.admin.DefinitionDecodingException; |
| | | import org.opends.server.admin.LDAPProfile; |
| | | import org.opends.server.admin.ManagedObjectAlreadyExistsException; |
| | | import org.opends.server.admin.ManagedObjectNotFoundException; |
| | | import org.opends.server.admin.MockLDAPProfile; |
| | | import org.opends.server.admin.TestCfg; |
| | | import org.opends.server.admin.TestChildCfgClient; |
| | | import org.opends.server.admin.TestChildCfgDefn; |
| | |
| | | // optional-multi-valued-dn-property. |
| | | "dn: cn=test parent 1,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-virtual-attribute", |
| | | "objectclass: ds-cfg-test-parent-dummy", |
| | | "cn: test parent 1", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | // optional-multi-valued-dn-property. |
| | | "dn: cn=test parent 2,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-virtual-attribute", |
| | | "objectclass: ds-cfg-test-parent-dummy", |
| | | "cn: test parent 2", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | // optional-multi-valued-dn-property. |
| | | "dn: cn=test parent 3,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-virtual-attribute", |
| | | "objectclass: ds-cfg-test-parent-dummy", |
| | | "cn: test parent 3", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | // optional-multi-valued-dn-property2. |
| | | "dn: cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-virtual-attribute", |
| | | "objectclass: ds-cfg-test-child-dummy", |
| | | "cn: test child 1", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | // optional-multi-valued-dn-property2. |
| | | "dn: cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-virtual-attribute", |
| | | "objectclass: ds-cfg-test-child-dummy", |
| | | "cn: test child 2", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | // optional-multi-valued-dn-property2. |
| | | "dn: cn=test child 3,cn=test children,cn=test parent 1,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-virtual-attribute", |
| | | "objectclass: ds-cfg-test-child-dummy", |
| | | "cn: test child 3", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | // optional-multi-valued-dn-property2. |
| | | "dn: cn=test child 1,cn=test children,cn=test parent 2,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-virtual-attribute", |
| | | "objectclass: ds-cfg-test-child-dummy", |
| | | "cn: test child 1", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | | "ds-cfg-virtual-attribute-type: description", |
| | | "" |
| | | "", |
| | | }; |
| | | |
| | | |
| | |
| | | // This test suite depends on having the schema available, so |
| | | // we'll start the server. |
| | | TestCaseUtils.startServer(); |
| | | LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile()); |
| | | TestCfg.setUp(); |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | @AfterClass |
| | | public void tearDown() { |
| | | LDAPProfile.getInstance().popWrapper(); |
| | | TestCfg.cleanup(); |
| | | } |
| | | |
| | |
| | | "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | c.addExpectedAttribute("cn", "test child new"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child-dummy"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-class", |
| | | "org.opends.server.extensions.UserDefinedVirtualAttributeProvider"); |
| | |
| | | "cn=test parent new,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | c.addExpectedAttribute("cn", "test parent new"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-parent-dummy"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-class", |
| | | "org.opends.server.extensions.UserDefinedVirtualAttributeProvider"); |
| | |
| | | "dc=domain1,dc=com", "dc=domain2,dc=com", "dc=domain3,dc=com"); |
| | | assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(), |
| | | "dc=domain1,dc=com", "dc=domain2,dc=com", "dc=domain3,dc=com"); |
| | | Assert.assertEquals(child.isMandatoryBooleanProperty(), Boolean.TRUE); |
| | | } |
| | | |
| | | |
| | |
| | | "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | c.addExpectedAttribute("cn", "test child new"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child-dummy"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-class", |
| | | "org.opends.server.extensions.UserDefinedVirtualAttributeProvider"); |
| | |
| | | "cn=test child new,cn=test children,cn=test parent 2,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | c.addExpectedAttribute("cn", "test child new"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child-dummy"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-class", |
| | | "org.opends.server.extensions.UserDefinedVirtualAttributeProvider"); |
| | |
| | | @Test |
| | | public void testAddConstraintSuccess() throws Exception { |
| | | Constraint constraint = new MockConstraint(true, false, false); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | TestCfg.addConstraint(constraint); |
| | | |
| | | try { |
| | | CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection( |
| | | "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | c.addExpectedAttribute("cn", "test child new"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child-dummy"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-class", |
| | | "org.opends.server.extensions.UserDefinedVirtualAttributeProvider"); |
| | |
| | | c.assertEntryIsCreated(); |
| | | } finally { |
| | | // Clean up. |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | TestCfg.removeConstraint(constraint); |
| | | } |
| | | } |
| | | |
| | |
| | | @Test(expectedExceptions=OperationRejectedException.class) |
| | | public void testAddConstraintFail() throws Exception { |
| | | Constraint constraint = new MockConstraint(false, true, true); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | TestCfg.addConstraint(constraint); |
| | | |
| | | try { |
| | | CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection( |
| | | "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | c.addExpectedAttribute("cn", "test child new"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child-dummy"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-class", |
| | | "org.opends.server.extensions.UserDefinedVirtualAttributeProvider"); |
| | |
| | | Assert.fail("The add constraint failed to prevent creation of the managed object"); |
| | | } finally { |
| | | // Clean up. |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | TestCfg.removeConstraint(constraint); |
| | | } |
| | | } |
| | | |
| | |
| | | @Test |
| | | public void testRemoveConstraintSuccess() throws Exception { |
| | | Constraint constraint = new MockConstraint(false, false, true); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | TestCfg.addConstraint(constraint); |
| | | |
| | | try { |
| | | DeleteSubtreeMockLDAPConnection c = new DeleteSubtreeMockLDAPConnection( |
| | |
| | | c.assertSubtreeIsDeleted(); |
| | | } finally { |
| | | // Clean up. |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | TestCfg.removeConstraint(constraint); |
| | | } |
| | | } |
| | | |
| | |
| | | @Test(expectedExceptions=OperationRejectedException.class) |
| | | public void testRemoveConstraintFail() throws Exception { |
| | | Constraint constraint = new MockConstraint(true, true, false); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | TestCfg.addConstraint(constraint); |
| | | |
| | | try { |
| | | DeleteSubtreeMockLDAPConnection c = new DeleteSubtreeMockLDAPConnection( |
| | |
| | | Assert.fail("The remove constraint failed to prevent removal of the managed object"); |
| | | } finally { |
| | | // Clean up. |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | TestCfg.removeConstraint(constraint); |
| | | } |
| | | } |
| | | |
| | |
| | | @Test |
| | | public void testModifyConstraintSuccess() throws Exception { |
| | | Constraint constraint = new MockConstraint(false, true, false); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | TestCfg.addConstraint(constraint); |
| | | |
| | | try { |
| | | ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection( |
| | |
| | | Assert.assertTrue(c.isEntryModified()); |
| | | } finally { |
| | | // Clean up. |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | TestCfg.removeConstraint(constraint); |
| | | } |
| | | } |
| | | |
| | |
| | | @Test(expectedExceptions = OperationRejectedException.class) |
| | | public void testModifyConstraintFail() throws Exception { |
| | | Constraint constraint = new MockConstraint(true, false, true); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | TestCfg.addConstraint(constraint); |
| | | |
| | | try { |
| | | ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection( |
| | |
| | | .fail("The modify constraint failed to prevent modification of the managed object"); |
| | | } finally { |
| | | // Clean up. |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | TestCfg.removeConstraint(constraint); |
| | | } |
| | | } |
| | | |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * 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 |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.admin.server; |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | |
| | | import javax.naming.ldap.LdapName; |
| | | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.AdminTestCase; |
| | | import org.opends.server.admin.IllegalPropertyValueStringException; |
| | | import org.opends.server.admin.PropertyException; |
| | | 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.client.ldap.JNDIDirContextAdaptor; |
| | | import org.opends.server.admin.std.server.RootCfg; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.core.DirectoryServer; |
| | | 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(sequential=true) |
| | | public final class AggregationTest extends AdminTestCase { |
| | | |
| | | // 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-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | | "ds-cfg-virtual-attribute-type: description", |
| | | "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real" |
| | | }; |
| | | |
| | | |
| | | |
| | | // 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]); |
| | | } |
| | | |
| | | // 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-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | | "ds-cfg-virtual-attribute-type: description", |
| | | "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real", |
| | | "ds-cfg-backend-base-dn: cn=LDAP Connection Handler, cn=connection handlers, cn=config" |
| | | }; |
| | | |
| | | |
| | | |
| | | // 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 "); |
| | | } |
| | | |
| | | // 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-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | | "ds-cfg-virtual-attribute-type: description", |
| | | "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real", |
| | | "ds-cfg-backend-base-dn: 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-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | | "ds-cfg-virtual-attribute-type: description", |
| | | "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real", |
| | | "ds-cfg-backend-base-dn: cn=LDAP Connection Handler, cn=connection handlers, cn=config", |
| | | "ds-cfg-backend-base-dn: cn=LDAPS Connection Handler, cn=connection handlers, cn=config" |
| | | }; |
| | | |
| | | |
| | | |
| | | // 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"); |
| | | } |
| | | |
| | | // 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-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | | "ds-cfg-virtual-attribute-type: description", |
| | | "ds-cfg-virtual-attribute-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", |
| | | "" |
| | | }; |
| | | |
| | | // JNDI LDAP context. |
| | | private JNDIDirContextAdaptor adaptor = null; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets up tests |
| | | * |
| | | * @throws Exception |
| | | * If the server could not be initialized. |
| | | */ |
| | | @BeforeClass |
| | | public void setUp() throws Exception { |
| | | // This test suite depends on having the schema available, so |
| | | // we'll start the server. |
| | | TestCaseUtils.startServer(); |
| | | TestCfg.setUp(); |
| | | |
| | | // Add test managed objects. |
| | | TestCaseUtils.addEntries(TEST_LDIF); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tears down test environment. |
| | | * |
| | | * @throws Exception |
| | | * If the test entries could not be removed. |
| | | */ |
| | | @AfterClass |
| | | public void tearDown() throws Exception { |
| | | TestCfg.cleanup(); |
| | | |
| | | // Remove test entries. |
| | | deleteSubtree("cn=test parents,cn=config"); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 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 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<PropertyException> 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 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"); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // Asserts that the actual set of DNs contains the expected values. |
| | | private void assertSetEquals(SortedSet<String> actual, String... expected) { |
| | | SortedSet<String> values = new TreeSet<String>(TestChildCfgDefn |
| | | .getInstance().getAggregationPropertyPropertyDefinition()); |
| | | if (expected != null) { |
| | | for (String value : expected) { |
| | | values.add(value); |
| | | } |
| | | } |
| | | Assert.assertEquals((Object) actual, (Object) values); |
| | | } |
| | | |
| | | |
| | | |
| | | // Deletes the named sub-tree. |
| | | private void deleteSubtree(String dn) throws Exception { |
| | | getAdaptor().deleteSubtree(new LdapName(dn)); |
| | | } |
| | | |
| | | |
| | | |
| | | // Gets the JNDI connection for the test server instance. |
| | | private synchronized JNDIDirContextAdaptor getAdaptor() throws Exception { |
| | | if (adaptor == null) { |
| | | adaptor = JNDIDirContextAdaptor.simpleBind("127.0.0.1", TestCaseUtils |
| | | .getServerLdapPort(), "cn=directory manager", "password"); |
| | | } |
| | | return adaptor; |
| | | } |
| | | |
| | | |
| | | |
| | | // Gets the named parent configuration. |
| | | private TestParentCfg getParent(String name) throws IllegalArgumentException, |
| | | ConfigException { |
| | | ServerManagementContext ctx = ServerManagementContext.getInstance(); |
| | | ServerManagedObject<RootCfg> root = ctx.getRootConfigurationManagedObject(); |
| | | TestParentCfg parent = root.getChild( |
| | | TestCfg.getTestOneToManyParentRelationDefinition(), name) |
| | | .getConfiguration(); |
| | | return parent; |
| | | } |
| | | } |
| | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.AdminTestCase; |
| | | import org.opends.server.admin.LDAPProfile; |
| | | import org.opends.server.admin.MockLDAPProfile; |
| | | 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.client.ldap.JNDIDirContextAdaptor; |
| | | import org.opends.server.admin.std.server.RootCfg; |
| | |
| | | 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-virtual-attribute", |
| | | "objectclass: ds-cfg-test-child-dummy", |
| | | "cn: test child 1", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | // optional-multi-valued-dn-property. |
| | | "dn: cn=test parent 1,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-virtual-attribute", |
| | | "objectclass: ds-cfg-test-parent-dummy", |
| | | "cn: test parent 1", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | // This test suite depends on having the schema available, so |
| | | // we'll start the server. |
| | | TestCaseUtils.startServer(); |
| | | LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile()); |
| | | TestCfg.setUp(); |
| | | |
| | | // Add test managed objects. |
| | | TestCaseUtils.addEntries(TEST_LDIF); |
| | |
| | | */ |
| | | @AfterClass |
| | | public void tearDown() throws Exception { |
| | | LDAPProfile.getInstance().popWrapper(); |
| | | TestCfg.cleanup(); |
| | | |
| | | // Remove test entries. |
| | |
| | | parent.addTestChildAddListener(listener); |
| | | |
| | | MockConstraint constraint = new MockConstraint(true, false, false); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | TestCfg.addConstraint(constraint); |
| | | |
| | | try { |
| | | try { |
| | |
| | | } |
| | | } |
| | | } finally { |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | TestCfg.removeConstraint(constraint); |
| | | parent.removeTestChildAddListener(listener); |
| | | } |
| | | } |
| | |
| | | parent.addTestChildAddListener(listener); |
| | | |
| | | MockConstraint constraint = new MockConstraint(false, true, true); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | TestCfg.addConstraint(constraint); |
| | | |
| | | try { |
| | | try { |
| | |
| | | } |
| | | } |
| | | } finally { |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | TestCfg.removeConstraint(constraint); |
| | | parent.removeTestChildAddListener(listener); |
| | | } |
| | | } |
| | |
| | | parent.addTestChildDeleteListener(listener); |
| | | |
| | | MockConstraint constraint = new MockConstraint(false, false, true); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | TestCfg.addConstraint(constraint); |
| | | |
| | | try { |
| | | // Add the entry. |
| | |
| | | // Now delete it - this should trigger the constraint. |
| | | deleteSubtree(TEST_CHILD_1_DN); |
| | | } finally { |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | TestCfg.removeConstraint(constraint); |
| | | parent.removeTestChildDeleteListener(listener); |
| | | |
| | | try { |
| | |
| | | parent.addTestChildDeleteListener(listener); |
| | | |
| | | MockConstraint constraint = new MockConstraint(true, true, false); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | TestCfg.addConstraint(constraint); |
| | | |
| | | try { |
| | | // Add the entry. |
| | |
| | | // Ignore - this is the expected exception. |
| | | } |
| | | } finally { |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | TestCfg.removeConstraint(constraint); |
| | | parent.removeTestChildDeleteListener(listener); |
| | | |
| | | try { |
| | |
| | | TestParentCfg parent = getParent("test parent 1"); |
| | | |
| | | MockConstraint constraint = new MockConstraint(false, true, false); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | TestCfg.addConstraint(constraint); |
| | | |
| | | try { |
| | | // Add the entry. |
| | |
| | | int result = TestCaseUtils.applyModifications(changes); |
| | | Assert.assertEquals(result, ResultCode.SUCCESS.getIntValue()); |
| | | } finally { |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | TestCfg.removeConstraint(constraint); |
| | | try { |
| | | deleteSubtree(TEST_CHILD_1_DN); |
| | | } catch (Exception e) { |
| | |
| | | TestParentCfg parent = getParent("test parent 1"); |
| | | |
| | | MockConstraint constraint = new MockConstraint(true, false, true); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | TestCfg.addConstraint(constraint); |
| | | |
| | | try { |
| | | // Add the entry. |
| | |
| | | Assert |
| | | .assertEquals(result, ResultCode.UNWILLING_TO_PERFORM.getIntValue()); |
| | | } finally { |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | TestCfg.removeConstraint(constraint); |
| | | try { |
| | | deleteSubtree(TEST_CHILD_1_DN); |
| | | } catch (Exception e) { |
| | |
| | | import org.opends.server.admin.ConfigurationClient; |
| | | import org.opends.server.admin.LDAPProfile; |
| | | import org.opends.server.admin.ManagedObjectPath; |
| | | import org.opends.server.admin.MockLDAPProfile; |
| | | import org.opends.server.admin.RelationDefinition; |
| | | import org.opends.server.admin.SingletonRelationDefinition; |
| | | import org.opends.server.admin.TestCfg; |
| | |
| | | // This test suite depends on having the schema available, so |
| | | // we'll start the server. |
| | | TestCaseUtils.startServer(); |
| | | LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile()); |
| | | TestCfg.setUp(); |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | @AfterClass |
| | | public void tearDown() { |
| | | LDAPProfile.getInstance().popWrapper(); |
| | | TestCfg.cleanup(); |
| | | } |
| | | |
| | |
| | | |
| | | import javax.naming.ldap.LdapName; |
| | | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.AdminTestCase; |
| | | import org.opends.server.admin.LDAPProfile; |
| | | import org.opends.server.admin.MockLDAPProfile; |
| | | import org.opends.server.admin.TestCfg; |
| | | import org.opends.server.admin.TestChildCfg; |
| | | import org.opends.server.admin.TestParentCfg; |
| | |
| | | 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-virtual-attribute", |
| | | "objectclass: ds-cfg-test-child-dummy", |
| | | "cn: test child 1", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | 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-virtual-attribute", |
| | | "objectclass: ds-cfg-test-child-dummy", |
| | | "cn: test child 2", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | 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-virtual-attribute", |
| | | "objectclass: ds-cfg-test-child-dummy", |
| | | "cn: test child 3", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | private static final String[] TEST_CHILD_4 = new String[] { |
| | | "dn: cn=test child 4,cn=test children,cn=test parent 2,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-virtual-attribute", |
| | | "objectclass: ds-cfg-test-child-dummy", |
| | | "cn: test child 4", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | // optional-multi-valued-dn-property. |
| | | "dn: cn=test parent 1,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-virtual-attribute", |
| | | "objectclass: ds-cfg-test-parent-dummy", |
| | | "cn: test parent 1", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | // optional-multi-valued-dn-property. |
| | | "dn: cn=test parent 2,cn=test parents,cn=config", |
| | | "objectclass: top", |
| | | "objectclass: ds-cfg-virtual-attribute", |
| | | "objectclass: ds-cfg-test-parent-dummy", |
| | | "cn: test parent 2", |
| | | "ds-cfg-virtual-attribute-enabled: true", |
| | | "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider", |
| | |
| | | // This test suite depends on having the schema available, so |
| | | // we'll start the server. |
| | | TestCaseUtils.startServer(); |
| | | LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile()); |
| | | TestCfg.setUp(); |
| | | |
| | | // Add test managed objects. |
| | | TestCaseUtils.addEntries(TEST_LDIF); |
| | |
| | | */ |
| | | @AfterClass |
| | | public void tearDown() throws Exception { |
| | | LDAPProfile.getInstance().popWrapper(); |
| | | TestCfg.cleanup(); |
| | | |
| | | // Remove test entries. |
| | |
| | | |
| | | import java.util.List; |
| | | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.AdminTestCase; |
| | | import org.opends.server.admin.LDAPProfile; |
| | | import org.opends.server.admin.MockLDAPProfile; |
| | | import org.opends.server.admin.TestCfg; |
| | | import org.opends.server.admin.TestParentCfg; |
| | | import org.opends.server.admin.std.server.RootCfg; |
| | |
| | | // This test suite depends on having the schema available, so |
| | | // we'll start the server. |
| | | TestCaseUtils.startServer(); |
| | | LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile()); |
| | | TestCfg.setUp(); |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | @AfterClass |
| | | public void tearDown() { |
| | | LDAPProfile.getInstance().popWrapper(); |
| | | TestCfg.cleanup(); |
| | | } |
| | | |