From 95df5cfdba474acb03076953e992b898fbb277a8 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Mon, 02 Feb 2009 23:37:54 +0000
Subject: [PATCH] Fix issue 3734 - Make network group policies extensible.
---
opends/src/server/org/opends/server/admin/AdminException.java | 9
opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java | 4
opends/src/server/org/opends/server/core/networkgroups/NetworkGroupConfigManager.java | 508 -
opends/src/server/org/opends/server/core/networkgroups/NetworkGroupPlugin.java | 16
opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml | 6
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/ANDConnectionCriteriaTest.java | 140
opends/src/server/org/opends/server/admin/server/ServerManagementContext.java | 63
opends/src/server/org/opends/server/core/networkgroups/ProtocolConnectionCriteria.java | 109
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockRequestFilteringQOSPolicyCfg.java | 189
opends/src/server/org/opends/server/core/networkgroups/NetworkGroup.java | 2777 ++++++++----
opends/src/admin/defn/org/opends/server/admin/std/QOSPolicyConfiguration.xml | 69
opends/src/server/org/opends/server/core/networkgroups/IPConnectionCriteria.java | 114
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliGlobalAdmin.java | 20
opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java | 346 +
opends/resource/schema/02-config.ldif | 95
opends/src/admin/defn/org/opends/server/admin/std/RequestFilteringQOSPolicyConfiguration.xml | 138
opends/src/server/org/opends/server/api/QOSPolicy.java | 30
opends/src/server/org/opends/server/admin/client/cli/SecureConnectionCliParser.java | 25
opends/src/server/org/opends/server/tools/dsconfig/GetPropSubCommandHandler.java | 24
opends/src/admin/defn/org/opends/server/admin/std/Package.xml | 80
opends/src/server/org/opends/server/admin/OptionalRelationDefinition.java | 5
opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicy.java | 135
opends/src/admin/defn/org/opends/server/admin/std/ResourceLimitsQOSPolicyConfiguration.xml | 225 +
opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandlerFactory.java | 62
opends/src/server/org/opends/server/admin/client/ManagedObject.java | 205
opends/src/server/org/opends/server/admin/doc/ConfigGuideGeneration.java | 61
opends/resource/config/config.ldif | 4
opends/src/server/org/opends/server/admin/SetRelationDefinition.java | 289 +
opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml | 10
opends/src/server/org/opends/server/admin/ManagedObjectPath.java | 212
opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java | 48
opends/src/server/org/opends/server/tools/dsconfig/DeleteSubCommandHandler.java | 58
opends/resource/admin/metaMO.xsl | 69
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServer.java | 20
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyTest.java | 160
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockResourceLimitsQOSPolicyCfg.java | 191
opends/src/server/org/opends/server/admin/InstantiableRelationDefinition.java | 7
opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyFactory.java | 672 +++
opends/src/server/org/opends/server/core/networkgroups/AuthMethodConnectionCriteria.java | 142
opends/src/admin/defn/org/opends/server/admin/std/ConnectionHandlerConfiguration.xml | 82
opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java | 134
opends/src/server/org/opends/server/admin/ManagedObjectPathSerializer.java | 24
opends/src/server/org/opends/server/admin/RelationDefinitionVisitor.java | 22
opends/src/server/org/opends/server/core/networkgroups/ANDConnectionCriteria.java | 104
opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyStatistics.java | 155
opends/src/server/org/opends/server/tools/dsconfig/CLIProfile.java | 24
opends/resource/admin/admin.xsd | 13
opends/resource/admin/clientMO.xsl | 90
opends/src/server/org/opends/server/admin/client/ManagementContext.java | 99
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/IPConnectionCriteriaTest.java | 157
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/AuthMethodConnectionCriteriaTest.java | 202
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/BindDNConnectionCriteriaTest.java | 156
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java | 177
opends/src/messages/messages/config.properties | 7
opends/src/server/org/opends/server/admin/SingletonRelationDefinition.java | 5
opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyFactory.java | 496 ++
opends/src/server/org/opends/server/admin/client/spi/Driver.java | 187
opends/src/server/org/opends/server/tools/dsconfig/ListSubCommandHandler.java | 69
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/SecurityConnectionCriteriaTest.java | 136
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java | 25
opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java | 22
opends/src/server/org/opends/server/admin/server/ConfigAddListenerAdaptor.java | 71
opends/src/server/org/opends/server/api/QOSPolicyFactory.java | 89
opends/src/server/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java | 71
opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java | 10
opends/src/server/org/opends/server/core/networkgroups/ConnectionCriteria.java | 139
opends/src/server/org/opends/server/admin/server/ServerManagedObject.java | 270 +
opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupConfiguration.xml | 305
opends/src/server/org/opends/server/admin/AdminRuntimeException.java | 9
opends/src/server/org/opends/server/admin/client/AdminSecurityException.java | 9
opends/src/server/org/opends/server/core/networkgroups/NetworkGroupStatistics.java | 58
opends/src/messages/messages/dsconfig.properties | 6
opends/src/server/org/opends/server/admin/LDAPProfile.java | 67
opends/src/server/org/opends/server/core/networkgroups/BindDNConnectionCriteria.java | 138
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockClientConnection.java | 374 +
opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicy.java | 632 --
/dev/null | 75
opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupPluginConfiguration.xml | 6
opends/src/server/org/opends/server/admin/DecodingException.java | 9
opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java | 58
opends/src/server/org/opends/server/api/ClientConnection.java | 33
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyTest.java | 86
opends/src/server/org/opends/server/admin/RelationDefinition.java | 8
opends/resource/admin/abbreviations.xsl | 4
opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java | 23
opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java | 4
opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java | 292
opends/src/server/org/opends/server/core/networkgroups/SecurityConnectionCriteria.java | 99
opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyStatistics.java | 121
89 files changed, 9,630 insertions(+), 3,159 deletions(-)
diff --git a/opends/resource/admin/abbreviations.xsl b/opends/resource/admin/abbreviations.xsl
index 64d52d2..4e38ab4 100644
--- a/opends/resource/admin/abbreviations.xsl
+++ b/opends/resource/admin/abbreviations.xsl
@@ -22,7 +22,7 @@
! CDDL HEADER END
!
!
- ! Copyright 2008 Sun Microsystems, Inc.
+ ! Copyright 2008-2009 Sun Microsystems, Inc.
! -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
@@ -52,7 +52,7 @@
or $value = 'md5' or $value = 'sha1' or $value = 'sha256'
or $value = 'sha384' or $value = 'sha512' or $value = 'tls'
or $value = 'des' or $value = 'aes' or $value = 'rc4'
- or $value = 'db' or $value = 'snmp'
+ or $value = 'db' or $value = 'snmp' or $value = 'qos'
"/>
</xsl:template>
</xsl:stylesheet>
diff --git a/opends/resource/admin/admin.xsd b/opends/resource/admin/admin.xsd
index ace9c9c..7eef037 100644
--- a/opends/resource/admin/admin.xsd
+++ b/opends/resource/admin/admin.xsd
@@ -791,6 +791,19 @@
</xsd:complexType>
</xsd:element>
</xsd:sequence>
+ <xsd:attribute name="unique" type="xsd:boolean"
+ use="optional" default="false">
+ <xsd:annotation>
+ <xsd:documentation>
+ Indicates whether or not this relation contains
+ unique members. If set to true then each
+ referenced managed object must have a distinct type.
+ In other words, there must not be more than one
+ referenced managed object having the same type. By
+ default, properties are single-valued.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
<xsd:attribute name="plural-name" type="tns:name-type"
use="optional">
<xsd:annotation>
diff --git a/opends/resource/admin/clientMO.xsl b/opends/resource/admin/clientMO.xsl
index e9bdee3..bc2b893 100644
--- a/opends/resource/admin/clientMO.xsl
+++ b/opends/resource/admin/clientMO.xsl
@@ -22,7 +22,7 @@
! CDDL HEADER END
!
!
- ! Copyright 2008 Sun Microsystems, Inc.
+ ! Copyright 2008-2009 Sun Microsystems, Inc.
! -->
<xsl:stylesheet version="1.0" xmlns:adm="http://www.opends.org/admin"
xmlns:admpp="http://www.opends.org/admin-preprocessor"
@@ -285,34 +285,64 @@
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:call-template name="add-java-comment2">
- <xsl:with-param name="indent" select="2" />
- <xsl:with-param name="content"
- select="concat(
- 'Creates a new ', $ufn,'. The new ', $ufn,' will initially ',
- 'not contain any property values (including mandatory ',
- 'properties). Once the ', $ufn,' has been configured it ',
- 'can be added to the server using the {@link #commit()} ',
- 'method.
',
- '
',
- '@param <C>
',
- ' The type of the ', $ufn,' being created.
',
- '@param d
',
- ' The definition of the ', $ufn,' to be created.
',
- '@param name
',
- ' The name of the new ', $ufn,'.
',
- '@param exceptions
',
- ' An optional collection in which to place any ',
- '{@link DefaultBehaviorException}s that occurred whilst ',
- 'attempting to determine the default values of the ', $ufn,
- '. This argument can be <code>null<code>.
',
- '@return Returns a new ', $ufn,' configuration instance.
',
- '@throws IllegalManagedObjectNameException
',
- ' If the name of the new ', $ufn,' is invalid.
')" />
- </xsl:call-template>
- <xsl:value-of
- select="concat(' <C extends ', $java-class-name,'CfgClient> C create', $java-relation-name, '(
',
- ' ManagedObjectDefinition<C, ? extends ', $java-class-name,'Cfg> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException;
')" />
+ <xsl:choose>
+ <xsl:when test="string(adm:one-to-many/@unique) != 'true'">
+ <xsl:call-template name="add-java-comment2">
+ <xsl:with-param name="indent" select="2" />
+ <xsl:with-param name="content"
+ select="concat(
+ 'Creates a new ', $ufn,'. The new ', $ufn,' will initially ',
+ 'not contain any property values (including mandatory ',
+ 'properties). Once the ', $ufn,' has been configured it ',
+ 'can be added to the server using the {@link #commit()} ',
+ 'method.
',
+ '
',
+ '@param <C>
',
+ ' The type of the ', $ufn,' being created.
',
+ '@param d
',
+ ' The definition of the ', $ufn,' to be created.
',
+ '@param name
',
+ ' The name of the new ', $ufn,'.
',
+ '@param exceptions
',
+ ' An optional collection in which to place any ',
+ '{@link DefaultBehaviorException}s that occurred whilst ',
+ 'attempting to determine the default values of the ', $ufn,
+ '. This argument can be <code>null<code>.
',
+ '@return Returns a new ', $ufn,' configuration instance.
',
+ '@throws IllegalManagedObjectNameException
',
+ ' If the name of the new ', $ufn,' is invalid.
')" />
+ </xsl:call-template>
+ <xsl:value-of
+ select="concat(' <C extends ', $java-class-name,'CfgClient> C create', $java-relation-name, '(
',
+ ' ManagedObjectDefinition<C, ? extends ', $java-class-name,'Cfg> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException;
')" />
+ </xsl:when>
+ <xsl:when test="string(adm:one-to-many/@unique) = 'true'">
+ <xsl:call-template name="add-java-comment2">
+ <xsl:with-param name="indent" select="2" />
+ <xsl:with-param name="content"
+ select="concat(
+ 'Creates a new ', $ufn,'. The new ', $ufn,' will initially ',
+ 'not contain any property values (including mandatory ',
+ 'properties). Once the ', $ufn,' has been configured it ',
+ 'can be added to the server using the {@link #commit()} ',
+ 'method.
',
+ '
',
+ '@param <C>
',
+ ' The type of the ', $ufn,' being created.
',
+ '@param d
',
+ ' The definition of the ', $ufn,' to be created.
',
+ '@param exceptions
',
+ ' An optional collection in which to place any ',
+ '{@link DefaultBehaviorException}s that occurred whilst ',
+ 'attempting to determine the default values of the ', $ufn,
+ '. This argument can be <code>null<code>.
',
+ '@return Returns a new ', $ufn,' configuration instance.
')" />
+ </xsl:call-template>
+ <xsl:value-of
+ select="concat(' <C extends ', $java-class-name,'CfgClient> C create', $java-relation-name, '(
',
+ ' ManagedObjectDefinition<C, ? extends ', $java-class-name,'Cfg> d, Collection<DefaultBehaviorException> exceptions);
')" />
+ </xsl:when>
+ </xsl:choose>
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
@@ -424,7 +454,7 @@
org.opends.server.admin.client.OperationRejectedException
</import>
</xsl:if>
- <xsl:if test="$this-local-relations/adm:one-to-many">
+ <xsl:if test="$this-local-relations/adm:one-to-many[not(@unique = 'true')]">
<import>
org.opends.server.admin.client.IllegalManagedObjectNameException
</import>
diff --git a/opends/resource/admin/metaMO.xsl b/opends/resource/admin/metaMO.xsl
index 469d41c..c6a57d6 100644
--- a/opends/resource/admin/metaMO.xsl
+++ b/opends/resource/admin/metaMO.xsl
@@ -22,7 +22,7 @@
! CDDL HEADER END
!
!
- ! Copyright 2007-2008 Sun Microsystems, Inc.
+ ! Copyright 2007-2009 Sun Microsystems, Inc.
! -->
<xsl:stylesheet version="1.0" xmlns:adm="http://www.opends.org/admin"
xmlns:admpp="http://www.opends.org/admin-preprocessor"
@@ -848,9 +848,12 @@
<xsl:when test="adm:one-to-zero-or-one">
<xsl:text>OptionalRelationDefinition<</xsl:text>
</xsl:when>
- <xsl:when test="adm:one-to-many">
+ <xsl:when test="string(adm:one-to-many/@unique) != 'true'">
<xsl:text>InstantiableRelationDefinition<</xsl:text>
</xsl:when>
+ <xsl:when test="string(adm:one-to-many/@unique) = 'true'">
+ <xsl:text>SetRelationDefinition<</xsl:text>
+ </xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
<xsl:value-of
@@ -893,9 +896,12 @@
<xsl:when test="adm:one-to-zero-or-one">
<xsl:text>OptionalRelationDefinition</xsl:text>
</xsl:when>
- <xsl:when test="adm:one-to-many">
+ <xsl:when test="string(adm:one-to-many/@unique) != 'true'">
<xsl:text>InstantiableRelationDefinition</xsl:text>
</xsl:when>
+ <xsl:when test="string(adm:one-to-many/@unique) = 'true'">
+ <xsl:text>SetRelationDefinition</xsl:text>
+ </xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
<xsl:value-of
@@ -918,6 +924,12 @@
<xsl:value-of
select="concat($java-managed-object-name, 'CfgDefn.getInstance());
')" />
<xsl:if test="adm:one-to-many/@naming-property">
+ <xsl:if test="string(adm:one-to-many/@unique) = 'true'">
+ <xsl:message terminate="yes">
+ <xsl:value-of
+ select="concat('Naming properties found in unique one-to-many relation "', @name, '".')" />
+ </xsl:message>
+ </xsl:if>
<xsl:variable name="java-property-name">
<xsl:call-template name="name-to-java">
<xsl:with-param name="value"
@@ -1111,9 +1123,12 @@
<xsl:when test="adm:one-to-zero-or-one">
<xsl:text>OptionalRelationDefinition<</xsl:text>
</xsl:when>
- <xsl:when test="adm:one-to-many">
+ <xsl:when test="string(adm:one-to-many/@unique) != 'true'">
<xsl:text>InstantiableRelationDefinition<</xsl:text>
</xsl:when>
+ <xsl:when test="string(adm:one-to-many/@unique) = 'true'">
+ <xsl:text>SetRelationDefinition<</xsl:text>
+ </xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
<xsl:value-of
@@ -1259,14 +1274,29 @@
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:value-of
- select="concat(' /**
',
- ' * {@inheritDoc}
',
- ' */
',
- ' public <M extends ', $java-class-name, 'CfgClient> M create', $java-relation-name, '(
',
- ' ManagedObjectDefinition<M, ? extends ', $java-class-name,'Cfg> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException {
',
- ' return impl.createChild(INSTANCE.get', $java-relation-plural-name,'RelationDefinition(), d, name, exceptions).getConfiguration();
',
- ' }
')" />
+ <xsl:choose>
+ <xsl:when test="string(adm:one-to-many/@unique) != 'true'">
+ <xsl:value-of
+ select="concat(' /**
',
+ ' * {@inheritDoc}
',
+ ' */
',
+ ' public <M extends ', $java-class-name, 'CfgClient> M create', $java-relation-name, '(
',
+ ' ManagedObjectDefinition<M, ? extends ', $java-class-name,'Cfg> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException {
',
+ ' return impl.createChild(INSTANCE.get', $java-relation-plural-name,'RelationDefinition(), d, name, exceptions).getConfiguration();
',
+ ' }
')" />
+ </xsl:when>
+ <xsl:when test="string(adm:one-to-many/@unique) = 'true'">
+ <!-- Unique one-to-many children are named implicitly by their definition -->
+ <xsl:value-of
+ select="concat(' /**
',
+ ' * {@inheritDoc}
',
+ ' */
',
+ ' public <M extends ', $java-class-name, 'CfgClient> M create', $java-relation-name, '(
',
+ ' ManagedObjectDefinition<M, ? extends ', $java-class-name,'Cfg> d, Collection<DefaultBehaviorException> exceptions) {
',
+ ' return impl.createChild(INSTANCE.get', $java-relation-plural-name,'RelationDefinition(), d, exceptions).getConfiguration();
',
+ ' }
')" />
+ </xsl:when>
+ </xsl:choose>
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
@@ -1841,11 +1871,16 @@
<xsl:if test="$this-is-hidden or $this-is-advanced">
<import>org.opends.server.admin.ManagedObjectOption</import>
</xsl:if>
- <xsl:if test="$this-all-relations/adm:one-to-many">
+ <xsl:if test="$this-all-relations/adm:one-to-many[not(@unique = 'true')]">
<import>
org.opends.server.admin.InstantiableRelationDefinition
</import>
</xsl:if>
+ <xsl:if test="$this-all-relations/adm:one-to-many[@unique = 'true']">
+ <import>
+ org.opends.server.admin.SetRelationDefinition
+ </import>
+ </xsl:if>
<xsl:if test="$this-all-relations/adm:one-to-zero-or-one">
<import>
org.opends.server.admin.OptionalRelationDefinition
@@ -1912,9 +1947,11 @@
</xsl:if>
<xsl:if test="$this-all-relations/adm:one-to-many">
<import>java.util.Collection</import>
- <import>
- org.opends.server.admin.client.IllegalManagedObjectNameException
- </import>
+ <xsl:if test="$this-all-relations/adm:one-to-many[not(@unique = 'true')]">
+ <import>
+ org.opends.server.admin.client.IllegalManagedObjectNameException
+ </import>
+ </xsl:if>
<import>
org.opends.server.admin.DefaultBehaviorException
</import>
diff --git a/opends/resource/config/config.ldif b/opends/resource/config/config.ldif
index 9f6f82a..f9f22d2 100644
--- a/opends/resource/config/config.ldif
+++ b/opends/resource/config/config.ldif
@@ -20,7 +20,7 @@
#
# CDDL HEADER END
#
-# Copyright 2006-2008 Sun Microsystems, Inc.
+# Copyright 2006-2009 Sun Microsystems, Inc.
#
#
# This file contains the primary Directory Server configuration. It must not
@@ -1796,7 +1796,7 @@
objectClass: ds-cfg-plugin
objectClass: ds-cfg-network-group-plugin
cn: Network Group
-ds-cfg-java-class: org.opends.server.plugins.NetworkGroupPlugin
+ds-cfg-java-class: org.opends.server.core.networkgroups.NetworkGroupPlugin
ds-cfg-enabled: true
ds-cfg-invoke-for-internal-operations: false
ds-cfg-plugin-type: postConnect
diff --git a/opends/resource/schema/02-config.ldif b/opends/resource/schema/02-config.ldif
index 93aafcb..3064dde 100644
--- a/opends/resource/schema/02-config.ldif
+++ b/opends/resource/schema/02-config.ldif
@@ -2103,11 +2103,6 @@
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE
X-ORIGIN 'OpenDS Directory Server' )
-attributeTypes: ( 1.3.6.1.4.1.26027.1.1.435
- NAME 'ds-cfg-network-group-id'
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- SINGLE-VALUE
- X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.436
NAME 'ds-cfg-workflow-id'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
@@ -2225,15 +2220,11 @@
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.462
- NAME 'ds-cfg-allowed-ldap-port'
+ NAME 'ds-cfg-allowed-protocol'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.463
- NAME 'ds-cfg-bind-dn-filter'
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- X-ORIGIN 'OpenDS Directory Server' )
-attributeTypes: ( 1.3.6.1.4.1.26027.1.1.464
- NAME 'ds-cfg-ip-address-filter'
+ NAME 'ds-cfg-allowed-bind-dn'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.465
@@ -2241,11 +2232,6 @@
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
SINGLE-VALUE
X-ORIGIN 'OpenDS Directory Server' )
-attributeTypes: ( 1.3.6.1.4.1.26027.1.1.466
- NAME 'ds-cfg-user-entry-filter'
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- SINGLE-VALUE
- X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.467
NAME 'ds-cfg-priority'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
@@ -2271,36 +2257,11 @@
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
SINGLE-VALUE
X-ORIGIN 'OpenDS Directory Server' )
-attributeTypes: ( 1.3.6.1.4.1.26027.1.1.472
- NAME 'ds-cfg-search-size-limit'
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- X-ORIGIN 'OpenDS Directory Server' )
-attributeTypes: ( 1.3.6.1.4.1.26027.1.1.473
- NAME 'ds-cfg-search-time-limit'
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- SINGLE-VALUE
- X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.474
NAME 'ds-cfg-min-substring-length'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
SINGLE-VALUE
X-ORIGIN 'OpenDS Directory Server' )
-attributeTypes: ( 1.3.6.1.4.1.26027.1.1.475
- NAME 'ds-cfg-referral-policy'
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- SINGLE-VALUE
- X-ORIGIN 'OpenDS Directory Server' )
-attributeTypes: ( 1.3.6.1.4.1.26027.1.1.476
- NAME 'ds-cfg-referral-bind-policy'
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- SINGLE-VALUE
- X-ORIGIN 'OpenDS Directory Server' )
-attributeTypes: ( 1.3.6.1.4.1.26027.1.1.477
- NAME 'ds-cfg-referral-hop-limit'
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.478
NAME 'ds-cfg-assured-type'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
@@ -2377,16 +2338,6 @@
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE
X-ORIGIN 'OpenDS Directory Server' )
-attributeTypes: ( 1.3.6.1.4.1.26027.1.1.516
- NAME 'ds-cfg-affinity-policy'
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- SINGLE-VALUE
- X-ORIGIN 'OpenDS Directory Server' )
-attributeTypes: ( 1.3.6.1.4.1.26027.1.1.517
- NAME 'ds-cfg-affinity-timeout'
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- SINGLE-VALUE
- X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.518
NAME 'ds-cfg-index-extensible-matching-rule'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
@@ -3876,12 +3827,16 @@
NAME 'ds-cfg-network-group'
SUP top
STRUCTURAL
- MUST ( ds-cfg-network-group-id $
+ MUST ( cn $
ds-cfg-priority $
ds-cfg-enabled )
MAY ( ds-cfg-workflow $
- ds-cfg-affinity-policy $
- ds-cfg-affinity-timeout )
+ ds-cfg-allowed-auth-method $
+ ds-cfg-allowed-protocol $
+ ds-cfg-allowed-bind-dn $
+ ds-cfg-allowed-client $
+ ds-cfg-denied-client $
+ ds-cfg-is-security-mandatory )
X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.177
NAME 'ds-cfg-workflow'
@@ -3941,33 +3896,24 @@
ds-cfg-ssl-cert-nickname )
MAY ( ds-cfg-listen-address )
X-ORIGIN 'OpenDS Directory Server' )
-objectClasses: ( 1.3.6.1.4.1.26027.1.2.184
- NAME 'ds-cfg-network-group-criteria'
+objectClasses: ( 1.3.6.1.4.1.26027.1.2.199
+ NAME 'ds-cfg-qos-policy'
SUP top
STRUCTURAL
- MUST (cn)
- MAY ( ds-cfg-allowed-auth-method $
- ds-cfg-allowed-ldap-port $
- ds-cfg-bind-dn-filter $
- ds-cfg-ip-address-filter $
- ds-cfg-is-security-mandatory $
- ds-cfg-user-entry-filter)
+ MUST ( cn $
+ ds-cfg-java-class)
X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.185
- NAME 'ds-cfg-network-group-resource-limits'
- SUP top
+ NAME 'ds-cfg-resource-limits-qos-policy'
+ SUP ds-cfg-qos-policy
STRUCTURAL
- MUST (cn)
MAY ( ds-cfg-max-connections $
ds-cfg-max-connections-from-same-ip $
ds-cfg-max-ops-per-connection $
ds-cfg-max-concurrent-ops-per-connection $
- ds-cfg-search-size-limit $
- ds-cfg-search-time-limit $
- ds-cfg-min-substring-length $
- ds-cfg-referral-policy $
- ds-cfg-referral-bind-policy $
- ds-cfg-referral-hop-limit)
+ ds-cfg-size-limit $
+ ds-cfg-time-limit $
+ ds-cfg-min-substring-length)
X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.186
NAME 'ds-cfg-network-group-plugin'
@@ -3980,10 +3926,9 @@
STRUCTURAL
X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.188
- NAME 'ds-cfg-network-group-request-filtering-policy'
- SUP top
+ NAME 'ds-cfg-request-filtering-qos-policy'
+ SUP ds-cfg-qos-policy
STRUCTURAL
- MUST (cn)
MAY ( ds-cfg-allowed-operations $
ds-cfg-allowed-attributes $
ds-cfg-prohibited-attributes $
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/ConnectionHandlerConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/ConnectionHandlerConfiguration.xml
index f97a80f..2b54bb1 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/ConnectionHandlerConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/ConnectionHandlerConfiguration.xml
@@ -23,7 +23,7 @@
! CDDL HEADER END
!
!
- ! Copyright 2007-2008 Sun Microsystems, Inc.
+ ! Copyright 2007-2009 Sun Microsystems, Inc.
! -->
<adm:managed-object name="connection-handler"
plural-name="connection-handlers"
@@ -84,82 +84,6 @@
</ldap:attribute>
</adm:profile>
</adm:property>
- <adm:property name="allowed-client" multi-valued="true">
- <adm:synopsis>
- Specifies a set of host names or address masks that determine the
- clients that are allowed to establish connections to this connection
- handler.
- </adm:synopsis>
- <adm:description>
- Valid values include a host name, a fully qualified domain name, a
- domain name, an IP address, or a subnetwork with subnetwork mask.
- </adm:description>
- <adm:requires-admin-action>
- <adm:none>
- <adm:synopsis>
- Changes to this configuration attribute take effect
- immediately and do not interfere with connections that may
- have already been established.
- </adm:synopsis>
- </adm:none>
- </adm:requires-admin-action>
- <adm:default-behavior>
- <adm:alias>
- <adm:synopsis>
- All clients with addresses that do not match an address on the
- deny list are allowed. If there is no deny list, then all
- clients are allowed.
- </adm:synopsis>
- </adm:alias>
- </adm:default-behavior>
- <adm:syntax>
- <adm:ip-address-mask />
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-allowed-client</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
- <adm:property name="denied-client" multi-valued="true">
- <adm:synopsis>
- Specifies a set of host names or address masks that determine
- the clients that are not allowed to establish connections to this
- connection handler.
- </adm:synopsis>
- <adm:description>
- Valid values include a host name, a fully qualified domain name, a
- domain name, an IP address, or a subnetwork with subnetwork mask.
- If both allowed and denied client masks are defined and a client
- connection matches one or more masks in both lists, then the
- connection is denied. If only a denied list is specified,
- then any client not matching a mask in that list is allowed.
- </adm:description>
- <adm:requires-admin-action>
- <adm:none>
- <adm:synopsis>
- Changes to this configuration attribute take effect
- immediately and do not interfere with connections that may
- have already been established.
- </adm:synopsis>
- </adm:none>
- </adm:requires-admin-action>
- <adm:default-behavior>
- <adm:alias>
- <adm:synopsis>
- If an allow list is specified, then only clients with
- addresses on the allow list are allowed. Otherwise, all
- clients are allowed.
- </adm:synopsis>
- </adm:alias>
- </adm:default-behavior>
- <adm:syntax>
- <adm:ip-address-mask />
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-denied-client</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
+ <adm:property-reference name="allowed-client" />
+ <adm:property-reference name="denied-client" />
</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
index bcbe6d2..cbfd739 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
@@ -23,7 +23,7 @@
! CDDL HEADER END
!
!
- ! Copyright 2007-2008 Sun Microsystems, Inc.
+ ! Copyright 2007-2009 Sun Microsystems, Inc.
! -->
<adm:managed-object name="global" plural-name="globals"
package="org.opends.server.admin.std"
@@ -266,8 +266,8 @@
</adm:property>
<adm:property name="size-limit">
<adm:synopsis>
- Specifies the maximum number of entries that the Directory Server
- should return to the client durin a search operation.
+ Specifies the maximum number of entries that can be returned
+ to the client during a single search operation.
</adm:synopsis>
<adm:description>
A value of 0 indicates that no size limit is enforced. Note
@@ -291,8 +291,8 @@
</adm:property>
<adm:property name="time-limit">
<adm:synopsis>
- Specifies the maximum length of time that the Directory Server
- should spend processing a search operation.
+ Specifies the maximum length of time that should be spent processing
+ a single search operation.
</adm:synopsis>
<adm:description>
A value of 0 seconds indicates that no time limit is
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupConfiguration.xml
index cc5457a..6e08be5 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupConfiguration.xml
@@ -25,84 +25,57 @@
!
! Copyright 2007-2009 Sun Microsystems, Inc.
! -->
-<adm:managed-object name="network-group" plural-name="network-groups"
+<adm:managed-object name="network-group"
+ plural-name="network-groups"
package="org.opends.server.admin.std"
xmlns:adm="http://www.opends.org/admin"
xmlns:ldap="http://www.opends.org/admin-ldap">
<adm:synopsis>
The
- <adm:user-friendly-name />
- is used to classify incoming connections and route requests to
+ <adm:user-friendly-name/>
+ is used to classify incoming client connections and route requests to
workflows.
</adm:synopsis>
- <adm:tag name="core-server" />
+ <adm:tag name="core-server"/>
<adm:profile name="ldap">
<ldap:object-class>
<ldap:name>ds-cfg-network-group</ldap:name>
<ldap:superior>top</ldap:superior>
</ldap:object-class>
</adm:profile>
-
- <adm:relation name="network-group-criteria"
- managed-object-name="network-group-criteria">
+ <adm:relation name="network-group-qos-policy"
+ managed-object-name="qos-policy">
<adm:synopsis>
- Specifies the set of criteria associated to this network group.
+ Specifies the set of quality of service (QoS) policies enforced by
+ the
+ <adm:user-friendly-name/>
+ .
</adm:synopsis>
<adm:description>
- A client connection can belong to a <adm:user-friendly-name /> only
- if it matches all the criteria defined for this
- <adm:user-friendly-name />.
+ All client connections belonging to the
+ <adm:user-friendly-name/>
+ will comply with its policies.
</adm:description>
- <adm:one-to-zero-or-one />
+ <adm:one-to-many unique="true"
+ plural-name="network-group-qos-policies"/>
<adm:profile name="ldap">
- <ldap:rdn-sequence>cn=Criteria</ldap:rdn-sequence>
+ <ldap:rdn-sequence>cn=QoS Policies</ldap:rdn-sequence>
</adm:profile>
</adm:relation>
-
- <adm:relation name="network-group-resource-limits"
- managed-object-name="network-group-resource-limits">
- <adm:synopsis>
- Specifies the set of resource limits enforced by this
- <adm:user-friendly-name />.
- </adm:synopsis>
- <adm:description>
- All client connections belonging to a <adm:user-friendly-name />
- must comply with the resource limits policy.
- </adm:description>
- <adm:one-to-zero-or-one />
- <adm:profile name="ldap">
- <ldap:rdn-sequence>cn=ResourceLimits</ldap:rdn-sequence>
- </adm:profile>
- </adm:relation>
-
- <adm:relation name="network-group-request-filtering-policy"
- managed-object-name="network-group-request-filtering-policy">
- <adm:synopsis>
- Specifies the request filtering policy enforced by this
- <adm:user-friendly-name />.
- </adm:synopsis>
- <adm:description>
- All client connections belonging to a <adm:user-friendly-name />
- must comply with the request filtering policy.
- </adm:description>
- <adm:one-to-zero-or-one />
- <adm:profile name="ldap">
- <ldap:rdn-sequence>cn=RequestFilteringPolicy</ldap:rdn-sequence>
- </adm:profile>
- </adm:relation>
-
<adm:property name="enabled" mandatory="true">
<adm:synopsis>
Indicates whether the
- <adm:user-friendly-name />
+ <adm:user-friendly-name/>
is enabled for use in the server.
</adm:synopsis>
<adm:description>
- If a network group is not enabled, its workflows will not be
- accessible when processing operations.
+ If a
+ <adm:user-friendly-name/>
+ is not enabled then its workflows will not be accessible when
+ processing operations.
</adm:description>
<adm:syntax>
- <adm:boolean />
+ <adm:boolean/>
</adm:syntax>
<adm:profile name="ldap">
<ldap:attribute>
@@ -110,36 +83,20 @@
</ldap:attribute>
</adm:profile>
</adm:property>
- <adm:property name="network-group-id" mandatory="true"
- read-only="true">
- <adm:synopsis>
- Specifies the name that is used to identify the associated
- <adm:user-friendly-name />
- .
- </adm:synopsis>
- <adm:description>
- The name must be unique among all the
- <adm:user-friendly-plural-name />
- in the server.
- </adm:description>
- <adm:syntax>
- <adm:string />
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-network-group-id</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
<adm:property name="priority" mandatory="true">
<adm:synopsis>
- Specifies the order in which the network groups are evaluated.
+ Specifies the priority for this <adm:user-friendly-name/>.
</adm:synopsis>
<adm:description>
- A client connection is first compared against network group with
- priority 1. If the client connection does not match the network group
- criteria, the client connection is compared against network group
- with priority 2 etc...
+ A client connection is first compared against the
+ <adm:user-friendly-name/>
+ with the lowest priority. If the client connection does not match
+ its connection criteria, then the client connection is compared against
+ the
+ <adm:user-friendly-name/>
+ with next lowest priority, and so on. If no
+ <adm:user-friendly-name/>
+ is selected then the client connection is rejected.
</adm:description>
<adm:syntax>
<adm:integer lower-limit="0"/>
@@ -152,19 +109,24 @@
</adm:property>
<adm:property name="workflow" multi-valued="true">
<adm:synopsis>
- Identifies the workflows in the network group.
+ Specifies a set of workflows which should be accessible from this
+ <adm:user-friendly-name/>
+ .
</adm:synopsis>
<adm:default-behavior>
- <adm:undefined />
+ <adm:alias>
+ <adm:synopsis>No workflows will be accessible.</adm:synopsis>
+ </adm:alias>
</adm:default-behavior>
<adm:syntax>
- <adm:aggregation relation-name="workflow" parent-path="/">
+ <adm:aggregation relation-name="workflow"
+ parent-path="/">
<adm:constraint>
<adm:synopsis>
The referenced workflows must be enabled.
</adm:synopsis>
<adm:target-is-enabled-condition>
- <adm:contains property="enabled" value="true" />
+ <adm:contains property="enabled" value="true"/>
</adm:target-is-enabled-condition>
</adm:constraint>
</adm:aggregation>
@@ -175,93 +137,162 @@
</ldap:attribute>
</adm:profile>
</adm:property>
- <adm:property name="affinity-policy" mandatory="false" advanced="true">
+ <adm:property name="allowed-auth-method" multi-valued="true">
<adm:synopsis>
- Defines the client connection affinity policy.
+ Specifies a set of allowed authorization methods that clients
+ must use in order to establish connections to this
+ <adm:user-friendly-name/>.
</adm:synopsis>
- <adm:description>
- A client connection affinity allows some requests to be routed
- to a specific data source regardless the regular routing
- process. For example, we can requires all the requests to be
- routed to a data source after a write has been complete on
- that data source. That way, a read request would return data
- that are consistent with a previous write request. By default,
- the client connection affinity is disabled.
- </adm:description>
+ <adm:requires-admin-action>
+ <adm:none>
+ <adm:synopsis>
+ Changes to this property take effect immediately and do not
+ interfere with connections that may have already been
+ established.
+ </adm:synopsis>
+ </adm:none>
+ </adm:requires-admin-action>
<adm:default-behavior>
- <adm:defined>
- <adm:value>none</adm:value>
- </adm:defined>
+ <adm:alias>
+ <adm:synopsis>
+ All authorization methods are allowed.
+ </adm:synopsis>
+ </adm:alias>
</adm:default-behavior>
<adm:syntax>
<adm:enumeration>
- <adm:value name="none">
+ <adm:value name="anonymous">
<adm:synopsis>
- Disables the client connection affinity.
+ Unauthorized clients.
</adm:synopsis>
</adm:value>
- <adm:value name="first-read-request-after-write-request">
+ <adm:value name="simple">
<adm:synopsis>
- Routes the first read request to the data source to which
- a previous write request has been routed to. This affinity
- is useful when a client application performs a read request
- after a write request and the read request should return
- consistent data.
+ Clients who bind using simple authentication (name and password).
</adm:synopsis>
</adm:value>
- <adm:value name="all-requests-after-first-write-request">
+ <adm:value name="sasl">
<adm:synopsis>
- Routes all the requests to the data source to which a
- previous write request has been routed to.
- </adm:synopsis>
- </adm:value>
- <adm:value name="all-write-requests-after-first-write-request">
- <adm:synopsis>
- Routes all the write requests to the data source to which
- a previous write request has been routed to. This affinity
- policy is useful for batch update where a parent entry and
- its subordinates must be sent to the same data source.
- </adm:synopsis>
- </adm:value>
- <adm:value name="all-requests-after-first-request">
- <adm:synopsis>
- Routes all the requests to the data source to which a
- previous request has been routed to. This affinity policy
- allows to create a kind of tunnel between a client application
- and a data source.
+ Clients who bind using SASL/external certificate based
+ authentication.
</adm:synopsis>
</adm:value>
</adm:enumeration>
</adm:syntax>
<adm:profile name="ldap">
<ldap:attribute>
- <ldap:name>ds-cfg-affinity-policy</ldap:name>
+ <ldap:name>ds-cfg-allowed-auth-method</ldap:name>
</ldap:attribute>
</adm:profile>
</adm:property>
- <adm:property name="affinity-timeout" mandatory="false" advanced="true">
+ <adm:property name="allowed-protocol" multi-valued="true">
<adm:synopsis>
- The period of time by which an affinity route remains active.
- The timeout value is a number of seconds and when the value is
- set to 0s (default value) then the route remains active forever.
+ Specifies a set of allowed supported protocols that clients
+ must use in order to establish connections to this
+ <adm:user-friendly-name/>.
</adm:synopsis>
- <adm:description>
- When the client connection affinity is enabled, an affinity route
- might be elected in accordance with the affinity policy. The affinity
- route is then used until the timeout value expires unless the timeout
- value is 0s in which case the route remains active forever.
- </adm:description>
+ <adm:requires-admin-action>
+ <adm:none>
+ <adm:synopsis>
+ Changes to this property take effect immediately and do not
+ interfere with connections that may have already been
+ established.
+ </adm:synopsis>
+ </adm:none>
+ </adm:requires-admin-action>
<adm:default-behavior>
- <adm:defined>
- <adm:value>0s</adm:value>
- </adm:defined>
+ <adm:alias>
+ <adm:synopsis>
+ All supported protocols are allowed.
+ </adm:synopsis>
+ </adm:alias>
</adm:default-behavior>
<adm:syntax>
- <adm:duration base-unit="s" lower-limit="0" />
+ <adm:enumeration>
+ <adm:value name="ldap">
+ <adm:synopsis>
+ Clients using LDAP are allowed.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="ldaps">
+ <adm:synopsis>
+ Clients using LDAPS are allowed.
+ </adm:synopsis>
+ </adm:value>
+ </adm:enumeration>
</adm:syntax>
<adm:profile name="ldap">
<ldap:attribute>
- <ldap:name>ds-cfg-affinity-timeout</ldap:name>
+ <ldap:name>ds-cfg-allowed-protocol</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="allowed-bind-dn" multi-valued="true">
+ <adm:synopsis>
+ Specifies a set of bind DN patterns that determine the
+ clients that are allowed to establish connections to this
+ <adm:user-friendly-name/>.
+ </adm:synopsis>
+ <adm:description>
+ Valid bind DN filters are strings composed of zero or more
+ wildcards. A double wildcard ** replaces one or more RDN
+ components (as in uid=dmiller,**,dc=example,dc=com). A simple
+ wildcard * replaces either a whole RDN, or a whole type, or a
+ value substring (as in uid=bj*,ou=people,dc=example,dc=com).
+ </adm:description>
+ <adm:requires-admin-action>
+ <adm:none>
+ <adm:synopsis>
+ Changes to this property take effect immediately and do not
+ interfere with connections that may have already been
+ established.
+ </adm:synopsis>
+ </adm:none>
+ </adm:requires-admin-action>
+ <adm:default-behavior>
+ <adm:alias>
+ <adm:synopsis>
+ All bind DNs are allowed.
+ </adm:synopsis>
+ </adm:alias>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:string />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-allowed-bind-dn</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property-reference name="allowed-client" />
+ <adm:property-reference name="denied-client" />
+ <adm:property name="is-security-mandatory">
+ <adm:synopsis>
+ Specifies whether or not a secured client connection
+ is required in order for clients to establish connections
+ to this <adm:user-friendly-name/>.
+ </adm:synopsis>
+ <adm:requires-admin-action>
+ <adm:none>
+ <adm:synopsis>
+ Changes to this property take effect immediately and do not
+ interfere with connections that may have already been
+ established.
+ </adm:synopsis>
+ </adm:none>
+ </adm:requires-admin-action>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>false</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:boolean />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-is-security-mandatory</ldap:name>
</ldap:attribute>
</adm:profile>
</adm:property>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupCriteriaConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupCriteriaConfiguration.xml
deleted file mode 100644
index dcb8982..0000000
--- a/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupCriteriaConfiguration.xml
+++ /dev/null
@@ -1,213 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ! 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
- !
- !
- ! Copyright 2007-2008 Sun Microsystems, Inc.
- ! -->
-<adm:managed-object name="network-group-criteria" plural-name="network-group-criteria"
- package="org.opends.server.admin.std"
- xmlns:adm="http://www.opends.org/admin"
- xmlns:ldap="http://www.opends.org/admin-ldap">
-
- <adm:synopsis>
- The <adm:user-friendly-name /> is used to classify incoming connections.
- </adm:synopsis>
-
- <adm:tag name="core-server" />
-
- <adm:profile name="ldap">
- <ldap:object-class>
- <ldap:name>ds-cfg-network-group-criteria</ldap:name>
- <ldap:superior>top</ldap:superior>
- </ldap:object-class>
- </adm:profile>
-
- <adm:property name="allowed-auth-method" multi-valued="true">
- <adm:synopsis>
- Specifies the allowed authorization methods for a client connection to
- match the <adm:user-friendly-name />.
- </adm:synopsis>
- <adm:default-behavior>
- <adm:undefined />
- </adm:default-behavior>
- <adm:syntax>
- <adm:enumeration>
- <adm:value name="anonymous">
- <adm:synopsis>
- Anonymous connections.
- </adm:synopsis>
- </adm:value>
- <adm:value name="simple">
- <adm:synopsis>
- Simple bind connections, with bind DN and password.
- </adm:synopsis>
- </adm:value>
- <adm:value name="sasl">
- <adm:synopsis>
- SASL/external connections, with a certificate containing the
- user authentication.
- </adm:synopsis>
- </adm:value>
- </adm:enumeration>
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-allowed-auth-method</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="allowed-ldap-port" multi-valued="true">
- <adm:synopsis>
- Specifies the allowed LDAP ports for the client connection to match the
- <adm:user-friendly-name />.
- </adm:synopsis>
- <adm:default-behavior>
- <adm:undefined />
- </adm:default-behavior>
- <adm:syntax>
- <adm:enumeration>
- <adm:value name="ldap">
- <adm:synopsis>
- Connection over ldap port.
- </adm:synopsis>
- </adm:value>
- <adm:value name="ldaps">
- <adm:synopsis>
- Connection over ldaps port.
- </adm:synopsis>
- </adm:value>
- </adm:enumeration>
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-allowed-ldap-port</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="bind-dn-filter" multi-valued="true">
- <adm:synopsis>
- Specifies a bind DN filter for the client connection to match the
- <adm:user-friendly-name />.
- </adm:synopsis>
- <adm:description>
- A valid bind DN filter is a string composed of zero or more
- wildcards. A double wildcard ** replaces one or more RDN
- components (as in uid=dmiller,**,dc=example,dc=com). A simple
- wildcard * replaces either a whole RDN, or a whole type, or a
- value substring (as in uid=bj*,ou=people,dc=example,dc=com).
- </adm:description>
- <adm:default-behavior>
- <adm:undefined />
- </adm:default-behavior>
- <adm:syntax>
- <adm:string />
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-bind-dn-filter</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="ip-address-filter" multi-valued="true">
- <adm:synopsis>
- Specifies an IP address filter for the <adm:user-friendly-name />.
- </adm:synopsis>
- <adm:description>
- A valid IP address mask can be one of the followings:
- 129.34.55.67
- 129.*.78.55
- .sun.com
- foo.sun.com
- foo.*.sun.*
- 128.*.*.*
- 129.45.23.67/22
- 128.33.21.21/32
- *.*.*.*
- 129.45.67.34/0
- foo.com
- foo
- 2001:fecd:ba23:cd1f:dcb1:1010:9234:4088/124
- 2001:fecd:ba23:cd1f:dcb1:1010:9234:4088
- [2001:fecd:ba23:cd1f:dcb1:1010:9234:4088]/45
- ::/128
- ::1/128
- ::
- </adm:description>
- <adm:default-behavior>
- <adm:undefined />
- </adm:default-behavior>
- <adm:syntax>
- <adm:ip-address-mask />
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-ip-address-filter</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="is-security-mandatory">
- <adm:synopsis>
- Specifies whether security is mandatory for the
- <adm:user-friendly-name />.
- </adm:synopsis>
- <adm:default-behavior>
- <adm:defined>
- <adm:value>
- false
- </adm:value>
- </adm:defined>
- </adm:default-behavior>
- <adm:syntax>
- <adm:boolean />
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-is-security-mandatory</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="user-entry-filter">
- <adm:synopsis>
- Specifies a search filter that the entry of a bound client
- must match.
- </adm:synopsis>
- <adm:default-behavior>
- <adm:undefined />
- </adm:default-behavior>
- <adm:syntax>
- <adm:string />
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-user-entry-filter</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
-</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupPluginConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupPluginConfiguration.xml
index 810decf..9109ccc 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupPluginConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupPluginConfiguration.xml
@@ -23,7 +23,7 @@
! CDDL HEADER END
!
!
- ! Copyright 2007-2008 Sun Microsystems, Inc.
+ ! Copyright 2007-2009 Sun Microsystems, Inc.
! -->
<adm:managed-object name="network-group-plugin"
plural-name="network-group-plugins" package="org.opends.server.admin.std"
@@ -55,7 +55,9 @@
<adm:property-override name="java-class" advanced="true">
<adm:default-behavior>
<adm:defined>
- <adm:value>org.opends.server.plugins.NetworkGroupPlugin</adm:value>
+ <adm:value>
+ org.opends.server.core.networkgroups.NetworkGroupPlugin
+ </adm:value>
</adm:defined>
</adm:default-behavior>
</adm:property-override>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupResourceLimitsConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupResourceLimitsConfiguration.xml
deleted file mode 100644
index cd502cd..0000000
--- a/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupResourceLimitsConfiguration.xml
+++ /dev/null
@@ -1,308 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ! 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
- !
- !
- ! Copyright 2007-2008 Sun Microsystems, Inc.
- ! -->
-<adm:managed-object name="network-group-resource-limits"
- plural-name="network-group-resource-limits"
- package="org.opends.server.admin.std"
- xmlns:adm="http://www.opends.org/admin"
- xmlns:ldap="http://www.opends.org/admin-ldap">
-
- <adm:synopsis>
- The
- <adm:user-friendly-name /> are used to define resource limits
- enforced by the network group.
- </adm:synopsis>
-
- <adm:tag name="core-server" />
-
- <adm:profile name="ldap">
- <ldap:object-class>
- <ldap:name>ds-cfg-network-group-resource-limits</ldap:name>
- <ldap:superior>top</ldap:superior>
- </ldap:object-class>
- </adm:profile>
-
- <adm:property name="max-connections" mandatory="false">
- <adm:synopsis>
- Specifies the maximum number of connections in the network group.
- </adm:synopsis>
- <adm:description>
- A value of 0 means that no limit is enforced.
- </adm:description>
- <adm:default-behavior>
- <adm:defined>
- <adm:value>0</adm:value>
- </adm:defined>
- </adm:default-behavior>
- <adm:syntax>
- <adm:integer lower-limit="0"/>
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-max-connections</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="max-connections-from-same-ip"
- mandatory="false">
- <adm:synopsis>
- Specifies the maximum number of connections from the same client
- (identified by its IP address).
- </adm:synopsis>
- <adm:description>
- A value of 0 means that no limit is enforced.
- </adm:description>
- <adm:default-behavior>
- <adm:defined>
- <adm:value>0</adm:value>
- </adm:defined>
- </adm:default-behavior>
- <adm:syntax>
- <adm:integer lower-limit="0"/>
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-max-connections-from-same-ip</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="max-ops-per-connection" mandatory="false">
- <adm:synopsis>
- Specifies the maximum number of operations per connection.
- </adm:synopsis>
- <adm:description>
- A value of 0 means that no limit is enforced.
- </adm:description>
- <adm:default-behavior>
- <adm:defined>
- <adm:value>0</adm:value>
- </adm:defined>
- </adm:default-behavior>
- <adm:syntax>
- <adm:integer lower-limit="0"/>
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-max-ops-per-connection</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="max-concurrent-ops-per-connection"
- mandatory="false">
- <adm:synopsis>
- Specifies the maximum number of concurrent operations per connection.
- </adm:synopsis>
- <adm:description>
- A value of 0 means that no limit is enforced.
- </adm:description>
- <adm:default-behavior>
- <adm:defined>
- <adm:value>0</adm:value>
- </adm:defined>
- </adm:default-behavior>
- <adm:syntax>
- <adm:integer lower-limit="0"/>
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-max-concurrent-ops-per-connection
- </ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="search-size-limit" mandatory="false">
- <adm:synopsis>
- Specifies the maximum number of entries that the Directory Server
- should return to the client during a search operation.
- </adm:synopsis>
- <adm:description>
- A value of 0 indicates that no size limit is enforced. Note that this
- is the network-group limit, but it may be overridden on a
- per-user basis.
- </adm:description>
- <adm:default-behavior>
- <adm:alias>
- <adm:synopsis>
- Use the global default size limit.
- </adm:synopsis>
- </adm:alias>
- </adm:default-behavior>
- <adm:syntax>
- <adm:integer lower-limit="0"/>
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-search-size-limit</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="search-time-limit" mandatory="false">
- <adm:synopsis>
- Specifies the maximum length of time that the Directory Server should
- spend processing a search operation.
- </adm:synopsis>
- <adm:description>
- A value of 0 seconds indicates that no time limit is enforced. Note that
- this is the network group time limit, but it may be overridden
- on a per-user basis.
- </adm:description>
- <adm:default-behavior>
- <adm:alias>
- <adm:synopsis>
- Use the global default time limit.
- </adm:synopsis>
- </adm:alias>
- </adm:default-behavior>
- <adm:syntax>
- <adm:duration base-unit="s" lower-limit="0" />
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-search-time-limit</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="min-substring-length" mandatory="false">
- <adm:synopsis>
- Specifies the minimum length for a search substring.
- </adm:synopsis>
- <adm:description>
- Search operations with short search substring are likely to match
- a high number of entries and might degrade performances. A value of 0
- indicates that no limit is enforced.
- </adm:description>
- <adm:default-behavior>
- <adm:defined>
- <adm:value>0</adm:value>
- </adm:defined>
- </adm:default-behavior>
- <adm:syntax>
- <adm:integer lower-limit="0"/>
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-min-substring-length</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="referral-policy" mandatory="false">
- <adm:synopsis>
- Specifies the referral policy.
- </adm:synopsis>
- <adm:description>
- The referral policy defines the behavior when a referral is
- received. The server can either discard the referral, forward
- the referral to the client or follow the referral.
- </adm:description>
- <adm:default-behavior>
- <adm:defined>
- <adm:value>forward</adm:value>
- </adm:defined>
- </adm:default-behavior>
- <adm:syntax>
- <adm:enumeration>
- <adm:value name="discard">
- <adm:synopsis>Discard referrals.</adm:synopsis>
- </adm:value>
- <adm:value name="forward">
- <adm:synopsis>Forward referrals.</adm:synopsis>
- </adm:value>
- <adm:value name="follow">
- <adm:synopsis>Follow referrals</adm:synopsis>
- </adm:value>
- </adm:enumeration>
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-referral-policy</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="referral-bind-policy" mandatory="false">
- <adm:synopsis>
- Specifies the referral bind policy.
- </adm:synopsis>
- <adm:description>
- The referral bind policy is used only when the referral policy
- is set to "follow". It specifies whether the referral is followed
- with the client bind DN and password or anonymously.
- </adm:description>
- <adm:default-behavior>
- <adm:defined>
- <adm:value>anonymous</adm:value>
- </adm:defined>
- </adm:default-behavior>
- <adm:syntax>
- <adm:enumeration>
- <adm:value name="anonymous">
- <adm:synopsis>Follow referrals anonymously.</adm:synopsis>
- </adm:value>
- <adm:value name="use-password">
- <adm:synopsis>
- Follow referrals with the client bind DN and password.
- </adm:synopsis>
- </adm:value>
- </adm:enumeration>
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-referral-bind-policy</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
- <adm:property name="referral-hop-limit" mandatory="false">
- <adm:synopsis>
- Specifies the maximum number of hops when following referrals.
- </adm:synopsis>
- <adm:description>
- A value of 0 means that no limit is enforced.
- </adm:description>
- <adm:default-behavior>
- <adm:defined>
- <adm:value>0</adm:value>
- </adm:defined>
- </adm:default-behavior>
- <adm:syntax>
- <adm:integer lower-limit="0"/>
- </adm:syntax>
- <adm:profile name="ldap">
- <ldap:attribute>
- <ldap:name>ds-cfg-referral-hop-limit</ldap:name>
- </ldap:attribute>
- </adm:profile>
- </adm:property>
-
-</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/Package.xml b/opends/src/admin/defn/org/opends/server/admin/std/Package.xml
index c061b51..dee716a 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/Package.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/Package.xml
@@ -23,7 +23,7 @@
! CDDL HEADER END
!
!
- ! Copyright 2007-2008 Sun Microsystems, Inc.
+ ! Copyright 2007-2009 Sun Microsystems, Inc.
! -->
<adm:package name="org.opends.server.admin.std"
xmlns:adm="http://www.opends.org/admin"
@@ -405,4 +405,82 @@
</ldap:attribute>
</adm:profile>
</adm:property>
+ <adm:property name="allowed-client" multi-valued="true">
+ <adm:synopsis>
+ Specifies a set of host names or address masks that determine the
+ clients that are allowed to establish connections to this
+ <adm:user-friendly-name/>.
+ </adm:synopsis>
+ <adm:description>
+ Valid values include a host name, a fully qualified domain name, a
+ domain name, an IP address, or a subnetwork with subnetwork mask.
+ </adm:description>
+ <adm:requires-admin-action>
+ <adm:none>
+ <adm:synopsis>
+ Changes to this property take effect immediately and do not
+ interfere with connections that may have already been
+ established.
+ </adm:synopsis>
+ </adm:none>
+ </adm:requires-admin-action>
+ <adm:default-behavior>
+ <adm:alias>
+ <adm:synopsis>
+ All clients with addresses that do not match an address on the
+ deny list are allowed. If there is no deny list, then all
+ clients are allowed.
+ </adm:synopsis>
+ </adm:alias>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:ip-address-mask />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-allowed-client</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="denied-client" multi-valued="true">
+ <adm:synopsis>
+ Specifies a set of host names or address masks that determine
+ the clients that are not allowed to establish connections to this
+ <adm:user-friendly-name/>.
+ </adm:synopsis>
+ <adm:description>
+ Valid values include a host name, a fully qualified domain name, a
+ domain name, an IP address, or a subnetwork with subnetwork mask.
+ If both allowed and denied client masks are defined and a client
+ connection matches one or more masks in both lists, then the
+ connection is denied. If only a denied list is specified,
+ then any client not matching a mask in that list is allowed.
+ </adm:description>
+ <adm:requires-admin-action>
+ <adm:none>
+ <adm:synopsis>
+ Changes to this property take effect immediately and do not
+ interfere with connections that may have already been
+ established.
+ </adm:synopsis>
+ </adm:none>
+ </adm:requires-admin-action>
+ <adm:default-behavior>
+ <adm:alias>
+ <adm:synopsis>
+ If an allow list is specified, then only clients with
+ addresses on the allow list are allowed. Otherwise, all
+ clients are allowed.
+ </adm:synopsis>
+ </adm:alias>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:ip-address-mask />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-denied-client</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
</adm:package>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/QOSPolicyConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/QOSPolicyConfiguration.xml
new file mode 100644
index 0000000..0af495d
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/QOSPolicyConfiguration.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ! 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
+ !
+ !
+ ! Copyright 2009 Sun Microsystems, Inc.
+ !
+-->
+<adm:managed-object name="qos-policy"
+ plural-name="qos-policies"
+ abstract="true"
+ package="org.opends.server.admin.std"
+ xmlns:adm="http://www.opends.org/admin"
+ xmlns:ldap="http://www.opends.org/admin-ldap">
+ <adm:synopsis>
+ <adm:user-friendly-plural-name/>
+ determine the quality of service (QoS) clients receive when
+ interacting with the server.
+ </adm:synopsis>
+ <adm:tag name="core-server"/>
+ <adm:profile name="ldap">
+ <ldap:object-class>
+ <ldap:name>ds-cfg-qos-policy</ldap:name>
+ <ldap:superior>top</ldap:superior>
+ </ldap:object-class>
+ </adm:profile>
+ <adm:property name="java-class" mandatory="true">
+ <adm:synopsis>
+ Specifies the fully-qualified name of the Java class that provides the
+ <adm:user-friendly-name />
+ implementation.
+ </adm:synopsis>
+ <adm:requires-admin-action>
+ <adm:component-restart />
+ </adm:requires-admin-action>
+ <adm:syntax>
+ <adm:java-class>
+ <adm:instance-of>
+ org.opends.server.api.QOSPolicyFactory
+ </adm:instance-of>
+ </adm:java-class>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-java-class</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupRequestFilteringPolicyConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/RequestFilteringQOSPolicyConfiguration.xml
similarity index 60%
rename from opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupRequestFilteringPolicyConfiguration.xml
rename to opends/src/admin/defn/org/opends/server/admin/std/RequestFilteringQOSPolicyConfiguration.xml
index 4c83f24..8354518 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/NetworkGroupRequestFilteringPolicyConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/RequestFilteringQOSPolicyConfiguration.xml
@@ -23,40 +23,42 @@
! CDDL HEADER END
!
!
- ! Copyright 2008 Sun Microsystems, Inc.
+ ! Copyright 2009 Sun Microsystems, Inc.
! -->
-<adm:managed-object name="network-group-request-filtering-policy"
- plural-name="network-group-request-filtering-policies"
+<adm:managed-object name="request-filtering-qos-policy"
+ plural-name="request-filtering-qos-policies"
+ extends="qos-policy"
package="org.opends.server.admin.std"
xmlns:adm="http://www.opends.org/admin"
xmlns:ldap="http://www.opends.org/admin-ldap">
-
<adm:synopsis>
The
- <adm:user-friendly-name /> is used to define the type of requests
- allowed in the network group.
+ <adm:user-friendly-name/>
+ is used to define the type of requests allowed by the server.
</adm:synopsis>
-
- <adm:tag name="core-server" />
-
<adm:profile name="ldap">
<ldap:object-class>
- <ldap:name>ds-cfg-network-group-request-filtering-policy</ldap:name>
- <ldap:superior>top</ldap:superior>
+ <ldap:name>ds-cfg-request-filtering-qos-policy</ldap:name>
+ <ldap:superior>ds-cfg-qos-policy</ldap:superior>
</ldap:object-class>
</adm:profile>
-
- <adm:property name="allowed-operations" mandatory="false" multi-valued="true">
- <adm:synopsis>
- Specifies which operations are allowed in the network group.
- </adm:synopsis>
- <adm:description>
- When this attribute is specified, only the listed operations are
- allowed in the network group. If the attribute is not defined, all
- the operations are allowed.
- </adm:description>
+ <adm:property-override name="java-class" advanced="true">
<adm:default-behavior>
- <adm:undefined />
+ <adm:defined>
+ <adm:value>
+ org.opends.server.core.networkgroups.RequestFilteringPolicyFactory
+ </adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ </adm:property-override>
+ <adm:property name="allowed-operations" multi-valued="true">
+ <adm:synopsis>
+ Specifies which operations are allowed by the server.
+ </adm:synopsis>
+ <adm:default-behavior>
+ <adm:alias>
+ <adm:synopsis>All operations are allowed.</adm:synopsis>
+ </adm:alias>
</adm:default-behavior>
<adm:syntax>
<adm:enumeration>
@@ -76,7 +78,8 @@
<adm:synopsis>Extended operations</adm:synopsis>
</adm:value>
<adm:value name="inequality-search">
- <adm:synopsis>Inequality Search operations</adm:synopsis>
+ <adm:synopsis>Inequality Search operations
+ </adm:synopsis>
</adm:value>
<adm:value name="modify">
<adm:synopsis>Modify operations</adm:synopsis>
@@ -95,21 +98,18 @@
</ldap:attribute>
</adm:profile>
</adm:property>
-
- <adm:property name="allowed-attributes" mandatory="false" multi-valued="true">
+ <adm:property name="allowed-attributes" multi-valued="true">
<adm:synopsis>
- Specifies which attributes are allowed in search and compare operations.
+ Specifies which attributes are allowed in search and
+ compare operations.
</adm:synopsis>
- <adm:description>
- When this attribute is specified, only the listed attributes are allowed
- in search and compare operations. If it is not set, all the attributes
- are allowed, except those listed in ds-cfg-prohibited-attributes.
- </adm:description>
<adm:default-behavior>
- <adm:undefined />
+ <adm:alias>
+ <adm:synopsis>All non-prohibited attributes.</adm:synopsis>
+ </adm:alias>
</adm:default-behavior>
<adm:syntax>
- <adm:string />
+ <adm:string/>
</adm:syntax>
<adm:profile name="ldap">
<ldap:attribute>
@@ -117,24 +117,19 @@
</ldap:attribute>
</adm:profile>
</adm:property>
-
<adm:property name="prohibited-attributes" mandatory="false"
- multi-valued="true">
+ multi-valued="true">
<adm:synopsis>
- Specifies which attributes are not allowed in search and compare
- operations.
- </adm:synopsis>
- <adm:description>
- When this attribute is specified, all the listed attributes are prohibited
- in search and compare operations. It should not be used in conjunction
- with ds-cfg-allowed-attributes.
-
- </adm:description>
+ Specifies which attributes are not allowed in search
+ and compare operations.
+ </adm:synopsis>
<adm:default-behavior>
- <adm:undefined />
+ <adm:alias>
+ <adm:synopsis>All allowed attributes.</adm:synopsis>
+ </adm:alias>
</adm:default-behavior>
<adm:syntax>
- <adm:string />
+ <adm:string/>
</adm:syntax>
<adm:profile name="ldap">
<ldap:attribute>
@@ -142,19 +137,14 @@
</ldap:attribute>
</adm:profile>
</adm:property>
-
- <adm:property name="allowed-search-scopes" mandatory="false"
- multi-valued="true">
+ <adm:property name="allowed-search-scopes" multi-valued="true">
<adm:synopsis>
- Specifies which search scopes are allowed in the network group.
+ Specifies which search scopes are allowed by the server.
</adm:synopsis>
- <adm:description>
- When this attribute is specified, only the listed scopes are
- allowed in the network group. If it is not set, all search scopes are
- allowed.
- </adm:description>
<adm:default-behavior>
- <adm:undefined />
+ <adm:alias>
+ <adm:synopsis>All search scopes are allowed.</adm:synopsis>
+ </adm:alias>
</adm:default-behavior>
<adm:syntax>
<adm:enumeration>
@@ -178,22 +168,17 @@
</ldap:attribute>
</adm:profile>
</adm:property>
-
- <adm:property name="allowed-subtrees" mandatory="false"
- multi-valued="true">
+ <adm:property name="allowed-subtrees" multi-valued="true">
<adm:synopsis>
- Specifies which subtrees are exposed to clients.
+ Specifies which subtrees are accessible to clients.
</adm:synopsis>
- <adm:description>
- When this attribute is specified, only the listed subtrees are exposed. If
- it is not set, all the substrees are exposed. Note that
- ds-cfg-prohibited-subtrees restricts the list of exposed subtrees.
- </adm:description>
<adm:default-behavior>
- <adm:undefined />
+ <adm:alias>
+ <adm:synopsis>All non-prohibited subtrees.</adm:synopsis>
+ </adm:alias>
</adm:default-behavior>
<adm:syntax>
- <adm:dn />
+ <adm:dn/>
</adm:syntax>
<adm:profile name="ldap">
<ldap:attribute>
@@ -201,22 +186,18 @@
</ldap:attribute>
</adm:profile>
</adm:property>
-
- <adm:property name="prohibited-subtrees" mandatory="false"
- multi-valued="true">
+ <adm:property name="prohibited-subtrees" multi-valued="true">
<adm:synopsis>
- Specifies which subtrees are not exposed to clients. Each prohibited
- subtree must be subordinate to an allowed subtree.
+ Specifies which subtrees must be hidden from clients. Each
+ prohibited subtree must be subordinate to an allowed subtree.
</adm:synopsis>
- <adm:description>
- When this attribute is specified, all the listed subtrees cannot be
- accessed.
- </adm:description>
<adm:default-behavior>
- <adm:undefined />
+ <adm:alias>
+ <adm:synopsis>All allowed subtrees.</adm:synopsis>
+ </adm:alias>
</adm:default-behavior>
<adm:syntax>
- <adm:dn />
+ <adm:dn/>
</adm:syntax>
<adm:profile name="ldap">
<ldap:attribute>
@@ -224,5 +205,4 @@
</ldap:attribute>
</adm:profile>
</adm:property>
-
</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/ResourceLimitsQOSPolicyConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/ResourceLimitsQOSPolicyConfiguration.xml
new file mode 100644
index 0000000..725a07f
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/ResourceLimitsQOSPolicyConfiguration.xml
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ! 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
+ !
+ !
+ ! Copyright 2009 Sun Microsystems, Inc.
+ ! -->
+<adm:managed-object name="resource-limits-qos-policy"
+ plural-name="resource-limits-qos-policies"
+ extends="qos-policy"
+ package="org.opends.server.admin.std"
+ xmlns:adm="http://www.opends.org/admin"
+ xmlns:ldap="http://www.opends.org/admin-ldap">
+ <adm:synopsis>
+ The
+ <adm:user-friendly-name/>
+ are used to define resource limits enforced by the server.
+ </adm:synopsis>
+ <adm:profile name="ldap">
+ <ldap:object-class>
+ <ldap:name>ds-cfg-resource-limits-qos-policy</ldap:name>
+ <ldap:superior>ds-cfg-qos-policy</ldap:superior>
+ </ldap:object-class>
+ </adm:profile>
+ <adm:property-override name="java-class" advanced="true">
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>
+ org.opends.server.core.networkgroups.ResourceLimitsPolicyFactory
+ </adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ </adm:property-override>
+ <adm:property name="max-connections">
+ <adm:TODO>Make use of unlimited.</adm:TODO>
+ <adm:synopsis>
+ Specifies the maximum number of concurrent client connections
+ to the server.
+ </adm:synopsis>
+ <adm:description>
+ A value of 0 means that no limit is enforced.
+ </adm:description>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>0</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:integer lower-limit="0"/>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-max-connections</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="max-connections-from-same-ip">
+ <adm:TODO>Make use of unlimited.</adm:TODO>
+ <adm:synopsis>
+ Specifies the maximum number of client connections from the
+ same source address.
+ </adm:synopsis>
+ <adm:description>
+ A value of 0 means that no limit is enforced.
+ </adm:description>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>0</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:integer lower-limit="0"/>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-max-connections-from-same-ip</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="max-ops-per-connection">
+ <adm:TODO>Make use of unlimited.</adm:TODO>
+ <adm:synopsis>
+ Specifies the maximum number of operations per
+ client connection.
+ </adm:synopsis>
+ <adm:description>
+ A value of 0 means that no limit is enforced.
+ </adm:description>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>0</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:integer lower-limit="0"/>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-max-ops-per-connection</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="max-concurrent-ops-per-connection">
+ <adm:TODO>Make use of unlimited.</adm:TODO>
+ <adm:synopsis>
+ Specifies the maximum number of concurrent operations
+ per client connection.
+ </adm:synopsis>
+ <adm:description>
+ A value of 0 means that no limit is enforced.
+ </adm:description>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>0</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:integer lower-limit="0"/>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-max-concurrent-ops-per-connection</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="size-limit">
+ <adm:TODO>Make use of unlimited.</adm:TODO>
+ <adm:synopsis>
+ Specifies the maximum number of entries that can be returned
+ to the client during a single search operation.
+ </adm:synopsis>
+ <adm:description>
+ A value of 0 indicates that no size limit is enforced. Note
+ that this is the default for the server, but it may be
+ overridden on a per-user basis using the ds-rlim-size-limit
+ operational attribute.
+ </adm:description>
+ <adm:default-behavior>
+ <adm:inherited>
+ <adm:absolute property-name="size-limit"
+ path="/relation=global-configuration"/>
+ </adm:inherited>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:integer lower-limit="0"/>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-size-limit</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="time-limit">
+ <adm:TODO>Make use of unlimited.</adm:TODO>
+ <adm:synopsis>
+ Specifies the maximum length of time that should be spent processing
+ a search operation.
+ </adm:synopsis>
+ <adm:description>
+ A value of 0 seconds indicates that no time limit is
+ enforced. Note that this is the default for the server,
+ but it may be overridden on a per-user basis using the
+ ds-rlim-time-limit operational attribute.
+ </adm:description>
+ <adm:default-behavior>
+ <adm:inherited>
+ <adm:absolute property-name="time-limit"
+ path="/relation=global-configuration"/>
+ </adm:inherited>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:duration base-unit="s" lower-limit="0"/>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-time-limit</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="min-substring-length">
+ <adm:TODO>Make use of unlimited.</adm:TODO>
+ <adm:synopsis>
+ Specifies the minimum length for a search filter substring.
+ </adm:synopsis>
+ <adm:description>
+ Search operations with short search filter substring are
+ likely to match a high number of entries and might degrade
+ performance overall. A value of 0 indicates that no limit is
+ enforced.
+ </adm:description>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>0</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:integer lower-limit="0"/>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-min-substring-length</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
index 845a6f6..5f6250d 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
@@ -23,7 +23,7 @@
! CDDL HEADER END
!
!
- ! Copyright 2007-2008 Sun Microsystems, Inc.
+ ! Copyright 2007-2009 Sun Microsystems, Inc.
! -->
<adm:root-managed-object xmlns:adm="http://www.opends.org/admin"
xmlns:ldap="http://www.opends.org/admin-ldap"
@@ -416,13 +416,15 @@
</adm:profile>
</adm:relation>
<adm:relation name="network-group">
- <adm:one-to-many naming-property="network-group-id" />
+ <adm:one-to-many />
<adm:profile name="ldap">
<ldap:rdn-sequence>cn=Network Groups,cn=config</ldap:rdn-sequence>
</adm:profile>
<adm:profile name="cli">
<cli:relation>
<cli:default-property name="enabled" />
+ <cli:default-property name="priority" />
+ <cli:default-property name="workflow" />
</cli:relation>
</adm:profile>
</adm:relation>
diff --git a/opends/src/messages/messages/config.properties b/opends/src/messages/messages/config.properties
index 2f2fd20..0763759 100644
--- a/opends/src/messages/messages/config.properties
+++ b/opends/src/messages/messages/config.properties
@@ -20,7 +20,7 @@
#
# CDDL HEADER END
#
-# Copyright 2006-2008 Sun Microsystems, Inc.
+# Copyright 2006-2009 Sun Microsystems, Inc.
@@ -2150,3 +2150,8 @@
SEVERE_ERR_CONFIG_NETWORKGROUPREQUESTFILTERINGPOLICY_INVALID_SUBTREE_720=The \
allowed subtree %s specified in configuration entry %s is also defined as \
a prohibited subtree
+SEVERE_ERR_CONFIG_NETWORK_GROUP_CONFIG_NOT_ACCEPTABLE_721=The configuration \
+ for the network group defined in configuration entry %s was not acceptable: %s
+SEVERE_ERR_CONFIG_NETWORK_GROUP_POLICY_CANNOT_INITIALIZE_722=An error occurred \
+ while trying to initialize a network group policy loaded from class %s with \
+ the information in configuration entry %s: %s
diff --git a/opends/src/messages/messages/dsconfig.properties b/opends/src/messages/messages/dsconfig.properties
index 0e663e5..0d5e492 100644
--- a/opends/src/messages/messages/dsconfig.properties
+++ b/opends/src/messages/messages/dsconfig.properties
@@ -470,4 +470,8 @@
server at %s on port %s. Check this port is an administration port
SEVERE_ERR_DSCFG_ERROR_LDAP_FAILED_TO_CONNECT_NOT_TRUSTED_158=Unable to connect to the \
server at %s on port %s. In non-interactive mode, you must use the '--trustAll' option
-SEVERE_ERR_DSCFG_ERROR_VALUE_DOES_NOT_EXIST_159=The value %s for the %s property does not exist
\ No newline at end of file
+SEVERE_ERR_DSCFG_ERROR_VALUE_DOES_NOT_EXIST_159=The value %s for the %s property does not exist
+SEVERE_ERR_DSCFG_ERROR_NO_AVAILABLE_TYPES_160=Unable to continue since there are \
+ no available types of %s to choose from
+INFO_DSCFG_TYPE_PROMPT_SINGLE_161=>>>> There is only one type of %s available: "%s". \
+ Are you sure that this is the correct one?
diff --git a/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java b/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
index b77e97d..14d5b1a 100644
--- a/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
+++ b/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2007-2008 Sun Microsystems, Inc.
+ * Copyright 2007-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -869,7 +869,7 @@
public final boolean isTop() {
// Casting to Object and instanceof check are required
// to workaround a bug in JDK versions prior to 1.5.0_08.
- return ((Object) this instanceof TopCfgDefn);
+ return (this instanceof TopCfgDefn);
}
diff --git a/opends/src/server/org/opends/server/admin/AdminException.java b/opends/src/server/org/opends/server/admin/AdminException.java
index f6b2b93..dea9632 100644
--- a/opends/src/server/org/opends/server/admin/AdminException.java
+++ b/opends/src/server/org/opends/server/admin/AdminException.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -41,6 +41,13 @@
public abstract class AdminException extends OpenDsException {
/**
+ * Fake serialization ID.
+ */
+ private static final long serialVersionUID = 1L;
+
+
+
+ /**
* Create an admin exception with a message and cause.
*
* @param message
diff --git a/opends/src/server/org/opends/server/admin/AdminRuntimeException.java b/opends/src/server/org/opends/server/admin/AdminRuntimeException.java
index 47dfbd0..379e2d1 100644
--- a/opends/src/server/org/opends/server/admin/AdminRuntimeException.java
+++ b/opends/src/server/org/opends/server/admin/AdminRuntimeException.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -39,6 +39,13 @@
*/
public abstract class AdminRuntimeException extends RuntimeException {
+ /**
+ * Fake serialization ID.
+ */
+ private static final long serialVersionUID = 1L;
+
+
+
// Message that explains the problem.
private final Message message;
diff --git a/opends/src/server/org/opends/server/admin/DecodingException.java b/opends/src/server/org/opends/server/admin/DecodingException.java
index aa5c4a9..1affb2a 100644
--- a/opends/src/server/org/opends/server/admin/DecodingException.java
+++ b/opends/src/server/org/opends/server/admin/DecodingException.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -39,6 +39,13 @@
public abstract class DecodingException extends OperationsException {
/**
+ * Fake serialization ID.
+ */
+ private static final long serialVersionUID = 1L;
+
+
+
+ /**
* Create a decoding exception with a message.
*
* @param message
diff --git a/opends/src/server/org/opends/server/admin/InstantiableRelationDefinition.java b/opends/src/server/org/opends/server/admin/InstantiableRelationDefinition.java
index 4b0bfed..2600a97 100644
--- a/opends/src/server/org/opends/server/admin/InstantiableRelationDefinition.java
+++ b/opends/src/server/org/opends/server/admin/InstantiableRelationDefinition.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -284,13 +284,10 @@
public void toString(StringBuilder builder) {
builder.append("name=");
builder.append(getName());
- builder.append(" type=composition parent=");
+ builder.append(" type=collection parent=");
builder.append(getParentDefinition().getName());
builder.append(" child=");
builder.append(getChildDefinition().getName());
- builder.append(" child=");
- builder.append(getChildDefinition().getName());
- builder.append(" minOccurs=0");
}
diff --git a/opends/src/server/org/opends/server/admin/LDAPProfile.java b/opends/src/server/org/opends/server/admin/LDAPProfile.java
index f5422e8..027b896 100644
--- a/opends/src/server/org/opends/server/admin/LDAPProfile.java
+++ b/opends/src/server/org/opends/server/admin/LDAPProfile.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -104,7 +104,7 @@
* the instantiable relation is not handled by this LDAP
* profile wrapper.
*/
- public String getInstantiableRelationChildRDNType(
+ public String getRelationChildRDNType(
InstantiableRelationDefinition<?, ?> r) {
return null;
}
@@ -112,6 +112,26 @@
/**
+ * Gets the LDAP RDN attribute type for child entries of an set
+ * relation.
+ * <p>
+ * The default implementation of this method is to return
+ * <code>null</code>.
+ *
+ * @param r
+ * The set relation.
+ * @return Returns the LDAP RDN attribute type for child entries of
+ * an set relation, or <code>null</code> if the set relation
+ * is not handled by this LDAP profile wrapper.
+ */
+ public String getRelationChildRDNType(SetRelationDefinition<?, ?> r)
+ {
+ return null;
+ }
+
+
+
+ /**
* Get the principle object class associated with the specified
* definition.
* <p>
@@ -217,7 +237,7 @@
* If the LDAP profile properties file associated with the
* provided managed object definition could not be loaded.
*/
- public String getInstantiableRelationChildRDNType(
+ public String getRelationChildRDNType(
InstantiableRelationDefinition<?, ?> r) throws MissingResourceException {
if (r.getNamingPropertyDefinition() != null) {
// Use the attribute associated with the naming property.
@@ -225,7 +245,7 @@
.getNamingPropertyDefinition());
} else {
for (Wrapper profile : profiles) {
- String rdnType = profile.getInstantiableRelationChildRDNType(r);
+ String rdnType = profile.getRelationChildRDNType(r);
if (rdnType != null) {
return rdnType;
}
@@ -238,23 +258,52 @@
/**
- * Gets the LDAP object classes associated with an instantiable
+ * Gets the LDAP object classes associated with an instantiable or set
* relation branch. The branch is the parent entry of child managed
* objects.
*
* @param r
- * The instantiable relation.
+ * The instantiable or set relation.
* @return Returns the LDAP object classes associated with an
- * instantiable relation branch.
+ * instantiable or set relation branch.
*/
- public List<String> getInstantiableRelationObjectClasses(
- InstantiableRelationDefinition<?, ?> r) {
+ public List<String> getRelationObjectClasses(
+ RelationDefinition<?, ?> r) {
return Arrays.asList(new String[] { "top", "ds-cfg-branch" });
}
/**
+ * Gets the LDAP RDN attribute type for child entries of an set
+ * relation.
+ *
+ * @param r
+ * The set relation.
+ * @return Returns the LDAP RDN attribute type for child entries of an
+ * set relation.
+ * @throws MissingResourceException
+ * If the LDAP profile properties file associated with the
+ * provided managed object definition could not be loaded.
+ */
+ public String getRelationChildRDNType(SetRelationDefinition<?, ?> r)
+ throws MissingResourceException
+ {
+ for (Wrapper profile : profiles)
+ {
+ String rdnType = profile.getRelationChildRDNType(r);
+ if (rdnType != null)
+ {
+ return rdnType;
+ }
+ }
+ return resource.getString(r.getParentDefinition(),
+ "naming-attribute." + r.getName());
+ }
+
+
+
+ /**
* Get the principle object class associated with the specified
* definition.
*
diff --git a/opends/src/server/org/opends/server/admin/ManagedObjectPath.java b/opends/src/server/org/opends/server/admin/ManagedObjectPath.java
index eb2edb6..3d79b04 100644
--- a/opends/src/server/org/opends/server/admin/ManagedObjectPath.java
+++ b/opends/src/server/org/opends/server/admin/ManagedObjectPath.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -84,7 +84,14 @@
* <i>definition</i> is the name of the referenced managed object's
* definition if required (usually this is implied by the relation
* itself), and <i>name</i> is the name of the managed object
- * instance.
+ * instance
+ * <li>an element representing a managed object associated with a
+ * one-to-many (set) relation has the form
+ * <code>relation=</code><i>relation</i><code>[+type=</code>
+ * <i>definition</i><code>]</code>,
+ * where <i>relation</i> is the name of the relation and
+ * <i>definition</i> is the name of the referenced managed object's
+ * definition.
* </ul>
* The following path string representation identifies a connection
* handler instance (note that the <code>type</code> is not
@@ -149,10 +156,10 @@
InstantiableRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d, String name) {
// Add the RDN sequence representing the relation.
- appendManagedObjectPathElement((RelationDefinition<?, ?>) r);
+ appendManagedObjectPathElement(r);
// Now add the single RDN representing the named instance.
- String type = profile.getInstantiableRelationChildRDNType(r);
+ String type = profile.getRelationChildRDNType(r);
AttributeType atype = DirectoryServer.getAttributeType(
type.toLowerCase(), true);
AttributeValue avalue = new AttributeValue(atype, name);
@@ -166,10 +173,30 @@
*/
public <C extends ConfigurationClient, S extends Configuration>
void appendManagedObjectPathElement(
+ SetRelationDefinition<? super C, ? super S> r,
+ AbstractManagedObjectDefinition<C, S> d) {
+ // Add the RDN sequence representing the relation.
+ appendManagedObjectPathElement(r);
+
+ // Now add the single RDN representing the instance.
+ String type = profile.getRelationChildRDNType(r);
+ AttributeType atype = DirectoryServer.getAttributeType(
+ type.toLowerCase(), true);
+ AttributeValue avalue = new AttributeValue(atype, d.getName());
+ dn = dn.concat(RDN.create(atype, avalue));
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ void appendManagedObjectPathElement(
OptionalRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d) {
// Add the RDN sequence representing the relation.
- appendManagedObjectPathElement((RelationDefinition<?, ?>) r);
+ appendManagedObjectPathElement(r);
}
@@ -182,7 +209,7 @@
SingletonRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d) {
// Add the RDN sequence representing the relation.
- appendManagedObjectPathElement((RelationDefinition<?, ?>) r);
+ appendManagedObjectPathElement(r);
}
@@ -400,6 +427,60 @@
/**
+ * A path element representing an set managed object.
+ */
+ private static final class SetElement
+ <C extends ConfigurationClient, S extends Configuration>
+ extends Element<C, S> {
+
+ // Factory method.
+ private static final <C extends ConfigurationClient,
+ S extends Configuration>
+ SetElement<C, S> create(
+ SetRelationDefinition<? super C, ? super S> r,
+ AbstractManagedObjectDefinition<C, S> d) {
+ return new SetElement<C, S>(r, d);
+ }
+
+ // The set relation.
+ private final SetRelationDefinition<? super C, ? super S> r;
+
+
+
+ // Private constructor.
+ private SetElement(
+ SetRelationDefinition<? super C, ? super S> r,
+ AbstractManagedObjectDefinition<C, S> d) {
+ super(d);
+ this.r = r;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public SetRelationDefinition<? super C, ? super S>
+ getRelationDefinition() {
+ return r;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void serialize(ManagedObjectPathSerializer serializer) {
+ serializer.appendManagedObjectPathElement(r,
+ getManagedObjectDefinition());
+ }
+ }
+
+
+
+ /**
* A path element representing a singleton managed object.
*/
private static final class SingletonElement
@@ -511,6 +592,18 @@
+ /**
+ * {@inheritDoc}
+ */
+ public <M extends ConfigurationClient, N extends Configuration>
+ void appendManagedObjectPathElement(
+ SetRelationDefinition<? super M, ? super N> r,
+ AbstractManagedObjectDefinition<M, N> d) {
+ serializeElement(r, d);
+ }
+
+
+
// Common element serialization.
private <M, N> void serializeElement(RelationDefinition<?, ?> r,
AbstractManagedObjectDefinition<?, ?> d) {
@@ -702,6 +795,16 @@
}
return InstantiableElement.create(ir, d, name);
+ } else if (r instanceof SetRelationDefinition) {
+ SetRelationDefinition<C, S> ir = (SetRelationDefinition<C, S>) r;
+
+ if (name != null) {
+ throw new IllegalArgumentException("Invalid path element \"" + element
+ + "\" in path \"" + path
+ + "\": instance name specified for set relation");
+ }
+
+ return SetElement.create(ir, d);
} else if (r instanceof OptionalRelationDefinition) {
OptionalRelationDefinition<C, S> or =
(OptionalRelationDefinition<C, S>) r;
@@ -782,6 +885,10 @@
return parent().child(ir, nd,
elements.get(elements.size() - 1).getName());
}
+ } else if (r instanceof SetRelationDefinition) {
+ SetRelationDefinition<? super C, ? super S> sr =
+ (SetRelationDefinition<? super C, ? super S>) r;
+ return parent().child(sr, nd);
} else if (r instanceof OptionalRelationDefinition) {
OptionalRelationDefinition<? super C, ? super S> or =
(OptionalRelationDefinition<? super C, ? super S>) r;
@@ -967,6 +1074,99 @@
/**
+ * Creates a new child managed object path beneath the provided
+ * parent path having the specified managed object definition.
+ *
+ * @param <M>
+ * The type of client managed object configuration that the
+ * child path references.
+ * @param <N>
+ * The type of server managed object configuration that the
+ * child path references.
+ * @param r
+ * The set relation referencing the child.
+ * @param d
+ * The managed object definition associated with the child
+ * (must be a sub-type of the relation).
+ * @return Returns a new child managed object path beneath the
+ * provided parent path.
+ * @throws IllegalArgumentException
+ * If the provided name is empty or blank.
+ */
+ public <M extends ConfigurationClient, N extends Configuration>
+ ManagedObjectPath<M, N> child(
+ SetRelationDefinition<? super M, ? super N> r,
+ AbstractManagedObjectDefinition<M, N> d)
+ throws IllegalArgumentException {
+ LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(
+ elements);
+ celements.add(new SetElement<M, N>(r, d));
+ return new ManagedObjectPath<M, N>(celements, r, d);
+ }
+
+
+
+ /**
+ * Creates a new child managed object path beneath the provided parent
+ * path having the managed object definition indicated by
+ * <code>name</code>.
+ *
+ * @param <M>
+ * The type of client managed object configuration that the
+ * path references.
+ * @param <N>
+ * The type of server managed object configuration that the
+ * path references.
+ * @param r
+ * The set relation referencing the child.
+ * @param name
+ * The name of the managed object definition associated with
+ * the child (must be a sub-type of the relation).
+ * @return Returns a new child managed object path beneath the
+ * provided parent path.
+ * @throws IllegalArgumentException
+ * If the provided name is empty or blank or specifies a
+ * managed object definition which is not a sub-type of the
+ * relation's child definition.
+ */
+ public <M extends ConfigurationClient, N extends Configuration>
+ ManagedObjectPath<? extends M, ? extends N> child(
+ SetRelationDefinition<M, N> r,
+ String name)
+ throws IllegalArgumentException {
+ AbstractManagedObjectDefinition<M, N> d = r.getChildDefinition();
+ return child(r, d.getChild(name));
+ }
+
+
+
+ /**
+ * Creates a new child managed object path beneath the provided
+ * parent path using the relation's child managed object definition.
+ *
+ * @param <M>
+ * The type of client managed object configuration that the
+ * child path references.
+ * @param <N>
+ * The type of server managed object configuration that the
+ * child path references.
+ * @param r
+ * The set relation referencing the child.
+ * @return Returns a new child managed object path beneath the
+ * provided parent path.
+ * @throws IllegalArgumentException
+ * If the provided name is empty or blank.
+ */
+ public <M extends ConfigurationClient, N extends Configuration>
+ ManagedObjectPath<M, N> child(
+ SetRelationDefinition<M, N> r)
+ throws IllegalArgumentException {
+ return child(r, r.getChildDefinition());
+ }
+
+
+
+ /**
* {@inheritDoc}
*/
@Override
diff --git a/opends/src/server/org/opends/server/admin/ManagedObjectPathSerializer.java b/opends/src/server/org/opends/server/admin/ManagedObjectPathSerializer.java
index 1bfd698..405f975 100644
--- a/opends/src/server/org/opends/server/admin/ManagedObjectPathSerializer.java
+++ b/opends/src/server/org/opends/server/admin/ManagedObjectPathSerializer.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -110,4 +110,26 @@
SingletonRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d);
+
+
+ /**
+ * Append a managed object path element identified by a
+ * set relation.
+ *
+ * @param <C>
+ * The type of client managed object configuration that
+ * this path element references.
+ * @param <S>
+ * The type of server managed object configuration that
+ * this path element references.
+ * @param r
+ * The set relation.
+ * @param d
+ * The managed object definition.
+ */
+ <C extends ConfigurationClient, S extends Configuration>
+ void appendManagedObjectPathElement(
+ SetRelationDefinition<? super C, ? super S> r,
+ AbstractManagedObjectDefinition<C, S> d);
+
}
diff --git a/opends/src/server/org/opends/server/admin/OptionalRelationDefinition.java b/opends/src/server/org/opends/server/admin/OptionalRelationDefinition.java
index 56cec94..2b5bf54 100644
--- a/opends/src/server/org/opends/server/admin/OptionalRelationDefinition.java
+++ b/opends/src/server/org/opends/server/admin/OptionalRelationDefinition.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -162,11 +162,10 @@
public void toString(StringBuilder builder) {
builder.append("name=");
builder.append(getName());
- builder.append(" type=composition parent=");
+ builder.append(" type=optional parent=");
builder.append(getParentDefinition().getName());
builder.append(" child=");
builder.append(getChildDefinition().getName());
- builder.append(" minOccurs=0 maxOccurs=1");
}
diff --git a/opends/src/server/org/opends/server/admin/RelationDefinition.java b/opends/src/server/org/opends/server/admin/RelationDefinition.java
index e3cbce1..bc6a863 100644
--- a/opends/src/server/org/opends/server/admin/RelationDefinition.java
+++ b/opends/src/server/org/opends/server/admin/RelationDefinition.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -68,7 +68,11 @@
* <li>instantiable relations (one to many): the relation is
* represented using a child entry directly beneath the parent.
* Referenced managed objects are represented using child entries of
- * this "relation entry".
+ * this "relation entry" and are named by the user
+ * <li>set relations (one to many): the relation is
+ * represented using a child entry directly beneath the parent.
+ * Referenced managed objects are represented using child entries of
+ * this "relation entry" whose name is the type of the managed object.
* </ul>
* Whereas, aggregations are represented by storing the DNs of the
* referenced managed objects in an attribute of the aggregating
diff --git a/opends/src/server/org/opends/server/admin/RelationDefinitionVisitor.java b/opends/src/server/org/opends/server/admin/RelationDefinitionVisitor.java
index 8a763cc..acbb429 100644
--- a/opends/src/server/org/opends/server/admin/RelationDefinitionVisitor.java
+++ b/opends/src/server/org/opends/server/admin/RelationDefinitionVisitor.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -70,6 +70,26 @@
/**
+ * Visit a set relation definition.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param rd
+ * The set relation definition to visit.
+ * @param p
+ * A visitor specified parameter.
+ * @return Returns a visitor specified result.
+ */
+ <C extends ConfigurationClient, S extends Configuration> R visitSet(
+ SetRelationDefinition<C, S> rd, P p);
+
+
+
+ /**
* Visit an optional relation definition.
*
* @param <C>
diff --git a/opends/src/server/org/opends/server/admin/SetRelationDefinition.java b/opends/src/server/org/opends/server/admin/SetRelationDefinition.java
new file mode 100644
index 0000000..426c97d
--- /dev/null
+++ b/opends/src/server/org/opends/server/admin/SetRelationDefinition.java
@@ -0,0 +1,289 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.admin;
+
+
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.opends.messages.Message;
+
+
+
+/**
+ * A managed object composite relationship definition which represents a
+ * composition of zero or more managed objects each of which must have a
+ * different type. The manage objects are named using their type name.
+ *
+ * @param <C>
+ * The type of client managed object configuration that this
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that this
+ * relation definition refers to.
+ */
+public final class SetRelationDefinition
+ <C extends ConfigurationClient, S extends Configuration>
+ extends RelationDefinition<C, S>
+{
+
+ /**
+ * An interface for incrementally constructing set relation
+ * definitions.
+ *
+ * @param <C>
+ * The type of client managed object configuration that this
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that this
+ * relation definition refers to.
+ */
+ public static final class Builder
+ <C extends ConfigurationClient, S extends Configuration>
+ extends AbstractBuilder<C, S, SetRelationDefinition<C, S>>
+ {
+
+ // The plural name of the relation.
+ private final String pluralName;
+
+ // The optional default managed objects associated with this
+ // set relation definition.
+ private final Map<String,
+ DefaultManagedObject<? extends C, ? extends S>>
+ defaultManagedObjects =
+ new HashMap<String, DefaultManagedObject<? extends C, ? extends S>>();
+
+
+
+ /**
+ * Creates a new builder which can be used to incrementally build a
+ * set relation definition.
+ *
+ * @param pd
+ * The parent managed object definition.
+ * @param name
+ * The name of the relation.
+ * @param pluralName
+ * The plural name of the relation.
+ * @param cd
+ * The child managed object definition.
+ */
+ public Builder(AbstractManagedObjectDefinition<?, ?> pd,
+ String name, String pluralName,
+ AbstractManagedObjectDefinition<C, S> cd)
+ {
+ super(pd, name, cd);
+ this.pluralName = pluralName;
+ }
+
+
+
+ /**
+ * Adds the default managed object to this set relation definition.
+ *
+ * @param defaultManagedObject
+ * The default managed object.
+ */
+ public void setDefaultManagedObject(
+ DefaultManagedObject<? extends C, ? extends S> defaultManagedObject)
+ {
+ this.defaultManagedObjects
+ .put(defaultManagedObject.getManagedObjectDefinition()
+ .getName(), defaultManagedObject);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected SetRelationDefinition<C, S> buildInstance(
+ Common<C, S> common)
+ {
+ return new SetRelationDefinition<C, S>(common, pluralName,
+ defaultManagedObjects);
+ }
+
+ }
+
+
+
+ // The plural name of the relation.
+ private final String pluralName;
+
+ // The optional default managed objects associated with this
+ // set relation definition.
+ private final Map<String,
+ DefaultManagedObject<? extends C, ? extends S>>
+ defaultManagedObjects;
+
+
+
+ // Private constructor.
+ private SetRelationDefinition(
+ Common<C, S> common,
+ String pluralName,
+ Map<String,
+ DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects)
+ {
+ super(common);
+ this.pluralName = pluralName;
+ this.defaultManagedObjects = defaultManagedObjects;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p)
+ {
+ return v.visitSet(this, p);
+ }
+
+
+
+ /**
+ * Gets the named default managed object associated with this set
+ * relation definition.
+ *
+ * @param name
+ * The name of the default managed object (for set relations
+ * this is the type of the default managed object).
+ * @return The named default managed object.
+ * @throws IllegalArgumentException
+ * If there is no default managed object associated with the
+ * provided name.
+ */
+ public DefaultManagedObject<? extends C, ? extends S> getDefaultManagedObject(
+ String name) throws IllegalArgumentException
+ {
+ if (!defaultManagedObjects.containsKey(name))
+ {
+ throw new IllegalArgumentException(
+ "unrecognized default managed object \"" + name + "\"");
+ }
+ return defaultManagedObjects.get(name);
+ }
+
+
+
+ /**
+ * Gets the names of the default managed objects associated with this
+ * set relation definition.
+ *
+ * @return An unmodifiable set containing the names of the default
+ * managed object.
+ */
+ public Set<String> getDefaultManagedObjectNames()
+ {
+ return Collections.unmodifiableSet(defaultManagedObjects.keySet());
+ }
+
+
+
+ /**
+ * Gets the plural name of the relation.
+ *
+ * @return The plural name of the relation.
+ */
+ public String getPluralName()
+ {
+ return pluralName;
+ }
+
+
+
+ /**
+ * Gets the user friendly plural name of this relation definition in
+ * the default locale.
+ *
+ * @return Returns the user friendly plural name of this relation
+ * definition in the default locale.
+ */
+ public Message getUserFriendlyPluralName()
+ {
+ return getUserFriendlyPluralName(Locale.getDefault());
+ }
+
+
+
+ /**
+ * Gets the user friendly plural name of this relation definition in
+ * the specified locale.
+ *
+ * @param locale
+ * The locale.
+ * @return Returns the user friendly plural name of this relation
+ * definition in the specified locale.
+ */
+ public Message getUserFriendlyPluralName(Locale locale)
+ {
+ String property =
+ "relation." + getName() + ".user-friendly-plural-name";
+ return ManagedObjectDefinitionI18NResource.getInstance()
+ .getMessage(getParentDefinition(), property, locale);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void toString(StringBuilder builder)
+ {
+ builder.append("name=");
+ builder.append(getName());
+ builder.append(" type=set parent=");
+ builder.append(getParentDefinition().getName());
+ builder.append(" child=");
+ builder.append(getChildDefinition().getName());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void initialize() throws Exception
+ {
+ for (DefaultManagedObject<?, ?> dmo : defaultManagedObjects
+ .values())
+ {
+ dmo.initialize();
+ }
+ }
+}
diff --git a/opends/src/server/org/opends/server/admin/SingletonRelationDefinition.java b/opends/src/server/org/opends/server/admin/SingletonRelationDefinition.java
index 1d965f6..2f4f746 100644
--- a/opends/src/server/org/opends/server/admin/SingletonRelationDefinition.java
+++ b/opends/src/server/org/opends/server/admin/SingletonRelationDefinition.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -163,11 +163,10 @@
public void toString(StringBuilder builder) {
builder.append("name=");
builder.append(getName());
- builder.append(" type=composition parent=");
+ builder.append(" type=singleton parent=");
builder.append(getParentDefinition().getName());
builder.append(" child=");
builder.append(getChildDefinition().getName());
- builder.append(" minOccurs=1 maxOccurs=1");
}
diff --git a/opends/src/server/org/opends/server/admin/client/AdminSecurityException.java b/opends/src/server/org/opends/server/admin/client/AdminSecurityException.java
index b24970a..2f92e71 100644
--- a/opends/src/server/org/opends/server/admin/client/AdminSecurityException.java
+++ b/opends/src/server/org/opends/server/admin/client/AdminSecurityException.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.client;
@@ -42,6 +42,13 @@
public abstract class AdminSecurityException extends AdminClientException {
/**
+ * Fake serialization ID.
+ */
+ private static final long serialVersionUID = 1L;
+
+
+
+ /**
* Create a security exception with a message and cause.
*
* @param message
diff --git a/opends/src/server/org/opends/server/admin/client/ManagedObject.java b/opends/src/server/org/opends/server/admin/client/ManagedObject.java
index 16af3a9..3b16697 100644
--- a/opends/src/server/org/opends/server/admin/client/ManagedObject.java
+++ b/opends/src/server/org/opends/server/admin/client/ManagedObject.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2007-2008 Sun Microsystems, Inc.
+ * Copyright 2007-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.client;
@@ -49,6 +49,7 @@
import org.opends.server.admin.PropertyIsReadOnlyException;
import org.opends.server.admin.PropertyIsSingleValuedException;
import org.opends.server.admin.PropertyProvider;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.SingletonRelationDefinition;
@@ -227,6 +228,45 @@
/**
+ * Creates a new child managed object bound to the specified
+ * set relation. The new managed object will initially not
+ * contain any property values (including mandatory properties).
+ * Once the managed object has been configured it can be added to
+ * the server using the {@link #commit()} method.
+ *
+ * @param <C>
+ * The expected type of the child managed object
+ * configuration client.
+ * @param <S>
+ * The expected type of the child managed object
+ * server configuration.
+ * @param <CC>
+ * The actual type of the added managed object
+ * configuration client.
+ * @param r
+ * The set relation definition.
+ * @param d
+ * The definition of the managed object to be created.
+ * @param exceptions
+ * A collection in which to place any
+ * {@link DefaultBehaviorException}s that occurred whilst
+ * attempting to determine the managed object's default
+ * values.
+ * @return Returns a new child managed object bound to the specified
+ * set relation.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with this
+ * managed object's definition.
+ */
+ <C extends ConfigurationClient, S extends Configuration, CC extends C>
+ ManagedObject<CC> createChild(SetRelationDefinition<C, S> r,
+ ManagedObjectDefinition<CC, ? extends S> d,
+ Collection<DefaultBehaviorException> exceptions)
+ throws IllegalArgumentException;
+
+
+
+ /**
* Retrieves an instantiable child managed object.
*
* @param <C>
@@ -361,6 +401,52 @@
/**
+ * Retrieves a set child managed object.
+ *
+ * @param <C>
+ * The requested type of the child managed object
+ * configuration client.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param r
+ * The set relation definition.
+ * @param name
+ * The name of the child managed object.
+ * @return Returns the set child managed object.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with this
+ * managed object's definition.
+ * @throws DefinitionDecodingException
+ * If the managed object was found but its type could not
+ * be determined.
+ * @throws ManagedObjectDecodingException
+ * If the managed object was found but one or more of its
+ * properties could not be decoded.
+ * @throws ManagedObjectNotFoundException
+ * If the requested managed object could not be found on
+ * the server.
+ * @throws ConcurrentModificationException
+ * If this managed object has been removed from the server
+ * by another client.
+ * @throws AuthorizationException
+ * If the server refuses to retrieve the managed object
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getChild(SetRelationDefinition<C, S> r,
+ String name) throws IllegalArgumentException, DefinitionDecodingException,
+ ManagedObjectDecodingException, ManagedObjectNotFoundException,
+ ConcurrentModificationException, AuthorizationException,
+ CommunicationException;
+
+
+
+ /**
* Creates a client configuration view of this managed object.
* Modifications made to this managed object will be reflected in
* the client configuration view and vice versa.
@@ -582,6 +668,80 @@
/**
+ * Lists the child managed objects associated with the specified set
+ * relation.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param r
+ * The set relation definition.
+ * @return Returns the names of the child managed objects which for
+ * set relations are the definition names of each managed
+ * object.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with this
+ * managed object's definition.
+ * @throws ConcurrentModificationException
+ * If this managed object has been removed from the server
+ * by another client.
+ * @throws AuthorizationException
+ * If the server refuses to list the managed objects because
+ * the client does not have the correct privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ <C extends ConfigurationClient, S extends Configuration>
+ String[] listChildren(SetRelationDefinition<C, S> r)
+ throws IllegalArgumentException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException;
+
+
+
+ /**
+ * Lists the child managed objects associated with the specified set
+ * relation which are a sub-type of the specified managed object
+ * definition.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param r
+ * The set relation definition.
+ * @param d
+ * The managed object definition.
+ * @return Returns the names of the child managed objects which for
+ * set relations are the definition names of each managed
+ * object.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with this
+ * managed object's definition.
+ * @throws ConcurrentModificationException
+ * If this managed object has been removed from the server
+ * by another client.
+ * @throws AuthorizationException
+ * If the server refuses to list the managed objects because
+ * the client does not have the correct privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ <C extends ConfigurationClient, S extends Configuration>
+ String[] listChildren(SetRelationDefinition<C, S> r,
+ AbstractManagedObjectDefinition<? extends C, ? extends S> d)
+ throws IllegalArgumentException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException;
+
+
+
+ /**
* Removes the named instantiable child managed object.
*
* @param <C>
@@ -666,6 +826,49 @@
/**
+ * Removes s set child managed object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param r
+ * The set relation definition.
+ * @param name
+ * The name of the child managed object to be removed.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with this
+ * managed object's definition.
+ * @throws ManagedObjectNotFoundException
+ * If the managed object could not be removed because it
+ * could not found on the server.
+ * @throws OperationRejectedException
+ * If the managed object cannot be removed due to some
+ * client-side or server-side constraint which cannot be
+ * satisfied (for example, if it is referenced by another
+ * managed object).
+ * @throws ConcurrentModificationException
+ * If this managed object has been removed from the server
+ * by another client.
+ * @throws AuthorizationException
+ * If the server refuses to remove the managed objects
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ <C extends ConfigurationClient, S extends Configuration>
+ void removeChild(SetRelationDefinition<C, S> r, String name)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ OperationRejectedException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException;
+
+
+
+ /**
* Sets a new pending value for the specified property.
* <p>
* See the class description for more information regarding pending
diff --git a/opends/src/server/org/opends/server/admin/client/ManagementContext.java b/opends/src/server/org/opends/server/admin/client/ManagementContext.java
index e971c34..0a1d047 100644
--- a/opends/src/server/org/opends/server/admin/client/ManagementContext.java
+++ b/opends/src/server/org/opends/server/admin/client/ManagementContext.java
@@ -22,13 +22,14 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.client;
+import java.util.Set;
import java.util.SortedSet;
import org.opends.server.admin.AbstractManagedObjectDefinition;
@@ -41,6 +42,7 @@
import org.opends.server.admin.OptionalRelationDefinition;
import org.opends.server.admin.PropertyDefinition;
import org.opends.server.admin.PropertyException;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.client.spi.Driver;
import org.opends.server.admin.std.client.RootCfgClient;
@@ -155,6 +157,54 @@
/**
+ * Deletes s set child managed object from the
+ * named parent managed object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param parent
+ * The path of the parent managed object.
+ * @param rd
+ * The set relation definition.
+ * @param name
+ * The name of the child managed object to be removed.
+ * @return Returns <code>true</code> if the set
+ * child managed object was found, or <code>false</code>
+ * if it was not found.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with the
+ * parent managed object's definition.
+ * @throws ManagedObjectNotFoundException
+ * If the parent managed object could not be found.
+ * @throws OperationRejectedException
+ * If the managed object cannot be removed due to some
+ * client-side or server-side constraint which cannot be
+ * satisfied (for example, if it is referenced by another
+ * managed object).
+ * @throws AuthorizationException
+ * If the server refuses to remove the managed objects
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ boolean deleteManagedObject(
+ ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd,
+ String name) throws IllegalArgumentException,
+ ManagedObjectNotFoundException, OperationRejectedException,
+ AuthorizationException, CommunicationException {
+ return getDriver().deleteManagedObject(parent, rd, name);
+ }
+
+
+
+ /**
* Gets the named managed object.
*
* @param <C>
@@ -236,7 +286,12 @@
DefinitionDecodingException, AuthorizationException,
ManagedObjectNotFoundException, CommunicationException,
PropertyException {
- return getDriver().getPropertyValue(path, pd);
+ Set<PD> values = getPropertyValues(path, pd);
+ if (values.isEmpty()) {
+ return null;
+ } else {
+ return values.iterator().next();
+ }
}
@@ -343,7 +398,7 @@
ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd)
throws IllegalArgumentException, ManagedObjectNotFoundException,
AuthorizationException, CommunicationException {
- return getDriver().listManagedObjects(parent, rd);
+ return listManagedObjects(parent, rd, rd.getChildDefinition());
}
@@ -392,6 +447,44 @@
/**
+ * Lists the child managed objects of the named parent managed
+ * object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param parent
+ * The path of the parent managed object.
+ * @param rd
+ * The set relation definition.
+ * @return Returns the names of the child managed objects.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with the
+ * parent managed object's definition.
+ * @throws ManagedObjectNotFoundException
+ * If the parent managed object could not be found.
+ * @throws AuthorizationException
+ * If the server refuses to list the managed objects
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ String[] listManagedObjects(
+ ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ AuthorizationException, CommunicationException {
+ return getDriver().listManagedObjects(parent, rd, rd.getChildDefinition());
+ }
+
+
+
+ /**
* Determines whether or not the named managed object exists.
*
* @param path
diff --git a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliGlobalAdmin.java b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliGlobalAdmin.java
index de2d34c..9212cd1 100644
--- a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliGlobalAdmin.java
+++ b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliGlobalAdmin.java
@@ -22,15 +22,16 @@
* CDDL HEADER END
*
*
- * Copyright 2007-2008 Sun Microsystems, Inc.
+ * Copyright 2007-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.client.cli;
-import org.opends.messages.Message;
-import org.opends.messages.MessageBuilder;
+
+
import static org.opends.messages.AdminMessages.*;
import static org.opends.messages.DSConfigMessages.*;
import static org.opends.messages.ToolMessages.*;
+import static org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.*;
import static org.opends.server.tools.ToolConstants.*;
import java.io.OutputStream;
@@ -50,6 +51,8 @@
import org.opends.admin.ads.ADSContextException;
import org.opends.admin.ads.ADSContext.AdministratorProperty;
import org.opends.admin.ads.ADSContextException.ErrorType;
+import org.opends.messages.Message;
+import org.opends.messages.MessageBuilder;
import org.opends.server.tools.dsconfig.ArgumentExceptionFactory;
import org.opends.server.types.Privilege;
import org.opends.server.util.args.Argument;
@@ -59,8 +62,6 @@
import org.opends.server.util.args.SubCommand;
import org.opends.server.util.table.TableBuilder;
import org.opends.server.util.table.TextTablePrinter;
-
-import static org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.*;
/**
* This class is handling user Admin CLI.
*/
@@ -88,11 +89,6 @@
private DsFrameworkCliParser argParser;
/**
- * The verbose argument.
- */
- private BooleanArgument verboseArg;
-
- /**
* The enumeration containing the different subCommand names.
*/
private enum SubCommandNameEnum
@@ -140,6 +136,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public String toString()
{
return name;
@@ -238,7 +235,7 @@
/**
* The subcommand list.
*/
- private HashSet<SubCommand> subCommands = new HashSet<SubCommand>();
+ private final HashSet<SubCommand> subCommands = new HashSet<SubCommand>();
/**
* Indicates whether this subCommand should be hidden in the usage
@@ -281,7 +278,6 @@
public void initializeCliGroup(DsFrameworkCliParser argParser,
BooleanArgument verboseArg) throws ArgumentException
{
- this.verboseArg = verboseArg;
isHidden = false;
groupName = "admin-user";
this.argParser = argParser;
diff --git a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java
index 9383cc1..4fe04e5 100644
--- a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java
+++ b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java
@@ -22,17 +22,16 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.client.cli;
-import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.messages.AdminMessages.*;
import static org.opends.messages.DSConfigMessages.*;
-import org.opends.messages.Message;
+import static org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.*;
import static org.opends.server.tools.ToolConstants.*;
-import static org.opends.server.util.ServerConstants.MAX_LINE_WIDTH;
-import static org.opends.server.util.StaticUtils.wrapText;
+import static org.opends.server.util.ServerConstants.*;
+import static org.opends.server.util.StaticUtils.*;
import java.io.IOException;
import java.io.OutputStream;
@@ -41,37 +40,23 @@
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
-import java.util.logging.Logger;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
import org.opends.admin.ads.ADSContextException;
import org.opends.admin.ads.util.ConnectionUtils;
-import org.opends.server.loggers.debug.DebugTracer;
+import org.opends.messages.Message;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.SubCommand;
-import static org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.*;
-
/**
* This class will parse CLI arguments for the dsframework command lines.
*/
public class DsFrameworkCliParser extends SecureConnectionCliParser
{
/**
- * The tracer object for the debug logger.
- */
- private static final DebugTracer TRACER = getTracer();
-
- /**
- * The Logger.
- */
- static private final Logger LOG =
- Logger.getLogger(DsFrameworkCliParser.class.getName());
-
- /**
* The different CLI group.
*/
public HashSet<DsFrameworkCliSubCommandGroup> cliGroup;
diff --git a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServer.java b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServer.java
index ce2bb3f..f2fb276 100644
--- a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServer.java
+++ b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServer.java
@@ -22,15 +22,16 @@
* CDDL HEADER END
*
*
- * Copyright 2006-2008 Sun Microsystems, Inc.
+ * Copyright 2006-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.client.cli;
-import org.opends.messages.Message;
-import org.opends.messages.MessageBuilder;
+
+
import static org.opends.messages.AdminMessages.*;
import static org.opends.messages.DSConfigMessages.*;
import static org.opends.messages.ToolMessages.*;
+import static org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.*;
import static org.opends.server.tools.ToolConstants.*;
import java.io.OutputStream;
@@ -50,6 +51,8 @@
import org.opends.admin.ads.ADSContextException;
import org.opends.admin.ads.ADSContext.ServerProperty;
import org.opends.admin.ads.ADSContextException.ErrorType;
+import org.opends.messages.Message;
+import org.opends.messages.MessageBuilder;
import org.opends.server.tools.dsconfig.ArgumentExceptionFactory;
import org.opends.server.util.args.Argument;
import org.opends.server.util.args.ArgumentException;
@@ -59,8 +62,6 @@
import org.opends.server.util.args.SubCommand;
import org.opends.server.util.table.TableBuilder;
import org.opends.server.util.table.TextTablePrinter;
-
-import static org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.*;
/**
* This class is handling server group CLI.
*/
@@ -88,11 +89,6 @@
private DsFrameworkCliParser argParser;
/**
- * The verbose argument.
- */
- private BooleanArgument verboseArg;
-
- /**
* The enumeration containing the different subCommand names.
*/
private enum SubCommandNameEnum
@@ -139,6 +135,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public String toString()
{
return name;
@@ -235,7 +232,7 @@
/**
* The subcommand list.
*/
- private HashSet<SubCommand> subCommands = new HashSet<SubCommand>();
+ private final HashSet<SubCommand> subCommands = new HashSet<SubCommand>();
/**
* Indicates whether this subCommand should be hidden in the usage
@@ -278,7 +275,6 @@
public void initializeCliGroup(DsFrameworkCliParser argParser,
BooleanArgument verboseArg) throws ArgumentException
{
- this.verboseArg = verboseArg;
isHidden = false;
groupName = "server";
this.argParser = argParser;
diff --git a/opends/src/server/org/opends/server/admin/client/cli/SecureConnectionCliParser.java b/opends/src/server/org/opends/server/admin/client/cli/SecureConnectionCliParser.java
index b7b455b..175ff7c 100644
--- a/opends/src/server/org/opends/server/admin/client/cli/SecureConnectionCliParser.java
+++ b/opends/src/server/org/opends/server/admin/client/cli/SecureConnectionCliParser.java
@@ -22,42 +22,39 @@
* CDDL HEADER END
*
*
- * Copyright 2007-2008 Sun Microsystems, Inc.
+ * Copyright 2007-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.client.cli;
-import static org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.*;
-import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
-import static org.opends.server.loggers.debug.DebugLogger.getTracer;
import static org.opends.messages.ToolMessages.*;
-
-import org.opends.messages.Message;
-import org.opends.messages.MessageBuilder;
+import static org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.tools.ToolConstants.*;
-import static org.opends.server.util.ServerConstants.MAX_LINE_WIDTH;
-import static org.opends.server.util.StaticUtils.wrapText;
+import static org.opends.server.util.ServerConstants.*;
+import static org.opends.server.util.StaticUtils.*;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Collection;
import java.util.LinkedHashSet;
-import java.util.logging.Logger;
import javax.net.ssl.KeyManager;
import org.opends.admin.ads.util.ApplicationTrustManager;
+import org.opends.messages.Message;
+import org.opends.messages.MessageBuilder;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.util.PasswordReader;
import org.opends.server.util.args.Argument;
import org.opends.server.util.args.ArgumentException;
+import org.opends.server.util.args.ArgumentGroup;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.FileBasedArgument;
import org.opends.server.util.args.StringArgument;
import org.opends.server.util.args.SubCommandArgumentParser;
-import org.opends.server.util.args.ArgumentGroup;
/**
* This is a commodity class that can be used to check the arguments required
@@ -105,12 +102,6 @@
public static String EOL = System.getProperty("line.separator");
/**
- * The Logger.
- */
- static private final Logger LOG =
- Logger.getLogger(SecureConnectionCliParser.class.getName());
-
- /**
* Creates a new instance of this argument parser with no arguments.
*
* @param mainClassName
diff --git a/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java b/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
index 5e0f300..c979a74 100644
--- a/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
+++ b/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.client.ldap;
@@ -69,6 +69,7 @@
import org.opends.server.admin.PropertyOption;
import org.opends.server.admin.Reference;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.UnknownPropertyDefinitionException;
import org.opends.server.admin.DefinitionDecodingException.Reason;
import org.opends.server.admin.client.AuthorizationException;
@@ -400,6 +401,51 @@
* {@inheritDoc}
*/
@Override
+ public <C extends ConfigurationClient, S extends Configuration>
+ String[] listManagedObjects(
+ ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd,
+ AbstractManagedObjectDefinition<? extends C, ? extends S> d)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(parent, rd);
+
+ if (!managedObjectExists(parent)) {
+ throw new ManagedObjectNotFoundException();
+ }
+
+ // Get the search base DN.
+ LdapName dn = LDAPNameBuilder.create(parent, rd, profile);
+
+ // Retrieve only those entries which are sub-types of the
+ // specified definition.
+ StringBuilder builder = new StringBuilder();
+ builder.append("(objectclass=");
+ builder.append(profile.getObjectClass(d));
+ builder.append(')');
+ String filter = builder.toString();
+
+ List<String> children = new ArrayList<String>();
+ try {
+ for (LdapName child : connection.listEntries(dn, filter)) {
+ children.add(child.getRdn(child.size() - 1).getValue().toString());
+ }
+ } catch (NameNotFoundException e) {
+ // Ignore this - it means that the base entry does not exist
+ // (which it might not if this managed object has just been
+ // created.
+ } catch (NamingException e) {
+ adaptNamingException(e);
+ }
+
+ return children.toArray(new String[children.size()]);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public boolean managedObjectExists(ManagedObjectPath<?, ?> path)
throws ManagedObjectNotFoundException, AuthorizationException,
CommunicationException {
diff --git a/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java b/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
index 30c1c43..70a46b1 100644
--- a/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
+++ b/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2007-2008 Sun Microsystems, Inc.
+ * Copyright 2007-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.client.ldap;
@@ -54,6 +54,7 @@
import org.opends.server.admin.PropertyValueVisitor;
import org.opends.server.admin.Reference;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.UnknownPropertyDefinitionException;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
@@ -174,16 +175,23 @@
}
// We may need to create the parent "relation" entry if this is a
- // child of an instantiable relation.
+ // child of an instantiable or set relation.
RelationDefinition<?, ?> r = path.getRelationDefinition();
- if (r instanceof InstantiableRelationDefinition) {
- InstantiableRelationDefinition<?, ?> ir =
- (InstantiableRelationDefinition<?, ?>) r;
+ if (r instanceof InstantiableRelationDefinition
+ || r instanceof SetRelationDefinition) {
// TODO: this implementation does not handle relations which
// comprise of more than one RDN arc (this will probably never
// be required anyway).
- LdapName dn = LDAPNameBuilder.create(parent, ir, driver.getLDAPProfile());
+ LdapName dn;
+ if (r instanceof InstantiableRelationDefinition) {
+ dn = LDAPNameBuilder.create(parent,
+ (InstantiableRelationDefinition) r, driver.getLDAPProfile());
+ } else {
+ dn = LDAPNameBuilder.create(parent,
+ (SetRelationDefinition) r, driver.getLDAPProfile());
+ }
+
if (!driver.entryExists(dn)) {
// We need to create the entry.
Attributes attributes = new BasicAttributes();
@@ -191,7 +199,7 @@
// Create the branch's object class attribute.
Attribute oc = new BasicAttribute("objectClass");
for (String objectClass : driver.getLDAPProfile()
- .getInstantiableRelationObjectClasses(ir)) {
+ .getRelationObjectClasses(r)) {
oc.add(objectClass);
}
attributes.put(oc);
diff --git a/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java b/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java
index a943e3a..0bbc756 100644
--- a/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java
+++ b/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.client.ldap;
@@ -44,6 +44,7 @@
import org.opends.server.admin.ManagedObjectPathSerializer;
import org.opends.server.admin.OptionalRelationDefinition;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.SingletonRelationDefinition;
@@ -96,6 +97,30 @@
return builder.getInstance();
}
+
+
+ /**
+ * Creates a new LDAP name representing the specified managed object
+ * path and set relation.
+ *
+ * @param path
+ * The managed object path.
+ * @param relation
+ * The child set relation.
+ * @param profile
+ * The LDAP profile which should be used to construct LDAP
+ * names.
+ * @return Returns a new LDAP name representing the specified
+ * managed object path and set relation.
+ */
+ public static LdapName create(ManagedObjectPath<?, ?> path,
+ SetRelationDefinition<?, ?> relation, LDAPProfile profile) {
+ LDAPNameBuilder builder = new LDAPNameBuilder(profile);
+ path.serialize(builder);
+ builder.appendManagedObjectPathElement(relation);
+ return builder.getInstance();
+ }
+
// The list of RDNs in big-endian order.
private final LinkedList<Rdn> rdns;
@@ -126,10 +151,10 @@
InstantiableRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d, String name) {
// Add the RDN sequence representing the relation.
- appendManagedObjectPathElement((RelationDefinition<?, ?>) r);
+ appendManagedObjectPathElement(r);
// Now add the single RDN representing the named instance.
- String type = profile.getInstantiableRelationChildRDNType(r);
+ String type = profile.getRelationChildRDNType(r);
try {
Rdn rdn = new Rdn(type, name.trim());
rdns.add(rdn);
@@ -168,7 +193,7 @@
OptionalRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d) {
// Add the RDN sequence representing the relation.
- appendManagedObjectPathElement((RelationDefinition<?, ?>) r);
+ appendManagedObjectPathElement(r);
}
@@ -181,7 +206,30 @@
SingletonRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d) {
// Add the RDN sequence representing the relation.
- appendManagedObjectPathElement((RelationDefinition<?, ?>) r);
+ appendManagedObjectPathElement(r);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ void appendManagedObjectPathElement(
+ SetRelationDefinition<? super C, ? super S> r,
+ AbstractManagedObjectDefinition<C, S> d) {
+ // Add the RDN sequence representing the relation.
+ appendManagedObjectPathElement(r);
+
+ // Now add the single RDN representing the named instance.
+ String type = profile.getRelationChildRDNType(r);
+ try {
+ Rdn rdn = new Rdn(type, d.getName());
+ rdns.add(rdn);
+ } catch (InvalidNameException e1) {
+ // Should not happen.
+ throw new RuntimeException(e1);
+ }
}
diff --git a/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java b/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java
index 0f1902b..947256d 100644
--- a/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java
+++ b/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.client.spi;
@@ -59,7 +59,9 @@
import org.opends.server.admin.PropertyOption;
import org.opends.server.admin.RelationDefinition;
import org.opends.server.admin.RelationDefinitionVisitor;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.SingletonRelationDefinition;
+import org.opends.server.admin.DefinitionDecodingException.Reason;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.ClientConstraintHandler;
import org.opends.server.admin.client.CommunicationException;
@@ -163,6 +165,25 @@
+ /**
+ * {@inheritDoc}
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ Void visitSet(
+ SetRelationDefinition<C, S> rd, Void p) {
+ for (String name : rd.getDefaultManagedObjectNames()) {
+ DefaultManagedObject<? extends C, ? extends S> dmo = rd
+ .getDefaultManagedObject(name);
+ ManagedObjectDefinition<? extends C, ? extends S> d = dmo
+ .getManagedObjectDefinition();
+ ManagedObject<? extends C> child = createChild(rd, d, null);
+ createDefaultManagedObject(d, child, dmo);
+ }
+ return null;
+ }
+
+
+
// Create the child managed object.
private void createDefaultManagedObject(ManagedObjectDefinition<?, ?> d,
ManagedObject<?> child, DefaultManagedObject<?, ?> dmo) {
@@ -411,6 +432,24 @@
/**
* {@inheritDoc}
*/
+ public final <C extends ConfigurationClient, S extends Configuration,
+ CC extends C>
+ ManagedObject<CC> createChild(
+ SetRelationDefinition<C, S> r,
+ ManagedObjectDefinition<CC, ? extends S> d,
+ Collection<DefaultBehaviorException> exceptions)
+ throws IllegalArgumentException {
+ validateRelationDefinition(r);
+
+ ManagedObjectPath<CC, ? extends S> childPath = path.child(r, d);
+ return createNewManagedObject(d, childPath, null, null, exceptions);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
public final <C extends ConfigurationClient, S extends Configuration>
ManagedObject<? extends C> getChild(
InstantiableRelationDefinition<C, S> r, String name)
@@ -463,6 +502,40 @@
/**
* {@inheritDoc}
*/
+ public final <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getChild(
+ SetRelationDefinition<C, S> r, String name)
+ throws IllegalArgumentException, DefinitionDecodingException,
+ ManagedObjectDecodingException, ManagedObjectNotFoundException,
+ ConcurrentModificationException, AuthorizationException,
+ CommunicationException {
+ validateRelationDefinition(r);
+ ensureThisManagedObjectExists();
+ Driver ctx = getDriver();
+
+ AbstractManagedObjectDefinition<C, S> d = r.getChildDefinition();
+ AbstractManagedObjectDefinition<? extends C, ? extends S> cd;
+
+ try
+ {
+ cd = d.getChild(name);
+ }
+ catch (IllegalArgumentException e)
+ {
+ // Unrecognized definition name - report this as a decoding
+ // exception.
+ throw new DefinitionDecodingException(d,
+ Reason.WRONG_TYPE_INFORMATION);
+ }
+
+ return ctx.getManagedObject(path.child(r, cd));
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
public final T getConfiguration() {
return definition.createClientConfiguration(this);
}
@@ -590,6 +663,39 @@
* {@inheritDoc}
*/
public final <C extends ConfigurationClient, S extends Configuration>
+ String[] listChildren(
+ SetRelationDefinition<C, S> r) throws IllegalArgumentException,
+ ConcurrentModificationException, AuthorizationException,
+ CommunicationException {
+ return listChildren(r, r.getChildDefinition());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ String[] listChildren(
+ SetRelationDefinition<C, S> r,
+ AbstractManagedObjectDefinition<? extends C, ? extends S> d)
+ throws IllegalArgumentException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(r);
+ Driver ctx = getDriver();
+ try {
+ return ctx.listManagedObjects(path, r, d);
+ } catch (ManagedObjectNotFoundException e) {
+ throw new ConcurrentModificationException();
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
void removeChild(
InstantiableRelationDefinition<C, S> r, String name)
throws IllegalArgumentException, ManagedObjectNotFoundException,
@@ -641,6 +747,32 @@
/**
* {@inheritDoc}
*/
+ public final <C extends ConfigurationClient, S extends Configuration>
+ void removeChild(
+ SetRelationDefinition<C, S> r, String name)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ OperationRejectedException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(r);
+ Driver ctx = getDriver();
+ boolean found;
+
+ try {
+ found = ctx.deleteManagedObject(path, r, name);
+ } catch (ManagedObjectNotFoundException e) {
+ throw new ConcurrentModificationException();
+ }
+
+ if (!found) {
+ throw new ManagedObjectNotFoundException();
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
public final <PD> void setPropertyValue(PropertyDefinition<PD> pd, PD value)
throws IllegalPropertyValueException, PropertyIsReadOnlyException,
PropertyIsMandatoryException, IllegalArgumentException {
diff --git a/opends/src/server/org/opends/server/admin/client/spi/Driver.java b/opends/src/server/org/opends/server/admin/client/spi/Driver.java
index 8befab9..ea501a0 100644
--- a/opends/src/server/org/opends/server/admin/client/spi/Driver.java
+++ b/opends/src/server/org/opends/server/admin/client/spi/Driver.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.client.spi;
@@ -34,7 +34,6 @@
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import java.util.Set;
import java.util.SortedSet;
import org.opends.messages.Message;
@@ -60,6 +59,7 @@
import org.opends.server.admin.PropertyOption;
import org.opends.server.admin.RelationDefinition;
import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
import org.opends.server.admin.DefinitionDecodingException.Reason;
import org.opends.server.admin.client.AuthorizationException;
@@ -403,6 +403,56 @@
/**
+ * Deletes the named instantiable child managed object from the
+ * named parent managed object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param parent
+ * The path of the parent managed object.
+ * @param rd
+ * The instantiable relation definition.
+ * @param name
+ * The name of the child managed object to be removed.
+ * @return Returns <code>true</code> if the named instantiable
+ * child managed object was found, or <code>false</code>
+ * if it was not found.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with the
+ * parent managed object's definition.
+ * @throws ManagedObjectNotFoundException
+ * If the parent managed object could not be found.
+ * @throws OperationRejectedException
+ * If the managed object cannot be removed due to some
+ * client-side or server-side constraint which cannot be
+ * satisfied (for example, if it is referenced by another
+ * managed object).
+ * @throws AuthorizationException
+ * If the server refuses to remove the managed objects
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ boolean deleteManagedObject(
+ ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd,
+ String name) throws IllegalArgumentException,
+ ManagedObjectNotFoundException, OperationRejectedException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(parent, rd);
+ ManagedObjectPath<?, ?> child = parent.child(rd, name);
+ return doDeleteManagedObject(child);
+ }
+
+
+
+ /**
* Gets the named managed object. The path is guaranteed to be
* non-empty, so implementations do not need to worry about handling
* this special case.
@@ -442,60 +492,6 @@
/**
- * 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
- * The path of the managed object containing the property.
- * @param pd
- * The property to be retrieved.
- * @return Returns the property's effective value, or
- * <code>null</code> if there are no values defined.
- * @throws IllegalArgumentException
- * If the property definition is not associated with the
- * referenced managed object's definition.
- * @throws DefinitionDecodingException
- * If the managed object was found but its type could not
- * be determined.
- * @throws PropertyException
- * If the managed object was found but the requested
- * property could not be decoded.
- * @throws ManagedObjectNotFoundException
- * If the requested managed object could not be found on
- * the server.
- * @throws AuthorizationException
- * If the server refuses to retrieve the managed object
- * because the client does not have the correct
- * privileges.
- * @throws CommunicationException
- * If the client cannot contact the server due to an
- * underlying communication problem.
- */
- public final <C extends ConfigurationClient, S extends Configuration, PD>
- PD getPropertyValue(ManagedObjectPath<C, S> path,
- PropertyDefinition<PD> pd) throws IllegalArgumentException,
- DefinitionDecodingException, AuthorizationException,
- ManagedObjectNotFoundException, CommunicationException,
- PropertyException {
- Set<PD> values = getPropertyValues(path, pd);
- if (values.isEmpty()) {
- return null;
- } else {
- return values.iterator().next();
- }
- }
-
-
-
- /**
* Gets the effective values of a property in the named managed
* object.
* <p>
@@ -565,44 +561,6 @@
/**
* Lists the child managed objects of the named parent managed
- * object.
- *
- * @param <C>
- * The type of client managed object configuration that the
- * relation definition refers to.
- * @param <S>
- * The type of server managed object configuration that the
- * relation definition refers to.
- * @param parent
- * The path of the parent managed object.
- * @param rd
- * The instantiable relation definition.
- * @return Returns the names of the child managed objects.
- * @throws IllegalArgumentException
- * If the relation definition is not associated with the
- * parent managed object's definition.
- * @throws ManagedObjectNotFoundException
- * If the parent managed object could not be found.
- * @throws AuthorizationException
- * If the server refuses to list the managed objects
- * because the client does not have the correct
- * privileges.
- * @throws CommunicationException
- * If the client cannot contact the server due to an
- * underlying communication problem.
- */
- public final <C extends ConfigurationClient, S extends Configuration>
- String[] listManagedObjects(
- ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd)
- throws IllegalArgumentException, ManagedObjectNotFoundException,
- AuthorizationException, CommunicationException {
- return listManagedObjects(parent, rd, rd.getChildDefinition());
- }
-
-
-
- /**
- * Lists the child managed objects of the named parent managed
* object which are a sub-type of the specified managed object
* definition.
*
@@ -643,6 +601,47 @@
/**
+ * Lists the child managed objects of the named parent managed
+ * object which are a sub-type of the specified managed object
+ * definition.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param parent
+ * The path of the parent managed object.
+ * @param rd
+ * The set relation definition.
+ * @param d
+ * The managed object definition.
+ * @return Returns the names of the child managed objects which are
+ * a sub-type of the specified managed object definition.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with the
+ * parent managed object's definition.
+ * @throws ManagedObjectNotFoundException
+ * If the parent managed object could not be found.
+ * @throws AuthorizationException
+ * If the server refuses to list the managed objects
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public abstract <C extends ConfigurationClient, S extends Configuration>
+ String[] listManagedObjects(
+ ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd,
+ AbstractManagedObjectDefinition<? extends C, ? extends S> d)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ AuthorizationException, CommunicationException;
+
+
+
+ /**
* Determines whether or not the named managed object exists.
* <p>
* Implementations should always return <code>true</code> when the
diff --git a/opends/src/server/org/opends/server/admin/doc/ConfigGuideGeneration.java b/opends/src/server/org/opends/server/admin/doc/ConfigGuideGeneration.java
index 2129d2b..cb4093c 100644
--- a/opends/src/server/org/opends/server/admin/doc/ConfigGuideGeneration.java
+++ b/opends/src/server/org/opends/server/admin/doc/ConfigGuideGeneration.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2007-2008 Sun Microsystems, Inc.
+ * Copyright 2007-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.doc;
@@ -38,6 +38,7 @@
import org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider;
import org.opends.server.admin.AbstractManagedObjectDefinition;
import org.opends.server.admin.AdministratorAction.Type;
+import org.opends.server.admin.std.meta.RootCfgDefn;
import org.opends.server.admin.AggregationPropertyDefinition;
import org.opends.server.admin.AliasDefaultBehaviorProvider;
import org.opends.server.admin.AttributeTypePropertyDefinition;
@@ -64,7 +65,6 @@
import org.opends.server.admin.Tag;
import org.opends.server.admin.TopCfgDefn;
import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
-import org.opends.server.admin.std.meta.RootCfgDefn;
import org.opends.server.types.InitializationException;
import org.opends.server.util.EmbeddedUtils;
@@ -727,13 +727,13 @@
Message synopsis = prop.getAdministratorAction().getSynopsis();
Type actionType = prop.getAdministratorAction().getType();
String actionStr = "";
- if (actionType == actionType.COMPONENT_RESTART) {
+ if (actionType == Type.COMPONENT_RESTART) {
actionStr = "The " + mo.getUserFriendlyName() +
" must be disabled and re-enabled for changes to this setting " +
"to take effect";
- } else if (actionType == actionType.SERVER_RESTART) {
+ } else if (actionType == Type.SERVER_RESTART) {
actionStr = "Restart the server";
- } else if (actionType == actionType.NONE) {
+ } else if (actionType == Type.NONE) {
actionStr = "None";
}
String dot = (actionStr.equals("") ? "" : ". ");
@@ -1448,12 +1448,6 @@
}
}
- private void paragraph(Message description, TextStyle style) {
- if (description != null) {
- paragraph(description.toString(), style, null);
- }
- }
-
private void paragraph(String description) {
paragraph(description, TextStyle.STANDARD, null);
}
@@ -1469,9 +1463,9 @@
if (getIndentPixels() > 0) {
indentStr = "style=\"margin-left: " + getIndentPixels() + "px;\"";
}
- if (style == style.BOLD) {
+ if (style == TextStyle.BOLD) {
styleStr = "style=\"font-weight: bold;\"";
- } else if (style == style.ITALIC) {
+ } else if (style == TextStyle.ITALIC) {
styleStr = "style=\"font-style: italic;\"";
}
if (pClass != null) {
@@ -1548,22 +1542,6 @@
STANDARD, BOLD, ITALIC, UNDERLINE, FIXED_WIDTH
}
- /**
- * List style.
- */
- private enum ListStyle {
-
- STANDARD, BULLET, NUMBER
- }
-
- private void indent() {
- ind++;
- }
-
- private void outdent() {
- ind--;
- }
-
private void beginList() {
inList = true;
listLevel++;
@@ -1586,12 +1564,6 @@
"</html>\n");
}
- private static void usage() {
- System.err.println(
- "Usage : Provide the argument : output generation directory.");
- System.exit(1);
- }
-
private void viewHelp(String helpStr) {
htmlBuff.append(
"<p class=\"view-help\" >" +
@@ -1617,21 +1589,22 @@
}
// Relation List from RootConfiguration
- private TreeMap<String, RelationDefinition> topRelList =
+ private final TreeMap<String, RelationDefinition> topRelList =
new TreeMap<String, RelationDefinition>();
- private TreeMap<String, RelationDefinition> relList =
+ private final TreeMap<String, RelationDefinition> relList =
new TreeMap<String, RelationDefinition>();
- private TreeMap<String, TreeMap<String, RelationDefinition>> catTopRelList =
- new TreeMap<String, TreeMap<String, RelationDefinition>>();
+ private final TreeMap<String, TreeMap<String, RelationDefinition>>
+ catTopRelList = new TreeMap<String, TreeMap<String, RelationDefinition>>();
// managed object list
- private TreeMap<String, AbstractManagedObjectDefinition> moList =
+ private final TreeMap<String, AbstractManagedObjectDefinition> moList =
new TreeMap<String, AbstractManagedObjectDefinition>();
- private TreeMap<String, AbstractManagedObjectDefinition> topMoList =
+ private final TreeMap<String, AbstractManagedObjectDefinition> topMoList =
new TreeMap<String, AbstractManagedObjectDefinition>();
- private TreeMap<String, TreeMap<String, AbstractManagedObjectDefinition>>
+ private final TreeMap<String,
+ TreeMap<String, AbstractManagedObjectDefinition>>
catTopMoList =
- new TreeMap<String, TreeMap<String, AbstractManagedObjectDefinition>>();
- private int ind = 0;
+ new TreeMap<String, TreeMap<String, AbstractManagedObjectDefinition>>();
+ private final int ind = 0;
private StringBuffer htmlBuff = new StringBuffer();
private static String generationDir;
private static boolean ldapMapping = false;
diff --git a/opends/src/server/org/opends/server/admin/server/ConfigAddListenerAdaptor.java b/opends/src/server/org/opends/server/admin/server/ConfigAddListenerAdaptor.java
index b07ab50..318e3b7 100644
--- a/opends/src/server/org/opends/server/admin/server/ConfigAddListenerAdaptor.java
+++ b/opends/src/server/org/opends/server/admin/server/ConfigAddListenerAdaptor.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2007-2008 Sun Microsystems, Inc.
+ * Copyright 2007-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.server;
@@ -38,10 +38,13 @@
import org.opends.server.admin.Configuration;
import org.opends.server.admin.Constraint;
import org.opends.server.admin.DecodingException;
+import org.opends.server.admin.DefinitionDecodingException;
import org.opends.server.admin.InstantiableRelationDefinition;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.OptionalRelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
+import org.opends.server.admin.DefinitionDecodingException.Reason;
import org.opends.server.api.ConfigAddListener;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
@@ -76,6 +79,9 @@
// The instantiable relation.
private final InstantiableRelationDefinition<?, S> instantiableRelation;
+ // The set relation.
+ private final SetRelationDefinition<?, S> setRelation;
+
// The underlying add listener.
private final ServerManagedObjectAddListener<S> listener;
@@ -104,6 +110,7 @@
this.path = path;
this.instantiableRelation = relation;
this.optionalRelation = null;
+ this.setRelation = null;
this.listener = listener;
this.cachedManagedObject = null;
}
@@ -127,6 +134,31 @@
this.path = path;
this.optionalRelation = relation;
this.instantiableRelation = null;
+ this.setRelation = null;
+ this.listener = listener;
+ this.cachedManagedObject = null;
+ }
+
+
+
+ /**
+ * Create a new configuration add listener adaptor for a
+ * set relation.
+ *
+ * @param path
+ * The managed object path of the parent.
+ * @param relation
+ * The set relation.
+ * @param listener
+ * The underlying add listener.
+ */
+ public ConfigAddListenerAdaptor(ManagedObjectPath<?, ?> path,
+ SetRelationDefinition<?, S> relation,
+ ServerManagedObjectAddListener<S> listener) {
+ this.path = path;
+ this.instantiableRelation = null;
+ this.optionalRelation = null;
+ this.setRelation = relation;
this.listener = listener;
this.cachedManagedObject = null;
}
@@ -186,22 +218,29 @@
AttributeValue av = dn.getRDN().getAttributeValue(0);
String name = av.getStringValue().trim();
- ManagedObjectPath<?, S> childPath;
- if (instantiableRelation != null) {
- childPath = path.child(instantiableRelation, name);
- } else {
- // Optional managed objects are located directly beneath the
- // parent and have a well-defined name. We need to make sure
- // that we are handling the correct entry.
- childPath = path.child(optionalRelation);
- DN expectedDN = DNBuilder.create(childPath);
- if (!dn.equals(expectedDN)) {
- // Doesn't apply to us.
- return true;
- }
- }
-
try {
+ ManagedObjectPath<?, ? extends S> childPath;
+ if (instantiableRelation != null) {
+ childPath = path.child(instantiableRelation, name);
+ } else if (setRelation != null) {
+ try {
+ childPath = path.child(setRelation, name);
+ } catch (IllegalArgumentException e) {
+ throw new DefinitionDecodingException(setRelation
+ .getChildDefinition(), Reason.WRONG_TYPE_INFORMATION);
+ }
+ } else {
+ // Optional managed objects are located directly beneath the
+ // parent and have a well-defined name. We need to make sure
+ // that we are handling the correct entry.
+ childPath = path.child(optionalRelation);
+ DN expectedDN = DNBuilder.create(childPath);
+ if (!dn.equals(expectedDN)) {
+ // Doesn't apply to us.
+ return true;
+ }
+ }
+
ServerManagementContext context = ServerManagementContext.getInstance();
cachedManagedObject = context.decode(childPath, configEntry, configEntry);
} catch (DecodingException e) {
diff --git a/opends/src/server/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java b/opends/src/server/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java
index ea75d06..52eddb6 100644
--- a/opends/src/server/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java
+++ b/opends/src/server/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2007-2008 Sun Microsystems, Inc.
+ * Copyright 2007-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.server;
@@ -39,10 +39,13 @@
import org.opends.server.admin.Configuration;
import org.opends.server.admin.Constraint;
import org.opends.server.admin.DecodingException;
+import org.opends.server.admin.DefinitionDecodingException;
import org.opends.server.admin.InstantiableRelationDefinition;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.OptionalRelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
+import org.opends.server.admin.DefinitionDecodingException.Reason;
import org.opends.server.api.ConfigDeleteListener;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
@@ -77,6 +80,9 @@
// The instantiable relation.
private final InstantiableRelationDefinition<?, S> instantiableRelation;
+ // The set relation.
+ private final SetRelationDefinition<?, S> setRelation;
+
// The underlying delete listener.
private final ServerManagedObjectDeleteListener<S> listener;
@@ -105,6 +111,7 @@
this.path = path;
this.optionalRelation = null;
this.instantiableRelation = relation;
+ this.setRelation = null;
this.listener = listener;
this.cachedManagedObject = null;
}
@@ -128,6 +135,31 @@
this.path = path;
this.optionalRelation = relation;
this.instantiableRelation = null;
+ this.setRelation = null;
+ this.listener = listener;
+ this.cachedManagedObject = null;
+ }
+
+
+
+ /**
+ * Create a new configuration delete listener adaptor for an
+ * set relation.
+ *
+ * @param path
+ * The managed object path of the parent.
+ * @param relation
+ * The set relation.
+ * @param listener
+ * The underlying delete listener.
+ */
+ public ConfigDeleteListenerAdaptor(ManagedObjectPath<?, ?> path,
+ SetRelationDefinition<?, S> relation,
+ ServerManagedObjectDeleteListener<S> listener) {
+ this.path = path;
+ this.optionalRelation = null;
+ this.instantiableRelation = null;
+ this.setRelation = relation;
this.listener = listener;
this.cachedManagedObject = null;
}
@@ -187,22 +219,29 @@
AttributeValue av = dn.getRDN().getAttributeValue(0);
String name = av.getStringValue().trim();
- ManagedObjectPath<?, S> childPath;
- if (instantiableRelation != null) {
- childPath = path.child(instantiableRelation, name);
- } else {
- // Optional managed objects are located directly beneath the
- // parent and have a well-defined name. We need to make sure
- // that we are handling the correct entry.
- childPath = path.child(optionalRelation);
- DN expectedDN = DNBuilder.create(childPath);
- if (!dn.equals(expectedDN)) {
- // Doesn't apply to us.
- return true;
- }
- }
-
try {
+ ManagedObjectPath<?, ? extends S> childPath;
+ if (instantiableRelation != null) {
+ childPath = path.child(instantiableRelation, name);
+ } else if (setRelation != null) {
+ try {
+ childPath = path.child(setRelation, name);
+ } catch (IllegalArgumentException e) {
+ throw new DefinitionDecodingException(setRelation
+ .getChildDefinition(), Reason.WRONG_TYPE_INFORMATION);
+ }
+ } else {
+ // Optional managed objects are located directly beneath the
+ // parent and have a well-defined name. We need to make sure
+ // that we are handling the correct entry.
+ childPath = path.child(optionalRelation);
+ DN expectedDN = DNBuilder.create(childPath);
+ if (!dn.equals(expectedDN)) {
+ // Doesn't apply to us.
+ return true;
+ }
+ }
+
ServerManagementContext context = ServerManagementContext.getInstance();
cachedManagedObject = context.decode(childPath, configEntry);
} catch (DecodingException e) {
diff --git a/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java b/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
index 6efaf10..991e19c 100644
--- a/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
+++ b/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2006-2008 Sun Microsystems, Inc.
+ * Copyright 2006-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.server;
@@ -40,7 +40,6 @@
import java.util.Set;
import java.util.SortedSet;
-import org.opends.messages.AdminMessages;
import org.opends.messages.Message;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.Constraint;
@@ -51,6 +50,7 @@
import org.opends.server.admin.PropertyDefinition;
import org.opends.server.admin.PropertyProvider;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.SingletonRelationDefinition;
import org.opends.server.api.ConfigAddListener;
import org.opends.server.api.ConfigChangeListener;
@@ -223,6 +223,55 @@
/**
+ * Deregisters an existing configuration add listener.
+ *
+ * @param <M>
+ * The type of the child server configuration object.
+ * @param d
+ * The set relation definition.
+ * @param listener
+ * The configuration add listener.
+ * @throws IllegalArgumentException
+ * If the set relation definition is not
+ * associated with this managed object's definition.
+ */
+ public <M extends Configuration> void deregisterAddListener(
+ SetRelationDefinition<?, M> d,
+ ConfigurationAddListener<M> listener) throws IllegalArgumentException {
+ validateRelationDefinition(d);
+
+ DN baseDN = DNBuilder.create(path, d);
+ deregisterAddListener(baseDN, listener);
+ }
+
+
+
+ /**
+ * Deregisters an existing server managed object add listener.
+ *
+ * @param <M>
+ * The type of the child server configuration object.
+ * @param d
+ * The set relation definition.
+ * @param listener
+ * The server managed object add listener.
+ * @throws IllegalArgumentException
+ * If the set relation definition is not
+ * associated with this managed object's definition.
+ */
+ public <M extends Configuration> void deregisterAddListener(
+ SetRelationDefinition<?, M> d,
+ ServerManagedObjectAddListener<M> listener)
+ throws IllegalArgumentException {
+ validateRelationDefinition(d);
+
+ DN baseDN = DNBuilder.create(path, d);
+ deregisterAddListener(baseDN, listener);
+ }
+
+
+
+ /**
* Deregisters an existing configuration change listener.
*
* @param listener
@@ -371,6 +420,55 @@
/**
+ * Deregisters an existing configuration delete listener.
+ *
+ * @param <M>
+ * The type of the child server configuration object.
+ * @param d
+ * The set relation definition.
+ * @param listener
+ * The configuration delete listener.
+ * @throws IllegalArgumentException
+ * If the set relation definition is not
+ * associated with this managed object's definition.
+ */
+ public <M extends Configuration> void deregisterDeleteListener(
+ SetRelationDefinition<?, M> d,
+ ConfigurationDeleteListener<M> listener) throws IllegalArgumentException {
+ validateRelationDefinition(d);
+
+ DN baseDN = DNBuilder.create(path, d);
+ deregisterDeleteListener(baseDN, listener);
+ }
+
+
+
+ /**
+ * Deregisters an existing server managed object delete listener.
+ *
+ * @param <M>
+ * The type of the child server configuration object.
+ * @param d
+ * The set relation definition.
+ * @param listener
+ * The server managed object delete listener.
+ * @throws IllegalArgumentException
+ * If the set relation definition is not
+ * associated with this managed object's definition.
+ */
+ public <M extends Configuration> void deregisterDeleteListener(
+ SetRelationDefinition<?, M> d,
+ ServerManagedObjectDeleteListener<M> listener)
+ throws IllegalArgumentException {
+ validateRelationDefinition(d);
+
+ DN baseDN = DNBuilder.create(path, d);
+ deregisterDeleteListener(baseDN, listener);
+ }
+
+
+
+ /**
* Retrieve an instantiable child managed object.
*
* @param <M>
@@ -423,6 +521,37 @@
/**
+ * Retrieve a set child managed object.
+ *
+ * @param <M>
+ * The requested type of the child server managed object
+ * configuration.
+ * @param d
+ * The set relation definition.
+ * @param name
+ * The name of the child managed object.
+ * @return Returns the set child managed object.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with this
+ * managed object's definition or if {@code name} specifies
+ * a managed object definition which is not a sub-type of
+ * the relation's child definition.
+ * @throws ConfigException
+ * If the child managed object could not be found or if it
+ * could not be decoded.
+ */
+ public <M extends Configuration> ServerManagedObject<? extends M> getChild(
+ SetRelationDefinition<?, M> d, String name)
+ throws IllegalArgumentException, ConfigException
+ {
+ validateRelationDefinition(d);
+
+ return context.getManagedObject(path.child(d, name));
+ }
+
+
+
+ /**
* Retrieve a singleton child managed object.
*
* @param <M>
@@ -599,6 +728,25 @@
/**
+ * Lists the child managed objects associated with the specified
+ * set relation.
+ *
+ * @param d
+ * The set relation definition.
+ * @return Returns the names of the child managed objects.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with this
+ * managed object's definition.
+ */
+ public String[] listChildren(SetRelationDefinition<?, ?> d)
+ throws IllegalArgumentException {
+ validateRelationDefinition(d);
+ return context.listManagedObjects(path, d);
+ }
+
+
+
+ /**
* Register to be notified when new child configurations are added
* beneath an instantiable relation.
*
@@ -712,6 +860,63 @@
/**
+ * Register to be notified when new child configurations are added
+ * beneath a set relation.
+ *
+ * @param <M>
+ * The type of the child server configuration object.
+ * @param d
+ * The set relation definition.
+ * @param listener
+ * The configuration add listener.
+ * @throws IllegalArgumentException
+ * If the set relation definition is not
+ * associated with this managed object's definition.
+ * @throws ConfigException
+ * If the configuration entry associated with the
+ * set relation could not be retrieved.
+ */
+ public <M extends Configuration> void registerAddListener(
+ SetRelationDefinition<?, M> d,
+ ConfigurationAddListener<M> listener) throws IllegalArgumentException,
+ ConfigException {
+ registerAddListener(d, new ServerManagedObjectAddListenerAdaptor<M>(
+ listener));
+ }
+
+
+
+ /**
+ * Register to be notified when new child server managed object are
+ * added beneath a set relation.
+ *
+ * @param <M>
+ * The type of the child server configuration object.
+ * @param d
+ * The set relation definition.
+ * @param listener
+ * The server managed object add listener.
+ * @throws IllegalArgumentException
+ * If the set relation definition is not
+ * associated with this managed object's definition.
+ * @throws ConfigException
+ * If the configuration entry associated with the
+ * set relation could not be retrieved.
+ */
+ public <M extends Configuration> void registerAddListener(
+ SetRelationDefinition<?, M> d,
+ ServerManagedObjectAddListener<M> listener)
+ throws IllegalArgumentException, ConfigException {
+ validateRelationDefinition(d);
+ DN baseDN = DNBuilder.create(path, d);
+ ConfigAddListener adaptor = new ConfigAddListenerAdaptor<M>(path, d,
+ listener);
+ registerAddListener(baseDN, adaptor);
+ }
+
+
+
+ /**
* Register to be notified when this server managed object is
* changed.
*
@@ -876,6 +1081,63 @@
/**
+ * Register to be notified when existing child configurations are
+ * deleted beneath a set relation.
+ *
+ * @param <M>
+ * The type of the child server configuration object.
+ * @param d
+ * The set relation definition.
+ * @param listener
+ * The configuration delete listener.
+ * @throws IllegalArgumentException
+ * If the set relation definition is not
+ * associated with this managed object's definition.
+ * @throws ConfigException
+ * If the configuration entry associated with the
+ * set relation could not be retrieved.
+ */
+ public <M extends Configuration> void registerDeleteListener(
+ SetRelationDefinition<?, M> d,
+ ConfigurationDeleteListener<M> listener) throws IllegalArgumentException,
+ ConfigException {
+ registerDeleteListener(d, new ServerManagedObjectDeleteListenerAdaptor<M>(
+ listener));
+ }
+
+
+
+ /**
+ * Register to be notified when existing child server managed
+ * objects are deleted beneath a set relation.
+ *
+ * @param <M>
+ * The type of the child server configuration object.
+ * @param d
+ * The set relation definition.
+ * @param listener
+ * The server managed objects delete listener.
+ * @throws IllegalArgumentException
+ * If the set relation definition is not
+ * associated with this managed object's definition.
+ * @throws ConfigException
+ * If the configuration entry associated with the
+ * set relation could not be retrieved.
+ */
+ public <M extends Configuration> void registerDeleteListener(
+ SetRelationDefinition<?, M> d,
+ ServerManagedObjectDeleteListener<M> listener)
+ throws IllegalArgumentException, ConfigException {
+ validateRelationDefinition(d);
+ DN baseDN = DNBuilder.create(path, d);
+ ConfigDeleteListener adaptor = new ConfigDeleteListenerAdaptor<M>(path, d,
+ listener);
+ registerDeleteListener(baseDN, adaptor);
+ }
+
+
+
+ /**
* {@inheritDoc}
*/
@Override
@@ -1079,7 +1341,7 @@
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- Message message = AdminMessages.ERR_ADMIN_CANNOT_GET_LISTENER_BASE.get(
+ Message message = ERR_ADMIN_CANNOT_GET_LISTENER_BASE.get(
String.valueOf(dn), stackTraceToSingleLineString(e));
throw new ConfigException(message, e);
}
@@ -1125,7 +1387,7 @@
}
// No parent entry could be found.
- Message message = AdminMessages.ERR_ADMIN_UNABLE_TO_REGISTER_LISTENER
+ Message message = ERR_ADMIN_UNABLE_TO_REGISTER_LISTENER
.get(String.valueOf(baseDN));
throw new ConfigException(message);
}
diff --git a/opends/src/server/org/opends/server/admin/server/ServerManagementContext.java b/opends/src/server/org/opends/server/admin/server/ServerManagementContext.java
index eba7c34..42fd5fd 100644
--- a/opends/src/server/org/opends/server/admin/server/ServerManagementContext.java
+++ b/opends/src/server/org/opends/server/admin/server/ServerManagementContext.java
@@ -22,13 +22,14 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin.server;
+import static org.opends.messages.AdminMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.StaticUtils.*;
@@ -43,7 +44,6 @@
import java.util.SortedSet;
import java.util.TreeSet;
-import org.opends.messages.AdminMessages;
import org.opends.messages.Message;
import org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider;
import org.opends.server.admin.AbstractManagedObjectDefinition;
@@ -72,6 +72,7 @@
import org.opends.server.admin.Reference;
import org.opends.server.admin.RelationDefinition;
import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
import org.opends.server.admin.UnknownPropertyDefinitionException;
import org.opends.server.admin.DefinitionDecodingException.Reason;
@@ -111,7 +112,7 @@
// Optional new configuration entry which does not yet exist in
// the configuration back-end.
- private ConfigEntry newConfigEntry;
+ private final ConfigEntry newConfigEntry;
// The path of the managed object containing the next property.
private ManagedObjectPath<?, ?> nextPath = null;
@@ -672,6 +673,58 @@
/**
+ * Lists the child managed objects of the named parent managed
+ * object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param parent
+ * The path of the parent managed object.
+ * @param rd
+ * The set relation definition.
+ * @return Returns the names of the child managed objects.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with the
+ * parent managed object's definition.
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ String[] listManagedObjects(
+ ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd)
+ throws IllegalArgumentException {
+ validateRelationDefinition(parent, rd);
+
+ // Get the target entry.
+ DN targetDN = DNBuilder.create(parent, rd);
+ ConfigEntry configEntry;
+ try {
+ configEntry = DirectoryServer.getConfigEntry(targetDN);
+ } catch (ConfigException e) {
+ return new String[0];
+ }
+
+ if (configEntry == null) {
+ return new String[0];
+ }
+
+ // Retrieve the children.
+ Set<DN> children = configEntry.getChildren().keySet();
+ ArrayList<String> names = new ArrayList<String>(children.size());
+ for (DN child : children) {
+ // Assume that RDNs are single-valued and can be trimmed.
+ AttributeValue av = child.getRDN().getAttributeValue(0);
+ names.add(av.getStringValue().trim());
+ }
+
+ return names.toArray(new String[names.size()]);
+ }
+
+
+
+ /**
* Determines whether or not the named managed object exists.
*
* @param path
@@ -902,7 +955,7 @@
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- Message message = AdminMessages.ERR_ADMIN_CANNOT_GET_MANAGED_OBJECT.get(
+ Message message = ERR_ADMIN_CANNOT_GET_MANAGED_OBJECT.get(
String.valueOf(dn), stackTraceToSingleLineString(e));
throw new ConfigException(message, e);
}
@@ -910,7 +963,7 @@
// The configuration handler is free to return null indicating
// that the entry does not exist.
if (configEntry == null) {
- Message message = AdminMessages.ERR_ADMIN_MANAGED_OBJECT_DOES_NOT_EXIST
+ Message message = ERR_ADMIN_MANAGED_OBJECT_DOES_NOT_EXIST
.get(String.valueOf(dn));
throw new ConfigException(message);
}
diff --git a/opends/src/server/org/opends/server/api/ClientConnection.java b/opends/src/server/org/opends/server/api/ClientConnection.java
index e2be916..e7d4e34 100644
--- a/opends/src/server/org/opends/server/api/ClientConnection.java
+++ b/opends/src/server/org/opends/server/api/ClientConnection.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2006-2008 Sun Microsystems, Inc.
+ * Copyright 2006-2009 Sun Microsystems, Inc.
*/
package org.opends.server.api;
@@ -71,8 +71,6 @@
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.StaticUtils.*;
-
-
/**
* This class defines the set of methods and structures that must be
* implemented by a Directory Server client connection.
@@ -114,7 +112,7 @@
private int lookthroughLimit;
// The time that this client connection was established.
- private long connectTime;
+ private final long connectTime;
// The idle time limit for this client connection.
private long idleTimeLimit;
@@ -125,10 +123,11 @@
// A string representation of the time that this client connection
// was established.
- private String connectTimeString;
+ private final String connectTimeString;
// A set of persistent searches registered for this client.
- private CopyOnWriteArrayList<PersistentSearch> persistentSearches;
+ private final CopyOnWriteArrayList<PersistentSearch>
+ persistentSearches;
// The network group to which the connection belongs to.
private NetworkGroup networkGroup;
@@ -1099,14 +1098,8 @@
public void setUnauthenticated()
{
setAuthenticationInfo(new AuthenticationInfo());
- this.sizeLimit = networkGroup.getSearchSizeLimit();
- if (this.sizeLimit == -1) {
- this.sizeLimit = DirectoryServer.getSizeLimit();
- }
- this.timeLimit = networkGroup.getSearchDurationLimit();
- if (this.timeLimit == -1) {
- this.timeLimit = DirectoryServer.getTimeLimit();
- }
+ this.sizeLimit = networkGroup.getSizeLimit();
+ this.timeLimit = networkGroup.getTimeLimit();
}
@@ -1746,6 +1739,7 @@
*
* @return A string representation of this client connection.
*/
+ @Override
public final String toString()
{
StringBuilder buffer = new StringBuilder();
@@ -1774,6 +1768,7 @@
* processing, then it should override this method and make sure to
* invoke {@code super.finalize} as its first call.
*/
+ @Override
protected void finalize()
{
finalizeConnectionInternal();
@@ -1818,14 +1813,8 @@
this.networkGroup.addConnection(this);
// The client connection inherits the resource limits
- sizeLimit = networkGroup.getSearchSizeLimit();
- if (sizeLimit == -1) {
- sizeLimit = DirectoryServer.getSizeLimit();
- }
- timeLimit = networkGroup.getSearchDurationLimit();
- if (timeLimit == -1) {
- timeLimit = DirectoryServer.getTimeLimit();
- }
+ sizeLimit = networkGroup.getSizeLimit();
+ timeLimit = networkGroup.getTimeLimit();
}
}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupPolicy.java b/opends/src/server/org/opends/server/api/QOSPolicy.java
similarity index 67%
rename from opends/src/server/org/opends/server/core/networkgroups/NetworkGroupPolicy.java
rename to opends/src/server/org/opends/server/api/QOSPolicy.java
index ec0d10b..d02ec5d 100644
--- a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupPolicy.java
+++ b/opends/src/server/org/opends/server/api/QOSPolicy.java
@@ -22,25 +22,35 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2009 Sun Microsystems, Inc.
*/
-package org.opends.server.core.networkgroups;
+
+package org.opends.server.api;
+
/**
- * This class defines the network group policy. A client connection
- * that belongs to a network group has to comply with the policies
- * attach to the network group.
+ * An abstract QOS policy.
*/
-public class NetworkGroupPolicy
+public abstract class QOSPolicy
{
-
/**
- * Creates a new instance of the network group policy.
+ * Creates a new abstract QOS Policy.
*/
- public NetworkGroupPolicy()
+ protected QOSPolicy()
{
- // No implementation is required.
+ // No implementation required.
}
+
+
+ /**
+ * Performs any necessary work to finalize this QOS policy.
+ * <p>
+ * The default implementation is to do nothing.
+ */
+ public void finalizeQOSPolicy()
+ {
+ // Do nothing by default.
+ }
}
diff --git a/opends/src/server/org/opends/server/api/QOSPolicyFactory.java b/opends/src/server/org/opends/server/api/QOSPolicyFactory.java
new file mode 100644
index 0000000..6ee790d
--- /dev/null
+++ b/opends/src/server/org/opends/server/api/QOSPolicyFactory.java
@@ -0,0 +1,89 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.api;
+
+
+
+import java.util.List;
+
+import org.opends.messages.Message;
+import org.opends.server.admin.std.server.QOSPolicyCfg;
+import org.opends.server.config.ConfigException;
+import org.opends.server.types.InitializationException;
+
+
+
+/**
+ * A factory for creating configurable quality of service (QOS)
+ * policies.
+ * <p>
+ * All implementations must have a default constructor, i.e. one that
+ * does not require and arguments.
+ *
+ * @param <T>
+ * The type of QOS policy configuration handled by this
+ * factory.
+ */
+public interface QOSPolicyFactory<T extends QOSPolicyCfg>
+{
+ /**
+ * Creates a new QOS policy using the provided configuration.
+ *
+ * @param configuration
+ * The configuration.
+ * @return The new QOS policy configured using the provided
+ * configuration.
+ * @throws ConfigException
+ * If an unrecoverable problem arises during
+ * initialization of the QOS policy as a result
+ * of the server configuration.
+ * @throws InitializationException
+ * If a problem occurs during initialization of the QOS
+ * policy.
+ */
+ QOSPolicy createQOSPolicy(T configuration) throws ConfigException,
+ InitializationException;
+
+
+
+ /**
+ * Indicates whether the provided QOS policy configuration is
+ * acceptable.
+ *
+ * @param configuration
+ * The QOS policy configuration.
+ * @param unacceptableReasons
+ * A list that can be used to hold messages about why the
+ * provided configuration is not acceptable.
+ * @return Returns <code>true</code> if the provided QOS policy
+ * configuration is acceptable, or <code>false</code> if
+ * it is not.
+ */
+ boolean isConfigurationAcceptable(T configuration,
+ List<Message> unacceptableReasons);
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/ANDConnectionCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/ANDConnectionCriteria.java
new file mode 100644
index 0000000..5c500d4
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/networkgroups/ANDConnectionCriteria.java
@@ -0,0 +1,104 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.opends.server.api.ClientConnection;
+import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.DN;
+
+
+
+/**
+ * A connection criteria which matches connections if and only if all
+ * the sub-criteria match. If there are no sub-criteria then the
+ * connection criteria will always match.
+ */
+final class ANDConnectionCriteria implements ConnectionCriteria
+{
+
+ // The list of underlying connection criteria.
+ private final List<ConnectionCriteria> subCriteria;
+
+
+
+ /**
+ * Creates a new AND connection criteria using the provided
+ * sub-criteria.
+ *
+ * @param subCriteria
+ * The sub-criteria.
+ */
+ public ANDConnectionCriteria(
+ Collection<? extends ConnectionCriteria> subCriteria)
+ {
+ this.subCriteria = new ArrayList<ConnectionCriteria>(subCriteria);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean matches(ClientConnection connection)
+ {
+ for (ConnectionCriteria filter : subCriteria)
+ {
+ if (!filter.matches(connection))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean willMatchAfterBind(ClientConnection connection,
+ DN bindDN, AuthenticationType authType, boolean isSecure)
+ {
+ for (ConnectionCriteria filter : subCriteria)
+ {
+ if (!filter.willMatchAfterBind(connection, bindDN, authType,
+ isSecure))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/AuthMethodConnectionCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/AuthMethodConnectionCriteria.java
new file mode 100644
index 0000000..202b91a
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/networkgroups/AuthMethodConnectionCriteria.java
@@ -0,0 +1,142 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.opends.server.admin.std.meta.NetworkGroupCfgDefn.AllowedAuthMethod;
+import org.opends.server.api.ClientConnection;
+import org.opends.server.types.AuthenticationInfo;
+import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.DN;
+
+
+
+/**
+ * A connection criteria which matches connections authenticated using a
+ * permitted authentication method.
+ */
+
+final class AuthMethodConnectionCriteria implements ConnectionCriteria
+{
+
+ // The set of allowed authentication methods.
+ private final Set<AllowedAuthMethod> authMethods;
+
+
+
+ /**
+ * Creates a new authentication method connection criteria using the
+ * provided allowed authentication methods.
+ *
+ * @param authMethods
+ * The allowed authentication methods.
+ */
+ public AuthMethodConnectionCriteria(
+ Collection<AllowedAuthMethod> authMethods)
+ {
+ this.authMethods = EnumSet.copyOf(authMethods);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean matches(ClientConnection connection)
+ {
+ AuthenticationInfo authInfo = connection.getAuthenticationInfo();
+
+ for (AllowedAuthMethod method : authMethods)
+ {
+ switch (method)
+ {
+ case ANONYMOUS:
+ if (!authInfo.isAuthenticated())
+ {
+ return true;
+ }
+ break;
+ case SIMPLE:
+ if (authInfo.hasAuthenticationType(AuthenticationType.SIMPLE))
+ {
+ return true;
+ }
+ break;
+ case SASL:
+ if (authInfo.hasAuthenticationType(AuthenticationType.SASL))
+ {
+ return true;
+ }
+ break;
+ }
+ }
+
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean willMatchAfterBind(ClientConnection connection,
+ DN bindDN, AuthenticationType authType, boolean isSecure)
+ {
+ for (AllowedAuthMethod method : authMethods)
+ {
+ switch (method)
+ {
+ case ANONYMOUS:
+ if (bindDN.toNormalizedString().length() == 0)
+ {
+ return true;
+ }
+ break;
+ case SIMPLE:
+ if (authType == AuthenticationType.SIMPLE
+ && bindDN.toNormalizedString().length() > 0)
+ {
+ return true;
+ }
+ break;
+ case SASL:
+ if (authType == AuthenticationType.SASL)
+ {
+ return true;
+ }
+ break;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/AuthMethodCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/AuthMethodCriteria.java
deleted file mode 100644
index 34edede..0000000
--- a/opends/src/server/org/opends/server/core/networkgroups/AuthMethodCriteria.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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
- *
- *
- * Copyright 2008 Sun Microsystems, Inc.
- */
-package org.opends.server.core.networkgroups;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.TreeSet;
-import
- org.opends.server.admin.std.meta.NetworkGroupCriteriaCfgDefn.AllowedAuthMethod;
-import org.opends.server.api.ClientConnection;
-import org.opends.server.types.AuthenticationType;
-import org.opends.server.types.DN;
-
-/**
- * This class defines the authentication method criteria.
- * A connection matches the criteria if the authentication
- * method used on this connection is one of the allowed
- * authentication methods specified in the criteria.
- */
-
-public class AuthMethodCriteria implements NetworkGroupCriterion {
- private Collection<AllowedAuthMethod> authMethods;
-
- /**
- * Constructor.
- */
- public AuthMethodCriteria() {
- authMethods = new TreeSet<AllowedAuthMethod>();
- }
-
- /**
- * Adds a new allowed authentication method to the list of allowed
- * authentication methods.
- * @param method The authentication method
- */
- public void addAuthMethod(AllowedAuthMethod method) {
- authMethods.add(method);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean match(ClientConnection connection) {
- Collection<AuthenticationType> authTypes =
- new ArrayList<AuthenticationType>();
-
- for (AllowedAuthMethod method:authMethods) {
- if (method == AllowedAuthMethod.ANONYMOUS) {
- if (connection.getAuthenticationInfo().isAuthenticated() == false) {
- return (true);
- }
- } else if (method == AllowedAuthMethod.SASL) {
- authTypes.add(AuthenticationType.SASL);
- } else if (method == AllowedAuthMethod.SIMPLE) {
- authTypes.add(AuthenticationType.SIMPLE);
- }
- }
- return (connection.getAuthenticationInfo().hasAnyAuthenticationType(
- authTypes));
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean matchAfterBind(ClientConnection connection, DN bindDN,
- AuthenticationType authType, boolean isSecure) {
- for (AllowedAuthMethod method:authMethods) {
- if (method == AllowedAuthMethod.ANONYMOUS
- && bindDN.toNormalizedString().equals("")) {
- return true;
- }
- if (method == AllowedAuthMethod.SASL
- && authType == AuthenticationType.SASL) {
- return true;
- }
- if (method == AllowedAuthMethod.SIMPLE
- && authType == AuthenticationType.SIMPLE
- && !bindDN.toNormalizedString().equals("")) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/BindDNConnectionCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/BindDNConnectionCriteria.java
new file mode 100644
index 0000000..f6b9aa9
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/networkgroups/BindDNConnectionCriteria.java
@@ -0,0 +1,138 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.opends.server.api.ClientConnection;
+import org.opends.server.authorization.dseecompat.PatternDN;
+import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+
+
+
+/**
+ * A connection criteria which matches connections authenticated using a
+ * permitted bind DN.
+ */
+final class BindDNConnectionCriteria implements ConnectionCriteria
+{
+
+ /**
+ * Creates a new bind DN connection criteria using the provided DN
+ * patterns.
+ *
+ * @param patterns
+ * The DN patterns.
+ * @return The new bind DN connection criteria.
+ */
+ public static BindDNConnectionCriteria create(
+ Collection<PatternDN> patterns)
+ {
+ return new BindDNConnectionCriteria(new ArrayList<PatternDN>(
+ patterns));
+ }
+
+
+
+ /**
+ * Creates a new bind DN connection criteria using the provided DN
+ * pattern string representations.
+ *
+ * @param patternStrings
+ * The string representation of the DN patterns.
+ * @return The new bind DN connection criteria.
+ * @throws DirectoryException
+ * If one of the pattern strings is not valid.
+ */
+ public static BindDNConnectionCriteria decode(
+ Collection<String> patternStrings) throws DirectoryException
+ {
+ List<PatternDN> patterns =
+ new ArrayList<PatternDN>(patternStrings.size());
+
+ for (String s : patternStrings)
+ {
+ patterns.add(PatternDN.decode(s));
+ }
+
+ return new BindDNConnectionCriteria(patterns);
+ }
+
+
+
+ // The list of permitted bind DN patterns.
+ private final List<PatternDN> patterns;
+
+
+
+ // Private constructor.
+ private BindDNConnectionCriteria(List<PatternDN> patterns)
+ {
+ this.patterns = patterns;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean matches(ClientConnection connection)
+ {
+ DN dn = connection.getAuthenticationInfo().getAuthenticationDN();
+ return willMatchAfterBind(connection, dn, null, false);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean willMatchAfterBind(ClientConnection connection,
+ DN bindDN, AuthenticationType authType, boolean isSecure)
+ {
+ if (bindDN == null)
+ {
+ return false;
+ }
+
+ for (PatternDN pattern : patterns)
+ {
+ if (pattern.matchesDN(bindDN))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/BindDnCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/BindDnCriteria.java
deleted file mode 100644
index c4ac72f..0000000
--- a/opends/src/server/org/opends/server/core/networkgroups/BindDnCriteria.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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
- *
- *
- * Copyright 2008 Sun Microsystems, Inc.
- */
-package org.opends.server.core.networkgroups;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import org.opends.server.api.ClientConnection;
-import org.opends.server.authorization.dseecompat.PatternDN;
-import org.opends.server.types.AuthenticationType;
-import org.opends.server.types.DN;
-import org.opends.server.types.DirectoryException;
-
-/**
- * This class defines the client bind DN criteria.
- * A client connection matches the criteria when the DN used by
- * the client to bind matches at least one of the DN patterns.
- */
-public class BindDnCriteria implements NetworkGroupCriterion {
-
- private Collection<PatternDN> patternDNs;
-
- /**
- * Constructor.
- */
- public BindDnCriteria() {
- patternDNs = new ArrayList<PatternDN>();
- }
-
- /**
- * Adds a new bind DN filter to the list of bind DN filters.
- * @param filter The bind DN filter
- * @throws DirectoryException if the filter is not a valid filter
- */
- public void addBindDnFilter(String filter)
- throws DirectoryException {
- patternDNs.add(PatternDN.decode(filter));
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean match(ClientConnection connection) {
- DN dn = connection.getAuthenticationInfo().getAuthenticationDN();
- return matchAfterBind(connection, dn, null, false);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean matchAfterBind(ClientConnection connection, DN bindDN,
- AuthenticationType authType, boolean isSecure) {
- if (bindDN == null) {
- return false;
- }
- for (PatternDN patternDN:patternDNs) {
- if (patternDN.matchesDN(bindDN)) {
- return (true);
- }
- }
- return (false);
- }
-}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/ClientConnectionAffinityPolicy.java b/opends/src/server/org/opends/server/core/networkgroups/ClientConnectionAffinityPolicy.java
deleted file mode 100644
index af53156..0000000
--- a/opends/src/server/org/opends/server/core/networkgroups/ClientConnectionAffinityPolicy.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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
- *
- *
- * Copyright 2009 Sun Microsystems, Inc.
- */
-package org.opends.server.core.networkgroups;
-
-import org.opends.server.admin.std.meta.NetworkGroupCfgDefn.AffinityPolicy;
-
-
-/**
- * This enumerate defines the client connection affinity policy.
- * An affinity is the ability for the server to bypass some
- * route algorithm so that requests are always sent to a specific
- * data source.
- */
-public enum ClientConnectionAffinityPolicy
-{
- /**
- * Disables the client connection affinity.
- */
- NONE,
-
- /**
- * Routes the first read request to the data source to which
- * a previous write request has been routed to. This affinity
- * is useful when a client application performs a read request
- * after a write request and the read request should return
- * consistent data.
- */
- FIRST_READ_REQUEST_AFTER_WRITE_REQUEST,
-
- /**
- * Routes all the write requests to the data source to which
- * a previous write request has been routed to. This affinity
- * policy is useful for batch update where a parent entry and
- * its subordinates must be sent to the same data source.
- */
- ALL_WRITE_REQUESTS_AFTER_FIRST_WRITE_REQUEST,
-
- /**
- * Routes all the requests to the data source to which a
- * previous write request has been routed to.
- */
- ALL_REQUESTS_AFTER_FIRST_WRITE_REQUEST,
-
- /**
- * Routes all the requests to the data source to which a
- * previous request has been routed to. This affinity policy
- * allows to create a kind of tunnel between a client application
- * and a data source.
- */
- ALL_REQUESTS_AFTER_FIRST_REQUEST;
-
-
- /**
- * Indicates whether the current policy defines an active affinity
- * policy or not.
- *
- * @return <code>true</code> if the current value of the policy indicates
- * an active affinity.
- */
- public boolean affinityIsActive()
- {
- return (this != NONE);
- }
-
-
- /**
- * Returns the client connection affinity policy that matches the
- * affinity policy as defined by the administration framework.
- *
- * @param affinityPolicy
- * The administration framework affinity policy for which we
- * want to make a determination.
- *
- * @return the client connection affinity policy that matches an affinity
- * policy as defined by the administration framework.
- */
- public static ClientConnectionAffinityPolicy
- toClientConnectionAffinityPolicy(AffinityPolicy affinityPolicy)
- {
- switch (affinityPolicy)
- {
- case NONE:
- return NONE;
-
- case ALL_REQUESTS_AFTER_FIRST_WRITE_REQUEST:
- return ALL_REQUESTS_AFTER_FIRST_WRITE_REQUEST;
-
- case ALL_REQUESTS_AFTER_FIRST_REQUEST:
- return ALL_REQUESTS_AFTER_FIRST_REQUEST;
-
- case ALL_WRITE_REQUESTS_AFTER_FIRST_WRITE_REQUEST:
- return ALL_WRITE_REQUESTS_AFTER_FIRST_WRITE_REQUEST;
-
- case FIRST_READ_REQUEST_AFTER_WRITE_REQUEST:
- return FIRST_READ_REQUEST_AFTER_WRITE_REQUEST;
-
- default:
- throw new AssertionError(
- "Unexpected afinity policy value " + affinityPolicy);
- }
- }
-
-}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/ConnectionCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/ConnectionCriteria.java
new file mode 100644
index 0000000..e801a5e
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/networkgroups/ConnectionCriteria.java
@@ -0,0 +1,139 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2008-2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import org.opends.server.api.ClientConnection;
+import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.DN;
+
+
+
+/**
+ * An interface for filtering connections based on implementation
+ * specific criteria. Connection criteria are used by network groups to
+ * determine whether a client connection should be associated with a
+ * network group or not.
+ */
+interface ConnectionCriteria
+{
+
+ /**
+ * A connection criteria which does not match any connections.
+ */
+ public static final ConnectionCriteria FALSE =
+ new ConnectionCriteria()
+ {
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean matches(ClientConnection connection)
+ {
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean willMatchAfterBind(
+ ClientConnection connection, DN bindDN,
+ AuthenticationType authType, boolean isSecure)
+ {
+ return false;
+ }
+
+ };
+
+ /**
+ * A connection criteria which matches all connections.
+ */
+ public static final ConnectionCriteria TRUE =
+ new ConnectionCriteria()
+ {
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean matches(ClientConnection connection)
+ {
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean willMatchAfterBind(
+ ClientConnection connection, DN bindDN,
+ AuthenticationType authType, boolean isSecure)
+ {
+ return true;
+ }
+
+ };
+
+
+
+ /**
+ * Indicates whether or not the provided client connection matches
+ * this connection criteria.
+ *
+ * @param connection
+ * The client connection.
+ * @return <code>true</code> if the provided client connection matches
+ * this connection criteria.
+ */
+ boolean matches(ClientConnection connection);
+
+
+
+ /**
+ * Indicates whether or not the provided client connection will match
+ * this connection criteria using the provided authentication
+ * parameters.
+ *
+ * @param connection
+ * The client connection.
+ * @param bindDN
+ * The bind DN which will be used to authenticate.
+ * @param authType
+ * The type of authentication which will be performed.
+ * @param isSecure
+ * <code>true</code> if the connection will be secured.
+ * @return <code>true</code> if the provided client connection will
+ * match this connection criteria using the provided
+ * authentication parameters.
+ */
+ boolean willMatchAfterBind(ClientConnection connection, DN bindDN,
+ AuthenticationType authType, boolean isSecure);
+
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/IPConnectionCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/IPConnectionCriteria.java
new file mode 100644
index 0000000..6575a22
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/networkgroups/IPConnectionCriteria.java
@@ -0,0 +1,114 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import java.net.InetAddress;
+import java.util.Collection;
+
+import org.opends.server.api.ClientConnection;
+import org.opends.server.types.AddressMask;
+import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.DN;
+
+
+
+/**
+ * A connection criteria which matches connections coming from a allowed
+ * client address.
+ */
+final class IPConnectionCriteria implements ConnectionCriteria
+{
+
+ // The list of allowed client address masks.
+ private final AddressMask[] allowedClients;
+
+ // The list of denied client address masks.
+ private final AddressMask[] deniedClients;
+
+
+
+ /**
+ * Creates a new IP connection criteria using the provided allowed and
+ * denied address masks.
+ *
+ * @param allowedClients
+ * The list of allowed client address masks.
+ * @param deniedClients
+ * The list of denied client address masks.
+ */
+ public IPConnectionCriteria(Collection<AddressMask> allowedClients,
+ Collection<AddressMask> deniedClients)
+ {
+ this.allowedClients = allowedClients.toArray(new AddressMask[0]);
+ this.deniedClients = deniedClients.toArray(new AddressMask[0]);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean matches(ClientConnection connection)
+ {
+ InetAddress ipAddr = connection.getRemoteAddress();
+ byte[] address = ipAddr.getAddress();
+ String hostName = ipAddr.getHostName();
+
+ if (deniedClients.length > 0)
+ {
+ if (AddressMask
+ .maskListContains(address, hostName, deniedClients))
+ {
+ return false;
+ }
+ }
+
+ if (allowedClients.length > 0)
+ {
+ if (!AddressMask.maskListContains(address, hostName,
+ allowedClients))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean willMatchAfterBind(ClientConnection connection,
+ DN bindDN, AuthenticationType authType, boolean isSecure)
+ {
+ return matches(connection);
+ }
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/IpFilterCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/IpFilterCriteria.java
deleted file mode 100644
index 32e4c0d..0000000
--- a/opends/src/server/org/opends/server/core/networkgroups/IpFilterCriteria.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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
- *
- *
- * Copyright 2008 Sun Microsystems, Inc.
- */
-package org.opends.server.core.networkgroups;
-
-import java.net.InetAddress;
-import java.util.Collection;
-import java.util.HashSet;
-import org.opends.server.api.ClientConnection;
-import org.opends.server.types.AddressMask;
-import org.opends.server.types.AuthenticationType;
-import org.opends.server.types.DN;
-
-/**
- * This class defines the IP filter criteria.
- * A client connection matches the criteria when it is performed from
- * a host whose IP address matches at least one of the specified filters.
- */
-public class IpFilterCriteria implements NetworkGroupCriterion {
-
- private Collection<AddressMask> ipFilters;
-
- /**
- * Constructor.
- */
- public IpFilterCriteria() {
- ipFilters = new HashSet<AddressMask>();
- }
-
- /**
- * Adds a new Ip Filter to the list of allowed IP filters.
- * @param filter The new IP filter
- */
- public void addIpFilter(AddressMask filter) {
- ipFilters.add(filter);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean match(ClientConnection connection) {
- InetAddress ipAddr = connection.getRemoteAddress();
- if (AddressMask.maskListContains(ipAddr.getAddress(),
- ipAddr.getCanonicalHostName(),
- ipFilters.toArray(new AddressMask[0]))) {
- return (true);
- } else {
- return false;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean matchAfterBind(ClientConnection connection, DN bindDN,
- AuthenticationType authType, boolean isSecure) {
- return (match(connection));
- }
-}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroup.java b/opends/src/server/org/opends/server/core/networkgroups/NetworkGroup.java
index 9afa115..60c1f11 100644
--- a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroup.java
+++ b/opends/src/server/org/opends/server/core/networkgroups/NetworkGroup.java
@@ -26,177 +26,1375 @@
*/
package org.opends.server.core.networkgroups;
-import org.opends.messages.Message;
+
+
+import static org.opends.messages.ConfigMessages.*;
import static org.opends.messages.CoreMessages.*;
-import static org.opends.server.util.Validator.ensureNotNull;
+import static org.opends.server.loggers.ErrorLogger.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.util.StaticUtils.*;
+import static org.opends.server.util.Validator.*;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.List;
-import java.util.TreeMap;
import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
-import org.opends.server.admin.std.meta.
- NetworkGroupResourceLimitsCfgDefn.ReferralBindPolicy;
-import org.opends.server.admin.std.meta.
- NetworkGroupResourceLimitsCfgDefn.ReferralPolicy;
+import org.opends.messages.Message;
+import org.opends.server.admin.ClassPropertyDefinition;
+import org.opends.server.admin.server.ConfigurationAddListener;
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.server.ConfigurationDeleteListener;
+import org.opends.server.admin.std.meta.QOSPolicyCfgDefn;
+import org.opends.server.admin.std.server.NetworkGroupCfg;
+import org.opends.server.admin.std.server.QOSPolicyCfg;
import org.opends.server.api.ClientConnection;
-import org.opends.server.core.*;
+import org.opends.server.api.QOSPolicy;
+import org.opends.server.api.QOSPolicyFactory;
+import org.opends.server.config.ConfigException;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.RootDseWorkflowTopology;
+import org.opends.server.core.Workflow;
+import org.opends.server.core.WorkflowImpl;
+import org.opends.server.core.WorkflowTopologyNode;
+import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DN;
+import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
+import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
import org.opends.server.types.operation.PreParseOperation;
import org.opends.server.workflowelement.WorkflowElement;
+
+
/**
- * This class defines the network group. A network group is used to categorize
- * client connections. A network group is defined by a set of criteria, a
- * set of policies and a set of workflow nodes. A client connection belongs to
- * a network group whenever it satisfies all the network group criteria. As
- * soon as a client connection belongs to a network group, it has to comply
- * with all the network group policies. Any cleared client operation can be
- * routed to one the network group workflow nodes.
+ * This class defines the network group. A network group is used to
+ * categorize client connections. A network group is defined by a set of
+ * criteria, a set of policies and a set of workflow nodes. A client
+ * connection belongs to a network group whenever it satisfies all the
+ * network group criteria. As soon as a client connection belongs to a
+ * network group, it has to comply with all the network group policies.
+ * Any cleared client operation can be routed to one the network group
+ * workflow nodes.
*/
public class NetworkGroup
{
- // Workflow nodes registered with the current network group.
- // Keys are workflowIDs.
- private TreeMap<String, WorkflowTopologyNode> registeredWorkflowNodes =
- new TreeMap<String, WorkflowTopologyNode>();
+ /**
+ * Configuration change listener for user network groups.
+ */
+ private final class ChangeListener implements
+ ConfigurationChangeListener<NetworkGroupCfg>
+ {
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationChange(
+ NetworkGroupCfg configuration)
+ {
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ List<Message> messages = new ArrayList<Message>();
+
+ // Update the priority.
+ setNetworkGroupPriority(configuration.getPriority());
+
+ // Deregister any workflows that have been removed.
+ SortedSet<String> configWorkflows = configuration.getWorkflow();
+ for (String id : getRegisteredWorkflows())
+ {
+ if (!configWorkflows.contains(id))
+ {
+ deregisterWorkflow(id);
+ }
+ }
+
+ // Register any workflows that have been added.
+ List<String> ngWorkflows = getRegisteredWorkflows();
+ for (String id : configuration.getWorkflow())
+ {
+ if (!ngWorkflows.contains(id))
+ {
+ WorkflowImpl workflowImpl =
+ (WorkflowImpl) WorkflowImpl.getWorkflow(id);
+ try
+ {
+ registerWorkflow(workflowImpl);
+ }
+ catch (DirectoryException e)
+ {
+ if (resultCode == ResultCode.SUCCESS)
+ {
+ resultCode = e.getResultCode();
+ }
+ messages.add(e.getMessageObject());
+ }
+ }
+ }
+
+ try
+ {
+ criteria = decodeConnectionCriteriaConfiguration(configuration);
+ }
+ catch (ConfigException e)
+ {
+ resultCode = DirectoryServer.getServerErrorResultCode();
+ messages.add(e.getMessageObject());
+ }
+
+ // Update the configuration.
+ NetworkGroup.this.configuration = configuration;
+
+ return new ConfigChangeResult(resultCode, adminActionRequired,
+ messages);
+ }
- // A lock to protect concurrent access to the registered Workflow nodes.
- private Object registeredWorkflowNodesLock = new Object();
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationChangeAcceptable(
+ NetworkGroupCfg configuration, List<Message> unacceptableReasons)
+ {
+ return isConfigurationAcceptable(configuration,
+ unacceptableReasons);
+ }
+
+ }
+
+ /**
+ * Configuration change listener for user network group QOS policies.
+ */
+ private final class QOSPolicyListener implements
+ ConfigurationAddListener<QOSPolicyCfg>,
+ ConfigurationDeleteListener<QOSPolicyCfg>
+ {
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationAdd(
+ QOSPolicyCfg configuration)
+ {
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ List<Message> messages = new ArrayList<Message>();
+
+ try
+ {
+ createNetworkGroupQOSPolicy(configuration);
+ }
+ catch (ConfigException e)
+ {
+ messages.add(e.getMessageObject());
+ resultCode = DirectoryServer.getServerErrorResultCode();
+ }
+ catch (InitializationException e)
+ {
+ messages.add(e.getMessageObject());
+ resultCode = DirectoryServer.getServerErrorResultCode();
+ }
+
+ return new ConfigChangeResult(resultCode, adminActionRequired,
+ messages);
+ }
- // The workflow node for the rootDSE entry. The RootDSE workflow node
- // is not stored in the list of registered workflow nodes.
- private RootDseWorkflowTopology rootDSEWorkflowNode = null;
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationDelete(
+ QOSPolicyCfg configuration)
+ {
+ QOSPolicy policy = policies.remove(configuration.dn());
+
+ if (policy != null)
+ {
+ if (requestFilteringPolicy == policy)
+ {
+ requestFilteringPolicy = null;
+ }
+ else if (resourceLimitsPolicy == policy)
+ {
+ resourceLimitsPolicy = null;
+ }
+
+ policy.finalizeQOSPolicy();
+ }
+
+ return new ConfigChangeResult(ResultCode.SUCCESS, false);
+ }
- // List of naming contexts handled by the network group.
- private NetworkGroupNamingContexts namingContexts =
- new NetworkGroupNamingContexts();
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationAddAcceptable(
+ QOSPolicyCfg configuration, List<Message> unacceptableReasons)
+ {
+ return isNetworkGroupQOSPolicyConfigurationAcceptable(
+ configuration, unacceptableReasons);
+ }
- // The default network group (singleton).
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationDeleteAcceptable(
+ QOSPolicyCfg configuration, List<Message> unacceptableReasons)
+ {
+ // Always ok.
+ return true;
+ }
+
+ }
+
+
+
+ // The admin network group has no criterion, no policy,
+ // and gives access to all the workflows.
+ private static final String ADMIN_NETWORK_GROUP_NAME = "admin";
+
+ private static NetworkGroup adminNetworkGroup =
+ new NetworkGroup(ADMIN_NETWORK_GROUP_NAME);
+
// The default network group has no criterion, no policy, and gives
// access to all the workflows. The purpose of the default network
// group is to allow new clients to perform a first operation before
// they can be attached to a specific network group.
private static final String DEFAULT_NETWORK_GROUP_NAME = "default";
- private final boolean isDefaultNetworkGroup;
+
private static NetworkGroup defaultNetworkGroup =
- new NetworkGroup (DEFAULT_NETWORK_GROUP_NAME);
+ new NetworkGroup(DEFAULT_NETWORK_GROUP_NAME);
-
- // The admin network group (singleton).
- // The admin network group has no criterion, no policy, and gives
- // access to all the workflows.
- private static final String ADMIN_NETWORK_GROUP_NAME = "admin";
- private final boolean isAdminNetworkGroup;
- private static NetworkGroup adminNetworkGroup =
- new NetworkGroup (ADMIN_NETWORK_GROUP_NAME);
-
-
- // The internal network group (singleton).
// The internal network group has no criterion, no policy, and gives
// access to all the workflows. The purpose of the internal network
// group is to allow internal connections to perform operations.
private static final String INTERNAL_NETWORK_GROUP_NAME = "internal";
- private boolean isInternalNetworkGroup;
private static NetworkGroup internalNetworkGroup =
new NetworkGroup(INTERNAL_NETWORK_GROUP_NAME);
+ // The ordered list of network groups.
+ private static List<NetworkGroup> orderedNetworkGroups =
+ new ArrayList<NetworkGroup>();
// The list of all network groups that are registered with the server.
- // The defaultNetworkGroup is not in the list of registered network groups.
+ // The defaultNetworkGroup is not in the list of registered network
+ // groups.
private static TreeMap<String, NetworkGroup> registeredNetworkGroups =
new TreeMap<String, NetworkGroup>();
// A lock to protect concurrent access to the registeredNetworkGroups.
private static Object registeredNetworkGroupsLock = new Object();
- // The ordered list of network groups.
- private static List<NetworkGroup> orderedNetworkGroups =
- new ArrayList<NetworkGroup>();
+ /**
+ * The tracer object for the debug logger.
+ */
+ private static final DebugTracer TRACER = getTracer();
- // The network group internal identifier.
- private String networkGroupID = null;
-
- // The network group priority
- private int priority = 100;
-
- // The network group criteria.
- private NetworkGroupCriteria criteria = null;
-
- // The network group resource limits
- private ResourceLimits resourceLimits = null;
-
- // The network group request filtering policy
- private RequestFilteringPolicy requestFilteringPolicy = null;
-
- // The statistics
- private NetworkGroupStatistics stats;
-
- // The client connection affinity policy.
- private ClientConnectionAffinityPolicy affinityPolicy =
- ClientConnectionAffinityPolicy.NONE;
-
- // The client connection affinity timeout (number of seconds).
- private long affinityTimeout = 0;
-
/**
- * Creates a new instance of the network group.
- *
- * @param networkGroupID the network group internal identifier
+ * Deregisters all network groups that have been registered. This
+ * should be called when the server is shutting down.
*/
- public NetworkGroup(
- String networkGroupID
- )
+ public static void deregisterAllOnShutdown()
+ {
+ synchronized (registeredNetworkGroupsLock)
+ {
+ // Invalidate all NetworkGroups so they cannot accidentally be
+ // used after a restart.
+ Collection<NetworkGroup> networkGroups =
+ registeredNetworkGroups.values();
+ for (NetworkGroup networkGroup : networkGroups)
+ {
+ networkGroup.invalidate();
+ }
+ defaultNetworkGroup.invalidate();
+ adminNetworkGroup.invalidate();
+ internalNetworkGroup.invalidate();
+
+ registeredNetworkGroups = new TreeMap<String, NetworkGroup>();
+ orderedNetworkGroups = new ArrayList<NetworkGroup>();
+ defaultNetworkGroup = new NetworkGroup("default");
+ adminNetworkGroup = new NetworkGroup("admin");
+ internalNetworkGroup = new NetworkGroup("internal");
+ }
+ }
+
+
+
+ /**
+ * Gets the highest priority matching network group for a BIND op.
+ *
+ * @param connection
+ * the client connection
+ * @param dn
+ * the operation bindDN
+ * @param authType
+ * the operation authentication type
+ * @param isSecure
+ * a boolean indicating whether the operation is secured
+ * @return matching network group
+ */
+ static NetworkGroup findBindMatchingNetworkGroup(
+ ClientConnection connection, DN dn, AuthenticationType authType,
+ boolean isSecure)
+ {
+ for (NetworkGroup ng : orderedNetworkGroups)
+ {
+ if (ng.matchAfterBind(connection, dn, authType, isSecure))
+ {
+ return ng;
+ }
+ }
+ return defaultNetworkGroup;
+ }
+
+
+
+ /**
+ * Gets the highest priority matching network group.
+ *
+ * @param connection
+ * the client connection
+ * @return matching network group
+ */
+ static NetworkGroup findMatchingNetworkGroup(
+ ClientConnection connection)
+ {
+ for (NetworkGroup ng : orderedNetworkGroups)
+ {
+ if (ng.match(connection))
+ {
+ return ng;
+ }
+ }
+ return defaultNetworkGroup;
+ }
+
+
+
+ /**
+ * Returns the admin network group.
+ *
+ * @return the admin network group
+ */
+ public static NetworkGroup getAdminNetworkGroup()
+ {
+ return adminNetworkGroup;
+ }
+
+
+
+ /**
+ * Returns the default network group. The default network group is
+ * always defined and has no criterion, no policy and provide full
+ * access to all the registered workflows.
+ *
+ * @return the default network group
+ */
+ public static NetworkGroup getDefaultNetworkGroup()
+ {
+ return defaultNetworkGroup;
+ }
+
+
+
+ /**
+ * Returns the internal network group.
+ *
+ * @return the internal network group
+ */
+ public static NetworkGroup getInternalNetworkGroup()
+ {
+ return internalNetworkGroup;
+ }
+
+
+
+ /**
+ * Gets the network group having the specified ID.
+ * <p>
+ * This method is for testing only.
+ *
+ * @param networkGroupID
+ * The network group ID.
+ * @return The network group, of <code>null</code> if no match was found.
+ */
+ public static NetworkGroup getNetworkGroup(String networkGroupID)
+ {
+ return registeredNetworkGroups.get(networkGroupID);
+ }
+
+
+
+ /**
+ * Resets the configuration of all the registered network groups.
+ */
+ public static void resetConfig()
+ {
+ // Reset the default network group
+ defaultNetworkGroup.reset();
+ adminNetworkGroup.reset();
+ internalNetworkGroup.reset();
+
+ // Reset all the registered network group
+ synchronized (registeredNetworkGroupsLock)
+ {
+ registeredNetworkGroups = new TreeMap<String, NetworkGroup>();
+ orderedNetworkGroups = new ArrayList<NetworkGroup>();
+ }
+ }
+
+
+
+ /**
+ * Initializes this network group as a user network group using the
+ * provided configuration. The network group will monitor the
+ * configuration and update its configuration when necessary.
+ *
+ * @param configuration
+ * The network group configuration.
+ * @return The new user network group.
+ * @throws ConfigException
+ * If an unrecoverable problem arises during initialization
+ * of the user network group as a result of the server
+ * configuration.
+ * @throws InitializationException
+ * If a problem occurs during initialization of the user
+ * network group that is not related to the server
+ * configuration.
+ */
+ static NetworkGroup createUserNetworkGroup(
+ NetworkGroupCfg configuration) throws InitializationException,
+ ConfigException
+ {
+ NetworkGroup networkGroup = new NetworkGroup(configuration);
+
+ try
+ {
+ // Set the priority.
+ networkGroup.priority = configuration.getPriority();
+
+ // Initialize the network group criteria.
+ networkGroup.criteria =
+ decodeConnectionCriteriaConfiguration(configuration);
+
+ // Initialize the network group policies.
+ for (String policyName : configuration
+ .listNetworkGroupQOSPolicies())
+ {
+ QOSPolicyCfg policyConfiguration =
+ configuration.getNetworkGroupQOSPolicy(policyName);
+ networkGroup.createNetworkGroupQOSPolicy(policyConfiguration);
+ }
+
+ // Register the root DSE workflow with the network group.
+ WorkflowImpl rootDSEworkflow =
+ (WorkflowImpl) WorkflowImpl.getWorkflow("__root.dse__#");
+ networkGroup.registerWorkflow(rootDSEworkflow);
+
+ // Register the workflows with the network group.
+ for (String workflowID : configuration.getWorkflow())
+ {
+ WorkflowImpl workflowImpl =
+ (WorkflowImpl) WorkflowImpl.getWorkflow(workflowID);
+
+ if (workflowImpl == null)
+ {
+ // The workflow does not exist, log an error message
+ // and skip the workflow.
+ Message message =
+ INFO_ERR_WORKFLOW_DOES_NOT_EXIST.get(workflowID,
+ networkGroup.getID());
+ logError(message);
+ }
+ else
+ {
+ networkGroup.registerWorkflow(workflowImpl);
+ }
+ }
+
+ // Register all configuration change listeners.
+ configuration.addChangeListener(networkGroup.changeListener);
+ configuration
+ .addNetworkGroupQOSPolicyAddListener(networkGroup.policyListener);
+ configuration
+ .addNetworkGroupQOSPolicyDeleteListener(networkGroup.policyListener);
+
+ // Register the network group with the server.
+ networkGroup.register();
+ }
+ catch (DirectoryException e)
+ {
+ networkGroup.finalizeNetworkGroup();
+ throw new InitializationException(e.getMessageObject());
+ }
+ catch (InitializationException e)
+ {
+ networkGroup.finalizeNetworkGroup();
+ throw e;
+ }
+ catch (ConfigException e)
+ {
+ networkGroup.finalizeNetworkGroup();
+ throw e;
+ }
+
+ return networkGroup;
+ }
+
+
+
+ /**
+ * Indicates whether the provided network group configuration is
+ * acceptable.
+ *
+ * @param configuration
+ * The network group configuration.
+ * @param unacceptableReasons
+ * A list that can be used to hold messages about why the
+ * provided configuration is not acceptable.
+ * @return Returns <code>true</code> if the provided network group
+ * configuration is acceptable, or <code>false</code> if it is
+ * not.
+ */
+ static boolean isConfigurationAcceptable(
+ NetworkGroupCfg configuration, List<Message> unacceptableReasons)
+ {
+ // The configuration is always acceptable if disabled.
+ if (!configuration.isEnabled())
+ {
+ return true;
+ }
+
+ // Check that all the workflows in the network group have a
+ // different base DN.
+ boolean isAcceptable = true;
+
+ Set<String> allBaseDNs = new HashSet<String>();
+ for (String workflowId : configuration.getWorkflow())
+ {
+ WorkflowImpl workflow =
+ (WorkflowImpl) WorkflowImpl.getWorkflow(workflowId);
+ String baseDN = workflow.getBaseDN().toNormalizedString();
+ if (allBaseDNs.contains(baseDN))
+ {
+ // This baseDN is duplicated
+ Message message =
+ ERR_WORKFLOW_BASE_DN_DUPLICATED_IN_NG.get(baseDN,
+ getNameFromConfiguration(configuration));
+ unacceptableReasons.add(message);
+ isAcceptable = false;
+ break;
+ }
+ else
+ {
+ allBaseDNs.add(baseDN);
+ }
+ }
+
+ // Validate any policy configurations.
+ for (String policyName : configuration
+ .listNetworkGroupQOSPolicies())
+ {
+ try
+ {
+ QOSPolicyCfg policyCfg =
+ configuration.getNetworkGroupQOSPolicy(policyName);
+ if (!isNetworkGroupQOSPolicyConfigurationAcceptable(policyCfg,
+ unacceptableReasons))
+ {
+ isAcceptable = false;
+ }
+ }
+ catch (ConfigException e)
+ {
+ // This is bad - give up immediately.
+ unacceptableReasons.add(e.getMessageObject());
+ return false;
+ }
+ }
+
+ // The bind DN patterns may be malformed.
+ if (!configuration.getAllowedBindDN().isEmpty())
+ {
+ try
+ {
+ BindDNConnectionCriteria.decode(configuration
+ .getAllowedBindDN());
+ }
+ catch (DirectoryException e)
+ {
+ unacceptableReasons.add(e.getMessageObject());
+ isAcceptable = false;
+ }
+ }
+
+ return isAcceptable;
+ }
+
+
+
+ // Decodes connection criteria configuration.
+ private static ConnectionCriteria decodeConnectionCriteriaConfiguration(
+ NetworkGroupCfg configuration) throws ConfigException
+ {
+ List<ConnectionCriteria> filters =
+ new LinkedList<ConnectionCriteria>();
+
+ if (!configuration.getAllowedAuthMethod().isEmpty())
+ {
+ filters.add(new AuthMethodConnectionCriteria(configuration
+ .getAllowedAuthMethod()));
+ }
+
+ if (!configuration.getAllowedBindDN().isEmpty())
+ {
+ try
+ {
+ filters.add(BindDNConnectionCriteria.decode(configuration
+ .getAllowedBindDN()));
+ }
+ catch (DirectoryException e)
+ {
+ throw new ConfigException(e.getMessageObject());
+ }
+ }
+
+ if (!configuration.getAllowedClient().isEmpty()
+ || !configuration.getDeniedClient().isEmpty())
+ {
+ filters.add(new IPConnectionCriteria(configuration
+ .getAllowedClient(), configuration.getDeniedClient()));
+ }
+
+ if (!configuration.getAllowedProtocol().isEmpty())
+ {
+ filters.add(new ProtocolConnectionCriteria(configuration
+ .getAllowedProtocol()));
+ }
+
+ if (configuration.isIsSecurityMandatory())
+ {
+ filters.add(SecurityConnectionCriteria.SECURITY_REQUIRED);
+ }
+
+ if (filters.isEmpty())
+ {
+ return ConnectionCriteria.TRUE;
+ }
+ else
+ {
+ return new ANDConnectionCriteria(filters);
+ }
+ }
+
+
+
+ /**
+ * Gets the name of the network group configuration.
+ *
+ * @param configuration
+ * The configuration.
+ * @return The network group name.
+ */
+ private static String getNameFromConfiguration(NetworkGroupCfg configuration)
+ {
+ DN dn = configuration.dn();
+ return dn.getRDN().getAttributeValue(0).getStringValue();
+ }
+
+
+
+ // Determines whether or not the new network group configuration's
+ // implementation class is acceptable.
+ private static boolean isNetworkGroupQOSPolicyConfigurationAcceptable(
+ QOSPolicyCfg policyConfiguration,
+ List<Message> unacceptableReasons)
+ {
+ String className = policyConfiguration.getJavaClass();
+ QOSPolicyCfgDefn d = QOSPolicyCfgDefn.getInstance();
+ ClassPropertyDefinition pd = d.getJavaClassPropertyDefinition();
+
+ // Validate the configuration.
+ try
+ {
+ // Load the class and cast it to a network group policy factory.
+ Class<? extends QOSPolicyFactory> theClass;
+ QOSPolicyFactory factory;
+
+ theClass = pd.loadClass(className, QOSPolicyFactory.class);
+ factory = theClass.newInstance();
+
+ // Determine the initialization method to use: it must take a
+ // single parameter which is the exact type of the configuration
+ // object.
+ Method method =
+ theClass.getMethod("isConfigurationAcceptable",
+ QOSPolicyCfg.class, List.class);
+ Boolean acceptable =
+ (Boolean) method.invoke(factory, policyConfiguration,
+ unacceptableReasons);
+
+ if (!acceptable)
+ {
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ unacceptableReasons
+ .add(ERR_CONFIG_NETWORK_GROUP_POLICY_CANNOT_INITIALIZE.get(
+ String.valueOf(className), String
+ .valueOf(policyConfiguration.dn()),
+ stackTraceToSingleLineString(e)));
+ return false;
+ }
+
+ // The configuration is valid as far as we can tell.
+ return true;
+ }
+
+
+
+ // Change listener (active for user network groups).
+ private final ChangeListener changeListener;
+
+ // Current configuration (active for user network groups).
+ private NetworkGroupCfg configuration = null;
+
+ // The network group connection criteria.
+ private ConnectionCriteria criteria = ConnectionCriteria.TRUE;
+
+ private final boolean isAdminNetworkGroup;
+
+ private final boolean isDefaultNetworkGroup;
+
+ private final boolean isInternalNetworkGroup;
+
+ // List of naming contexts handled by the network group.
+ private NetworkGroupNamingContexts namingContexts =
+ new NetworkGroupNamingContexts();
+
+ // The network group internal identifier.
+ private final String networkGroupID;
+
+ // All network group policies mapping factory class name to policy.
+ private final Map<DN, QOSPolicy> policies =
+ new ConcurrentHashMap<DN, QOSPolicy>();
+
+ // Add/delete policy listener (active for user network groups).
+ private final QOSPolicyListener policyListener;
+
+ // The network group priority.
+ private int priority = 100;
+
+ // Workflow nodes registered with the current network group.
+ // Keys are workflowIDs.
+ private TreeMap<String, WorkflowTopologyNode> registeredWorkflowNodes =
+ new TreeMap<String, WorkflowTopologyNode>();
+
+ // A lock to protect concurrent access to the registered Workflow
+ // nodes.
+ private final Object registeredWorkflowNodesLock = new Object();
+
+ // The network group request filtering policy.
+ private RequestFilteringPolicy requestFilteringPolicy = null;
+
+ // The network group resource limits policy.
+ private ResourceLimitsPolicy resourceLimitsPolicy = null;
+
+ // The workflow node for the rootDSE entry. The RootDSE workflow node
+ // is not stored in the list of registered workflow nodes.
+ private RootDseWorkflowTopology rootDSEWorkflowNode = null;
+
+ // The network group statistics.
+ private final NetworkGroupStatistics statistics;
+
+
+
+ /**
+ * Creates a new system network group using the provided ID.
+ *
+ * @param networkGroupID
+ * The network group internal identifier.
+ */
+ public NetworkGroup(String networkGroupID)
{
this.networkGroupID = networkGroupID;
-
- isInternalNetworkGroup = INTERNAL_NETWORK_GROUP_NAME.equals(networkGroupID);
- isAdminNetworkGroup = ADMIN_NETWORK_GROUP_NAME.equals(networkGroupID);
- isDefaultNetworkGroup = DEFAULT_NETWORK_GROUP_NAME.equals(networkGroupID);
-
- stats = new NetworkGroupStatistics(this);
+ this.isInternalNetworkGroup =
+ INTERNAL_NETWORK_GROUP_NAME.equals(networkGroupID);
+ this.isAdminNetworkGroup =
+ ADMIN_NETWORK_GROUP_NAME.equals(networkGroupID);
+ this.isDefaultNetworkGroup =
+ DEFAULT_NETWORK_GROUP_NAME.equals(networkGroupID);
+ this.statistics = new NetworkGroupStatistics(this);
+ this.configuration = null;
+ this.changeListener = null;
+ this.policyListener = null;
}
+
+ /**
+ * Creates a new user network group using the provided configuration.
+ */
+ private NetworkGroup(NetworkGroupCfg configuration)
+ {
+ this.networkGroupID = getNameFromConfiguration(configuration);
+ this.isInternalNetworkGroup = false;
+ this.isAdminNetworkGroup = false;
+ this.isDefaultNetworkGroup = false;
+ this.statistics = new NetworkGroupStatistics(this);
+ this.configuration = configuration;
+ this.changeListener = new ChangeListener();
+ this.policyListener = new QOSPolicyListener();
+ }
+
+
+
+ /**
+ * Adds a connection to the group.
+ *
+ * @param connection
+ * the ClientConnection
+ */
+ public void addConnection(ClientConnection connection)
+ {
+ if (resourceLimitsPolicy != null)
+ {
+ resourceLimitsPolicy.addConnection(connection);
+ }
+ }
+
+
+
+ /**
+ * Checks the request filtering policy.
+ *
+ * @param operation
+ * the operation to be checked
+ * @param messages
+ * the error messages
+ * @return boolean indicating whether the operation conforms to the
+ * network group request filtering policy
+ */
+ boolean checkRequestFilteringPolicy(
+ PreParseOperation operation, List<Message> messages)
+ {
+ if (requestFilteringPolicy != null)
+ {
+ return requestFilteringPolicy.isAllowed(operation, messages);
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+
+
+ /**
+ * Checks the resource limits policy.
+ *
+ * @param connection
+ * the client connection
+ * @param operation
+ * the ongoing operation
+ * @param fullCheck
+ * a boolean indicating the level of checking: full/partial
+ * @param messages
+ * the messages indicating the cause of the failure.
+ * @return a boolean indicating whether resource limits are exceeded
+ */
+ boolean checkResourceLimitsPolicy(ClientConnection connection,
+ PreParseOperation operation, boolean fullCheck,
+ List<Message> messages)
+ {
+ if (resourceLimitsPolicy != null)
+ {
+ return resourceLimitsPolicy.isAllowed(connection, operation,
+ fullCheck, messages);
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+
+
+ /**
+ * Deregisters a workflow with the network group. The workflow to
+ * deregister is identified by its baseDN.
+ *
+ * @param baseDN
+ * the baseDN of the workflow to deregister, may be null
+ * @return the deregistered workflow
+ */
+ public Workflow deregisterWorkflow(DN baseDN)
+ {
+ Workflow workflow = null;
+
+ if (baseDN == null)
+ {
+ return workflow;
+ }
+
+ if (baseDN.isNullDN())
+ {
+ // deregister the rootDSE
+ deregisterWorkflow(rootDSEWorkflowNode);
+ workflow = rootDSEWorkflowNode.getWorkflowImpl();
+ }
+ else
+ {
+ // deregister a workflow node
+ synchronized (registeredWorkflowNodesLock)
+ {
+ for (WorkflowTopologyNode node : registeredWorkflowNodes
+ .values())
+ {
+ DN curDN = node.getBaseDN();
+ if (curDN.equals(baseDN))
+ {
+ // Call deregisterWorkflow() instead of
+ // deregisterWorkflowNode() because we want the naming
+ // context list to be updated as well.
+ deregisterWorkflow(node);
+ workflow = node.getWorkflowImpl();
+
+ // Only one workflow can match the baseDN, so we can break
+ // the loop here.
+ break;
+ }
+ }
+ }
+ }
+
+ // Now that the workflow node has been deregistered with the network
+ // group, update the reference counter of the workflow.
+ if ((workflow != null) && !isAdminNetworkGroup
+ && !isInternalNetworkGroup && !isDefaultNetworkGroup)
+ {
+ WorkflowImpl workflowImpl = (WorkflowImpl) workflow;
+ workflowImpl.decrementReferenceCounter();
+ }
+
+ return workflow;
+ }
+
+
+
+ /**
+ * Deregisters a workflow with the network group. The workflow to
+ * deregister is identified by its workflow ID.
+ *
+ * @param workflowID
+ * the workflow identifier of the workflow to deregister
+ * @return the deregistered workflow
+ */
+ public Workflow deregisterWorkflow(String workflowID)
+ {
+ Workflow workflow = null;
+
+ String rootDSEWorkflowID = null;
+ if (rootDSEWorkflowNode != null)
+ {
+ rootDSEWorkflowID =
+ rootDSEWorkflowNode.getWorkflowImpl().getWorkflowId();
+ }
+
+ if (workflowID.equalsIgnoreCase(rootDSEWorkflowID))
+ {
+ // deregister the rootDSE
+ deregisterWorkflow(rootDSEWorkflowNode);
+ workflow = rootDSEWorkflowNode.getWorkflowImpl();
+ }
+ else
+ {
+ // deregister a workflow node
+ synchronized (registeredWorkflowNodesLock)
+ {
+ for (WorkflowTopologyNode node : registeredWorkflowNodes
+ .values())
+ {
+ String curID = node.getWorkflowImpl().getWorkflowId();
+ if (curID.equals(workflowID))
+ {
+ // Call deregisterWorkflow() instead of
+ // deregisterWorkflowNode() because we want the naming
+ // context list to be updated as well.
+ deregisterWorkflow(node);
+ workflow = node.getWorkflowImpl();
+
+ // Only one workflow can match the baseDN, so we can break
+ // the loop here.
+ break;
+ }
+ }
+ }
+ }
+
+ // Now that the workflow node has been deregistered with the network
+ // group, update the reference counter of the workflow.
+ if ((workflow != null) && !isAdminNetworkGroup
+ && !isInternalNetworkGroup && !isDefaultNetworkGroup)
+ {
+ WorkflowImpl workflowImpl = (WorkflowImpl) workflow;
+ workflowImpl.decrementReferenceCounter();
+ }
+
+ return workflow;
+ }
+
+
+
+ /**
+ * Performs any finalization that might be required when this network
+ * group is unloaded. No action is taken in the default
+ * implementation.
+ */
+ public void finalizeNetworkGroup()
+ {
+ if (configuration != null)
+ {
+ // Finalization specific to user network groups.
+ deregister();
+
+ // Remove all change listeners.
+ configuration.removeChangeListener(changeListener);
+ configuration
+ .removeNetworkGroupQOSPolicyAddListener(policyListener);
+ configuration
+ .removeNetworkGroupQOSPolicyDeleteListener(policyListener);
+
+ configuration = null;
+ }
+
+ // Clean up policies.
+ for (QOSPolicy policy : policies.values())
+ {
+ policy.finalizeQOSPolicy();
+ }
+
+ requestFilteringPolicy = null;
+ resourceLimitsPolicy = null;
+ criteria = ConnectionCriteria.TRUE;
+ policies.clear();
+ }
+
+
+
/**
* Retrieves the network group ID.
+ *
* @return a string indicating the network group ID
*/
- public String getID() {
+ public String getID()
+ {
return networkGroupID;
}
+
/**
- * Performs any finalization that might be required when this
- * network group is unloaded. No action is taken in the
- * default implementation.
+ * Gets the minimum string length of a substring filter in a search
+ * operation.
+ *
+ * @return the minimum substring length
*/
- public void finalizeNetworkGroup()
+ public int getMinSubstring()
{
- // No action is required by default.
+ if (resourceLimitsPolicy != null)
+ {
+ return resourceLimitsPolicy.getMinSubstring();
+ }
+ else
+ {
+ return 0;
+ }
}
+
+ /**
+ * Returns the list of naming contexts handled by the network group.
+ *
+ * @return the list of naming contexts
+ */
+ public NetworkGroupNamingContexts getNamingContexts()
+ {
+ return namingContexts;
+ }
+
+
+
+ /**
+ * Returns the QOS policy associated with this network group having
+ * the specified class.
+ *
+ * @param <T>
+ * The type of QOS policy.
+ * @param clazz
+ * The class of QOS policy requested.
+ * @return The QOS policy associated with this network group having
+ * the specified class, or <code>null</code> if none was
+ * found.
+ */
+ public <T extends QOSPolicy> T getNetworkGroupQOSPolicy(Class<T> clazz)
+ {
+ for (QOSPolicy policy : policies.values())
+ {
+ if (clazz.isAssignableFrom(policy.getClass()))
+ {
+ return clazz.cast(policy);
+ }
+ }
+
+ return null;
+ }
+
+
+
+ /**
+ * Gets the search size limit, i.e. the maximum number of entries
+ * returned by a search.
+ *
+ * @return the maximum number of entries returned by a search
+ */
+ public int getSizeLimit()
+ {
+ if (resourceLimitsPolicy != null)
+ {
+ return resourceLimitsPolicy.getSizeLimit();
+ }
+ else
+ {
+ return DirectoryServer.getSizeLimit();
+ }
+ }
+
+
+
+ /**
+ * Gets the search duration limit, i.e. the maximum duration of a
+ * search operation.
+ *
+ * @return the maximum duration in ms of a search operation
+ */
+ public int getTimeLimit()
+ {
+ if (resourceLimitsPolicy != null)
+ {
+ return resourceLimitsPolicy.getTimeLimit();
+ }
+ else
+ {
+ return DirectoryServer.getTimeLimit();
+ }
+ }
+
+
+
+ /**
+ * Gets the highest workflow in the topology that can handle the
+ * baseDN.
+ *
+ * @param baseDN
+ * the base DN of the request
+ * @return the highest workflow in the topology that can handle the
+ * base DN, <code>null</code> if none was found
+ */
+ public Workflow getWorkflowCandidate(DN baseDN)
+ {
+ // the top workflow to return
+ Workflow workflowCandidate = null;
+
+ // get the list of workflow candidates
+ if (baseDN.isNullDN())
+ {
+ // The rootDSE workflow is the candidate.
+ workflowCandidate = rootDSEWorkflowNode;
+ }
+ else
+ {
+ // Search the highest workflow in the topology that can handle
+ // the baseDN.
+ for (WorkflowTopologyNode curWorkflow : namingContexts
+ .getNamingContexts())
+ {
+ workflowCandidate = curWorkflow.getWorkflowCandidate(baseDN);
+ if (workflowCandidate != null)
+ {
+ break;
+ }
+ }
+ }
+
+ return workflowCandidate;
+ }
+
+
+
+ /**
+ * Registers a workflow with the network group.
+ *
+ * @param workflow
+ * the workflow to register
+ * @throws DirectoryException
+ * If the workflow ID for the provided workflow conflicts
+ * with the workflow ID of an existing workflow.
+ */
+ public void registerWorkflow(WorkflowImpl workflow)
+ throws DirectoryException
+ {
+ // The workflow is registered with no pre/post workflow element.
+ registerWorkflow(workflow, null, null);
+ }
+
+
+
+ /**
+ * Removes a connection from the group.
+ *
+ * @param connection
+ * the ClientConnection
+ */
+ public void removeConnection(ClientConnection connection)
+ {
+ if (resourceLimitsPolicy != null)
+ {
+ resourceLimitsPolicy.removeConnection(connection);
+ }
+ }
+
+
+
+ /**
+ * Updates the operations statistics.
+ *
+ * @param message
+ * The LDAP message being processed
+ */
+ public void updateMessageRead(LDAPMessage message)
+ {
+ statistics.updateMessageRead(message);
+ }
+
+
+
+ /**
+ * Deregisters the current network group (this) with the server. The
+ * method also decrements the reference counter of the workflows so
+ * that workflows can be disabled or deleted if needed.
+ * <p>
+ * This methods is package private for testing purposes.
+ */
+ void deregister()
+ {
+ // Finalization specific to user network groups.
+ synchronized (registeredNetworkGroupsLock)
+ {
+ // Deregister this network group.
+ TreeMap<String, NetworkGroup> networkGroups =
+ new TreeMap<String, NetworkGroup>(registeredNetworkGroups);
+ networkGroups.remove(networkGroupID);
+ registeredNetworkGroups = networkGroups;
+ orderedNetworkGroups.remove(this);
+
+ // Decrement the reference counter of the workflows registered
+ // with this network group.
+ synchronized (registeredWorkflowNodesLock)
+ {
+ for (WorkflowTopologyNode workflowNode : registeredWorkflowNodes
+ .values())
+ {
+ WorkflowImpl workflowImpl = workflowNode.getWorkflowImpl();
+ workflowImpl.decrementReferenceCounter();
+ }
+ }
+ }
+ }
+
+
+
+ /**
+ * Returns the request filtering policy statistics associated with
+ * this network group.
+ *
+ * @return The request filtering policy statistics associated with
+ * this network group.
+ */
+ RequestFilteringPolicyStatistics getRequestFilteringPolicyStatistics()
+ {
+ if (requestFilteringPolicy != null)
+ {
+ return requestFilteringPolicy.getStatistics();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+
+ /**
+ * Returns the resource limits policy statistics associated with this
+ * network group.
+ *
+ * @return The resource limits policy statistics associated with this
+ * network group.
+ */
+ ResourceLimitsPolicyStatistics getResourceLimitsPolicyStatistics()
+ {
+ if (resourceLimitsPolicy != null)
+ {
+ return resourceLimitsPolicy.getStatistics();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+
/**
* Registers the current network group (this) with the server.
+ * <p>
+ * This methods is package private for testing purposes.
*
- * @throws DirectoryException If the network group ID for the provided
- * network group conflicts with the network
- * group ID of an existing network group.
+ * @throws InitializationException
+ * If the network group ID for the provided network group
+ * conflicts with the network group ID of an existing
+ * network group.
*/
- public void register()
- throws DirectoryException
+ void register() throws InitializationException
{
ensureNotNull(networkGroupID);
@@ -205,24 +1403,28 @@
// The network group must not be already registered
if (registeredNetworkGroups.containsKey(networkGroupID))
{
- Message message = ERR_REGISTER_NETWORK_GROUP_ALREADY_EXISTS.get(
- networkGroupID);
- throw new DirectoryException(
- ResultCode.UNWILLING_TO_PERFORM, message);
+ Message message =
+ ERR_REGISTER_NETWORK_GROUP_ALREADY_EXISTS
+ .get(networkGroupID);
+ throw new InitializationException(message);
}
TreeMap<String, NetworkGroup> newRegisteredNetworkGroups =
- new TreeMap<String, NetworkGroup>(registeredNetworkGroups);
+ new TreeMap<String, NetworkGroup>(registeredNetworkGroups);
newRegisteredNetworkGroups.put(networkGroupID, this);
registeredNetworkGroups = newRegisteredNetworkGroups;
- // Insert the network group at the right position in the ordered list
+ // Insert the network group at the right position in the ordered
+ // list.
int index = 0;
- for (NetworkGroup ng : registeredNetworkGroups.values()) {
- if (ng.equals(this)) {
+ for (NetworkGroup ng : registeredNetworkGroups.values())
+ {
+ if (ng.equals(this))
+ {
continue;
}
- if (this.priority > ng.priority) {
+ if (this.priority > ng.priority)
+ {
index++;
}
}
@@ -231,103 +1433,474 @@
}
- /**
- * Deregisters the current network group (this) with the server.
- * The method also decrements the reference counter of the workflows
- * so that workflows can be disabled or deleted if needed.
- */
- public void deregister()
- {
- synchronized (registeredNetworkGroupsLock)
- {
- TreeMap<String, NetworkGroup> networkGroups =
- new TreeMap<String, NetworkGroup>(registeredNetworkGroups);
- networkGroups.remove(networkGroupID);
- registeredNetworkGroups = networkGroups;
- orderedNetworkGroups.remove(this);
- // decrement the reference counter of the workflows registered with
- // this network group
- updateWorkflowReferenceCounters();
- }
+ /**
+ * Sets the network group connection criteria.
+ * <p>
+ * This method is intended for testing only.
+ *
+ * @param criteria
+ * The connection criteria.
+ */
+ void setConnectionCriteria(ConnectionCriteria criteria)
+ {
+ this.criteria = criteria;
}
+
/**
- * Decrements the workflow reference counters of all the workflows
- * registered with this network group.
+ * Sets the network group priority.
+ * <p>
+ * This methods is package private for testing purposes.
+ *
+ * @param prio
+ * the network group priority
*/
- private void updateWorkflowReferenceCounters()
+ void setNetworkGroupPriority(int prio)
{
- synchronized (registeredWorkflowNodesLock)
+ // Check whether the priority has changed
+ if (priority != prio)
{
- for (WorkflowTopologyNode workflowNode: registeredWorkflowNodes.values())
+ synchronized (registeredNetworkGroupsLock)
{
- WorkflowImpl workflowImpl = workflowNode.getWorkflowImpl();
- workflowImpl.decrementReferenceCounter();
+ priority = prio;
+
+ // Nothing to do if the network group is not registered
+ if (registeredNetworkGroups.containsKey(networkGroupID))
+ {
+ // If the network group was already registered, remove it from
+ // the ordered list
+ orderedNetworkGroups.remove(this);
+
+ // Then insert it at the right position in the ordered list
+ int index = 0;
+ for (NetworkGroup ng : registeredNetworkGroups.values())
+ {
+ if (ng.equals(this))
+ {
+ continue;
+ }
+ if (this.priority > ng.priority)
+ {
+ index++;
+ }
+ }
+ orderedNetworkGroups.add(index, this);
+ }
}
}
}
+
/**
- * Registers a workflow with the network group.
+ * Dumps info from the current network group for debug purpose.
+ * <p>
+ * This method is intended for testing only.
*
- * @param workflow the workflow to register
- *
- * @throws DirectoryException If the workflow ID for the provided
- * workflow conflicts with the workflow
- * ID of an existing workflow.
+ * @param leftMargin
+ * white spaces used to indent traces
+ * @return a string buffer that contains trace information
*/
- public void registerWorkflow(
- WorkflowImpl workflow
- ) throws DirectoryException
+ StringBuilder toString(String leftMargin)
{
- // The workflow is registered with no pre/post workflow element.
- registerWorkflow(workflow, null, null);
+ StringBuilder sb = new StringBuilder();
+ String newMargin = leftMargin + " ";
+
+ sb.append(leftMargin + "Networkgroup (" + networkGroupID + "\n");
+ sb.append(leftMargin + "List of registered workflows:\n");
+ for (WorkflowTopologyNode node : registeredWorkflowNodes.values())
+ {
+ sb.append(node.toString(newMargin));
+ }
+
+ namingContexts.toString(leftMargin);
+
+ sb.append(leftMargin + "rootDSEWorkflow:\n");
+ if (rootDSEWorkflowNode == null)
+ {
+ sb.append(newMargin + "null\n");
+ }
+ else
+ {
+ sb.append(rootDSEWorkflowNode.toString(newMargin));
+ }
+
+ return sb;
}
+
/**
- * Registers a workflow with the network group and the workflow may have
- * pre and post workflow element.
+ * Checks whether the base DN of a new workflow to register is present
+ * in a workflow already registered with the network group.
*
- * @param workflow the workflow to register
- * @param preWorkflowElements the tasks to execute before the workflow
- * @param postWorkflowElements the tasks to execute after the workflow
- *
- * @throws DirectoryException If the workflow ID for the provided
- * workflow conflicts with the workflow ID of an existing
- * workflow or if the base DN of the workflow is the same
- * than the base DN of another workflow already registered
+ * @param workflowNode
+ * the workflow to check
+ * @throws DirectoryException
+ * If the base DN of the workflow is already present in the
+ * network group
*/
- private void registerWorkflow(
- WorkflowImpl workflow,
+ private void checkWorkflowBaseDN(WorkflowTopologyNode workflowNode)
+ throws DirectoryException
+ {
+ String workflowID = workflowNode.getWorkflowImpl().getWorkflowId();
+ ensureNotNull(workflowID);
+
+ // If the network group is the "internal" network group then bypass
+ // the check because the internal network group may contain
+ // duplicates of base DNs.
+ if (isInternalNetworkGroup)
+ {
+ return;
+ }
+
+ // If the network group is the "admin" network group then bypass
+ // the check because the internal network group may contain
+ // duplicates of base DNs.
+ if (isAdminNetworkGroup)
+ {
+ return;
+ }
+
+ // The workflow base DN should not be already present in the
+ // network group. Bypass the check for the private workflows...
+ for (WorkflowTopologyNode node : registeredWorkflowNodes.values())
+ {
+ DN nodeBaseDN = node.getBaseDN();
+ if (nodeBaseDN.equals(workflowNode.getBaseDN()))
+ {
+ // The base DN is already registered in the network group,
+ // we must reject the registration request
+ Message message =
+ ERR_REGISTER_WORKFLOW_BASE_DN_ALREADY_EXISTS.get(
+ workflowID, networkGroupID, node.getWorkflowImpl()
+ .getWorkflowId(), workflowNode.getWorkflowImpl()
+ .getBaseDN().toString());
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
+ message);
+ }
+ }
+ }
+
+
+
+ // Creates and registers the provided network group policy
+ // configuration.
+ private void createNetworkGroupQOSPolicy(
+ QOSPolicyCfg policyConfiguration) throws ConfigException,
+ InitializationException
+ {
+ String className = policyConfiguration.getJavaClass();
+ QOSPolicyCfgDefn d = QOSPolicyCfgDefn.getInstance();
+ ClassPropertyDefinition pd = d.getJavaClassPropertyDefinition();
+
+ // Load the class and cast it to a network group policy.
+ Class<? extends QOSPolicyFactory> theClass;
+ QOSPolicyFactory factory;
+
+ try
+ {
+ theClass = pd.loadClass(className, QOSPolicyFactory.class);
+ factory = theClass.newInstance();
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message message =
+ ERR_CONFIG_NETWORK_GROUP_POLICY_CANNOT_INITIALIZE.get(String
+ .valueOf(className), String.valueOf(policyConfiguration
+ .dn()), stackTraceToSingleLineString(e));
+ throw new InitializationException(message, e);
+ }
+
+ // Perform the necessary initialization for the network group
+ // policy.
+ QOSPolicy policy;
+
+ try
+ {
+ // Determine the initialization method to use: it must take a
+ // single parameter which is the exact type of the configuration
+ // object.
+ Method method =
+ theClass.getMethod("createQOSPolicy", policyConfiguration
+ .configurationClass());
+
+ policy = (QOSPolicy) method.invoke(factory, policyConfiguration);
+ }
+ catch (Exception e)
+ {
+ if (e instanceof InvocationTargetException)
+ {
+ Throwable t = e.getCause();
+
+ if (t instanceof InitializationException)
+ {
+ throw (InitializationException) t;
+ }
+ else if (t instanceof ConfigException)
+ {
+ throw (ConfigException) t;
+ }
+ }
+
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message message =
+ ERR_CONFIG_NETWORK_GROUP_POLICY_CANNOT_INITIALIZE.get(String
+ .valueOf(className), String.valueOf(policyConfiguration
+ .dn()), stackTraceToSingleLineString(e));
+ throw new InitializationException(message, e);
+ }
+
+ // The network group has been successfully initialized - so register
+ // it.
+ QOSPolicy oldPolicy =
+ policies.put(policyConfiguration.dn(), policy);
+
+ if (policy instanceof RequestFilteringPolicy)
+ {
+ requestFilteringPolicy = (RequestFilteringPolicy) policy;
+ }
+ else if (policy instanceof ResourceLimitsPolicy)
+ {
+ resourceLimitsPolicy = (ResourceLimitsPolicy) policy;
+ }
+
+ if (oldPolicy != null)
+ {
+ oldPolicy.finalizeQOSPolicy();
+ }
+ }
+
+
+
+ /**
+ * Deregisters a workflow node with the network group.
+ *
+ * @param workflow
+ * the workflow node to deregister
+ * @return <code>true</code> when the workflow has been successfully
+ * deregistered
+ */
+ private boolean deregisterWorkflow(Workflow workflow)
+ {
+ // true as soon as the workflow has been deregistered
+ boolean deregistered = false;
+
+ // Is it the rootDSE workflow?
+ if (workflow == rootDSEWorkflowNode)
+ {
+ rootDSEWorkflowNode = null;
+ deregistered = true;
+ }
+ else
+ {
+ // Deregister the workflow with the network group.
+ WorkflowTopologyNode workflowNode =
+ (WorkflowTopologyNode) workflow;
+ deregisterWorkflowNode(workflowNode);
+ deregistered = true;
+
+ // The workflow to deregister is not the root DSE workflow.
+ // Remove it from the workflow topology.
+ workflowNode.remove();
+
+ // Rebuild the list of naming context handled by the network group
+ rebuildNamingContextList();
+ }
+
+ return deregistered;
+ }
+
+
+
+ /**
+ * Deregisters the current workflow (this) with the server.
+ *
+ * @param workflowNode
+ * the workflow node to deregister
+ */
+ private void deregisterWorkflowNode(WorkflowTopologyNode workflowNode)
+ {
+ synchronized (registeredWorkflowNodesLock)
+ {
+ TreeMap<String, WorkflowTopologyNode> newWorkflowNodes =
+ new TreeMap<String, WorkflowTopologyNode>(
+ registeredWorkflowNodes);
+ newWorkflowNodes.remove(workflowNode.getWorkflowImpl()
+ .getWorkflowId());
+ registeredWorkflowNodes = newWorkflowNodes;
+ }
+ }
+
+
+
+ /**
+ * Retrieves the list of registered workflows.
+ *
+ * @return a list of workflow ids
+ */
+ private List<String> getRegisteredWorkflows()
+ {
+ List<String> workflowIDs = new ArrayList<String>();
+ synchronized (registeredWorkflowNodesLock)
+ {
+ for (WorkflowTopologyNode node : registeredWorkflowNodes.values())
+ {
+ workflowIDs.add(node.getWorkflowImpl().getWorkflowId());
+ }
+ }
+ return workflowIDs;
+ }
+
+
+
+ /**
+ * We've seen parts of the server hold references to a NetworkGroup
+ * during an in-core server restart. To help detect when this happens,
+ * we null out the member variables, so we will fail fast with an NPE
+ * if an invalidate NetworkGroup is used.
+ */
+ private void invalidate()
+ {
+ namingContexts = null;
+ rootDSEWorkflowNode = null;
+ registeredWorkflowNodes = null;
+ }
+
+
+
+ /**
+ * Checks whether the connection matches the network group criteria.
+ *
+ * @param connection
+ * the client connection
+ * @return a boolean indicating the match
+ */
+ private boolean match(ClientConnection connection)
+ {
+ if (criteria != null)
+ {
+ return criteria.matches(connection);
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+
+
+ /**
+ * Checks whether the client connection matches the criteria after
+ * bind.
+ *
+ * @param connection
+ * the ClientConnection
+ * @param bindDN
+ * the DN used to bind
+ * @param authType
+ * the authentication type
+ * @param isSecure
+ * a boolean indicating whether the connection is secure
+ * @return a boolean indicating whether the connection matches the
+ * criteria
+ */
+ private boolean matchAfterBind(ClientConnection connection,
+ DN bindDN, AuthenticationType authType, boolean isSecure)
+ {
+ if (criteria != null)
+ {
+ return criteria.willMatchAfterBind(connection, bindDN, authType,
+ isSecure);
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+
+
+ /**
+ * Rebuilds the list of naming contexts handled by the network group.
+ * This operation should be performed whenever a workflow topology has
+ * been updated (workflow registration or de-registration).
+ */
+ private void rebuildNamingContextList()
+ {
+ // reset lists of naming contexts
+ namingContexts.resetLists();
+
+ // a registered workflow with no parent is a naming context
+ for (WorkflowTopologyNode workflowNode : registeredWorkflowNodes
+ .values())
+ {
+ WorkflowTopologyNode parent = workflowNode.getParent();
+ if (parent == null)
+ {
+ namingContexts.addNamingContext(workflowNode);
+ }
+ }
+ }
+
+
+
+ /**
+ * Registers a workflow with the network group and the workflow may
+ * have pre and post workflow element.
+ *
+ * @param workflow
+ * the workflow to register
+ * @param preWorkflowElements
+ * the tasks to execute before the workflow
+ * @param postWorkflowElements
+ * the tasks to execute after the workflow
+ * @throws DirectoryException
+ * If the workflow ID for the provided workflow conflicts
+ * with the workflow ID of an existing workflow or if the
+ * base DN of the workflow is the same than the base DN of
+ * another workflow already registered
+ */
+ private void registerWorkflow(WorkflowImpl workflow,
WorkflowElement<?>[] preWorkflowElements,
- WorkflowElement<?>[] postWorkflowElements
- ) throws DirectoryException
+ WorkflowElement<?>[] postWorkflowElements)
+ throws DirectoryException
{
// Is it the rootDSE workflow?
DN baseDN = workflow.getBaseDN();
if (baseDN.isNullDN())
{
- // NOTE - The rootDSE workflow is stored with the registeredWorkflows.
+ // NOTE - The rootDSE workflow is stored with the
+ // registeredWorkflows.
rootDSEWorkflowNode =
- new RootDseWorkflowTopology(workflow, namingContexts);
+ new RootDseWorkflowTopology(workflow, namingContexts);
}
else
{
- // This workflow is not the rootDSE workflow. Try to insert it in the
- // workflow topology.
- WorkflowTopologyNode workflowNode = new WorkflowTopologyNode(
- workflow, preWorkflowElements, postWorkflowElements);
+ // This workflow is not the rootDSE workflow. Try to insert it in
+ // the workflow topology.
+ WorkflowTopologyNode workflowNode =
+ new WorkflowTopologyNode(workflow, preWorkflowElements,
+ postWorkflowElements);
- // Register the workflow node with the network group. If the workflow
- // ID is already existing then an exception is raised.
+ // Register the workflow node with the network group. If the
+ // workflow ID is already existing then an exception is raised.
registerWorkflowNode(workflowNode);
// Now add the workflow in the workflow topology...
- for (WorkflowTopologyNode curNode: registeredWorkflowNodes.values())
+ for (WorkflowTopologyNode curNode : registeredWorkflowNodes
+ .values())
{
// Try to insert the new workflow under an existing workflow...
if (curNode.insertSubordinate(workflowNode))
@@ -350,10 +1923,9 @@
// Now that the workflow node has been registered with the network
// group, update the reference counter of the workflow, unless
- // the network group is either default, or administration, or internal
- // network group.
- if (!isAdminNetworkGroup
- && !isInternalNetworkGroup
+ // the network group is either default, or administration, or
+ // internal network group.
+ if (!isAdminNetworkGroup && !isInternalNetworkGroup
&& !isDefaultNetworkGroup)
{
workflow.incrementReferenceCounter();
@@ -362,196 +1934,19 @@
}
- /**
- * Deregisters a workflow with the network group. The workflow to
- * deregister is identified by its baseDN.
- *
- * @param baseDN the baseDN of the workflow to deregister, may be null
- *
- * @return the deregistered workflow
- */
- public Workflow deregisterWorkflow(
- DN baseDN
- )
- {
- Workflow workflow = null;
-
- if (baseDN == null)
- {
- return workflow;
- }
-
- if (baseDN.isNullDN())
- {
- // deregister the rootDSE
- deregisterWorkflow(rootDSEWorkflowNode);
- workflow = rootDSEWorkflowNode.getWorkflowImpl();
- }
- else
- {
- // deregister a workflow node
- synchronized (registeredWorkflowNodesLock)
- {
- for (WorkflowTopologyNode node: registeredWorkflowNodes.values())
- {
- DN curDN = node.getBaseDN();
- if (curDN.equals(baseDN))
- {
- // Call deregisterWorkflow() instead of deregisterWorkflowNode()
- // because we want the naming context list to be updated as well.
- deregisterWorkflow(node);
- workflow = node.getWorkflowImpl();
-
- // Only one workflow can match the baseDN, so we can break
- // the loop here.
- break;
- }
- }
- }
- }
-
- // Now that the workflow node has been deregistered with the network
- // group, update the reference counter of the workflow.
- if ((workflow != null)
- && !isAdminNetworkGroup
- && !isInternalNetworkGroup
- && !isDefaultNetworkGroup)
- {
- WorkflowImpl workflowImpl = (WorkflowImpl) workflow;
- workflowImpl.decrementReferenceCounter();
- }
-
- return workflow;
- }
-
-
- /**
- * Deregisters a workflow with the network group. The workflow to
- * deregister is identified by its workflow ID.
- *
- * @param workflowID the workflow identifier of the workflow to deregister
- * @return the deregistered workflow
- */
- public Workflow deregisterWorkflow(
- String workflowID
- )
- {
- Workflow workflow = null;
-
- String rootDSEWorkflowID = null;
- if (rootDSEWorkflowNode != null)
- {
- rootDSEWorkflowID = rootDSEWorkflowNode.getWorkflowImpl().getWorkflowId();
- }
-
- if (workflowID.equalsIgnoreCase(rootDSEWorkflowID))
- {
- // deregister the rootDSE
- deregisterWorkflow(rootDSEWorkflowNode);
- workflow = rootDSEWorkflowNode.getWorkflowImpl();
- }
- else
- {
- // deregister a workflow node
- synchronized (registeredWorkflowNodesLock)
- {
- for (WorkflowTopologyNode node: registeredWorkflowNodes.values())
- {
- String curID = node.getWorkflowImpl().getWorkflowId();
- if (curID.equals(workflowID))
- {
- // Call deregisterWorkflow() instead of deregisterWorkflowNode()
- // because we want the naming context list to be updated as well.
- deregisterWorkflow(node);
- workflow = node.getWorkflowImpl();
-
- // Only one workflow can match the baseDN, so we can break
- // the loop here.
- break;
- }
- }
- }
- }
-
- // Now that the workflow node has been deregistered with the network
- // group, update the reference counter of the workflow.
- if ((workflow != null)
- && !isAdminNetworkGroup
- && !isInternalNetworkGroup
- && !isDefaultNetworkGroup)
- {
- WorkflowImpl workflowImpl = (WorkflowImpl) workflow;
- workflowImpl.decrementReferenceCounter();
- }
-
- return workflow;
- }
-
-
- /**
- * Deregisters a workflow node with the network group.
- *
- * @param workflow the workflow node to deregister
- * @return <code>true</code> when the workflow has been successfully
- * deregistered
- */
- private boolean deregisterWorkflow(Workflow workflow)
- {
- // true as soon as the workflow has been deregistered
- boolean deregistered = false;
-
- // Is it the rootDSE workflow?
- if (workflow == rootDSEWorkflowNode)
- {
- rootDSEWorkflowNode = null;
- deregistered = true;
- }
- else
- {
- // Deregister the workflow with the network group.
- WorkflowTopologyNode workflowNode = (WorkflowTopologyNode) workflow;
- deregisterWorkflowNode(workflowNode);
- deregistered = true;
-
- // The workflow to deregister is not the root DSE workflow.
- // Remove it from the workflow topology.
- workflowNode.remove();
-
- // Rebuild the list of naming context handled by the network group
- rebuildNamingContextList();
- }
-
- return deregistered;
- }
-
-
- /**
- * Retrieves the list of registered workflows.
- * @return a list of workflow ids
- */
- public List<String> getRegisteredWorkflows() {
- List<String> workflowIDs = new ArrayList<String>();
- synchronized (registeredWorkflowNodesLock) {
- for (WorkflowTopologyNode node : registeredWorkflowNodes.values()) {
- workflowIDs.add(node.getWorkflowImpl().getWorkflowId());
- }
- }
- return workflowIDs;
- }
-
/**
* Registers a workflow node with the network group.
*
- * @param workflowNode the workflow node to register
- *
- * @throws DirectoryException If the workflow node ID for the provided
- * workflow node conflicts with the workflow
- * node ID of an existing workflow node.
+ * @param workflowNode
+ * the workflow node to register
+ * @throws DirectoryException
+ * If the workflow node ID for the provided workflow node
+ * conflicts with the workflow node ID of an existing
+ * workflow node.
*/
- private void registerWorkflowNode(
- WorkflowTopologyNode workflowNode
- ) throws DirectoryException
+ private void registerWorkflowNode(WorkflowTopologyNode workflowNode)
+ throws DirectoryException
{
String workflowID = workflowNode.getWorkflowImpl().getWorkflowId();
ensureNotNull(workflowID);
@@ -561,10 +1956,11 @@
// The workflow must not be already registered
if (registeredWorkflowNodes.containsKey(workflowID))
{
- Message message = ERR_REGISTER_WORKFLOW_NODE_ALREADY_EXISTS.get(
- workflowID, networkGroupID);
- throw new DirectoryException(
- ResultCode.UNWILLING_TO_PERFORM, message);
+ Message message =
+ ERR_REGISTER_WORKFLOW_NODE_ALREADY_EXISTS.get(workflowID,
+ networkGroupID);
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
+ message);
}
// The workflow base DN should not be already present in the
@@ -573,685 +1969,26 @@
// All is fine, let's register the workflow
TreeMap<String, WorkflowTopologyNode> newRegisteredWorkflowNodes =
- new TreeMap<String, WorkflowTopologyNode>(registeredWorkflowNodes);
+ new TreeMap<String, WorkflowTopologyNode>(
+ registeredWorkflowNodes);
newRegisteredWorkflowNodes.put(workflowID, workflowNode);
registeredWorkflowNodes = newRegisteredWorkflowNodes;
}
}
- /**
- * Checks whether the base DN of a new workflow to register is
- * present in a workflow already registered with the network group.
- *
- * @param workflowNode the workflow to check
- *
- * @throws DirectoryException If the base DN of the workflow is already
- * present in the network group
- */
- private void checkWorkflowBaseDN(
- WorkflowTopologyNode workflowNode
- ) throws DirectoryException
- {
- String workflowID = workflowNode.getWorkflowImpl().getWorkflowId();
- ensureNotNull(workflowID);
-
- // If the network group is the "internal" network group then bypass
- // the check because the internal network group may contain duplicates
- // of base DNs.
- if (isInternalNetworkGroup)
- {
- return;
- }
-
- // If the network group is the "admin" network group then bypass
- // the check because the internal network group may contain duplicates
- // of base DNs.
- if (isAdminNetworkGroup)
- {
- return;
- }
-
- // The workflow base DN should not be already present in the
- // network group. Bypass the check for the private workflows...
- for (WorkflowTopologyNode node: registeredWorkflowNodes.values())
- {
- DN nodeBaseDN = node.getBaseDN();
- if (nodeBaseDN.equals(workflowNode.getBaseDN()))
- {
- // The base DN is already registered in the network group,
- // we must reject the registration request
- Message message = ERR_REGISTER_WORKFLOW_BASE_DN_ALREADY_EXISTS.get(
- workflowID,
- networkGroupID,
- node.getWorkflowImpl().getWorkflowId(),
- workflowNode.getWorkflowImpl().getBaseDN().toString());
- throw new DirectoryException(
- ResultCode.UNWILLING_TO_PERFORM, message);
- }
- }
- }
-
-
- /**
- * Deregisters the current workflow (this) with the server.
- *
- * @param workflowNode the workflow node to deregister
- */
- private void deregisterWorkflowNode(
- WorkflowTopologyNode workflowNode
- )
- {
- synchronized (registeredWorkflowNodesLock)
- {
- TreeMap<String, WorkflowTopologyNode> newWorkflowNodes =
- new TreeMap<String, WorkflowTopologyNode>(registeredWorkflowNodes);
- newWorkflowNodes.remove(workflowNode.getWorkflowImpl().getWorkflowId());
- registeredWorkflowNodes = newWorkflowNodes;
- }
- }
-
-
- /**
- * Adds a connection to the group.
- *
- * @param connection the ClientConnection
- */
- public void addConnection(ClientConnection connection) {
- if (resourceLimits != null) {
- resourceLimits.addConnection(connection);
- }
- }
-
- /**
- * Removes a connection from the group.
- *
- * @param connection the ClientConnection
- */
- public void removeConnection(ClientConnection connection) {
- if (resourceLimits != null) {
- resourceLimits.removeConnection(connection);
- }
- }
-
- /**
- *
- * Sets the network group priority.
- *
- * @param prio the network group priority
- */
- public void setNetworkGroupPriority(int prio) {
- // Check whether the priority has changed
- if (priority != prio) {
- synchronized (registeredNetworkGroupsLock)
- {
- priority = prio;
-
- // Nothing to do if the network group is not registered
- if (registeredNetworkGroups.containsKey(networkGroupID)) {
- // If the network group was already registered, remove it from the
- // ordered list
- orderedNetworkGroups.remove(this);
-
- // Then insert it at the right position in the ordered list
- int index = 0;
- for (NetworkGroup ng : registeredNetworkGroups.values()) {
- if (ng.equals(this)) {
- continue;
- }
- if (this.priority > ng.priority) {
- index++;
- }
- }
- orderedNetworkGroups.add(index, this);
- }
- }
- }
- }
-
- /**
- *
- * Sets the network group criteria.
- *
- * @param ngCriteria the criteria
- */
- public void setCriteria(NetworkGroupCriteria ngCriteria) {
- criteria = ngCriteria;
- }
-
- /**
- * Sets the Resource Limits.
- *
- * @param limits the new resource limits
- */
- public void setResourceLimits(ResourceLimits limits) {
- resourceLimits = limits;
- }
-
-
- /**
- * Sets the Request Filtering Policy.
- *
- * @param policy the new request filtering policy
- */
- public void setRequestFilteringPolicy(RequestFilteringPolicy policy) {
- requestFilteringPolicy = policy;
- }
-
- /**
- * Sets the affinity policy. The client connection affinity is the ability
- * for the server to bypass a route algorithm like "load balancing" so
- * that a request is always sent to the same data source regardless the
- * route algorithm.
- *
- * @param affinityPolicy
- * The client connection affinity policy of the network group.
- */
- public void setAffinityPolicy(
- ClientConnectionAffinityPolicy affinityPolicy)
- {
- this.affinityPolicy = affinityPolicy;
- }
-
- /**
- * Sets the affinity timeout value. The client connection affinity, when
- * set, remains active until the time out expires. When the time out
- * value is set to 0 then an active affinity never expires.
- *
- * @param timeout
- * The affinity timeout value (0 means never expire).
- */
- public void setAffinityTimeout(long timeout)
- {
- this.affinityTimeout = timeout;
- }
-
- /**
- * Gets the highest priority matching network group.
- *
- * @param connection the client connection
- * @return matching network group
- */
- public static NetworkGroup findMatchingNetworkGroup(
- ClientConnection connection) {
- for (NetworkGroup ng : getOrderedNetworkGroups()) {
- if (ng.match(connection)) {
- return ng;
- }
- }
- return defaultNetworkGroup;
- }
-
- /**
- * Gets the highest priority matching network group for a BIND op.
- *
- * @param connection the client connection
- * @param dn the operation bindDN
- * @param authType the operation authentication type
- * @param isSecure a boolean indicating whether the operation is secured
- * @return matching network group
- */
- public static NetworkGroup findBindMatchingNetworkGroup(
- ClientConnection connection, DN dn, AuthenticationType authType,
- boolean isSecure) {
- for (NetworkGroup ng:getOrderedNetworkGroups()) {
- if (ng.matchAfterBind(connection, dn, authType, isSecure)) {
- return ng;
- }
- }
- return defaultNetworkGroup;
- }
-
- /**
- * Checks whether the connection matches the network group criteria.
- *
- * @param connection the client connection
- * @return a boolean indicating the match
- */
- private boolean match(ClientConnection connection) {
- if (criteria != null) {
- return (criteria.match(connection));
- }
- return (true);
- }
-
- /**
- * Checks whether the client connection matches the criteria after bind.
- *
- * @param connection the ClientConnection
- * @param bindDN the DN used to bind
- * @param authType the authentication type
- * @param isSecure a boolean indicating whether the connection is secure
- * @return a boolean indicating whether the connection matches the criteria
- */
- private boolean matchAfterBind(ClientConnection connection, DN bindDN,
- AuthenticationType authType, boolean isSecure) {
- if (criteria != null) {
- return (criteria.matchAfterBind(connection, bindDN, authType, isSecure));
- }
- return (true);
- }
-
-
- /**
- * Checks the resource limits.
- *
- * @param connection the client connection
- * @param operation the ongoing operation
- * @param fullCheck a boolean indicating the level of checking: full/partial
- * @param messages the messages indicating the cause of the failure.
- * @return a boolean indicating whether resource limits are exceeded
- */
- public boolean checkResourceLimits(
- ClientConnection connection,
- PreParseOperation operation,
- boolean fullCheck,
- List<Message> messages)
- {
- if (resourceLimits != null) {
- return (resourceLimits.checkLimits(connection, operation,
- fullCheck, messages));
- }
- return (true);
- }
-
- /**
- * Gets the search size limit, i.e. the maximum number of entries returned
- * by a search.
- * @return the maximum number of entries returned by a search
- */
- public int getSearchSizeLimit() {
- if (resourceLimits != null) {
- return resourceLimits.getSizeLimit();
- }
- return -1;
- }
-
- /**
- * Gets the search duration limit, i.e. the maximum duration of a search
- * operation.
- * @return the maximum duration in ms of a search operation
- */
- public int getSearchDurationLimit() {
- if (resourceLimits != null) {
- return resourceLimits.getTimeLimit();
- }
- return -1;
- }
-
- /**
- * Gets the minimum string length of a substring filter in a search
- * operation.
- * @return the minimum substring length
- */
- public int getMinSubstring() {
- if (resourceLimits != null) {
- return resourceLimits.getMinSubstring();
- }
- return 0;
- }
-
- /**
- * Gets the referral policy. The referral policy defines the behavior
- * when a referral or a search continuation reference is received.
- * The referral can either be discarded (ie an error is returned to the
- * client), forwarded (ie the result is passed as-is to the client) or
- * followed (ie the server contacts the server targeted by the referral to
- * pursue the request).
- * @return the referral policy for this network group
- */
- public ReferralPolicy getReferralPolicy() {
- if (resourceLimits != null) {
- return resourceLimits.getReferralPolicy();
- }
- return ReferralPolicy.FORWARD;
- }
-
- /**
- * Gets the referral bind policy. The referral bind policy defines
- * the bind credentials used when the server tries to follow a referral. It
- * can either bind to the referred server anonymously, or using the same
- * credentials as in the original request.
- * @return the referral binf policy
- */
- public ReferralBindPolicy getReferralBindPolicy() {
- if (resourceLimits != null) {
- return resourceLimits.getReferralBindPolicy();
- }
- return ReferralBindPolicy.ANONYMOUS;
- }
-
- /**
- * Gets the referral hop limit. When configured to follow referrals,
- * the request to the referred server can also contain a referral. The hop
- * limit is the maximum number of subsequent operations.
- * @return the referral hop limit
- */
- public int getReferralHopLimit() {
- if (resourceLimits != null) {
- return resourceLimits.getReferralHopLimit();
- }
- return 0;
- }
-
- /**
- * Gets the affinity policy. The client connection affinity is the ability
- * for the server to bypass a route algorithm like "load balancing" so
- * that a request is always sent to the same data source regardless the
- * route algorithm.
- *
- * @return the client connection affinity policy of the network group
- */
- public ClientConnectionAffinityPolicy getAffinityPolicy()
- {
- return this.affinityPolicy;
- }
-
- /**
- * Gets the affinity timeout value. The client connection affinity, when
- * set, is active for a period of time. Once that period of time has
- * expired, the client connection affinity is reset. A value of 0 means
- * "no limit" - when an affinity is set it remains active for ever.
- *
- * @return the affinity timeout value (0 means no limit).
- */
- public long getAffinityTimeout()
- {
- return this.affinityTimeout;
- }
-
- /**
- * Checks the request filtering policy.
- * @param operation the operation to be checked
- * @param messages the error messages
- * @return boolean indicating whether the operation conforms to the
- * network group request filtering policy
- */
- public boolean checkRequestFilteringPolicy(
- PreParseOperation operation,
- List<Message> messages) {
- if (requestFilteringPolicy != null) {
- return requestFilteringPolicy.checkPolicy(operation, messages);
- }
- return true;
- }
-
-
- /**
- * Gets the highest workflow in the topology that can handle the baseDN.
- *
- * @param baseDN the base DN of the request
- * @return the highest workflow in the topology that can handle the base DN,
- * <code>null</code> if none was found
- */
- public Workflow getWorkflowCandidate(
- DN baseDN
- )
- {
- // the top workflow to return
- Workflow workflowCandidate = null;
-
- // get the list of workflow candidates
- if (baseDN.isNullDN())
- {
- // The rootDSE workflow is the candidate.
- workflowCandidate = rootDSEWorkflowNode;
- }
- else
- {
- // Search the highest workflow in the topology that can handle
- // the baseDN.
- for (WorkflowTopologyNode curWorkflow: namingContexts.getNamingContexts())
- {
- workflowCandidate = curWorkflow.getWorkflowCandidate (baseDN);
- if (workflowCandidate != null)
- {
- break;
- }
- }
- }
-
- return workflowCandidate;
- }
-
-
- /**
- * Returns the default network group. The default network group is always
- * defined and has no criterion, no policy and provide full access to
- * all the registered workflows.
- *
- * @return the default network group
- */
- public static NetworkGroup getDefaultNetworkGroup()
- {
- return defaultNetworkGroup;
- }
-
-
- /**
- * Returns the admin network group.
- * @return the admin network group
- */
- public static NetworkGroup getAdminNetworkGroup()
- {
- return adminNetworkGroup;
- }
-
-
- /**
- * Returns the internal network group.
- * @return the internal network group
- */
- public static NetworkGroup getInternalNetworkGroup()
- {
- return internalNetworkGroup;
- }
-
-
- /**
- * Rebuilds the list of naming contexts handled by the network group.
- * This operation should be performed whenever a workflow topology
- * has been updated (workflow registration or de-registration).
- */
- private void rebuildNamingContextList()
- {
- // reset lists of naming contexts
- namingContexts.resetLists();
-
- // a registered workflow with no parent is a naming context
- for (WorkflowTopologyNode workflowNode: registeredWorkflowNodes.values())
- {
- WorkflowTopologyNode parent = workflowNode.getParent();
- if (parent == null)
- {
- namingContexts.addNamingContext (workflowNode);
- }
- }
- }
-
-
- /**
- * Returns the list of naming contexts handled by the network group.
- *
- * @return the list of naming contexts
- */
- public NetworkGroupNamingContexts getNamingContexts()
- {
- return namingContexts;
- }
-
-
- /**
- * Dumps info from the current network group for debug purpose.
- *
- * @param leftMargin white spaces used to indent traces
- * @return a string buffer that contains trace information
- */
- public StringBuilder toString(String leftMargin)
- {
- StringBuilder sb = new StringBuilder();
- String newMargin = leftMargin + " ";
-
- sb.append (leftMargin + "Networkgroup (" + networkGroupID+ "\n");
- sb.append (leftMargin + "List of registered workflows:\n");
- for (WorkflowTopologyNode node: registeredWorkflowNodes.values())
- {
- sb.append (node.toString (newMargin));
- }
-
- namingContexts.toString (leftMargin);
-
- sb.append (leftMargin + "rootDSEWorkflow:\n");
- if (rootDSEWorkflowNode == null)
- {
- sb.append (newMargin + "null\n");
- }
- else
- {
- sb.append (rootDSEWorkflowNode.toString (newMargin));
- }
-
- return sb;
- }
-
-
- /**
- * Deregisters all network groups that have been registered. This should be
- * called when the server is shutting down.
- */
- public static void deregisterAllOnShutdown()
- {
- synchronized (registeredNetworkGroupsLock)
- {
- // Invalidate all NetworkGroups so they cannot accidentally be used
- // after a restart.
- Collection<NetworkGroup> networkGroups = registeredNetworkGroups.values();
- for (NetworkGroup networkGroup: networkGroups)
- {
- networkGroup.invalidate();
- }
- defaultNetworkGroup.invalidate();
- adminNetworkGroup.invalidate();
- internalNetworkGroup.invalidate();
-
- registeredNetworkGroups = new TreeMap<String,NetworkGroup>();
- orderedNetworkGroups = new ArrayList<NetworkGroup>();
- defaultNetworkGroup = new NetworkGroup ("default");
- adminNetworkGroup = new NetworkGroup ("admin");
- internalNetworkGroup = new NetworkGroup("internal");
- }
- }
-
- /**
- * We've seen parts of the server hold references to a NetworkGroup
- * during an in-core server restart. To help detect when this happens,
- * we null out the member variables, so we will fail fast with an NPE if an
- * invalidate NetworkGroup is used.
- */
- private void invalidate()
- {
- namingContexts = null;
- networkGroupID = null;
- rootDSEWorkflowNode = null;
- registeredWorkflowNodes = null;
- }
-
-
- /**
- * Provides the list of network group registered with the server.
- *
- * @return the list of registered network groups
- */
- public static Collection<NetworkGroup> getRegisteredNetworkGroups()
- {
- return registeredNetworkGroups.values();
- }
-
-
- /**
- * Provides the ordered list of registered Network groups.
- *
- * @return the ordered list of registered network groups
- */
- private static List<NetworkGroup> getOrderedNetworkGroups()
- {
- return orderedNetworkGroups;
- }
-
-
- /**
- * Returns a specific NetworkGroup.
- *
- * @param networkGroupId the identifier of the requested network group
- * @return the requested NetworkGroup
- */
- public static NetworkGroup getNetworkGroup(String networkGroupId)
- {
- return registeredNetworkGroups.get(networkGroupId);
- }
-
-
- /**
- * Resets the configuration of all the registered network groups.
- */
- public static void resetConfig()
- {
- // Reset the default network group
- defaultNetworkGroup.reset();
- adminNetworkGroup.reset();
- internalNetworkGroup.reset();
-
- // Reset all the registered network group
- synchronized (registeredNetworkGroupsLock)
- {
- registeredNetworkGroups = new TreeMap<String, NetworkGroup>();
- orderedNetworkGroups = new ArrayList<NetworkGroup>();
- }
- }
-
/**
* Resets the configuration of the current network group.
*/
- public void reset()
+ private void reset()
{
synchronized (registeredWorkflowNodesLock)
{
- registeredWorkflowNodes = new TreeMap<String, WorkflowTopologyNode>();
+ registeredWorkflowNodes =
+ new TreeMap<String, WorkflowTopologyNode>();
rootDSEWorkflowNode = null;
namingContexts = new NetworkGroupNamingContexts();
}
}
-
- /**
- * Retrieves the statistics associated to the request filtering policy.
- *
- * @return the statistics associated to the request filtering policy
- */
- public RequestFilteringPolicyStat getRequestFilteringPolicyStat() {
- if (requestFilteringPolicy != null) {
- return requestFilteringPolicy.getStat();
- }
- return null;
- }
-
- /**
- * Retrieves the statistics associated to the resource limits.
- *
- * @return the statistics associated to the resource limits
- */
- public ResourceLimitsStat getResourceLimitStat() {
- if (resourceLimits != null) {
- return resourceLimits.getStat();
- }
- return null;
- }
-
- /**
- * Updates the operations statistics.
- * @param message The LDAP message being processed
- */
- public void updateMessageRead(LDAPMessage message) {
- stats.updateMessageRead(message);
- }
}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupConfigManager.java b/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupConfigManager.java
index 781574e..5608ad9 100644
--- a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupConfigManager.java
+++ b/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupConfigManager.java
@@ -28,14 +28,11 @@
-import static org.opends.messages.CoreMessages.*;
-import static org.opends.server.loggers.ErrorLogger.logError;
+import static org.opends.messages.ConfigMessages.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
-import java.util.SortedSet;
import java.util.concurrent.ConcurrentHashMap;
import org.opends.messages.Message;
@@ -44,35 +41,40 @@
import org.opends.server.admin.server.ConfigurationDeleteListener;
import org.opends.server.admin.server.ServerManagementContext;
import org.opends.server.admin.std.server.NetworkGroupCfg;
-import org.opends.server.admin.std.server.NetworkGroupCriteriaCfg;
-import
- org.opends.server.admin.std.server.NetworkGroupRequestFilteringPolicyCfg;
-import org.opends.server.admin.std.server.NetworkGroupResourceLimitsCfg;
import org.opends.server.admin.std.server.RootCfg;
import org.opends.server.config.ConfigException;
-import org.opends.server.core.*;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DN;
-import org.opends.server.types.DirectoryException;
+import org.opends.server.types.DebugLogLevel;
+import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
+import org.opends.server.util.StaticUtils;
+
/**
- * This class defines a utility that will be used to manage the configuration
- * for the set of network groups defined in the Directory Server.
- * It will perform the necessary initialization of those network groups when
- * the server is first started, and then will manage any changes to them while
- * the server is running.
+ * This class defines a utility that will be used to manage the
+ * configuration for the set of network groups defined in the Directory
+ * Server. It will perform the necessary initialization of those network
+ * groups when the server is first started, and then will manage any
+ * changes to them while the server is running.
*/
-public class NetworkGroupConfigManager
- implements ConfigurationChangeListener<NetworkGroupCfg>,
- ConfigurationAddListener<NetworkGroupCfg>,
- ConfigurationDeleteListener<NetworkGroupCfg>
+public class NetworkGroupConfigManager implements
+ ConfigurationChangeListener<NetworkGroupCfg>,
+ ConfigurationAddListener<NetworkGroupCfg>,
+ ConfigurationDeleteListener<NetworkGroupCfg>
{
+ /**
+ * The tracer object for the debug logger.
+ */
+ private static final DebugTracer TRACER = getTracer();
+
// A mapping between the DNs of the config entries and the associated
// network groups.
- private ConcurrentHashMap<DN, NetworkGroup> networkGroups;
+ private final ConcurrentHashMap<DN, NetworkGroup> networkGroups;
@@ -87,175 +89,52 @@
/**
- * Initializes all network groups currently defined in the Directory
- * Server configuration. This should only be called at Directory Server
- * startup.
- *
- * @throws ConfigException If a configuration problem causes the network
- * group initialization process to fail.
- */
- public void initializeNetworkGroups()
- throws ConfigException
- {
- // Get the root configuration object.
- ServerManagementContext managementContext =
- ServerManagementContext.getInstance();
- RootCfg rootConfiguration =
- managementContext.getRootConfiguration();
-
-
- // Register as an add and delete listener with the root configuration so we
- // can be notified if any network group entries are added or removed.
- rootConfiguration.addNetworkGroupAddListener(this);
- rootConfiguration.addNetworkGroupDeleteListener(this);
-
-
- //Initialize the existing network groups.
- for (String networkGroupName : rootConfiguration.listNetworkGroups())
- {
- NetworkGroupCfg networkGroupConfiguration =
- rootConfiguration.getNetworkGroup(networkGroupName);
- networkGroupConfiguration.addChangeListener(this);
-
- if (networkGroupConfiguration.isEnabled())
- {
- try
- {
- createAndRegisterNetworkGroup(networkGroupConfiguration);
- }
- catch (DirectoryException de)
- {
- throw new ConfigException(de.getMessageObject());
- }
- }
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationAddAcceptable(
- NetworkGroupCfg configuration,
- List<Message> unacceptableReasons)
- {
- // Nothing to check.
- return true;
- }
-
-
-
- /**
* {@inheritDoc}
*/
public ConfigChangeResult applyConfigurationAdd(
NetworkGroupCfg configuration)
{
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- List<Message> messages = new ArrayList<Message>();
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ List<Message> messages = new ArrayList<Message>();
+ // Register to be notified of changes to the new network group.
configuration.addChangeListener(this);
- // If the new network group is enabled then create it and register it.
+ // If the new network group is enabled then create it and register
+ // it.
if (configuration.isEnabled())
{
try
{
- createAndRegisterNetworkGroup(configuration);
+ NetworkGroup networkGroup =
+ NetworkGroup.createUserNetworkGroup(configuration);
+ networkGroups.put(configuration.dn(), networkGroup);
}
- catch (DirectoryException de)
+ catch (InitializationException e)
{
- if (resultCode == ResultCode.SUCCESS)
+ if (debugEnabled())
{
- resultCode = DirectoryServer.getServerErrorResultCode();
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- messages.add(de.getMessageObject());
+ messages.add(e.getMessageObject());
+ resultCode = DirectoryServer.getServerErrorResultCode();
}
-
- }
-
- return new ConfigChangeResult(resultCode, adminActionRequired, messages);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationDeleteAcceptable(
- NetworkGroupCfg configuration,
- List<Message> unacceptableReasons)
- {
- return true;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public ConfigChangeResult applyConfigurationDelete(
- NetworkGroupCfg configuration)
- {
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- List<Message> messages = new ArrayList<Message>();
-
-
- NetworkGroup networkGroup = networkGroups.remove(configuration.dn());
- if (networkGroup != null)
- {
- networkGroup.deregister();
- networkGroup.finalizeNetworkGroup();
- }
-
- return new ConfigChangeResult(resultCode, adminActionRequired, messages);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationChangeAcceptable(
- NetworkGroupCfg configuration,
- List<Message> unacceptableReasons)
- {
- // If the network group is disabled then there is nothing to check.
- if (! configuration.isEnabled())
- {
- return true;
- }
-
- // Check that all the workflows in the network group have a
- // different base DN.
-
- boolean result = true;
- Set<String> allBaseDNs = new HashSet<String>();
- for (String workflowId : configuration.getWorkflow())
- {
- WorkflowImpl workflow =
- (WorkflowImpl) WorkflowImpl.getWorkflow(workflowId);
- String baseDN = workflow.getBaseDN().toNormalizedString();
- if (allBaseDNs.contains(baseDN))
+ catch (ConfigException e)
{
- // This baseDN is duplicated
- Message message = ERR_WORKFLOW_BASE_DN_DUPLICATED_IN_NG.get(
- baseDN, configuration.getNetworkGroupId());
- unacceptableReasons.add(message);
- result = false;
- break;
- }
- else
- {
- allBaseDNs.add(baseDN);
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ messages.add(e.getMessageObject());
+ resultCode = DirectoryServer.getServerErrorResultCode();
}
}
- return result;
+ return new ConfigChangeResult(resultCode, adminActionRequired,
+ messages);
}
@@ -266,215 +145,168 @@
public ConfigChangeResult applyConfigurationChange(
NetworkGroupCfg configuration)
{
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- List<Message> messages = new ArrayList<Message>();
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ List<Message> messages = new ArrayList<Message>();
- ConfigChangeResult configChangeResult =
- new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ // Enable / disable the network group as required.
+ NetworkGroup networkGroup = networkGroups.get(configuration.dn());
- // Get the existing network group if it's already enabled.
- NetworkGroup existingNetworkGroup = networkGroups.get(configuration.dn());
-
- // If the new configuration has the network group disabled, then disable
- // it if it is enabled, or do nothing if it's already disabled.
- if (! configuration.isEnabled())
+ if (networkGroup != null && !configuration.isEnabled())
{
- if (existingNetworkGroup != null)
- {
- networkGroups.remove(configuration.dn());
- existingNetworkGroup.deregister();
- existingNetworkGroup.finalizeNetworkGroup();
- }
-
- return configChangeResult;
+ // The network group has been disabled.
+ networkGroups.remove(configuration.dn());
+ networkGroup.finalizeNetworkGroup();
}
-
- // If the network group is disabled then create it and register it.
- if (existingNetworkGroup == null)
+ else if (networkGroup == null && configuration.isEnabled())
{
+ // The network group has been enabled.
try
{
- createAndRegisterNetworkGroup(configuration);
+ networkGroup =
+ NetworkGroup.createUserNetworkGroup(configuration);
+ networkGroups.put(configuration.dn(), networkGroup);
}
- catch (DirectoryException de)
+ catch (InitializationException e)
{
- if (resultCode == ResultCode.SUCCESS)
+ if (debugEnabled())
{
- resultCode = DirectoryServer.getServerErrorResultCode();
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- messages.add(de.getMessageObject());
+ messages.add(e.getMessageObject());
+ resultCode = DirectoryServer.getServerErrorResultCode();
}
- } else {
- // The network group is already defined
- // Simply update the properties
- existingNetworkGroup.setNetworkGroupPriority(configuration.getPriority());
-
- // Check for workflows currently registered in the network group
- // but that must be removed
- SortedSet<String> configWorkflows = configuration.getWorkflow();
- for (String id : existingNetworkGroup.getRegisteredWorkflows()) {
- if (!configWorkflows.contains(id)) {
- existingNetworkGroup.deregisterWorkflow(id);
+ catch (ConfigException e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
+
+ messages.add(e.getMessageObject());
+ resultCode = DirectoryServer.getServerErrorResultCode();
}
-
- // Check for newly defined workflows
- List<String> ngWorkflows = existingNetworkGroup.getRegisteredWorkflows();
- for (String id : configuration.getWorkflow()) {
- if (! ngWorkflows.contains(id)) {
- WorkflowImpl workflowImpl =
- (WorkflowImpl) WorkflowImpl.getWorkflow(id);
- try {
- existingNetworkGroup.registerWorkflow(workflowImpl);
- } catch (DirectoryException de) {
- if (resultCode == ResultCode.SUCCESS)
- {
- resultCode = de.getResultCode();
- }
- messages.add(de.getMessageObject());
- }
- }
- }
-
- // Update the client connection affinity policy.
- existingNetworkGroup.setAffinityPolicy(
- ClientConnectionAffinityPolicy.toClientConnectionAffinityPolicy(
- configuration.getAffinityPolicy()));
-
- // Update the client connection affinity timeout
- existingNetworkGroup.setAffinityTimeout(
- configuration.getAffinityTimeout());
}
- configChangeResult =
- new ConfigChangeResult(resultCode, adminActionRequired, messages);
-
- return configChangeResult;
+ return new ConfigChangeResult(resultCode, adminActionRequired,
+ messages);
}
+
/**
- * Creates and registers a network group.
- *
- * @param networkGroupCfg the network group configuration
- *
- * @throws DirectoryException If a problem occurs while trying to
- * register a network group.
+ * {@inheritDoc}
*/
- private void createAndRegisterNetworkGroup(
- NetworkGroupCfg networkGroupCfg
- ) throws DirectoryException
+ public ConfigChangeResult applyConfigurationDelete(
+ NetworkGroupCfg configuration)
{
- // create the network group
- String networkGroupId = networkGroupCfg.getNetworkGroupId();
- NetworkGroup networkGroup = new NetworkGroup(networkGroupId);
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ List<Message> messages = new ArrayList<Message>();
- // register the workflows with the network group
- for (String workflowID: networkGroupCfg.getWorkflow())
+ NetworkGroup networkGroup =
+ networkGroups.remove(configuration.dn());
+ if (networkGroup != null)
{
- WorkflowImpl workflowImpl =
- (WorkflowImpl) WorkflowImpl.getWorkflow(workflowID);
- if (workflowImpl == null)
+ networkGroup.finalizeNetworkGroup();
+ }
+
+ return new ConfigChangeResult(resultCode, adminActionRequired,
+ messages);
+ }
+
+
+
+ /**
+ * Initializes all network groups currently defined in the Directory
+ * Server configuration. This should only be called at Directory
+ * Server startup.
+ *
+ * @throws ConfigException
+ * If a critical configuration problem prevents the network
+ * group initialization from succeeding.
+ * @throws InitializationException
+ * If a problem occurs while initializing the network groups
+ * that is not related to the server configuration.
+ */
+ public void initializeNetworkGroups() throws ConfigException,
+ InitializationException
+ {
+ // Get the root configuration object.
+ ServerManagementContext managementContext =
+ ServerManagementContext.getInstance();
+ RootCfg rootConfiguration =
+ managementContext.getRootConfiguration();
+
+ // Register as an add and delete listener with the root
+ // configuration so we can be notified if any network group entries
+ // are added or removed.
+ rootConfiguration.addNetworkGroupAddListener(this);
+ rootConfiguration.addNetworkGroupDeleteListener(this);
+
+ // Initialize the existing network groups.
+ for (String networkGroupName : rootConfiguration
+ .listNetworkGroups())
+ {
+ NetworkGroupCfg configuration =
+ rootConfiguration.getNetworkGroup(networkGroupName);
+ configuration.addChangeListener(this);
+
+ List<Message> unacceptableReasons = new ArrayList<Message>();
+ if (!NetworkGroup.isConfigurationAcceptable(configuration,
+ unacceptableReasons))
{
- // The workflow does not exist, log an error message
- // and skip the workflow
- Message message = INFO_ERR_WORKFLOW_DOES_NOT_EXIST.get(
- workflowID, networkGroupId);
- logError(message);
+ Message message =
+ ERR_CONFIG_NETWORK_GROUP_CONFIG_NOT_ACCEPTABLE.get(String
+ .valueOf(configuration.dn()), StaticUtils.listToString(
+ unacceptableReasons, ". "));
+ throw new InitializationException(message);
}
- else
+
+ if (configuration.isEnabled())
{
- networkGroup.registerWorkflow(workflowImpl);
+ NetworkGroup networkGroup =
+ NetworkGroup.createUserNetworkGroup(configuration);
+ networkGroups.put(configuration.dn(), networkGroup);
}
}
+ }
- // register the root DSE workflow with the network group
- WorkflowImpl rootDSEworkflow =
- (WorkflowImpl) WorkflowImpl.getWorkflow("__root.dse__#");
- networkGroup.registerWorkflow(rootDSEworkflow);
- // finally register the network group with the server
- networkGroups.put(networkGroupCfg.dn(), networkGroup);
- networkGroup.register();
- // Set the priority
- networkGroup.setNetworkGroupPriority(networkGroupCfg.getPriority());
- // Set the criteria
- NetworkGroupCriteriaCfg criteriaCfg;
- NetworkGroupCriteria criteria;
- try {
- criteriaCfg = networkGroupCfg.getNetworkGroupCriteria();
- } catch (ConfigException ce) {
- criteriaCfg = null;
- }
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationAddAcceptable(
+ NetworkGroupCfg configuration, List<Message> unacceptableReasons)
+ {
+ return NetworkGroup.isConfigurationAcceptable(configuration,
+ unacceptableReasons);
+ }
- criteria = new NetworkGroupCriteria(criteriaCfg);
- networkGroup.setCriteria(criteria);
- // Add a config listener on the criteria
- try {
- networkGroupCfg.addNetworkGroupCriteriaAddListener(criteria);
- networkGroupCfg.addNetworkGroupCriteriaDeleteListener(criteria);
- } catch (ConfigException ex) {
- throw new DirectoryException(ResultCode.UNDEFINED,
- ex.getMessageObject());
- }
- // Set the resource limits
- NetworkGroupResourceLimitsCfg limitsCfg;
- ResourceLimits limits;
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationChangeAcceptable(
+ NetworkGroupCfg configuration, List<Message> unacceptableReasons)
+ {
+ return NetworkGroup.isConfigurationAcceptable(configuration,
+ unacceptableReasons);
+ }
- try {
- limitsCfg = networkGroupCfg.getNetworkGroupResourceLimits();
- } catch (ConfigException ex) {
- limitsCfg = null;
- }
- limits = new ResourceLimits(limitsCfg);
- networkGroup.setResourceLimits(limits);
- // Add a config listener on the resource limits
- try {
- networkGroupCfg.addNetworkGroupResourceLimitsAddListener(limits);
- networkGroupCfg.addNetworkGroupResourceLimitsDeleteListener(limits);
- } catch (ConfigException ex) {
- throw new DirectoryException(ResultCode.UNDEFINED,
- ex.getMessageObject());
- }
- // Set the request filtering policy
- NetworkGroupRequestFilteringPolicyCfg policyCfg;
- RequestFilteringPolicy policy;
- try {
- policyCfg = networkGroupCfg.getNetworkGroupRequestFilteringPolicy();
- } catch (ConfigException ex) {
- policyCfg = null;
- }
- policy = new RequestFilteringPolicy(policyCfg);
- networkGroup.setRequestFilteringPolicy(policy);
-
- // Add a config listener on the request filtering policy
- try {
- networkGroupCfg.addNetworkGroupRequestFilteringPolicyAddListener
- (policy);
- networkGroupCfg.addNetworkGroupRequestFilteringPolicyDeleteListener(
- policy);
- } catch (ConfigException ex) {
- throw new DirectoryException(ResultCode.UNDEFINED,
- ex.getMessageObject());
- }
-
- // Set the client connection affinity policy.
- ClientConnectionAffinityPolicy affinityPolicy =
- ClientConnectionAffinityPolicy.toClientConnectionAffinityPolicy(
- networkGroupCfg.getAffinityPolicy());
- networkGroup.setAffinityPolicy(affinityPolicy);
-
- // Set the client connection affinity timeout
- long affinityTimeout = networkGroupCfg.getAffinityTimeout();
- networkGroup.setAffinityTimeout(affinityTimeout);
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationDeleteAcceptable(
+ NetworkGroupCfg configuration, List<Message> unacceptableReasons)
+ {
+ // Always ok.
+ return true;
}
}
-
diff --git a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupCriteria.java
deleted file mode 100644
index f8b3c7a..0000000
--- a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupCriteria.java
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * 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
- *
- *
- * Copyright 2008 Sun Microsystems, Inc.
- */
-package org.opends.server.core.networkgroups;
-
-
-import org.opends.server.core.*;
-import java.util.ArrayList;
-import java.util.List;
-import org.opends.messages.Message;
-import org.opends.server.admin.server.ConfigurationAddListener;
-import org.opends.server.admin.server.ConfigurationChangeListener;
-import org.opends.server.admin.server.ConfigurationDeleteListener;
-import
- org.opends.server.admin.std.meta.NetworkGroupCriteriaCfgDefn.AllowedAuthMethod;
-import
- org.opends.server.admin.std.meta.NetworkGroupCriteriaCfgDefn.AllowedLDAPPort;
-import org.opends.server.admin.std.server.NetworkGroupCriteriaCfg;
-import org.opends.server.api.ClientConnection;
-import org.opends.server.types.AddressMask;
-import org.opends.server.types.AuthenticationType;
-import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.DN;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.ResultCode;
-
-
-/**
- * This class defines the network group criteria. A criterion is used
- * by the network groups to determine whether a client connection belongs
- * to the network group or not.
- */
-public class NetworkGroupCriteria
- implements ConfigurationAddListener<NetworkGroupCriteriaCfg>,
- ConfigurationDeleteListener<NetworkGroupCriteriaCfg>,
- ConfigurationChangeListener<NetworkGroupCriteriaCfg>,
- NetworkGroupCriterion
-
-{
- // Indicates whether the criteria are defined through the config
- private boolean isConfigured = false;
-
- // The network group criteria.
- private AuthMethodCriteria authMethodCriteria;
- private BindDnCriteria bindDnCriteria;
- private IpFilterCriteria ipFilterCriteria;
- private PortCriteria portCriteria;
- private SecurityCriteria securityCriteria;
-
- // The current config
- private NetworkGroupCriteriaCfg config;
-
- /**
- * Constructor.
- *
- * @param criteriaCfg the configuration object used to build the Network
- * Group Criteria.
- * @throws DirectoryException If the criteria could not be created because
- * of an invalid configuration parameter
- */
- public NetworkGroupCriteria(NetworkGroupCriteriaCfg criteriaCfg)
- throws DirectoryException {
- createCriteria(criteriaCfg);
- }
-
- /**
- * Resets all the fields.
- */
- private void resetCriteria() {
- authMethodCriteria = null;
- bindDnCriteria = null;
- ipFilterCriteria = null;
- portCriteria = null;
- securityCriteria = null;
- isConfigured = false;
- if (config != null) {
- config.removeChangeListener(this);
- config = null;
- }
- }
-
- /**
- * Creates a new NetworkGroupCriteria based on the configuration object.
- *
- * @param criteriaCfg the configuration
- * @throws DirectoryException If the bind-dn-filter is not a valid DN filter
- */
- private void createCriteria(NetworkGroupCriteriaCfg criteriaCfg)
- throws DirectoryException {
- if (criteriaCfg != null) {
- if (!criteriaCfg.getAllowedAuthMethod().isEmpty()) {
- authMethodCriteria = new AuthMethodCriteria();
- for (AllowedAuthMethod method: criteriaCfg.getAllowedAuthMethod()) {
- authMethodCriteria.addAuthMethod(method);
- }
- } else {
- authMethodCriteria = null;
- }
- if (!criteriaCfg.getBindDNFilter().isEmpty()) {
- bindDnCriteria = new BindDnCriteria();
- for (String filter: criteriaCfg.getBindDNFilter()) {
- bindDnCriteria.addBindDnFilter(filter);
- }
- } else {
- bindDnCriteria = null;
- }
- if (!criteriaCfg.getIPAddressFilter().isEmpty()) {
- ipFilterCriteria = new IpFilterCriteria();
- for (AddressMask filter: criteriaCfg.getIPAddressFilter()) {
- ipFilterCriteria.addIpFilter(filter);
- }
- } else {
- ipFilterCriteria = null;
- }
- if (!criteriaCfg.getAllowedLDAPPort().isEmpty()) {
- portCriteria = new PortCriteria();
- for (AllowedLDAPPort port : criteriaCfg.getAllowedLDAPPort()) {
- portCriteria.addPort(port);
- }
- } else {
- portCriteria = null;
- }
- if (criteriaCfg.isIsSecurityMandatory()) {
- securityCriteria = new SecurityCriteria(true);
- } else {
- securityCriteria = null;
- }
- isConfigured = true;
- if (config == null) {
- criteriaCfg.addChangeListener(this);
- }
- config = criteriaCfg;
- } else {
- resetCriteria();
- }
- }
-
- /**
- * Sets the authentication method criteria.
- * @param criteria The authentication method criteria
- */
- public void setAuthMethodCriteria(AuthMethodCriteria criteria) {
- authMethodCriteria = criteria;
- isConfigured = true;
- }
-
- /**
- * Sets the bind dn criteria.
- * @param criteria The bind DN criteria
- */
- public void setBindDnCriteria(BindDnCriteria criteria) {
- bindDnCriteria = criteria;
- isConfigured = true;
- }
-
- /**
- * Sets the IP filter criteria.
- * @param criteria The IP filter criteria
- */
- public void setIpFilterCriteria(IpFilterCriteria criteria) {
- ipFilterCriteria = criteria;
- isConfigured = true;
- }
-
- /**
- * Sets the port criteria.
- * @param criteria The IP filter criteria
- */
- public void setPortCriteria(PortCriteria criteria) {
- portCriteria = criteria;
- isConfigured = true;
- }
-
- /**
- * Sets the IP filter criteria.
- * @param criteria The IP filter criteria
- */
- public void setSecurityCriteria(SecurityCriteria criteria) {
- securityCriteria = criteria;
- isConfigured = true;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean match(ClientConnection connection) {
- if ((authMethodCriteria != null)
- && (!authMethodCriteria.match(connection))) {
- return (false);
- }
- if ((bindDnCriteria != null) && (!bindDnCriteria.match(connection))) {
- return (false);
- }
- if ((ipFilterCriteria != null) && (!ipFilterCriteria.match(connection))) {
- return (false);
- }
- if ((portCriteria != null) && (!portCriteria.match(connection))) {
- return (false);
- }
- if ((securityCriteria != null) && (!securityCriteria.match(connection))) {
- return (false);
- }
- return (true);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean matchAfterBind(ClientConnection connection,
- DN bindDN,
- AuthenticationType authType,
- boolean isSecure) {
- if ((authMethodCriteria != null) && (!authMethodCriteria.matchAfterBind(
- connection, bindDN, authType, isSecure))) {
- return (false);
- }
- if ((bindDnCriteria != null) && (!bindDnCriteria.matchAfterBind(
- connection, bindDN, authType, isSecure))) {
- return (false);
- }
- if ((ipFilterCriteria != null) && (!ipFilterCriteria.matchAfterBind(
- connection, bindDN, authType, isSecure))) {
- return (false);
- }
- if ((portCriteria != null) && (!portCriteria.matchAfterBind(
- connection, bindDN, authType, isSecure))) {
- return (false);
- }
- if ((securityCriteria != null) && (!securityCriteria.matchAfterBind(
- connection, bindDN, authType, isSecure))) {
- return (false);
- }
- return (true);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationAddAcceptable(
- NetworkGroupCriteriaCfg configuration,
- List<Message> unacceptableReasons) {
- return (!isConfigured);
- }
-
- /**
- * {@inheritDoc}
- */
- public ConfigChangeResult applyConfigurationAdd(
- NetworkGroupCriteriaCfg cfg) {
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
-
- ConfigChangeResult configChangeResult =
- new ConfigChangeResult(resultCode, adminActionRequired, messages);
- try {
- createCriteria(cfg);
- } catch (DirectoryException de) {
- if (resultCode == ResultCode.SUCCESS) {
- resultCode = DirectoryServer.getServerErrorResultCode();
- }
- messages.add(de.getMessageObject());
- }
- return configChangeResult;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationDeleteAcceptable(
- NetworkGroupCriteriaCfg configuration,
- List<Message> unacceptableReasons) {
- return (isConfigured);
- }
-
- /**
- * {@inheritDoc}
- */
- public ConfigChangeResult applyConfigurationDelete(
- NetworkGroupCriteriaCfg configuration) {
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
-
- ConfigChangeResult configChangeResult =
- new ConfigChangeResult(resultCode, adminActionRequired, messages);
-
- resetCriteria();
-
- return configChangeResult;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationChangeAcceptable(
- NetworkGroupCriteriaCfg configuration,
- List<Message> unacceptableReasons) {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public ConfigChangeResult applyConfigurationChange(
- NetworkGroupCriteriaCfg cfg) {
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
-
- ConfigChangeResult configChangeResult =
- new ConfigChangeResult(resultCode, adminActionRequired, messages);
- try {
- createCriteria(cfg);
- } catch (DirectoryException de) {
- if (resultCode == ResultCode.SUCCESS) {
- resultCode = DirectoryServer.getServerErrorResultCode();
- }
- messages.add(de.getMessageObject());
- }
- return configChangeResult;
- }
-}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupCriterion.java b/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupCriterion.java
deleted file mode 100644
index ad39a13..0000000
--- a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupCriterion.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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
- *
- *
- * Copyright 2008 Sun Microsystems, Inc.
- */
-package org.opends.server.core.networkgroups;
-
-import org.opends.server.api.ClientConnection;
-import org.opends.server.types.AuthenticationType;
-import org.opends.server.types.DN;
-
-/**
- * This class defines the network group criteria. A criterion is used
- * by the network groups to determine whether a client connection belongs
- * to the network group or not.
- */
-public interface NetworkGroupCriterion
-{
-
- /**
- * Checks whether the client connection matches the criteria.
- *
- * @param connection the ClientConnection
- * @return a boolean indicating whether the connection matches the criteria
- */
- public boolean match(ClientConnection connection);
-
- /**
- * Checks whether the client connection matches the criteria after bind.
- *
- * @param connection the ClientConnection
- * @param bindDN the DN used to bind
- * @param authType the authentication type
- * @param isSecure a boolean indicating whether the connection is secure
- * @return a boolean indicating whether the connection matches the criteria
- */
- public boolean matchAfterBind(ClientConnection connection,
- DN bindDN,
- AuthenticationType authType,
- boolean isSecure);
-
-}
diff --git a/opends/src/server/org/opends/server/plugins/NetworkGroupPlugin.java b/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupPlugin.java
similarity index 97%
rename from opends/src/server/org/opends/server/plugins/NetworkGroupPlugin.java
rename to opends/src/server/org/opends/server/core/networkgroups/NetworkGroupPlugin.java
index b643a5f..468f69f 100644
--- a/opends/src/server/org/opends/server/plugins/NetworkGroupPlugin.java
+++ b/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupPlugin.java
@@ -22,9 +22,9 @@
* CDDL HEADER END
*
*
- * Copyright 2006-2008 Sun Microsystems, Inc.
+ * Copyright 2006-2009 Sun Microsystems, Inc.
*/
-package org.opends.server.plugins;
+package org.opends.server.core.networkgroups;
@@ -40,7 +40,6 @@
import org.opends.server.api.ClientConnection;
import org.opends.server.api.plugin.*;
import org.opends.server.config.ConfigException;
-import org.opends.server.core.networkgroups.NetworkGroup;
import org.opends.server.types.AuthenticationType;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DirectoryException;
@@ -73,10 +72,6 @@
extends DirectoryServerPlugin<NetworkGroupPluginCfg>
implements ConfigurationChangeListener<NetworkGroupPluginCfg>
{
- // The current configuration for this plugin.
- private NetworkGroupPluginCfg currentConfig;
-
-
/**
* Creates a new instance of this Directory Server plugin. Every plugin must
@@ -87,8 +82,6 @@
public NetworkGroupPlugin()
{
super();
-
-
}
/**
@@ -99,8 +92,6 @@
NetworkGroupPluginCfg configuration)
throws ConfigException
{
- currentConfig = configuration;
-
// Make sure that the plugin has been enabled for the appropriate types.
for (PluginType t : pluginTypes)
{
@@ -151,7 +142,7 @@
boolean fullCheck,
ArrayList<Message> messages)
{
- if (!connection.getNetworkGroup().checkResourceLimits(
+ if (!connection.getNetworkGroup().checkResourceLimitsPolicy(
connection, operation, fullCheck, messages)) {
return false;
}
@@ -449,7 +440,6 @@
public ConfigChangeResult applyConfigurationChange(
NetworkGroupPluginCfg configuration)
{
- currentConfig = configuration;
return new ConfigChangeResult(ResultCode.SUCCESS, false);
}
}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupStatistics.java b/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupStatistics.java
index c323e1d..b3041f8 100644
--- a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupStatistics.java
+++ b/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupStatistics.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2009 Sun Microsystems, Inc.
*/
package org.opends.server.core.networkgroups;
@@ -40,8 +40,8 @@
import org.opends.server.types.InitializationException;
import org.opends.server.types.SearchScope;
-import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.protocols.ldap.LDAPConstants.*;
+import static org.opends.messages.ProtocolMessages.*;
/**
* This class implements the statistics associated to a network group.
@@ -50,10 +50,10 @@
extends MonitorProvider<MonitorProviderCfg> {
// The instance name for this monitor provider instance.
- private String instanceName;
- private NetworkGroup networkGroup;
+ private final String instanceName;
+ private final NetworkGroup networkGroup;
- private Object lock = new Object();
+ private final Object lock = new Object();
private long abandonRequests = 0;
private long addRequests = 0;
private long bindRequests = 0;
@@ -131,6 +131,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public void initializeMonitorProvider(MonitorProviderCfg configuration)
throws ConfigException, InitializationException {
// Throw an exception, because this monitor is not intended to be
@@ -145,6 +146,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public String getMonitorInstanceName() {
return this.instanceName+",cn=Network Groups";
}
@@ -152,6 +154,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public long getUpdateInterval() {
// This monitor should not run periodically.
return -1;
@@ -160,6 +163,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public void updateMonitorData() {
// No implementation is required since this does not do periodic updates.
}
@@ -167,30 +171,39 @@
/**
* {@inheritDoc}
*/
+ @Override
public List<Attribute> getMonitorData() {
ArrayList<Attribute> attrs = new ArrayList<Attribute>();
- RequestFilteringPolicyStat requestFilteringPolicyStat =
- networkGroup.getRequestFilteringPolicyStat();
- if (requestFilteringPolicyStat != null) {
- attrs.add(Attributes.create("ds-mon-rejected-attributes-total-count",
- String.valueOf(requestFilteringPolicyStat.getRejectedAttributes())));
- attrs.add(Attributes.create("ds-mon-rejected-operations-total-count",
- String.valueOf(requestFilteringPolicyStat.getRejectedOperations())));
- attrs.add(Attributes.create("ds-mon-rejected-search-scopes-total-count",
- String.valueOf(requestFilteringPolicyStat.getRejectedScopes())));
- attrs.add(Attributes.create("ds-mon-rejected-subtrees-total-count",
- String.valueOf(requestFilteringPolicyStat.getRejectedSubtrees())));
+ RequestFilteringPolicyStatistics rfpStatistics =
+ networkGroup.getRequestFilteringPolicyStatistics();
+ if (rfpStatistics != null)
+ {
+ attrs.add(Attributes.create(
+ "ds-mon-rejected-attributes-total-count", String
+ .valueOf(rfpStatistics.getRejectedAttributes())));
+ attrs.add(Attributes.create(
+ "ds-mon-rejected-operations-total-count", String
+ .valueOf(rfpStatistics.getRejectedOperations())));
+ attrs.add(Attributes.create(
+ "ds-mon-rejected-search-scopes-total-count", String
+ .valueOf(rfpStatistics.getRejectedScopes())));
+ attrs.add(Attributes.create(
+ "ds-mon-rejected-subtrees-total-count", String
+ .valueOf(rfpStatistics.getRejectedSubtrees())));
}
- ResourceLimitsStat resLimitStat = networkGroup.getResourceLimitStat();
- if (resLimitStat != null) {
+ ResourceLimitsPolicyStatistics rlpStatistics =
+ networkGroup.getResourceLimitsPolicyStatistics();
+ if (rlpStatistics != null)
+ {
attrs.add(Attributes.create("ds-mon-client-connection-count",
- String.valueOf(resLimitStat.getClientConnections())));
+ String.valueOf(rlpStatistics.getClientConnections())));
attrs.add(Attributes.create("ds-mon-client-connection-max-count",
- String.valueOf(resLimitStat.getMaxClientConnections())));
- attrs.add(Attributes.create("ds-mon-client-connection-total-count",
- String.valueOf(resLimitStat.getTotalClientConnections())));
+ String.valueOf(rlpStatistics.getMaxClientConnections())));
+ attrs.add(Attributes.create(
+ "ds-mon-client-connection-total-count", String
+ .valueOf(rlpStatistics.getTotalClientConnections())));
}
synchronized(lock) {
@@ -218,6 +231,7 @@
attrs.add(Attributes.create("ds-mon-unbind-operations-total-count",
String.valueOf(unbindRequests)));
}
+
attrs.add(Attributes.create("ds-mon-discarded-referrals-total-count",
"Not implemented"));
attrs.add(Attributes.create("ds-mon-forwarded-referrals-total-count",
diff --git a/opends/src/server/org/opends/server/core/networkgroups/PortCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/PortCriteria.java
deleted file mode 100644
index cba4fd0..0000000
--- a/opends/src/server/org/opends/server/core/networkgroups/PortCriteria.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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
- *
- *
- * Copyright 2008 Sun Microsystems, Inc.
- */
-package org.opends.server.core.networkgroups;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import
- org.opends.server.admin.std.meta.NetworkGroupCriteriaCfgDefn.AllowedLDAPPort;
-import org.opends.server.api.ClientConnection;
-import org.opends.server.types.AuthenticationType;
-import org.opends.server.types.DN;
-
-/**
- * This class defines the port criteria.
- * A client connection matches the criteria when it is received in
- * a port matching at least one of the specified ports.
- * The port can be "ldap" or "ldaps".
- */
-public class PortCriteria implements NetworkGroupCriterion {
- private Collection<String> allowedPorts;
-
- /**
- * Constructor.
- */
- public PortCriteria() {
- allowedPorts = new ArrayList<String>();
- }
-
- /**
- * Adds a new allowed LDAP port to the list of allowed LDAP ports.
- * @param port The new LDAP port
- */
- public void addPort(AllowedLDAPPort port) {
- if (port.toString().equals("ldap")) {
- allowedPorts.add("LDAP");
- } else if (port.toString().equals("ldaps")) {
- allowedPorts.add("LDAP+SSL");
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean match(ClientConnection connection) {
- String connectionPort = connection.getConnectionHandler().getProtocol();
- for (String port:allowedPorts) {
- if (connectionPort.equalsIgnoreCase(port)) {
- return true;
- }
- }
- return (false);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean matchAfterBind(ClientConnection connection, DN bindDN,
- AuthenticationType authType, boolean isSecure) {
- return (match(connection));
- }
-}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/ProtocolConnectionCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/ProtocolConnectionCriteria.java
new file mode 100644
index 0000000..eab4a65
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/networkgroups/ProtocolConnectionCriteria.java
@@ -0,0 +1,109 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.opends.server.admin.std.meta.NetworkGroupCfgDefn.AllowedProtocol;
+import org.opends.server.api.ClientConnection;
+import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.DN;
+
+
+
+/**
+ * A connection criteria which matches connections which use a permitted
+ * protocol.
+ */
+final class ProtocolConnectionCriteria implements ConnectionCriteria
+{
+
+ // The set of allowed protocols.
+ private final Set<AllowedProtocol> protocols;
+
+
+
+ /**
+ * Creates a new protocol connection criteria using the provided
+ * allowed protocols.
+ *
+ * @param protocols
+ * The allowed protocols.
+ */
+ public ProtocolConnectionCriteria(
+ Collection<AllowedProtocol> protocols)
+ {
+ this.protocols = EnumSet.copyOf(protocols);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean matches(ClientConnection connection)
+ {
+ String protocolName =
+ connection.getConnectionHandler().getProtocol();
+
+ for (AllowedProtocol protocol : protocols)
+ {
+ switch (protocol)
+ {
+ case LDAP:
+ if (protocolName.equals("LDAP"))
+ {
+ return true;
+ }
+ break;
+ case LDAPS:
+ if (protocolName.equals("LDAP+SSL"))
+ {
+ return true;
+ }
+ break;
+ }
+ }
+
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean willMatchAfterBind(ClientConnection connection,
+ DN bindDN, AuthenticationType authType, boolean isSecure)
+ {
+ return matches(connection);
+ }
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicy.java b/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicy.java
index 8d1f938..1fab56d 100644
--- a/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicy.java
+++ b/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicy.java
@@ -22,637 +22,59 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2009 Sun Microsystems, Inc.
*/
package org.opends.server.core.networkgroups;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.opends.messages.Message;
-import org.opends.server.admin.server.ConfigurationAddListener;
-import org.opends.server.admin.server.ConfigurationChangeListener;
-import org.opends.server.admin.server.ConfigurationDeleteListener;
-import org.opends.server.admin.std.server.
- NetworkGroupRequestFilteringPolicyCfg;
-import org.opends.server.admin.std.meta.
- NetworkGroupRequestFilteringPolicyCfgDefn.AllowedOperations;
-import org.opends.server.admin.std.meta.
- NetworkGroupRequestFilteringPolicyCfgDefn.AllowedSearchScopes;
-import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.DN;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.RawFilter;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.operation.PreParseAddOperation;
-import org.opends.server.types.operation.PreParseCompareOperation;
-import org.opends.server.types.operation.PreParseDeleteOperation;
-import org.opends.server.types.operation.PreParseModifyDNOperation;
-import org.opends.server.types.operation.PreParseModifyOperation;
+
+import java.util.List;
+
+import org.opends.messages.Message;
+import org.opends.server.api.QOSPolicy;
import org.opends.server.types.operation.PreParseOperation;
-import org.opends.server.types.operation.PreParseSearchOperation;
-import static org.opends.messages.CoreMessages.*;
-import static org.opends.messages.ConfigMessages.*;
+
/**
* This class defines the request filtering policy applicable to all
* connections inside the same network group.
*/
-public class RequestFilteringPolicy
-implements ConfigurationAddListener<NetworkGroupRequestFilteringPolicyCfg>,
- ConfigurationDeleteListener<NetworkGroupRequestFilteringPolicyCfg>,
- ConfigurationChangeListener<NetworkGroupRequestFilteringPolicyCfg>
+abstract class RequestFilteringPolicy extends QOSPolicy
{
- // The request filtering policy is defined through the config
- private boolean isConfigured = false;
-
- // The list of allowed operations
- Set<AllowedOperations> allowedOperations = null;
-
- // The list of allowed attributes
- Set<String> allowedAttributes = null;
-
- // The list of prohibited attributes
- Set<String> prohibitedAttributes = null;
-
- // The list of allowed search scopes
- Set<AllowedSearchScopes> allowedSearchScopes = null;
-
- // The list of allowed subtrees
- Set<DN> allowedSubtrees = null;
-
- // The list of prohibited subtrees
- Set<DN> prohibitedSubtrees = null;
-
- // The stats for the request filtering policy
- private RequestFilteringPolicyStat stat = new RequestFilteringPolicyStat();
-
- // The current configuration
- NetworkGroupRequestFilteringPolicyCfg config = null;
-
/**
- * Constructor.
- *
- * @param policyCfg configuration
+ * Creates a new request filtering policy.
*/
- public RequestFilteringPolicy(
- NetworkGroupRequestFilteringPolicyCfg policyCfg)
+ protected RequestFilteringPolicy()
{
- createPolicy(policyCfg);
+ // No implementation required.
}
- /**
- * Resets all the fields.
- */
- private void resetPolicy() {
- allowedOperations = Collections.emptySet();
- allowedAttributes = Collections.emptySet();
- prohibitedAttributes = Collections.emptySet();
- allowedSearchScopes = Collections.emptySet();
- allowedSubtrees = Collections.emptySet();
- prohibitedSubtrees = Collections.emptySet();
- isConfigured = false;
- if (config != null) {
- config.removeChangeListener(this);
- }
- config = null;
- }
/**
- * Creates a RequestFilteringPolicy from a configuration object.
+ * Returns the statistics associated with this request filtering
+ * policy.
*
- * @param policyCfg the configuration
+ * @return The statistics associated with this request filtering
+ * policy.
*/
- private void createPolicy(
- NetworkGroupRequestFilteringPolicyCfg policyCfg)
- {
- if (policyCfg != null) {
- allowedOperations = policyCfg.getAllowedOperations();
- allowedAttributes = policyCfg.getAllowedAttributes();
- prohibitedAttributes = policyCfg.getProhibitedAttributes();
- allowedSearchScopes = policyCfg.getAllowedSearchScopes();
- allowedSubtrees = policyCfg.getAllowedSubtrees();
- prohibitedSubtrees = policyCfg.getProhibitedSubtrees();
+ abstract RequestFilteringPolicyStatistics getStatistics();
- if (config == null) {
- policyCfg.addChangeListener(this);
- }
- config = policyCfg;
- isConfigured = true;
- } else {
- resetPolicy();
- }
- }
-
- /**
- * Returns the statistics associated to this policy.
- * @return The statistics associated to this policy
- */
- public RequestFilteringPolicyStat getStat() {
- return stat;
- }
-
- /**
- * Configures the set of allowed operations.
- * @param allowedOps The set of allowed operations
- */
- public void setAllowedOperations(Set<AllowedOperations> allowedOps) {
- if (allowedOps == null) {
- allowedOperations = Collections.emptySet();
- } else {
- allowedOperations = allowedOps;
- }
- }
-
- /**
- * Configures the set of allowed attributes in search and compare operations.
- * @param allowedAttrs The set of allowed attributes
- */
- public void setAllowedAttributes(Set<String> allowedAttrs) {
- if (allowedAttrs == null) {
- allowedAttributes = Collections.emptySet();
- } else {
- allowedAttributes = allowedAttrs;
- }
- }
-
- /**
- * Configures the set of prohibited attributes in search and compare
- * operations.
- * @param prohibitedAttrs The set of prohibited attributes
- */
- public void setProhibitedAttributes(Set<String> prohibitedAttrs) {
- if (prohibitedAttrs == null) {
- prohibitedAttributes = Collections.emptySet();
- } else {
- prohibitedAttributes = prohibitedAttrs;
- }
- }
-
- /**
- * Configures the set of allowed search scopes.
- * @param allowedScopes The set of scopes
- */
- public void setAllowedSearchScopes(Set<AllowedSearchScopes> allowedScopes) {
- if (allowedScopes == null) {
- allowedSearchScopes = Collections.emptySet();
- } else {
- allowedSearchScopes = allowedScopes;
- }
- }
-
- /**
- * Configures the set of subtrees allowed in search operations.
- * @param allowedSubt The set of allowed subtrees
- */
- public void setAllowedSubtrees(Set<DN> allowedSubt) {
- if (allowedSubt == null) {
- allowedSubtrees = Collections.emptySet();
- } else {
- allowedSubtrees = allowedSubt;
- }
- }
-
- /**
- * Configures the set of subtrees prohibited in search operations.
- * @param prohibitedSubt The set of prohibited subtrees
- */
- public void setProhibitedSubtrees(Set<DN> prohibitedSubt) {
- if (prohibitedSubt == null) {
- prohibitedSubtrees = Collections.emptySet();
- } else {
- prohibitedSubtrees = prohibitedSubt;
- }
- }
/**
- * Checks the request filtering policy.
+ * Determines if the provided operation is allowed according to this
+ * request filtering policy.
*
- * @param operation the ongoing operation
- * @param messages the messages to include in the disconnect notification
- * response. It may be <CODE>null</CODE> if no message
- * is to be sent.
- * @return a boolean indicating whether the operation is allowed
+ * @param operation
+ * The operation
+ * @param messages
+ * The messages to include in the disconnect notification
+ * response. It may be <CODE>null</CODE> if no message is to
+ * be sent.
+ * @return {@code true} if the operation is allowed.
*/
- public boolean checkPolicy(
- PreParseOperation operation,
- List<Message> messages)
- {
- boolean result = true;
-
- // Check the allowed operations
- if (!allowedOperations.isEmpty()) {
- switch (operation.getOperationType()) {
- case ABANDON:
- result= true;
- break;
- case ADD:
- result = allowedOperations.contains(AllowedOperations.ADD);
- break;
- case BIND:
- result = allowedOperations.contains(AllowedOperations.BIND);
- break;
- case COMPARE:
- result = allowedOperations.contains(AllowedOperations.COMPARE);
- break;
- case DELETE:
- result = allowedOperations.contains(AllowedOperations.DELETE);
- break;
- case EXTENDED:
- result = allowedOperations.contains(AllowedOperations.EXTENDED);
- break;
- case MODIFY:
- result = allowedOperations.contains(AllowedOperations.MODIFY);
- break;
- case MODIFY_DN:
- result = allowedOperations.contains(AllowedOperations.RENAME);
- break;
- case SEARCH:
- result = allowedOperations.contains(AllowedOperations.SEARCH);
-
- // If inequality search are prohibited, need to check
- if (result && !allowedOperations.contains(
- AllowedOperations.INEQUALITY_SEARCH)) {
- RawFilter flt =
- ((PreParseSearchOperation) operation).getRawFilter();
- result = (!containsInequalitySearch(flt));
- }
- break;
- case UNBIND:
- result = true;
- break;
- }
-
- if (!result) {
- stat.updateRejectedOperations();
- messages.add(INFO_ERROR_OPERATION_NOT_ALLOWED.get());
- return result;
- }
- }
-
- // For search operations:
- if (operation.getOperationType().equals(OperationType.SEARCH)) {
- PreParseSearchOperation searchOp = (PreParseSearchOperation) operation;
-
- // Check the allowed/prohibited attributes in search filter
- if (!prohibitedAttributes.isEmpty()) {
- // The attributes specified in prohibitedAttributes are not OK
- result = (!containsProhibitedAttribute(searchOp.getRawFilter()));
- }
- if (!result) {
- stat.updateRejectedAttributes();
- messages.add(INFO_ERROR_ATTRIBUTE_NOT_ALLOWED.get());
- return result;
- }
-
- if (!allowedAttributes.isEmpty()) {
- // Only the attributes specified in allowedAttributes are OK
- result = (containsOnlyAllowedAttributes(searchOp.getRawFilter()));
- }
- if (!result) {
- stat.updateRejectedAttributes();
- messages.add(INFO_ERROR_ATTRIBUTE_NOT_ALLOWED.get());
- return result;
- }
-
- // Check the search scope
- if (!allowedSearchScopes.isEmpty()) {
- switch (searchOp.getScope()) {
- case BASE_OBJECT:
- result = allowedSearchScopes.contains(AllowedSearchScopes.BASE);
- break;
- case SINGLE_LEVEL:
- result = allowedSearchScopes.contains(AllowedSearchScopes.ONE);
- break;
- case WHOLE_SUBTREE:
- result = allowedSearchScopes.contains(AllowedSearchScopes.SUB);
- break;
- case SUBORDINATE_SUBTREE:
- result = allowedSearchScopes.contains(AllowedSearchScopes.CHILDREN);
- break;
- }
-
- if (!result) {
- stat.updateRejectedScopes();
- messages.add(INFO_ERROR_SEARCH_SCOPE_NOT_ALLOWED.get());
- return result;
- }
- }
- }
-
- // For compare operation
- if (operation.getOperationType().equals(OperationType.COMPARE)) {
- PreParseCompareOperation compareOp = (PreParseCompareOperation) operation;
-
- // Check the allowed/prohibited attributes
- if (!prohibitedAttributes.isEmpty()) {
- result = (!prohibitedAttributes.contains(
- compareOp.getRawAttributeType()));
- }
- if (!result) {
- stat.updateRejectedAttributes();
- messages.add(INFO_ERROR_ATTRIBUTE_NOT_ALLOWED.get());
- return result;
- }
- if (!allowedAttributes.isEmpty()) {
- result = (allowedAttributes.contains(compareOp.getRawAttributeType()));
- }
- if (!result) {
- stat.updateRejectedAttributes();
- messages.add(INFO_ERROR_ATTRIBUTE_NOT_ALLOWED.get());
- return result;
- }
- }
-
- DN entryDN = null;
- DN newEntryDN = null;
- try {
- switch (operation.getOperationType()) {
- case ADD:
- entryDN = DN.decode(
- ((PreParseAddOperation) operation).getRawEntryDN());
- break;
- case COMPARE:
- entryDN = DN.decode(
- ((PreParseCompareOperation) operation).getRawEntryDN());
- break;
- case DELETE:
- entryDN = DN.decode(
- ((PreParseDeleteOperation) operation).getRawEntryDN());
- break;
- case EXTENDED:
- break;
- case MODIFY:
- entryDN = DN.decode(
- ((PreParseModifyOperation) operation).getRawEntryDN());
- break;
- case MODIFY_DN:
- entryDN = DN.decode(
- ((PreParseModifyDNOperation) operation).getRawEntryDN());
- newEntryDN = DN.decode(
- ((PreParseModifyDNOperation) operation).getRawNewRDN());
- break;
- case SEARCH:
- entryDN = DN.decode(
- ((PreParseSearchOperation) operation).getRawBaseDN());
- break;
- default:
- break;
- }
- if (entryDN != null) {
- result = ((isInAllowedSubtrees(entryDN))
- && !(isInProhibitedSubtrees(entryDN)));
- }
- if (newEntryDN != null) {
- result = ((isInAllowedSubtrees(newEntryDN))
- && !(isInProhibitedSubtrees(newEntryDN)));
- }
-
- } catch (DirectoryException ex) {
- Logger.getLogger(RequestFilteringPolicy.class.getName())
- .log(Level.SEVERE, null, ex);
- }
- if (!result) {
- stat.updateRejectedSubtrees();
- messages.add(INFO_ERROR_SUBTREE_NOT_ALLOWED.get());
- return result;
- }
-
- return (true);
- }
-
-
- /**
- * Checks whether a filter contains an inequality search filter
- * (i.e. either a greater_or_equal or a less_or_equal filter).
- * @param filter The filter to be tested
- * @return boolean indicating whether the filter contains an inequality
- * search filter
- */
- private boolean containsInequalitySearch(RawFilter filter) {
- boolean result = false;
- switch (filter.getFilterType()) {
- case AND:
- case OR:
- ArrayList<RawFilter> filterComponents = filter.getFilterComponents();
- if (filterComponents != null) {
- for (RawFilter element : filterComponents) {
- if (containsInequalitySearch(element)) {
- return true;
- }
- }
- }
- return false;
- case NOT:
- return containsInequalitySearch(filter.getNOTComponent());
- case GREATER_OR_EQUAL:
- case LESS_OR_EQUAL:
- return true;
- default:
- return false;
- }
-
- }
-
- /**
- * Checks whether a filter contains one of the prohibited attributes.
- * @param filter The filter to be tested
- * @return boolean indicating whether the filter contains at least one of
- * the prohibited attributes
- */
- private boolean containsProhibitedAttribute(
- RawFilter filter) {
- boolean result = false;
- switch (filter.getFilterType()) {
- case AND:
- case OR:
- ArrayList<RawFilter> filterComponents = filter.getFilterComponents();
- if (filterComponents != null) {
- for (RawFilter element : filterComponents) {
- if (containsProhibitedAttribute(element)) {
- return true;
- }
- }
- }
- return false;
- case NOT:
- return (containsProhibitedAttribute(filter.getNOTComponent()));
- default:
- return (prohibitedAttributes.contains(filter.getAttributeType()));
- }
- }
-
- /**
- * Checks whether a filter contains unallowed attributes.
- * @param filter The filter to be tested
- * @return boolean indicating whether the filter contains at least one
- * attribute which is not in the allowed list
- */
- private boolean containsOnlyAllowedAttributes(
- RawFilter filter) {
- switch (filter.getFilterType()) {
- case AND:
- case OR:
- ArrayList<RawFilter> filterComponents = filter.getFilterComponents();
- if (filterComponents != null) {
- for (RawFilter element : filterComponents) {
- if (!containsOnlyAllowedAttributes(element)) {
- return false;
- }
- }
- }
- return true;
- case NOT:
- return (containsOnlyAllowedAttributes(filter.getNOTComponent()));
- default:
- return (allowedAttributes.contains(filter.getAttributeType()));
- }
- }
-
- /**
- * Checks whether a DN is in a branch of the allowed subtrees.
- * @param dn The DN to be tested
- * @return boolean indicating whether the dn is in a branch of the allowed
- * subtrees
- */
- private boolean isInAllowedSubtrees(DN dn) {
- boolean result = false;
- // If the variable is not set, consider allowedSubtrees = rootDSE
- if (allowedSubtrees.isEmpty()) {
- return true;
- }
- for (DN branch:allowedSubtrees) {
- if (dn.isDescendantOf(branch)) {
- result = true;
- break;
- }
- }
- return result;
- }
-
- /**
- * Checks whether a DN is in a branch of the prohibited subtrees.
- * @param dn The Dn to be tested
- * @return boolean indicating whether the dn is in a branch of the prohibited
- * subtrees
- */
- private boolean isInProhibitedSubtrees(DN dn) {
- boolean result = false;
- for (DN branch:prohibitedSubtrees) {
- if (dn.isDescendantOf(branch)) {
- result = true;
- break;
- }
- }
- return result;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationAddAcceptable(
- NetworkGroupRequestFilteringPolicyCfg configuration,
- List<Message> unacceptableReasons) {
- if (isConfigured) {
- return false;
- }
- return (isConfigurationChangeAcceptable(configuration,
- unacceptableReasons));
- }
-
- /**
- * {@inheritDoc}
- */
- public ConfigChangeResult applyConfigurationAdd(
- NetworkGroupRequestFilteringPolicyCfg configuration) {
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
-
- ConfigChangeResult configChangeResult =
- new ConfigChangeResult(resultCode, adminActionRequired, messages);
- createPolicy(configuration);
- return configChangeResult;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationDeleteAcceptable(
- NetworkGroupRequestFilteringPolicyCfg configuration,
- List<Message> unacceptableReasons) {
- return isConfigured;
- }
-
- /**
- * {@inheritDoc}
- */
- public ConfigChangeResult applyConfigurationDelete(
- NetworkGroupRequestFilteringPolicyCfg configuration) {
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
-
- ConfigChangeResult configChangeResult =
- new ConfigChangeResult(resultCode, adminActionRequired, messages);
-
- resetPolicy();
-
- return configChangeResult;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationChangeAcceptable(
- NetworkGroupRequestFilteringPolicyCfg configuration,
- List<Message> unacceptableReasons) {
- if (configuration != null) {
- // Check that allowed-attributes does not contain any attribute
- // also configured in prohibited-attributes
- for (String allowedAttr: configuration.getAllowedAttributes()) {
- if (configuration.getProhibitedAttributes().contains(allowedAttr)) {
- unacceptableReasons.add(
- ERR_CONFIG_NETWORKGROUPREQUESTFILTERINGPOLICY_INVALID_ATTRIBUTE
- .get(allowedAttr, configuration.dn().toString()));
- return false;
- }
- }
-
- // Check that allowed-subtrees does not contain any subtree also
- // configured in prohibited-subtrees
- for (DN allowedSubtree: configuration.getAllowedSubtrees()) {
- if (configuration.getProhibitedSubtrees().contains(allowedSubtree)) {
- unacceptableReasons.add(
- ERR_CONFIG_NETWORKGROUPREQUESTFILTERINGPOLICY_INVALID_SUBTREE.get(
- allowedSubtree.toString(), configuration.dn().toString()));
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public ConfigChangeResult applyConfigurationChange(
- NetworkGroupRequestFilteringPolicyCfg configuration) {
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
-
- ConfigChangeResult configChangeResult =
- new ConfigChangeResult(resultCode, adminActionRequired, messages);
- createPolicy(configuration);
- return configChangeResult;
- }
+ abstract boolean isAllowed(PreParseOperation operation,
+ List<Message> messages);
}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyFactory.java b/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyFactory.java
new file mode 100644
index 0000000..945f25f
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyFactory.java
@@ -0,0 +1,672 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import static org.opends.messages.ConfigMessages.*;
+import static org.opends.messages.CoreMessages.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.opends.messages.Message;
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.std.meta.
+ RequestFilteringQOSPolicyCfgDefn.AllowedOperations;
+import org.opends.server.admin.std.meta.
+ RequestFilteringQOSPolicyCfgDefn.AllowedSearchScopes;
+import org.opends.server.admin.std.server.RequestFilteringQOSPolicyCfg;
+import org.opends.server.api.QOSPolicyFactory;
+import org.opends.server.config.ConfigException;
+import org.opends.server.types.ConfigChangeResult;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.InitializationException;
+import org.opends.server.types.OperationType;
+import org.opends.server.types.RawFilter;
+import org.opends.server.types.ResultCode;
+import org.opends.server.types.operation.PreParseAddOperation;
+import org.opends.server.types.operation.PreParseCompareOperation;
+import org.opends.server.types.operation.PreParseDeleteOperation;
+import org.opends.server.types.operation.PreParseModifyDNOperation;
+import org.opends.server.types.operation.PreParseModifyOperation;
+import org.opends.server.types.operation.PreParseOperation;
+import org.opends.server.types.operation.PreParseSearchOperation;
+
+
+
+/**
+ * This class defines a factory for creating user configurable request
+ * filtering policies.
+ */
+public final class RequestFilteringPolicyFactory implements
+ QOSPolicyFactory<RequestFilteringQOSPolicyCfg>
+{
+
+ /**
+ * Policy implementation.
+ */
+ private static final class Policy extends RequestFilteringPolicy
+ implements
+ ConfigurationChangeListener<RequestFilteringQOSPolicyCfg>
+ {
+
+ // The list of allowed attributes
+ private Set<String> allowedAttributes = null;
+
+ // The list of allowed operations
+ private Set<AllowedOperations> allowedOperations = null;
+
+ // The list of allowed search scopes
+ private Set<AllowedSearchScopes> allowedSearchScopes = null;
+
+ // The list of allowed subtrees
+ private Set<DN> allowedSubtrees = null;
+
+ // The list of prohibited attributes
+ private Set<String> prohibitedAttributes = null;
+
+ // The list of prohibited subtrees
+ private Set<DN> prohibitedSubtrees = null;
+
+ // The statistics for the request filtering policy
+ private final RequestFilteringPolicyStatistics statistics =
+ new RequestFilteringPolicyStatistics();
+
+
+
+ /**
+ * Creates a new request filtering policy.
+ */
+ private Policy()
+ {
+ // Nothing to do.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationChange(
+ RequestFilteringQOSPolicyCfg configuration)
+ {
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ ArrayList<Message> messages = new ArrayList<Message>();
+
+ // Save the configuration.
+ updateConfiguration(configuration);
+
+ return new ConfigChangeResult(resultCode, adminActionRequired,
+ messages);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationChangeAcceptable(
+ RequestFilteringQOSPolicyCfg configuration,
+ List<Message> unacceptableReasons)
+ {
+ return RequestFilteringPolicyFactory.validateConfiguration(
+ configuration, unacceptableReasons);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ RequestFilteringPolicyStatistics getStatistics()
+ {
+ return statistics;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ boolean isAllowed(PreParseOperation operation,
+ List<Message> messages)
+ {
+ boolean allowRequest = true;
+
+ // Check the allowed operations
+ if (!allowedOperations.isEmpty())
+ {
+ switch (operation.getOperationType())
+ {
+ case ABANDON:
+ allowRequest = true;
+ break;
+ case ADD:
+ allowRequest =
+ allowedOperations.contains(AllowedOperations.ADD);
+ break;
+ case BIND:
+ allowRequest =
+ allowedOperations.contains(AllowedOperations.BIND);
+ break;
+ case COMPARE:
+ allowRequest =
+ allowedOperations.contains(AllowedOperations.COMPARE);
+ break;
+ case DELETE:
+ allowRequest =
+ allowedOperations.contains(AllowedOperations.DELETE);
+ break;
+ case EXTENDED:
+ allowRequest =
+ allowedOperations.contains(AllowedOperations.EXTENDED);
+ break;
+ case MODIFY:
+ allowRequest =
+ allowedOperations.contains(AllowedOperations.MODIFY);
+ break;
+ case MODIFY_DN:
+ allowRequest =
+ allowedOperations.contains(AllowedOperations.RENAME);
+ break;
+ case SEARCH:
+ allowRequest =
+ allowedOperations.contains(AllowedOperations.SEARCH);
+
+ // If inequality search are prohibited, need to check
+ if (allowRequest
+ && !allowedOperations
+ .contains(AllowedOperations.INEQUALITY_SEARCH))
+ {
+ RawFilter flt =
+ ((PreParseSearchOperation) operation).getRawFilter();
+ allowRequest = !containsInequalitySearch(flt);
+ }
+ break;
+ case UNBIND:
+ allowRequest = true;
+ break;
+ }
+
+ if (!allowRequest)
+ {
+ statistics.updateRejectedOperations();
+ messages.add(INFO_ERROR_OPERATION_NOT_ALLOWED.get());
+ return allowRequest;
+ }
+ }
+
+ // For search operations:
+ if (operation.getOperationType().equals(OperationType.SEARCH))
+ {
+ PreParseSearchOperation searchOp =
+ (PreParseSearchOperation) operation;
+
+ // Check the allowed/prohibited attributes in search filter
+ if (!prohibitedAttributes.isEmpty())
+ {
+ // The attributes specified in prohibitedAttributes are not OK
+ allowRequest =
+ !containsProhibitedAttribute(searchOp.getRawFilter());
+ }
+
+ if (!allowRequest)
+ {
+ statistics.updateRejectedAttributes();
+ messages.add(INFO_ERROR_ATTRIBUTE_NOT_ALLOWED.get());
+ return allowRequest;
+ }
+
+ if (!allowedAttributes.isEmpty())
+ {
+ // Only the attributes specified in allowedAttributes are OK
+ allowRequest =
+ containsOnlyAllowedAttributes(searchOp.getRawFilter());
+ }
+
+ if (!allowRequest)
+ {
+ statistics.updateRejectedAttributes();
+ messages.add(INFO_ERROR_ATTRIBUTE_NOT_ALLOWED.get());
+ return allowRequest;
+ }
+
+ // Check the search scope
+ if (!allowedSearchScopes.isEmpty())
+ {
+ switch (searchOp.getScope())
+ {
+ case BASE_OBJECT:
+ allowRequest =
+ allowedSearchScopes.contains(AllowedSearchScopes.BASE);
+ break;
+ case SINGLE_LEVEL:
+ allowRequest =
+ allowedSearchScopes.contains(AllowedSearchScopes.ONE);
+ break;
+ case WHOLE_SUBTREE:
+ allowRequest =
+ allowedSearchScopes.contains(AllowedSearchScopes.SUB);
+ break;
+ case SUBORDINATE_SUBTREE:
+ allowRequest =
+ allowedSearchScopes
+ .contains(AllowedSearchScopes.CHILDREN);
+ break;
+ }
+
+ if (!allowRequest)
+ {
+ statistics.updateRejectedScopes();
+ messages.add(INFO_ERROR_SEARCH_SCOPE_NOT_ALLOWED.get());
+ return allowRequest;
+ }
+ }
+ }
+
+ // For compare operation
+ if (operation.getOperationType().equals(OperationType.COMPARE))
+ {
+ PreParseCompareOperation compareOp =
+ (PreParseCompareOperation) operation;
+
+ // Check the allowed/prohibited attributes
+ if (!prohibitedAttributes.isEmpty())
+ {
+ allowRequest =
+ !prohibitedAttributes.contains(compareOp
+ .getRawAttributeType());
+ }
+
+ if (!allowRequest)
+ {
+ statistics.updateRejectedAttributes();
+ messages.add(INFO_ERROR_ATTRIBUTE_NOT_ALLOWED.get());
+ return allowRequest;
+ }
+
+ if (!allowedAttributes.isEmpty())
+ {
+ allowRequest =
+ allowedAttributes.contains(compareOp
+ .getRawAttributeType());
+ }
+
+ if (!allowRequest)
+ {
+ statistics.updateRejectedAttributes();
+ messages.add(INFO_ERROR_ATTRIBUTE_NOT_ALLOWED.get());
+ return allowRequest;
+ }
+ }
+
+ DN entryDN = null;
+ DN newEntryDN = null;
+
+ try
+ {
+ switch (operation.getOperationType())
+ {
+ case ADD:
+ entryDN =
+ DN.decode(((PreParseAddOperation) operation)
+ .getRawEntryDN());
+ break;
+ case COMPARE:
+ entryDN =
+ DN.decode(((PreParseCompareOperation) operation)
+ .getRawEntryDN());
+ break;
+ case DELETE:
+ entryDN =
+ DN.decode(((PreParseDeleteOperation) operation)
+ .getRawEntryDN());
+ break;
+ case EXTENDED:
+ break;
+ case MODIFY:
+ entryDN =
+ DN.decode(((PreParseModifyOperation) operation)
+ .getRawEntryDN());
+ break;
+ case MODIFY_DN:
+ entryDN =
+ DN.decode(((PreParseModifyDNOperation) operation)
+ .getRawEntryDN());
+ newEntryDN =
+ DN.decode(((PreParseModifyDNOperation) operation)
+ .getRawNewRDN());
+ break;
+ case SEARCH:
+ entryDN =
+ DN.decode(((PreParseSearchOperation) operation)
+ .getRawBaseDN());
+ break;
+ default:
+ break;
+ }
+
+ if (entryDN != null)
+ {
+ allowRequest =
+ isInAllowedSubtrees(entryDN)
+ && !isInProhibitedSubtrees(entryDN);
+ }
+
+ if (newEntryDN != null)
+ {
+ allowRequest =
+ isInAllowedSubtrees(newEntryDN)
+ && !isInProhibitedSubtrees(newEntryDN);
+ }
+ }
+ catch (DirectoryException e)
+ {
+ // Invalid DN - reject the request.
+ allowRequest = true;
+ }
+
+ if (!allowRequest)
+ {
+ statistics.updateRejectedSubtrees();
+ messages.add(INFO_ERROR_SUBTREE_NOT_ALLOWED.get());
+ return allowRequest;
+ }
+
+ return true;
+
+ }
+
+
+
+ /**
+ * Checks whether a filter contains an inequality search filter
+ * (i.e. either a greater_or_equal or a less_or_equal filter).
+ *
+ * @param filter
+ * The filter to be tested
+ * @return boolean indicating whether the filter contains an
+ * inequality search filter
+ */
+ private boolean containsInequalitySearch(RawFilter filter)
+ {
+ switch (filter.getFilterType())
+ {
+ case AND:
+ case OR:
+ ArrayList<RawFilter> filterComponents =
+ filter.getFilterComponents();
+ if (filterComponents != null)
+ {
+ for (RawFilter element : filterComponents)
+ {
+ if (containsInequalitySearch(element))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ case NOT:
+ return containsInequalitySearch(filter.getNOTComponent());
+ case GREATER_OR_EQUAL:
+ case LESS_OR_EQUAL:
+ return true;
+ default:
+ return false;
+ }
+
+ }
+
+
+
+ /**
+ * Checks whether a filter contains unallowed attributes.
+ *
+ * @param filter
+ * The filter to be tested
+ * @return boolean indicating whether the filter contains at least
+ * one attribute which is not in the allowed list
+ */
+ private boolean containsOnlyAllowedAttributes(RawFilter filter)
+ {
+ switch (filter.getFilterType())
+ {
+ case AND:
+ case OR:
+ ArrayList<RawFilter> filterComponents =
+ filter.getFilterComponents();
+ if (filterComponents != null)
+ {
+ for (RawFilter element : filterComponents)
+ {
+ if (!containsOnlyAllowedAttributes(element))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ case NOT:
+ return containsOnlyAllowedAttributes(filter.getNOTComponent());
+ default:
+ return allowedAttributes.contains(filter.getAttributeType());
+ }
+ }
+
+
+
+ /**
+ * Checks whether a filter contains one of the prohibited
+ * attributes.
+ *
+ * @param filter
+ * The filter to be tested
+ * @return boolean indicating whether the filter contains at least
+ * one of the prohibited attributes
+ */
+ private boolean containsProhibitedAttribute(RawFilter filter)
+ {
+ switch (filter.getFilterType())
+ {
+ case AND:
+ case OR:
+ ArrayList<RawFilter> filterComponents =
+ filter.getFilterComponents();
+ if (filterComponents != null)
+ {
+ for (RawFilter element : filterComponents)
+ {
+ if (containsProhibitedAttribute(element))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ case NOT:
+ return containsProhibitedAttribute(filter.getNOTComponent());
+ default:
+ return prohibitedAttributes.contains(filter.getAttributeType());
+ }
+ }
+
+
+
+ /**
+ * Checks whether a DN is in a branch of the allowed subtrees.
+ *
+ * @param dn
+ * The DN to be tested
+ * @return boolean indicating whether the dn is in a branch of the
+ * allowed subtrees
+ */
+ private boolean isInAllowedSubtrees(DN dn)
+ {
+ boolean result = false;
+ // If the variable is not set, consider allowedSubtrees = rootDSE
+ if (allowedSubtrees.isEmpty())
+ {
+ return true;
+ }
+ for (DN branch : allowedSubtrees)
+ {
+ if (dn.isDescendantOf(branch))
+ {
+ result = true;
+ break;
+ }
+ }
+ return result;
+ }
+
+
+
+ /**
+ * Checks whether a DN is in a branch of the prohibited subtrees.
+ *
+ * @param dn
+ * The Dn to be tested
+ * @return boolean indicating whether the dn is in a branch of the
+ * prohibited subtrees
+ */
+ private boolean isInProhibitedSubtrees(DN dn)
+ {
+ boolean result = false;
+ for (DN branch : prohibitedSubtrees)
+ {
+ if (dn.isDescendantOf(branch))
+ {
+ result = true;
+ break;
+ }
+ }
+ return result;
+ }
+
+
+
+ // Updates this policy's configuration.
+ private void updateConfiguration(
+ RequestFilteringQOSPolicyCfg configuration)
+ {
+ this.allowedOperations = configuration.getAllowedOperations();
+ this.allowedAttributes = configuration.getAllowedAttributes();
+ this.prohibitedAttributes =
+ configuration.getProhibitedAttributes();
+ this.allowedSearchScopes = configuration.getAllowedSearchScopes();
+ this.allowedSubtrees = configuration.getAllowedSubtrees();
+ this.prohibitedSubtrees = configuration.getProhibitedSubtrees();
+ }
+ }
+
+
+
+ // Validates a configuration.
+ private static boolean validateConfiguration(
+ RequestFilteringQOSPolicyCfg configuration,
+ List<Message> unacceptableReasons)
+ {
+ // Check that allowed-attributes does not contain any attribute
+ // also configured in prohibited-attributes
+ for (String allowedAttr : configuration.getAllowedAttributes())
+ {
+ if (configuration.getProhibitedAttributes().contains(allowedAttr))
+ {
+ unacceptableReasons
+ .add(ERR_CONFIG_NETWORKGROUPREQUESTFILTERINGPOLICY_INVALID_ATTRIBUTE
+ .get(allowedAttr, configuration.dn().toString()));
+ return false;
+ }
+ }
+
+ // Check that allowed-subtrees does not contain any subtree also
+ // configured in prohibited-subtrees
+ for (DN allowedSubtree : configuration.getAllowedSubtrees())
+ {
+ if (configuration.getProhibitedSubtrees()
+ .contains(allowedSubtree))
+ {
+ unacceptableReasons
+ .add(ERR_CONFIG_NETWORKGROUPREQUESTFILTERINGPOLICY_INVALID_SUBTREE
+ .get(allowedSubtree.toString(), configuration.dn()
+ .toString()));
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+
+ /**
+ * Creates a new request filtering policy factory.
+ */
+ public RequestFilteringPolicyFactory()
+ {
+ // Nothing to do.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public RequestFilteringPolicy createQOSPolicy(
+ RequestFilteringQOSPolicyCfg configuration)
+ throws ConfigException, InitializationException
+ {
+ Policy policy = new Policy();
+
+ // Save the configuration.
+ policy.updateConfiguration(configuration);
+
+ // Register change listener.
+ configuration.addRequestFilteringChangeListener(policy);
+
+ return policy;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationAcceptable(
+ RequestFilteringQOSPolicyCfg configuration,
+ List<Message> unacceptableReasons)
+ {
+ return validateConfiguration(configuration, unacceptableReasons);
+ }
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyStat.java b/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyStat.java
deleted file mode 100644
index 3985208..0000000
--- a/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyStat.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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
- *
- *
- * Copyright 2008 Sun Microsystems, Inc.
- */
-
-package org.opends.server.core.networkgroups;
-
-/**
- * This class implements the statistics associated to a
- * network group request filtering policy.
- */
-public class RequestFilteringPolicyStat {
- private long rejectedAttributes;
- private long rejectedOperations;
- private long rejectedSubtrees;
- private long rejectedScopes;
- private Object statLock;
-
- /**
- * Constructor.
- */
- public RequestFilteringPolicyStat() {
- rejectedAttributes = 0;
- rejectedOperations = 0;
- rejectedSubtrees = 0;
- rejectedScopes = 0;
- statLock = new Object();
- }
-
- /**
- * Increments the number of rejected operations due to an
- * attribute not allowed by the request filtering policy.
- */
- public void updateRejectedAttributes() {
- synchronized(statLock) {
- rejectedAttributes++;
- }
- }
-
- /**
- * Increments the number of rejected operations due to an
- * operation type not allowed by the request filtering policy.
- */
- public void updateRejectedOperations() {
- synchronized(statLock) {
- rejectedOperations++;
- }
- }
-
- /**
- * Increments the number of rejected operations due to a subtree
- * not allowed by the request filtering policy.
- */
- public void updateRejectedSubtrees() {
- synchronized(statLock) {
- rejectedSubtrees++;
- }
- }
-
- /**
- * Increments the number of rejected operations due to a search scope
- * not allowed by the request filtering policy.
- */
- public void updateRejectedScopes() {
- synchronized(statLock) {
- rejectedScopes++;
- }
- }
-
- /**
- * Retrieves the number of rejected operations due to an
- * attribute not allowed by the request filtering policy.
- * @return number of rejected operations due to an invalid attribute
- */
- public long getRejectedAttributes() {
- return rejectedAttributes;
- }
-
- /**
- * Retrieves the number of rejected operations due to an
- * operation type not allowed by the request filtering policy.
- * @return number of rejected operations due to an invalid op type
- */
- public long getRejectedOperations() {
- return rejectedOperations;
- }
-
- /**
- * Retrieves the number of rejected operations due to a
- * subtree not allowed by the request filtering policy.
- * @return number of rejected operations due to an invalid subtree
- */
- public long getRejectedSubtrees() {
- return rejectedSubtrees;
- }
-
- /**
- * Retrieves the number of rejected operations due to a
- * scope not allowed by the request filtering policy.
- * @return number of rejected operations due to an invalid scope
- */
- public long getRejectedScopes() {
- return rejectedScopes;
- }
-}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyStatistics.java b/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyStatistics.java
new file mode 100644
index 0000000..1f9da11
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyStatistics.java
@@ -0,0 +1,155 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.core.networkgroups;
+
+
+
+import java.util.concurrent.atomic.AtomicLong;
+
+
+
+/**
+ * This class implements the statistics associated with a network group
+ * request filtering policy.
+ */
+final class RequestFilteringPolicyStatistics
+{
+ private final AtomicLong rejectedAttributes = new AtomicLong();
+ private final AtomicLong rejectedOperations = new AtomicLong();
+ private final AtomicLong rejectedScopes = new AtomicLong();
+ private final AtomicLong rejectedSubtrees = new AtomicLong();
+
+
+
+ /**
+ * Creates a new request filtering policy statistics.
+ */
+ RequestFilteringPolicyStatistics()
+ {
+ // Do nothing.
+ }
+
+
+
+ /**
+ * Returns the number of rejected operations due to an attribute not
+ * allowed by the request filtering policy.
+ *
+ * @return The number of rejected operations due to an invalid
+ * attribute.
+ */
+ long getRejectedAttributes()
+ {
+ return rejectedAttributes.get();
+ }
+
+
+
+ /**
+ * Returns the number of rejected operations due to an operation type
+ * not allowed by the request filtering policy.
+ *
+ * @return The number of rejected operations due to an invalid
+ * operation type.
+ */
+ long getRejectedOperations()
+ {
+ return rejectedOperations.get();
+ }
+
+
+
+ /**
+ * Returns the number of rejected operations due to a scope not
+ * allowed by the request filtering policy.
+ *
+ * @return The number of rejected operations due to an invalid scope.
+ */
+ long getRejectedScopes()
+ {
+ return rejectedScopes.get();
+ }
+
+
+
+ /**
+ * Returns the number of rejected operations due to a subtree not
+ * allowed by the request filtering policy.
+ *
+ * @return The number of rejected operations due to an invalid
+ * subtree.
+ */
+ long getRejectedSubtrees()
+ {
+ return rejectedSubtrees.get();
+ }
+
+
+
+ /**
+ * Increments the number of rejected operations due to an attribute
+ * not allowed by the request filtering policy.
+ */
+ void updateRejectedAttributes()
+ {
+ rejectedAttributes.incrementAndGet();
+ }
+
+
+
+ /**
+ * Increments the number of rejected operations due to an operation
+ * type not allowed by the request filtering policy.
+ */
+ void updateRejectedOperations()
+ {
+ rejectedOperations.incrementAndGet();
+ }
+
+
+
+ /**
+ * Increments the number of rejected operations due to a search scope
+ * not allowed by the request filtering policy.
+ */
+ void updateRejectedScopes()
+ {
+ rejectedScopes.incrementAndGet();
+ }
+
+
+
+ /**
+ * Increments the number of rejected operations due to a subtree not
+ * allowed by the request filtering policy.
+ */
+ void updateRejectedSubtrees()
+ {
+ rejectedSubtrees.incrementAndGet();
+ }
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/ResourceLimits.java b/opends/src/server/org/opends/server/core/networkgroups/ResourceLimits.java
deleted file mode 100644
index b1f116b..0000000
--- a/opends/src/server/org/opends/server/core/networkgroups/ResourceLimits.java
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * 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
- *
- *
- * Copyright 2008 Sun Microsystems, Inc.
- */
-package org.opends.server.core.networkgroups;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import org.opends.messages.Message;
-import org.opends.server.admin.server.ConfigurationAddListener;
-import org.opends.server.admin.server.ConfigurationChangeListener;
-import org.opends.server.admin.server.ConfigurationDeleteListener;
-import org.opends.server.admin.std.meta.
- NetworkGroupResourceLimitsCfgDefn.ReferralBindPolicy;
-import org.opends.server.admin.std.meta.
- NetworkGroupResourceLimitsCfgDefn.ReferralPolicy;
-import org.opends.server.admin.std.server.NetworkGroupResourceLimitsCfg;
-import org.opends.server.api.ClientConnection;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.RawFilter;
-import org.opends.server.types.ResultCode;
-
-import org.opends.server.types.operation.PreParseOperation;
-import org.opends.server.types.operation.PreParseSearchOperation;
-import static org.opends.messages.CoreMessages.*;
-
-
-/**
- * This class defines the resource limits applicable to all
- * connections inside the same network group.
- */
-public class ResourceLimits
- implements ConfigurationAddListener<NetworkGroupResourceLimitsCfg>,
- ConfigurationDeleteListener<NetworkGroupResourceLimitsCfg>,
- ConfigurationChangeListener<NetworkGroupResourceLimitsCfg>
-{
- // The resource limits are defined through the config
- private boolean isConfigured = false;
-
- // The maximum number of connections in the network group
- private int maxConnections;
-
- // The maximum number of connections coming from the same IP address
- private int maxConnectionsFromSameIP;
-
- // The maximum number of operations per connection
- private int maxOpsPerConnection;
-
- // The maximum number of concurrent operations per connection
- private int maxConcurrentOpsPerConnection;
-
- // The maximum size for a search
- private int searchSizeLimit;
-
- // The maximum duration for a search
- private int searchTimeLimit;
-
- // The minimum substring length in a search
- private int minSearchSubstringLength;
-
- // The referral policy
- private ReferralPolicy referralPolicy = ReferralPolicy.FORWARD;
-
- // The referral policy
- private ReferralBindPolicy referralBindPolicy = ReferralBindPolicy.ANONYMOUS;
-
- // The referral hop limit
- private int referralHopLimit = 0;
-
- // The number of connections in the group
- private int numConnections = 0;
-
- // The maximum number of simultaneous connections in the group
- // since group creation
- private int maxNumConnections = 0;
-
- // The total number of connections managed by the group
- private int totalNumConnections = 0;
-
- // Map containing the connections sorted by incoming IP address
- HashMap<String, Integer> connectionsPerIpMap = new HashMap<String, Integer>();
-
- // The lock for the counter numConnections and the map connectionsPerIpMap
- Object connMutex = new Object();
-
- // The current configuration
- private NetworkGroupResourceLimitsCfg config = null;
-
- /**
- * Constructor.
- *
- * @param resourceLimitsCfg configuration
- */
- public ResourceLimits(NetworkGroupResourceLimitsCfg resourceLimitsCfg) {
- createLimits(resourceLimitsCfg);
- }
-
- /**
- * Resets all the fields.
- */
- private void resetLimits() {
- maxConnections = 0;
- maxConnectionsFromSameIP = 0;
- maxOpsPerConnection = 0;
- maxConcurrentOpsPerConnection = 0;
-
- searchSizeLimit = -1;
- searchTimeLimit = -1;
- minSearchSubstringLength = 0;
-
- referralPolicy = ReferralPolicy.FORWARD;
- referralBindPolicy = ReferralBindPolicy.ANONYMOUS;
- referralHopLimit = 0;
-
- isConfigured = false;
- if (config != null) {
- config.removeChangeListener(this);
- config = null;
- }
- }
-
- /**
- * Creates a ResourceLimits from a configuration object.
- *
- * @param resourcesCfg the configuration
- */
- private void createLimits(NetworkGroupResourceLimitsCfg resourcesCfg) {
- if (resourcesCfg != null) {
- maxConnections = resourcesCfg.getMaxConnections();
- maxConnectionsFromSameIP = resourcesCfg.getMaxConnectionsFromSameIP();
- maxOpsPerConnection = resourcesCfg.getMaxOpsPerConnection();
- maxConcurrentOpsPerConnection =
- resourcesCfg.getMaxConcurrentOpsPerConnection();
-
- Integer tmpSizeLimit = resourcesCfg.getSearchSizeLimit();
- if (tmpSizeLimit != null) {
- searchSizeLimit = tmpSizeLimit;
- } else {
- searchSizeLimit = -1;
- }
- Long tmpTimeLimit = resourcesCfg.getSearchTimeLimit();
- if (tmpTimeLimit != null) {
- searchTimeLimit = tmpTimeLimit.intValue();
- } else {
- searchTimeLimit = -1;
- }
- minSearchSubstringLength = resourcesCfg.getMinSubstringLength();
-
- referralPolicy = resourcesCfg.getReferralPolicy();
- referralBindPolicy = resourcesCfg.getReferralBindPolicy();
- referralHopLimit = resourcesCfg.getReferralHopLimit();
-
- if (config == null) {
- resourcesCfg.addChangeListener(this);
- }
- config = resourcesCfg;
- isConfigured = true;
- } else {
- resetLimits();
- }
- }
-
- /**
- * Sets the maximum number of connections allowed in this network group.
- * @param maxConn The maximum number of connections handled by this
- * network group
- */
- public void setMaxConnections(int maxConn) {
- maxConnections = maxConn;
- }
-
- /**
- * Sets the maximum number of connections coming from the same client
- * in this network group.
- * @param maxConnFromSameClient The maximum number of connections coming
- * from the same client in this network group
- */
- public void setMaxConnectionsFromSameIP(int maxConnFromSameClient) {
- maxConnectionsFromSameIP = maxConnFromSameClient;
- }
-
- /**
- * Sets the maximum number of operations performed on the same connection
- * in this network group.
- * @param maxOpsPerConn The maximum number of operations performed on
- * the same connection
- */
- public void setMaxOpsPerConnection(int maxOpsPerConn) {
- maxOpsPerConnection = maxOpsPerConn;
- }
-
- /**
- * Sets the maximum number of concurrent operations performed on the same
- * connection in this network group.
- * @param maxConcurrentOpsPerConn The maximum number of simultaneous
- * operations per connection on the same
- * connection
- */
- public void setMaxConcurrentOpsPerConnection(int maxConcurrentOpsPerConn) {
- maxConcurrentOpsPerConnection = maxConcurrentOpsPerConn;
- }
-
- /**
- * Sets the search time limit for operations performed in this network group.
- * @param maxSearchTime The search time limit
- */
- public void setSearchTimeLimit(int maxSearchTime) {
- searchTimeLimit = maxSearchTime;
- }
-
- /**
- * Sets the search size limit for operations performed in this network group.
- * @param maxSearchSize The search size limit
- */
- public void setSearchSizeLimit(int maxSearchSize) {
- searchSizeLimit = maxSearchSize;
- }
-
- /**
- * Sets the minimum substring length for a search filter in this network
- * group.
- * @param minLength The minimum substring length
- */
- public void setMinSearchSubstringLength(int minLength) {
- minSearchSubstringLength = minLength;
- }
-
- /**
- * Returns the maximum number of entries returned by a search operation
- * performed in this network group.
- * @return the maximum number of entries
- */
- public int getSizeLimit() {
- return searchSizeLimit;
- }
-
- /**
- * Returns the maximum duration for a search operation performed in this
- * network group.
- * @return the maximum duration in ms
- */
- public int getTimeLimit() {
- return searchTimeLimit;
- }
-
- /**
- * Returns the minimum string length for a substring filter.
- * @return minimum string length
- */
- public int getMinSubstring() {
- return minSearchSubstringLength;
- }
-
- /**
- * Returns the referral policy.
- * @return referral policy
- */
- public ReferralPolicy getReferralPolicy() {
- return referralPolicy;
- }
-
- /**
- * Returns the referralBindPolicy.
- * @return referral bind policy
- */
- public ReferralBindPolicy getReferralBindPolicy() {
- return referralBindPolicy;
- }
-
- /**
- * Returns the referral hop limit.
- * @return referral hop limit
- */
- public int getReferralHopLimit() {
- return referralHopLimit;
- }
-
- /**
- * Adds a connection to the resource group.
- *
- * @param connection the ClientConnection to ad
- */
- public void addConnection(ClientConnection connection) {
- synchronized(connMutex) {
- // increment the number of connections managed by the network group
- numConnections++;
- totalNumConnections++;
- if (numConnections > maxNumConnections) {
- maxNumConnections = numConnections;
- }
-
- // increment the number of connections from the given IP address
- String ip = connection.getClientAddress();
- Integer currentCount = connectionsPerIpMap.get(ip);
- if (currentCount == null) {
- currentCount = new Integer(0);
- }
-
- connectionsPerIpMap.put(ip, currentCount + 1);
- }
- }
-
- /**
- * Removes a connection from the nerwork group.
- *
- * @param connection the ClientConnection to remove
- */
- public void removeConnection(ClientConnection connection) {
- synchronized(connMutex) {
- // decrement the number of connections managed by the network group
- numConnections--;
-
- // decrement the number of connections from the given IP address
- String ip = connection.getClientAddress();
- Integer currentCount = connectionsPerIpMap.get(ip);
- if (currentCount == null) {
- // Should be error!
- currentCount = new Integer(1);
- }
- if (currentCount == 1) {
- // This was the last connection
- connectionsPerIpMap.remove(ip);
- } else {
- connectionsPerIpMap.put(ip, currentCount - 1);
- }
- }
- }
-
- /**
- * Checks the resource limits.
- *
- * @param connection the ClientConnection to check
- * @param operation the ongoing operation
- * @param fullCheck a boolean indicating if full checks must be done
- * @param messages the messages to include in the disconnect notification
- * response. It may be <CODE>null</CODE> if no message
- * is to be sent.
- * @return a boolean indicating whether the connection is allowed
- */
- public boolean checkLimits(
- ClientConnection connection,
- PreParseOperation operation,
- boolean fullCheck,
- List<Message> messages)
- {
- boolean result = true;
-
- if (fullCheck) {
- // Check the total number of connections in the resource group
- synchronized(connMutex) {
- if ((maxConnections > 0) && (numConnections > maxConnections)) {
- messages.add(INFO_ERROR_MAX_CONNECTIONS_LIMIT_EXCEEDED.get());
- result = false;
- }
- }
- if (! result) {
- return result;
- }
-
- // Check the number of connections coming from the same IP
- synchronized(connMutex) {
- // Add the connection in the map
- String ip = connection.getClientAddress();
-
- Integer currentCount = connectionsPerIpMap.get(ip);
- if (currentCount == null) {
- currentCount = new Integer(0);
- }
-
- if ((maxConnectionsFromSameIP > 0)
- && (currentCount.intValue() > maxConnectionsFromSameIP)) {
- messages.add(
- INFO_ERROR_MAX_CONNECTIONS_FROM_SAME_IP_LIMIT_EXCEEDED.get());
- result = false;
- }
- }
- if (! result) {
- return result;
- }
- }
-
- // Check the max number of operations per connection
- if ((maxOpsPerConnection > 0)
- && (connection.getNumberOfOperations() > maxOpsPerConnection)) {
- messages.add(
- INFO_ERROR_MAX_OPERATIONS_PER_CONNECTION_LIMIT_EXCEEDED.get());
- return false;
- }
-
- // Check the max number of concurrent operations per connection
- if ((maxConcurrentOpsPerConnection > 0)
- && (connection.getOperationsInProgress().size()
- > maxConcurrentOpsPerConnection)) {
- messages.add(
- INFO_ERROR_MAX_CONCURRENT_OPERATIONS_PER_CONNECTION_LIMIT_EXCEEDED
- .get());
- return false;
- }
-
- // If the operation is a search, check the min search substring length
- if ((operation != null) && (operation instanceof PreParseSearchOperation)) {
- if (!checkSubstringFilter(
- ((PreParseSearchOperation)operation).getRawFilter())) {
- messages.add(
- INFO_ERROR_MIN_SEARCH_SUBSTRING_LENGTH_LIMIT_EXCEEDED.get());
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks whether a filter enforces minimum substring length. If the
- * filter is a composed filter (AND, OR, NOT filters), each component
- * of the filter is recursively checked.
- * When the filter is a substring filter, this routine checks that
- * the substring length is greater or equal to the minimum substring
- * length.
- * For other search filter types, true is returned.
- * @param filter The LDAP search filter to be tested
- * @return boolean indicating whether the filter conforms to the
- * minimum substring length rule.
- */
- private boolean checkSubstringFilter(RawFilter filter) {
- switch (filter.getFilterType()) {
- case AND:
- case OR:
- ArrayList<RawFilter> filterComponents = filter.getFilterComponents();
- if (filterComponents != null) {
- for (RawFilter element : filterComponents) {
- if (!checkSubstringFilter(element)) {
- return false;
- }
- }
- }
- return true;
- case NOT:
- return checkSubstringFilter(filter.getNOTComponent());
- case SUBSTRING:
- int length = 0;
- ByteString subInitialElement = filter.getSubInitialElement();
- if (subInitialElement != null) {
- length += subInitialElement.stringValue().length();
- }
- ArrayList<ByteString> subAnyElements = filter.getSubAnyElements();
- if (subAnyElements != null) {
- for (ByteString element : subAnyElements) {
- length += element.stringValue().length();
- }
- }
- ByteString subFinalElement = filter.getSubFinalElement();
- if (subFinalElement != null) {
- length += subFinalElement.stringValue().length();
- }
- return (length >= minSearchSubstringLength);
- default:
- return true;
- }
- }
-
- /**
- * Retrieves the statistics associated to the resource limits.
- * @return the statistics
- */
- public ResourceLimitsStat getStat() {
- ResourceLimitsStat stat;
- synchronized(connMutex) {
- stat = new ResourceLimitsStat(
- numConnections, maxNumConnections, totalNumConnections);
- }
- return stat;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationAddAcceptable(
- NetworkGroupResourceLimitsCfg configuration,
- List<Message> unacceptableReasons) {
- return (!isConfigured);
- }
-
- /**
- * {@inheritDoc}
- */
- public ConfigChangeResult applyConfigurationAdd(
- NetworkGroupResourceLimitsCfg configuration) {
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
-
- ConfigChangeResult configChangeResult =
- new ConfigChangeResult(resultCode, adminActionRequired, messages);
- createLimits(configuration);
- return configChangeResult;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationDeleteAcceptable(
- NetworkGroupResourceLimitsCfg configuration,
- List<Message> unacceptableReasons) {
- return isConfigured;
- }
-
- /**
- * {@inheritDoc}
- */
- public ConfigChangeResult applyConfigurationDelete(
- NetworkGroupResourceLimitsCfg configuration) {
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
-
- ConfigChangeResult configChangeResult =
- new ConfigChangeResult(resultCode, adminActionRequired, messages);
-
- resetLimits();
- isConfigured = false;
-
- return configChangeResult;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationChangeAcceptable(
- NetworkGroupResourceLimitsCfg configuration,
- List<Message> unacceptableReasons) {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public ConfigChangeResult applyConfigurationChange(
- NetworkGroupResourceLimitsCfg configuration) {
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
-
- ConfigChangeResult configChangeResult =
- new ConfigChangeResult(resultCode, adminActionRequired, messages);
- createLimits(configuration);
- return configChangeResult;
- }
-}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicy.java b/opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicy.java
new file mode 100644
index 0000000..157808b
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicy.java
@@ -0,0 +1,135 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import java.util.List;
+
+import org.opends.messages.Message;
+import org.opends.server.api.ClientConnection;
+import org.opends.server.api.QOSPolicy;
+import org.opends.server.types.operation.PreParseOperation;
+
+
+
+/**
+ * This class defines the resource limits policy applicable to all
+ * connections inside the same network group.
+ */
+abstract class ResourceLimitsPolicy extends QOSPolicy
+{
+ /**
+ * Creates a new resource limits policy.
+ */
+ protected ResourceLimitsPolicy()
+ {
+ // No implementation required.
+ }
+
+
+
+ /**
+ * Adds a connection to the network group.
+ *
+ * @param connection
+ * The client connection.
+ */
+ abstract void addConnection(ClientConnection connection);
+
+
+
+ /**
+ * Returns the minimum string length for a substring filter.
+ *
+ * @return The minimum string length for a substring filter.
+ */
+ abstract int getMinSubstring();
+
+
+
+ /**
+ * Returns the default maximum number of entries that should be
+ * returned for a searches processed by this network group.
+ *
+ * @return The default maximum number of entries that should be
+ * returned for a searches processed by this network group.
+ */
+ abstract int getSizeLimit();
+
+
+
+ /**
+ * Returns the statistics associated with this resource limits policy.
+ *
+ * @return The statistics associated with this resource limits policy.
+ */
+ abstract ResourceLimitsPolicyStatistics getStatistics();
+
+
+
+ /**
+ * Returns the maximum length of time in seconds permitted for a
+ * search operation processed by this network group.
+ *
+ * @return The maximum length of time in seconds permitted for a
+ * search operation processed by this network group.
+ */
+ abstract int getTimeLimit();
+
+
+
+ /**
+ * Determines if the provided operation is allowed according to this
+ * resource limits policy.
+ *
+ * @param connection
+ * the ClientConnection to check
+ * @param operation
+ * the ongoing operation
+ * @param fullCheck
+ * a boolean indicating if full checks must be done
+ * @param messages
+ * the messages to include in the disconnect notification
+ * response. It may be <CODE>null</CODE> if no message is to
+ * be sent.
+ * @return a boolean indicating whether the connection is allowed
+ */
+ abstract boolean isAllowed(ClientConnection connection,
+ PreParseOperation operation, boolean fullCheck,
+ List<Message> messages);
+
+
+
+ /**
+ * Removes a connection from the network group.
+ *
+ * @param connection
+ * The client connection to remove.
+ */
+ abstract void removeConnection(ClientConnection connection);
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyFactory.java b/opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyFactory.java
new file mode 100644
index 0000000..3516a5f
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyFactory.java
@@ -0,0 +1,496 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import static org.opends.messages.CoreMessages.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.opends.messages.Message;
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.std.server.ResourceLimitsQOSPolicyCfg;
+import org.opends.server.api.ClientConnection;
+import org.opends.server.api.QOSPolicyFactory;
+import org.opends.server.config.ConfigException;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.ByteString;
+import org.opends.server.types.ConfigChangeResult;
+import org.opends.server.types.InitializationException;
+import org.opends.server.types.RawFilter;
+import org.opends.server.types.ResultCode;
+import org.opends.server.types.operation.PreParseOperation;
+import org.opends.server.types.operation.PreParseSearchOperation;
+
+
+
+/**
+ * This class defines a factory for creating user configurable resource
+ * limits policies.
+ */
+public final class ResourceLimitsPolicyFactory implements
+ QOSPolicyFactory<ResourceLimitsQOSPolicyCfg>
+{
+
+ /**
+ * Policy implementation.
+ */
+ private static final class Policy extends ResourceLimitsPolicy
+ implements
+ ConfigurationChangeListener<ResourceLimitsQOSPolicyCfg>
+ {
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationChange(
+ ResourceLimitsQOSPolicyCfg configuration)
+ {
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ ArrayList<Message> messages = new ArrayList<Message>();
+
+ // Save the configuration.
+ updateConfiguration(configuration);
+
+ return new ConfigChangeResult(resultCode, adminActionRequired,
+ messages);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationChangeAcceptable(
+ ResourceLimitsQOSPolicyCfg configuration,
+ List<Message> unacceptableReasons)
+ {
+ return ResourceLimitsPolicyFactory.validateConfiguration(
+ configuration, unacceptableReasons);
+ }
+
+
+
+ // Map containing the connections sorted by incoming IP address.
+ private final HashMap<String, Integer> connectionsPerIPMap =
+ new HashMap<String, Integer>();
+
+ // The maximum number of concurrent operations per connection.
+ private int maxConcurrentOpsPerConnection;
+
+ // The maximum number of connections in the network group.
+ private int maxConnections;
+
+ // The maximum number of connections coming from the same IP
+ // address.
+ private int maxConnectionsFromSameIP;
+
+ // The maximum number of operations per connection.
+ private int maxOpsPerConnection;
+
+ // The minimum substring length in a search.
+ private int minSearchSubstringLength;
+
+ // The lock for connections per IP map.
+ private final Object mutex = new Object();
+
+ // The maximum size for a search.
+ private int sizeLimit;
+
+ // The statistics for the resource limits policy.
+ private final ResourceLimitsPolicyStatistics statistics =
+ new ResourceLimitsPolicyStatistics();
+
+ // The maximum time for a search.
+ private int timeLimit;
+
+
+
+ /**
+ * Creates a new resource limits policy.
+ */
+ private Policy()
+ {
+ // Nothing to do.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ void addConnection(ClientConnection connection)
+ {
+ synchronized (mutex)
+ {
+ // Update the statistics.
+ statistics.addClientConnection();
+
+ // Increment the number of connections from the given IP
+ // address.
+ String ip = connection.getClientAddress();
+ Integer currentCount = connectionsPerIPMap.get(ip);
+ if (currentCount == null)
+ {
+ connectionsPerIPMap.put(ip, 1);
+ }
+ else
+ {
+ connectionsPerIPMap.put(ip, currentCount + 1);
+ }
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ int getMinSubstring()
+ {
+ return minSearchSubstringLength;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ int getSizeLimit()
+ {
+ return sizeLimit;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ ResourceLimitsPolicyStatistics getStatistics()
+ {
+ return statistics;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ int getTimeLimit()
+ {
+ return timeLimit;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ boolean isAllowed(ClientConnection connection,
+ PreParseOperation operation, boolean fullCheck,
+ List<Message> messages)
+ {
+ boolean result = true;
+
+ if (fullCheck)
+ {
+ // Check the total number of connections in the resource group
+ synchronized (mutex)
+ {
+ if (maxConnections > 0
+ && statistics.getClientConnections() > maxConnections)
+ {
+ messages.add(INFO_ERROR_MAX_CONNECTIONS_LIMIT_EXCEEDED
+ .get());
+ result = false;
+ }
+ }
+ if (!result)
+ {
+ return result;
+ }
+
+ // Check the number of connections coming from the same IP
+ synchronized (mutex)
+ {
+ // Add the connection in the map
+ String ip = connection.getClientAddress();
+
+ Integer currentCount = connectionsPerIPMap.get(ip);
+ if (currentCount == null)
+ {
+ currentCount = new Integer(0);
+ }
+
+ if (maxConnectionsFromSameIP > 0
+ && currentCount.intValue() > maxConnectionsFromSameIP)
+ {
+ messages
+ .add(INFO_ERROR_MAX_CONNECTIONS_FROM_SAME_IP_LIMIT_EXCEEDED
+ .get());
+ result = false;
+ }
+ }
+ if (!result)
+ {
+ return result;
+ }
+ }
+
+ // Check the max number of operations per connection
+ if (maxOpsPerConnection > 0
+ && connection.getNumberOfOperations() > maxOpsPerConnection)
+ {
+ messages
+ .add(INFO_ERROR_MAX_OPERATIONS_PER_CONNECTION_LIMIT_EXCEEDED
+ .get());
+ return false;
+ }
+
+ // Check the max number of concurrent operations per connection
+ if (maxConcurrentOpsPerConnection > 0
+ && connection.getOperationsInProgress().size()
+ > maxConcurrentOpsPerConnection)
+ {
+ messages.add(
+ INFO_ERROR_MAX_CONCURRENT_OPERATIONS_PER_CONNECTION_LIMIT_EXCEEDED
+ .get());
+ return false;
+ }
+
+ // If the operation is a search, check the min search substring
+ // length
+ if (operation != null
+ && operation instanceof PreParseSearchOperation)
+ {
+ if (!checkSubstringFilter(((PreParseSearchOperation) operation)
+ .getRawFilter()))
+ {
+ messages
+ .add(INFO_ERROR_MIN_SEARCH_SUBSTRING_LENGTH_LIMIT_EXCEEDED
+ .get());
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ void removeConnection(ClientConnection connection)
+ {
+ synchronized (mutex)
+ {
+ // Update the statistics.
+ statistics.removeClientConnection();
+
+ // Decrement the number of connections from the given IP
+ // address.
+ String ip = connection.getClientAddress();
+ Integer currentCount = connectionsPerIPMap.get(ip);
+ if (currentCount != null)
+ {
+ if (currentCount == 1)
+ {
+ // This was the last connection.
+ connectionsPerIPMap.remove(ip);
+ }
+ else
+ {
+ connectionsPerIPMap.put(ip, currentCount - 1);
+ }
+ }
+ }
+ }
+
+
+
+ /**
+ * Checks whether a filter enforces minimum substring length. If the
+ * filter is a composed filter (AND, OR, NOT filters), each
+ * component of the filter is recursively checked. When the filter
+ * is a substring filter, this routine checks that the substring
+ * length is greater or equal to the minimum substring length. For
+ * other search filter types, true is returned.
+ *
+ * @param filter
+ * The LDAP search filter to be tested
+ * @return boolean indicating whether the filter conforms to the
+ * minimum substring length rule.
+ */
+ private boolean checkSubstringFilter(RawFilter filter)
+ {
+ switch (filter.getFilterType())
+ {
+ case AND:
+ case OR:
+ ArrayList<RawFilter> filterComponents =
+ filter.getFilterComponents();
+ if (filterComponents != null)
+ {
+ for (RawFilter element : filterComponents)
+ {
+ if (!checkSubstringFilter(element))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ case NOT:
+ return checkSubstringFilter(filter.getNOTComponent());
+ case SUBSTRING:
+ int length = 0;
+ ByteString subInitialElement = filter.getSubInitialElement();
+ if (subInitialElement != null)
+ {
+ length += subInitialElement.stringValue().length();
+ }
+ ArrayList<ByteString> subAnyElements =
+ filter.getSubAnyElements();
+ if (subAnyElements != null)
+ {
+ for (ByteString element : subAnyElements)
+ {
+ length += element.stringValue().length();
+ }
+ }
+ ByteString subFinalElement = filter.getSubFinalElement();
+ if (subFinalElement != null)
+ {
+ length += subFinalElement.stringValue().length();
+ }
+ return length >= minSearchSubstringLength;
+ default:
+ return true;
+ }
+ }
+
+
+
+ // Updates this policy's configuration.
+ private void updateConfiguration(
+ ResourceLimitsQOSPolicyCfg configuration)
+ {
+ maxConnections = configuration.getMaxConnections();
+ maxConnectionsFromSameIP =
+ configuration.getMaxConnectionsFromSameIP();
+ maxOpsPerConnection = configuration.getMaxOpsPerConnection();
+ maxConcurrentOpsPerConnection =
+ configuration.getMaxConcurrentOpsPerConnection();
+
+ Integer tmpSizeLimit = configuration.getSizeLimit();
+ if (tmpSizeLimit != null)
+ {
+ sizeLimit = tmpSizeLimit;
+ }
+ else
+ {
+ sizeLimit = DirectoryServer.getSizeLimit();
+ }
+
+ Long tmpTimeLimit = configuration.getTimeLimit();
+ if (tmpTimeLimit != null)
+ {
+ timeLimit = tmpTimeLimit.intValue();
+ }
+ else
+ {
+ timeLimit = DirectoryServer.getTimeLimit();
+ }
+
+ minSearchSubstringLength = configuration.getMinSubstringLength();
+ }
+ }
+
+
+
+ // Validates a configuration.
+ private static boolean validateConfiguration(
+ ResourceLimitsQOSPolicyCfg configuration,
+ List<Message> unacceptableReasons)
+ {
+ // Always valid.
+ return true;
+ }
+
+
+
+ /**
+ * Creates a new resource limits policy factory.
+ */
+ public ResourceLimitsPolicyFactory()
+ {
+ // Nothing to do.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public ResourceLimitsPolicy createQOSPolicy(
+ ResourceLimitsQOSPolicyCfg configuration) throws ConfigException,
+ InitializationException
+ {
+ Policy policy = new Policy();
+
+ // Save the configuration.
+ policy.updateConfiguration(configuration);
+
+ // Register change listener.
+ configuration.addResourceLimitsChangeListener(policy);
+
+ return policy;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationAcceptable(
+ ResourceLimitsQOSPolicyCfg configuration,
+ List<Message> unacceptableReasons)
+ {
+ return validateConfiguration(configuration, unacceptableReasons);
+ }
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyStatistics.java b/opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyStatistics.java
new file mode 100644
index 0000000..bb74270
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyStatistics.java
@@ -0,0 +1,121 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+/**
+ * This class implements the statistics associated to a network group
+ * resource limit.
+ */
+final class ResourceLimitsPolicyStatistics
+{
+ // Updates to these are protected by a mutex in the resource limits
+ // policy.
+ private long clientConnections = 0;
+ private long maxClientConnections = 0;
+ private long totalClientConnections = 0;
+
+
+
+ /**
+ * Creates a new resource limits statistics.
+ */
+ ResourceLimitsPolicyStatistics()
+ {
+ // Do nothing.
+ }
+
+
+
+ /**
+ * Updates these statistics to reflect a new client connection being
+ * added.
+ */
+ void addClientConnection()
+ {
+ clientConnections++;
+ totalClientConnections++;
+ if (clientConnections > maxClientConnections)
+ {
+ maxClientConnections = clientConnections;
+ }
+ }
+
+
+
+ /**
+ * Returns the number of client connections currently in the network
+ * group.
+ *
+ * @return The number of client connections currently in the network
+ * group.
+ */
+ long getClientConnections()
+ {
+ return clientConnections;
+ }
+
+
+
+ /**
+ * Returns the maximum number of simultaneous client connections in
+ * the network group.
+ *
+ * @return The maximum number of simultaneous client connections in
+ * the network group.
+ */
+ long getMaxClientConnections()
+ {
+ return maxClientConnections;
+ }
+
+
+
+ /**
+ * Returns the total number of client connections managed by the
+ * network group since its creation.
+ *
+ * @return The total number of client connections managed by the
+ * network group since its creation.
+ */
+ long getTotalClientConnections()
+ {
+ return totalClientConnections;
+ }
+
+
+
+ /**
+ * Updates these statistics to reflect an existing client connection
+ * being closed.
+ */
+ void removeClientConnection()
+ {
+ clientConnections--;
+ }
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsStat.java b/opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsStat.java
deleted file mode 100644
index 2aad532..0000000
--- a/opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsStat.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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
- *
- *
- * Copyright 2008 Sun Microsystems, Inc.
- */
-
-package org.opends.server.core.networkgroups;
-
-
-/**
- * This class implements the statistics associated to a network group
- * resource limit.
- */
-public class ResourceLimitsStat {
- private long clientConnections;
- private long maxClientConnections;
- private long totalClientConnections;
-
- /**
- * Constructor.
- * @param clientConnections number of client connections currently
- * in the network group
- * @param maxClientConnections maximum number of simultaneous
- * connections in the network group
- * @param totalClientConnections total number of client connections
- * managed by the network group since its creation
- */
- public ResourceLimitsStat(
- long clientConnections,
- long maxClientConnections,
- long totalClientConnections) {
- this.clientConnections = clientConnections;
- this.maxClientConnections = maxClientConnections;
- this.totalClientConnections = totalClientConnections;
- }
-
- /**
- * Returns the number of client connections currently in the network
- * group.
- * @return number of client connections currently in the network
- * group
- */
- public long getClientConnections() {
- return clientConnections;
- }
-
- /**
- * Returns the maximum number of simultaneous client connections in
- * the network group.
- * @return the maximum number of simultaneous client connections in
- * the network group
- */
- public long getMaxClientConnections() {
- return maxClientConnections;
- }
-
- /**
- * Returns the total number of client connections managed by the
- * network group since its creation.
- * @return the cumulated number of client connections managed by
- * the network group since its creation
- */
- public long getTotalClientConnections() {
- return totalClientConnections;
- }
-}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/SecurityConnectionCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/SecurityConnectionCriteria.java
new file mode 100644
index 0000000..ac5ded8
--- /dev/null
+++ b/opends/src/server/org/opends/server/core/networkgroups/SecurityConnectionCriteria.java
@@ -0,0 +1,99 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import org.opends.server.api.ClientConnection;
+import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.DN;
+
+
+
+/**
+ * A connection criteria which matches connections which are secured
+ * using SSL or TLS.
+ */
+final class SecurityConnectionCriteria implements ConnectionCriteria
+{
+
+ /**
+ * A connection criteria which does not require a secured connection.
+ */
+ public static final SecurityConnectionCriteria SECURITY_NOT_REQUIRED =
+ new SecurityConnectionCriteria(false);
+
+ /**
+ * A connection criteria which requires a secured connection.
+ */
+ public static final SecurityConnectionCriteria SECURITY_REQUIRED =
+ new SecurityConnectionCriteria(true);
+
+ // Indicates whether or not the connection must be secured.
+ private final boolean mustBeSecured;
+
+
+
+ /**
+ * Creates a new security connection criteria.
+ *
+ * @param mustBeSecured
+ * Indicates whether or not the connection must be secured.
+ */
+ private SecurityConnectionCriteria(boolean mustBeSecured)
+ {
+ this.mustBeSecured = mustBeSecured;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean matches(ClientConnection connection)
+ {
+ return willMatchAfterBind(null, null, null, connection.isSecure());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean willMatchAfterBind(ClientConnection connection,
+ DN bindDN, AuthenticationType authType, boolean isSecure)
+ {
+ if (mustBeSecured)
+ {
+ return isSecure;
+ }
+ else
+ {
+ return true;
+ }
+ }
+}
diff --git a/opends/src/server/org/opends/server/core/networkgroups/SecurityCriteria.java b/opends/src/server/org/opends/server/core/networkgroups/SecurityCriteria.java
deleted file mode 100644
index b84a2be..0000000
--- a/opends/src/server/org/opends/server/core/networkgroups/SecurityCriteria.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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
- *
- *
- * Copyright 2008 Sun Microsystems, Inc.
- */
-package org.opends.server.core.networkgroups;
-
-import org.opends.server.api.ClientConnection;
-import org.opends.server.types.AuthenticationType;
-import org.opends.server.types.DN;
-
-/**
- * This class defines a Security criteria.
- * The criteria specifies whether all connections are allowed
- * or only secured connections.
- * A connection is considered secure if it takes place over
- * SSL or with StartTLS.
- */
-public class SecurityCriteria implements NetworkGroupCriterion {
-
- // If the Security Criteria is enabled,
- // a connection matches only if it is secured
- // Otherwise (Security Criteria disabled),
- // all connections match
- private boolean enabled = true;
-
- /**
- * Constructor.
- *
- * @param isEnabled boolean indicating if security is mandatory
- */
- public SecurityCriteria(boolean isEnabled) {
- enabled = isEnabled;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean match(ClientConnection connection) {
- return (matchAfterBind(null, null, null, connection.isSecure()));
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean matchAfterBind(ClientConnection connection, DN bindDN,
- AuthenticationType authType, boolean isSecure) {
- if (enabled) {
- return isSecure;
- } else {
- return true;
- }
- }
-}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/CLIProfile.java b/opends/src/server/org/opends/server/tools/dsconfig/CLIProfile.java
index fa9d2d1..8fbb0b6 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/CLIProfile.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/CLIProfile.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2009 Sun Microsystems, Inc.
*/
package org.opends.server.tools.dsconfig;
@@ -30,13 +30,14 @@
import java.util.Arrays;
+import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.opends.server.admin.AbstractManagedObjectDefinition;
-import org.opends.server.admin.InstantiableRelationDefinition;
import org.opends.server.admin.ManagedObjectDefinitionResource;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
@@ -83,7 +84,11 @@
public Set<String> getDefaultListPropertyNames(RelationDefinition<?, ?> r) {
String s = resource.getString(r.getParentDefinition(), "relation."
+ r.getName() + ".list-properties");
- return new LinkedHashSet<String>(Arrays.asList(s.split(",")));
+ if (s.trim().length() == 0) {
+ return Collections.emptySet();
+ } else {
+ return new LinkedHashSet<String>(Arrays.asList(s.split(",")));
+ }
}
@@ -97,7 +102,7 @@
* @return Returns the naming argument which should be used for a
* relation definition.
*/
- public String getNamingArgument(InstantiableRelationDefinition<?, ?> r) {
+ public String getNamingArgument(RelationDefinition<?, ?> r) {
String s = resource.getString(r.getParentDefinition(),
"relation." + r.getName() + ".naming-argument-override").trim();
@@ -112,7 +117,16 @@
} else {
builder.append(s.substring(i + 1));
}
- builder.append("-name");
+
+ if (r instanceof SetRelationDefinition) {
+ // Set relations are named using their type, so be consistent
+ // with their associated create-xxx sub-command.
+ builder.append("-type");
+ } else {
+ // Other relations (instantiable) are named by the user.
+ builder.append("-name");
+ }
+
s = builder.toString();
}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java
index b9a23c2..c2281d2 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java
@@ -35,13 +35,14 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
-import java.util.TreeMap;
import java.util.TreeSet;
import org.opends.messages.Message;
@@ -66,6 +67,7 @@
import org.opends.server.admin.PropertyOption;
import org.opends.server.admin.PropertyProvider;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
@@ -397,6 +399,33 @@
/**
+ * Creates a new create-xxx sub-command for a sets
+ * relation.
+ *
+ * @param <C>
+ * The type of managed object which can be created.
+ * @param <S>
+ * The type of server managed object which can be created.
+ * @param parser
+ * The sub-command argument parser.
+ * @param p
+ * The parent managed object path.
+ * @param r
+ * The set relation.
+ * @return Returns the new create-xxx sub-command.
+ * @throws ArgumentException
+ * If the sub-command could not be created successfully.
+ */
+ public static <C extends ConfigurationClient, S extends Configuration>
+ CreateSubCommandHandler<C, S> create(
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p,
+ SetRelationDefinition<C, S> r) throws ArgumentException {
+ return new CreateSubCommandHandler<C, S>(parser, p, r, null, p.child(r));
+ }
+
+
+
+ /**
* Creates a new create-xxx sub-command for an optional relation.
*
* @param <C>
@@ -499,7 +528,7 @@
// First determine what type of component the user wants to create.
MenuResult<ManagedObjectDefinition<? extends C, ? extends S>> result;
- result = getTypeInteractively(app, d);
+ result = getTypeInteractively(app, d, Collections.<String>emptySet());
ManagedObjectDefinition<? extends C, ? extends S> mod;
if (result.isSuccess()) {
@@ -913,78 +942,56 @@
- // Generate the type name - definition mapping table.
- @SuppressWarnings("unchecked")
- private static <C extends ConfigurationClient, S extends Configuration>
- SortedMap<String, ManagedObjectDefinition<? extends C, ? extends S>>
- getSubTypes(AbstractManagedObjectDefinition<C, S> d) {
- SortedMap<String, ManagedObjectDefinition<? extends C, ? extends S>> map;
- map =
- new TreeMap<String, ManagedObjectDefinition<? extends C, ? extends S>>();
-
- // If the top-level definition is instantiable, we use the value
- // "generic" or "custom".
- if (!d.hasOption(ManagedObjectOption.HIDDEN)) {
- if (d instanceof ManagedObjectDefinition) {
- ManagedObjectDefinition<? extends C, ? extends S> mod =
- (ManagedObjectDefinition<? extends C, ? extends S>) d;
- if (CLIProfile.getInstance().isForCustomization(mod)) {
- map.put(DSConfig.CUSTOM_TYPE, mod);
- } else {
- map.put(DSConfig.GENERIC_TYPE, mod);
- }
- }
- }
-
- // Process its sub-definitions.
- String suffix = "-" + d.getName();
- for (AbstractManagedObjectDefinition<? extends C, ? extends S> c : d
- .getAllChildren()) {
- if (d.hasOption(ManagedObjectOption.HIDDEN)) {
- continue;
- }
-
- if (c instanceof ManagedObjectDefinition) {
- ManagedObjectDefinition<? extends C, ? extends S> mod =
- (ManagedObjectDefinition<? extends C, ? extends S>) c;
-
- // For the type name we shorten it, if possible, by stripping
- // off the trailing part of the name which matches the
- // base-type.
- String name = mod.getName();
- if (name.endsWith(suffix)) {
- name = name.substring(0, name.length() - suffix.length());
- }
-
- // If this type is intended for customization, prefix it with
- // "custom".
- if (CLIProfile.getInstance().isForCustomization(mod)) {
- name = String.format("%s-%s", DSConfig.CUSTOM_TYPE, name);
- }
-
- map.put(name, mod);
- }
- }
-
- return map;
- }
-
-
-
// Interactively ask the user which type of component they want to create.
private static <C extends ConfigurationClient, S extends Configuration>
MenuResult<ManagedObjectDefinition<? extends C, ? extends S>>
getTypeInteractively(ConsoleApplication app,
- AbstractManagedObjectDefinition<C, S> d) throws CLIException {
- Collection<ManagedObjectDefinition<? extends C, ? extends S>> types;
- types = getSubTypes(d).values();
+ AbstractManagedObjectDefinition<C, S> d,
+ Set<String> prohibitedTypes) throws CLIException {
+ // First get the list of available of sub-types.
+ List<ManagedObjectDefinition<? extends C, ? extends S>> filteredTypes =
+ new LinkedList<ManagedObjectDefinition<? extends C,? extends S>>(
+ getSubTypes(d).values());
+ boolean isOnlyOneType = filteredTypes.size() == 1;
+
+ Iterator<ManagedObjectDefinition<? extends C,? extends S>> i;
+ for (i = filteredTypes.iterator() ; i.hasNext();) {
+ ManagedObjectDefinition<? extends C,? extends S> cd = i.next();
+
+ if (prohibitedTypes.contains(cd.getName())) {
+ // Remove filtered types.
+ i.remove();
+ } else if (!app.isAdvancedMode()) {
+ // Only display advanced types and custom types in advanced mode.
+ if (cd.hasOption(ManagedObjectOption.ADVANCED)) {
+ i.remove();
+ } else if (CLIProfile.getInstance().isForCustomization(cd)) {
+ i.remove();
+ }
+ }
+ }
// If there is only one choice then return immediately.
- if (types.size() == 1) {
- ManagedObjectDefinition<? extends C, ? extends S> type =
- types.iterator().next();
+ if (filteredTypes.size() == 0) {
+ Message msg =
+ ERR_DSCFG_ERROR_NO_AVAILABLE_TYPES.get(d.getUserFriendlyName());
+ app.println(msg);
return MenuResult.<ManagedObjectDefinition<? extends C,
- ? extends S>>success(type);
+ ? extends S>>cancel();
+ } else if (filteredTypes.size() == 1) {
+ ManagedObjectDefinition<? extends C, ? extends S> type =
+ filteredTypes.iterator().next();
+ if (!isOnlyOneType) {
+ // Only one option available so confirm that the user wishes to
+ // use it.
+ Message msg = INFO_DSCFG_TYPE_PROMPT_SINGLE.get(
+ d.getUserFriendlyName(), type.getUserFriendlyName());
+ if (!app.confirmAction(msg, true)) {
+ return MenuResult.cancel();
+ }
+ }
+ return MenuResult.<ManagedObjectDefinition<? extends C, ? extends S>>
+ success(type);
} else {
MenuBuilder<ManagedObjectDefinition<? extends C, ? extends S>> builder =
new MenuBuilder<ManagedObjectDefinition<? extends C, ? extends S>>(app);
@@ -992,17 +999,8 @@
builder.setMultipleColumnThreshold(MULTI_COLUMN_THRESHOLD);
builder.setPrompt(msg);
- for (ManagedObjectDefinition<? extends C, ? extends S> mod : types) {
- // Only display advanced types and custom types in advanced mode.
- if (!app.isAdvancedMode()) {
- if (mod.hasOption(ManagedObjectOption.ADVANCED)) {
- continue;
- }
-
- if (CLIProfile.getInstance().isForCustomization(mod)) {
- continue;
- }
- }
+ for (ManagedObjectDefinition<? extends C, ? extends S> mod :
+ filteredTypes) {
Message option = mod.getUserFriendlyName();
if (CLIProfile.getInstance().isForCustomization(mod)) {
@@ -1083,6 +1081,9 @@
// Create the naming arguments.
this.namingArgs = createNamingArgs(subCommand, c, true);
+ // Build the -t option usage.
+ this.typeUsage = getSubTypesUsage(r.getChildDefinition());
+
// Create the --property argument which is used to specify
// property values.
this.propertySetArgument = new StringArgument(OPTION_DSCFG_LONG_SET,
@@ -1091,18 +1092,6 @@
INFO_DSCFG_DESCRIPTION_PROP_VAL.get());
this.subCommand.addArgument(this.propertySetArgument);
- // Build the -t option usage.
- StringBuilder builder = new StringBuilder();
- boolean isFirst = true;
- for (String s : types.keySet()) {
- if (!isFirst) {
- builder.append(" | ");
- }
- builder.append(s);
- isFirst = false;
- }
- this.typeUsage = builder.toString();
-
if (!types.containsKey(DSConfig.GENERIC_TYPE)) {
// The option is mandatory when non-interactive.
this.typeArgument = new StringArgument("type", OPTION_DSCFG_SHORT_TYPE,
@@ -1163,43 +1152,7 @@
public MenuResult<Integer> run(ConsoleApplication app,
ManagementContextFactory factory) throws ArgumentException,
ClientException, CLIException {
- // Determine the type of managed object to be created.
- ManagedObjectDefinition<? extends C, ? extends S> d;
- if (!typeArgument.isPresent()) {
- if (app.isInteractive()) {
- // Let the user choose.
- MenuResult<ManagedObjectDefinition<? extends C, ? extends S>> result;
- app.println();
- app.println();
- result = getTypeInteractively(app, relation.getChildDefinition());
-
- if (result.isSuccess()) {
- d = result.getValue();
- } else if (result.isCancel()) {
- return MenuResult.cancel();
- } else {
- // Must be quit.
- if (!app.isMenuDrivenMode()) {
- app.printVerboseMessage(INFO_DSCFG_CONFIRM_CREATE_FAIL.get(relation
- .getUserFriendlyName()));
- }
- return MenuResult.quit();
- }
- } else if (typeArgument.getDefaultValue() != null) {
- d = types.get(typeArgument.getDefaultValue());
- } else {
- throw ArgumentExceptionFactory
- .missingMandatoryNonInteractiveArgument(typeArgument);
- }
- } else {
- d = types.get(typeArgument.getValue());
- if (d == null) {
- throw ArgumentExceptionFactory.unknownSubType(relation, typeArgument
- .getValue(), typeUsage);
- }
- }
-
- Message ufn = d.getUserFriendlyName();
+ Message ufn = relation.getUserFriendlyName();
// Get the naming argument values.
List<String> names = getNamingArgValues(app, namingArgs);
@@ -1212,11 +1165,6 @@
// Update the command builder.
updateCommandBuilderWithSubCommand();
- // Encode the provided properties.
- List<String> propertyArgs = propertySetArgument.getValues();
- MyPropertyProvider provider = new MyPropertyProvider(d,
- namingPropertyDefinition, propertyArgs);
-
// Add the child managed object.
ManagementContext context = factory.getManagementContext(app);
MenuResult<ManagedObject<?>> result;
@@ -1265,6 +1213,82 @@
}
ManagedObject<?> parent = result.getValue();
+
+ // Determine the type of managed object to be created. If we are creating
+ // a managed object beneath a set relation then prevent creation of
+ // duplicates.
+ Set<String> prohibitedTypes;
+ if (relation instanceof SetRelationDefinition) {
+ SetRelationDefinition<C, S> sr = (SetRelationDefinition<C, S>) relation;
+ prohibitedTypes = new HashSet<String>();
+ try
+ {
+ for (String child : parent.listChildren(sr)) {
+ prohibitedTypes.add(child);
+ }
+ }
+ catch (AuthorizationException e)
+ {
+ Message msg = ERR_DSCFG_ERROR_CREATE_AUTHZ.get(ufn);
+ throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS,
+ msg);
+ }
+ catch (ConcurrentModificationException e)
+ {
+ Message msg = ERR_DSCFG_ERROR_CREATE_CME.get(ufn);
+ throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg);
+ }
+ catch (CommunicationException e)
+ {
+ Message msg = ERR_DSCFG_ERROR_CREATE_CE.get(ufn, e
+ .getMessage());
+ throw new ClientException(LDAPResultCode.CLIENT_SIDE_SERVER_DOWN, msg);
+ }
+ } else {
+ // No prohibited types.
+ prohibitedTypes = Collections.emptySet();
+ }
+
+ ManagedObjectDefinition<? extends C, ? extends S> d;
+ if (!typeArgument.isPresent()) {
+ if (app.isInteractive()) {
+ // Let the user choose.
+ MenuResult<ManagedObjectDefinition<? extends C, ? extends S>> dresult;
+ app.println();
+ app.println();
+ dresult = getTypeInteractively(app, relation.getChildDefinition(),
+ prohibitedTypes);
+
+ if (dresult.isSuccess()) {
+ d = dresult.getValue();
+ } else if (dresult.isCancel()) {
+ return MenuResult.cancel();
+ } else {
+ // Must be quit.
+ if (!app.isMenuDrivenMode()) {
+ app.printVerboseMessage(INFO_DSCFG_CONFIRM_CREATE_FAIL.get(ufn));
+ }
+ return MenuResult.quit();
+ }
+ } else if (typeArgument.getDefaultValue() != null) {
+ d = types.get(typeArgument.getDefaultValue());
+ } else {
+ throw ArgumentExceptionFactory
+ .missingMandatoryNonInteractiveArgument(typeArgument);
+ }
+ } else {
+ d = types.get(typeArgument.getValue());
+ if (d == null) {
+ throw ArgumentExceptionFactory.unknownSubType(relation, typeArgument
+ .getValue(), typeUsage);
+ }
+ }
+
+ // Encode the provided properties.
+ List<String> propertyArgs = propertySetArgument.getValues();
+ MyPropertyProvider provider = new MyPropertyProvider(d,
+ namingPropertyDefinition, propertyArgs);
+
ManagedObject<? extends C> child;
List<DefaultBehaviorException> exceptions =
new LinkedList<DefaultBehaviorException>();
@@ -1297,6 +1321,10 @@
.adaptIllegalManagedObjectNameException(e, d);
}
}
+ } else if (relation instanceof SetRelationDefinition) {
+ SetRelationDefinition<C, S> srelation =
+ (SetRelationDefinition<C, S>) relation;
+ child = parent.createChild(srelation, d, exceptions);
} else {
OptionalRelationDefinition<C, S> orelation =
(OptionalRelationDefinition<C, S>) relation;
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java b/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
index 3052c92..19333af 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
@@ -56,6 +56,7 @@
import org.opends.server.admin.ClassPropertyDefinition;
import org.opends.server.admin.InstantiableRelationDefinition;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.Tag;
import org.opends.server.admin.client.ManagedObjectDecodingException;
import org.opends.server.admin.client.MissingMandatoryPropertiesException;
@@ -181,6 +182,10 @@
InstantiableRelationDefinition<?, ?> ir =
(InstantiableRelationDefinition<?, ?>) rd;
ufpn = ir.getUserFriendlyPluralName();
+ } else if (rd instanceof SetRelationDefinition) {
+ SetRelationDefinition<?, ?> sr =
+ (SetRelationDefinition<?, ?>) rd;
+ ufpn = sr.getUserFriendlyPluralName();
}
MenuBuilder<Integer> builder = new MenuBuilder<Integer>(app);
@@ -467,6 +472,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean isAdvancedMode() {
return advancedModeArgument.isPresent();
}
@@ -476,6 +482,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean isInteractive() {
return !noPromptArgument.isPresent();
}
@@ -495,6 +502,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean isQuiet() {
return quietArgument.isPresent();
}
@@ -504,6 +512,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean isScriptFriendly() {
return scriptFriendlyArgument.isPresent();
}
@@ -513,6 +522,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean isVerbose() {
return verboseArgument.isPresent();
}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/DeleteSubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/DeleteSubCommandHandler.java
index cb0c959..6ab4000 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/DeleteSubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/DeleteSubCommandHandler.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2009 Sun Microsystems, Inc.
*/
package org.opends.server.tools.dsconfig;
@@ -31,14 +31,17 @@
import static org.opends.messages.DSConfigMessages.*;
import java.util.List;
+import java.util.SortedMap;
import org.opends.messages.Message;
import org.opends.server.admin.DefinitionDecodingException;
import org.opends.server.admin.InstantiableRelationDefinition;
+import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.ManagedObjectNotFoundException;
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.OptionalRelationDefinition;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
@@ -122,6 +125,29 @@
return new DeleteSubCommandHandler(parser, p, r, p.child(r));
}
+
+
+ /**
+ * Creates a new delete-xxx sub-command for a set relation.
+ *
+ * @param parser
+ * The sub-command argument parser.
+ * @param p
+ * The parent managed object path.
+ * @param r
+ * The set relation.
+ * @return Returns the new delete-xxx sub-command.
+ * @throws ArgumentException
+ * If the sub-command could not be created successfully.
+ */
+ public static DeleteSubCommandHandler create(
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p,
+ SetRelationDefinition<?, ?> r) throws ArgumentException {
+ return new DeleteSubCommandHandler(parser, p, r, p.child(r));
+ }
+
+
+
// The argument which should be used to force deletion.
private final BooleanArgument forceArgument;
@@ -255,14 +281,13 @@
ManagedObject<?> parent = result.getValue();
try {
- if (relation instanceof InstantiableRelationDefinition) {
- InstantiableRelationDefinition<?, ?> irelation =
- (InstantiableRelationDefinition<?, ?>) relation;
+ if (relation instanceof InstantiableRelationDefinition
+ || relation instanceof SetRelationDefinition) {
String childName = names.get(names.size() - 1);
if (childName == null) {
MenuResult<String> sresult =
- readChildName(app, parent, irelation, null);
+ readChildName(app, parent, relation, null);
if (sresult.isQuit()) {
if (!app.isMenuDrivenMode()) {
@@ -277,11 +302,32 @@
} else {
childName = sresult.getValue();
}
+ } else if (relation instanceof SetRelationDefinition) {
+ // The provided type short name needs mapping to the full name.
+ String name = childName.trim();
+ SortedMap types = getSubTypes(relation.getChildDefinition());
+ ManagedObjectDefinition cd =
+ (ManagedObjectDefinition) types.get(name);
+ if (cd == null) {
+ // The name must be invalid.
+ String typeUsage = getSubTypesUsage(relation.getChildDefinition());
+ Message msg = ERR_DSCFG_ERROR_SUB_TYPE_UNRECOGNIZED.get(
+ name, relation.getUserFriendlyName(), typeUsage);
+ throw new ArgumentException(msg);
+ } else {
+ childName = cd.getName();
+ }
}
if (confirmDeletion(app)) {
setCommandBuilderUseful(true);
- parent.removeChild(irelation, childName);
+ if (relation instanceof InstantiableRelationDefinition) {
+ parent.removeChild((InstantiableRelationDefinition<?,?>) relation,
+ childName);
+ } else {
+ parent.removeChild((SetRelationDefinition<?,?>) relation,
+ childName);
+ }
} else {
return MenuResult.cancel();
}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/GetPropSubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/GetPropSubCommandHandler.java
index d073944..1c292fd 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/GetPropSubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/GetPropSubCommandHandler.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2009 Sun Microsystems, Inc.
*/
package org.opends.server.tools.dsconfig;
@@ -52,6 +52,7 @@
import org.opends.server.admin.PropertyOption;
import org.opends.server.admin.RelationDefinition;
import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.SingletonRelationDefinition;
import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
import org.opends.server.admin.client.AuthorizationException;
@@ -128,6 +129,27 @@
/**
+ * Creates a new get-xxx-prop sub-command for a set relation.
+ *
+ * @param parser
+ * The sub-command argument parser.
+ * @param path
+ * The parent managed object path.
+ * @param r
+ * The set relation.
+ * @return Returns the new get-xxx-prop sub-command.
+ * @throws ArgumentException
+ * If the sub-command could not be created successfully.
+ */
+ public static GetPropSubCommandHandler create(
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> path,
+ SetRelationDefinition<?, ?> r) throws ArgumentException {
+ return new GetPropSubCommandHandler(parser, path.child(r), r);
+ }
+
+
+
+ /**
* Creates a new get-xxx-prop sub-command for a singleton relation.
*
* @param parser
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/ListSubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/ListSubCommandHandler.java
index 2dfe238..247da4f 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/ListSubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/ListSubCommandHandler.java
@@ -21,7 +21,6 @@
*
* CDDL HEADER END
*
- *
* Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.tools.dsconfig;
@@ -47,6 +46,7 @@
import org.opends.server.admin.OptionalRelationDefinition;
import org.opends.server.admin.PropertyDefinition;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
@@ -100,6 +100,28 @@
/**
+ * Creates a new list-xxx sub-command for a set relation.
+ *
+ * @param parser
+ * The sub-command argument parser.
+ * @param p
+ * The parent managed object path.
+ * @param r
+ * The set relation.
+ * @return Returns the new list-xxx sub-command.
+ * @throws ArgumentException
+ * If the sub-command could not be created successfully.
+ */
+ public static ListSubCommandHandler create(
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p,
+ SetRelationDefinition<?, ?> r) throws ArgumentException {
+ return new ListSubCommandHandler(parser, p, r, r.getPluralName(), r
+ .getUserFriendlyPluralName());
+ }
+
+
+
+ /**
* Creates a new list-xxx sub-command for an optional relation.
*
* @param parser
@@ -216,6 +238,10 @@
InstantiableRelationDefinition<?, ?> irelation =
(InstantiableRelationDefinition<?, ?>) relation;
ufn = irelation.getUserFriendlyPluralName();
+ } else if (relation instanceof SetRelationDefinition) {
+ SetRelationDefinition<?, ?> srelation =
+ (SetRelationDefinition<?, ?>) relation;
+ ufn = srelation.getUserFriendlyPluralName();
} else {
ufn = relation.getUserFriendlyName();
}
@@ -291,6 +317,39 @@
throw new ClientException(LDAPResultCode.CLIENT_SIDE_SERVER_DOWN,
msg);
}
+ } else if (relation instanceof SetRelationDefinition) {
+ SetRelationDefinition<?, ?> srelation =
+ (SetRelationDefinition<?, ?>) relation;
+ try {
+ for (String s : parent.listChildren(srelation)) {
+ try {
+ children.put(s, parent.getChild(srelation, s));
+ } catch (ManagedObjectNotFoundException e) {
+ // Ignore - as it's been removed since we did the list.
+ }
+ }
+ } catch (DefinitionDecodingException e) {
+ // FIXME: just output this as a warnings (incl. the name) but
+ // continue.
+ Message msg = ERR_DSCFG_ERROR_LIST_DDE.get(ufn, ufn, ufn);
+ throw new ClientException(LDAPResultCode.OTHER, msg);
+ } catch (ManagedObjectDecodingException e) {
+ // FIXME: just output this as a warnings (incl. the name) but
+ // continue.
+ Message msg = ERR_DSCFG_ERROR_LIST_MODE.get(ufn);
+ throw new ClientException(LDAPResultCode.OTHER, msg, e);
+ } catch (AuthorizationException e) {
+ Message msg = ERR_DSCFG_ERROR_LIST_AUTHZ.get(ufn);
+ throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS,
+ msg);
+ } catch (ConcurrentModificationException e) {
+ Message msg = ERR_DSCFG_ERROR_LIST_CME.get(ufn);
+ throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg);
+ } catch (CommunicationException e) {
+ Message msg = ERR_DSCFG_ERROR_LIST_CE.get(ufn, e.getMessage());
+ throw new ClientException(LDAPResultCode.CLIENT_SIDE_SERVER_DOWN,
+ msg);
+ }
} else if (relation instanceof OptionalRelationDefinition) {
OptionalRelationDefinition<?, ?> orelation =
(OptionalRelationDefinition<?, ?>) relation;
@@ -363,7 +422,7 @@
}
builder.addSortKey(0);
- String baseType = relation.getName();
+ String baseType = relation.getChildDefinition().getName();
String typeSuffix = "-" + baseType;
for (String name : children.keySet()) {
ManagedObject<?> child = children.get(name);
@@ -382,7 +441,11 @@
// First output the name.
builder.startRow();
- builder.appendCell(name);
+ if (relation instanceof SetRelationDefinition) {
+ builder.appendCell(d.getUserFriendlyName());
+ } else {
+ builder.appendCell(name);
+ }
// Output the managed object type in the form used in
// create-xxx commands.
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java
index e77a5f0..29a77c7 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java
@@ -53,6 +53,7 @@
import org.opends.server.admin.PropertyException;
import org.opends.server.admin.PropertyOption;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.SingletonRelationDefinition;
import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
import org.opends.server.admin.client.AuthorizationException;
@@ -192,6 +193,27 @@
/**
+ * Creates a new set-xxx-prop sub-command for a set relation.
+ *
+ * @param parser
+ * The sub-command argument parser.
+ * @param path
+ * The parent managed object path.
+ * @param r
+ * The set relation.
+ * @return Returns the new set-xxx-prop sub-command.
+ * @throws ArgumentException
+ * If the sub-command could not be created successfully.
+ */
+ public static SetPropSubCommandHandler create(
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> path,
+ SetRelationDefinition<?, ?> r) throws ArgumentException {
+ return new SetPropSubCommandHandler(parser, path.child(r), r);
+ }
+
+
+
+ /**
* Creates a new set-xxx-prop sub-command for a singleton relation.
*
* @param parser
@@ -429,7 +451,6 @@
{
String argName =
CLIProfile.getInstance().getNamingArgument(
- (InstantiableRelationDefinition<?, ?>)
path.getRelationDefinition());
try
{
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java
index 735e3ef..1737bf8 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2007-2008 Sun Microsystems, Inc.
+ * Copyright 2007-2009 Sun Microsystems, Inc.
*/
package org.opends.server.tools.dsconfig;
@@ -40,10 +40,10 @@
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
+import java.util.SortedMap;
+import java.util.TreeMap;
import org.opends.messages.Message;
import org.opends.server.admin.AbstractManagedObjectDefinition;
import org.opends.server.admin.Configuration;
@@ -59,6 +59,8 @@
import org.opends.server.admin.OptionalRelationDefinition;
import org.opends.server.admin.PropertyDefinition;
import org.opends.server.admin.PropertyDefinitionUsageBuilder;
+import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.SingletonRelationDefinition;
import org.opends.server.admin.SizeUnit;
import org.opends.server.admin.Tag;
@@ -256,6 +258,100 @@
*/
public <C extends ConfigurationClient, S extends Configuration>
void appendManagedObjectPathElement(
+ SetRelationDefinition<? super C, ? super S> r,
+ AbstractManagedObjectDefinition<C, S> d) {
+ if (result.isSuccess()) {
+ // We should ignore the "template" name here and use a path
+ // argument.
+ String childName = args.get(argIndex++);
+
+ try {
+ // If the name is null then we must be interactive - so let
+ // the user choose.
+ if (childName == null) {
+ try {
+ MenuResult<String> sresult = readChildName(app,
+ result.getValue(), r, d);
+
+ if (sresult.isCancel()) {
+ result = MenuResult.cancel();
+ return;
+ } else if (sresult.isQuit()) {
+ result = MenuResult.quit();
+ return;
+ } else {
+ childName = sresult.getValue();
+ }
+ } catch (CLIException e) {
+ clie = e;
+ result = MenuResult.quit();
+ return;
+ }
+ } else if (childName.trim().length() == 0) {
+ IllegalManagedObjectNameException e =
+ new IllegalManagedObjectNameException(childName);
+ clie = ArgumentExceptionFactory
+ .adaptIllegalManagedObjectNameException(e, d);
+ result = MenuResult.quit();
+ return;
+ } else {
+ String name = childName.trim();
+ SortedMap<String, ManagedObjectDefinition<? extends C, ? extends S>>
+ types = getSubTypes(d);
+ ManagedObjectDefinition<?, ?> cd = types.get(name);
+ if (cd == null) {
+ // The name must be invalid.
+ String typeUsage = getSubTypesUsage(d);
+ Message msg = ERR_DSCFG_ERROR_SUB_TYPE_UNRECOGNIZED.get(
+ name, r.getUserFriendlyName(), typeUsage);
+ clie = new CLIException(msg);
+ result = MenuResult.quit();
+ return;
+ } else {
+ childName = cd.getName();
+ }
+ }
+
+ ManagedObject<?> child = result.getValue().getChild(r, childName);
+
+ // Check that child is a sub-type of the specified
+ // definition.
+ if (!child.getManagedObjectDefinition().isChildOf(d)) {
+ clie = ArgumentExceptionFactory.wrongManagedObjectType(r, child
+ .getManagedObjectDefinition(), getSubCommand().getName());
+ result = MenuResult.quit();
+ } else {
+ result = MenuResult.<ManagedObject<?>>success(child);
+ }
+ } catch (DefinitionDecodingException e) {
+ dde = e;
+ result = MenuResult.quit();
+ } catch (ManagedObjectDecodingException e) {
+ mode = e;
+ result = MenuResult.quit();
+ } catch (AuthorizationException e) {
+ authze = e;
+ result = MenuResult.quit();
+ } catch (ManagedObjectNotFoundException e) {
+ monfe = e;
+ result = MenuResult.quit();
+ } catch (ConcurrentModificationException e) {
+ cme = e;
+ result = MenuResult.quit();
+ } catch (CommunicationException e) {
+ ce = e;
+ result = MenuResult.quit();
+ }
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ void appendManagedObjectPathElement(
SingletonRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d) {
if (result.isSuccess()) {
@@ -513,6 +609,38 @@
*/
public <C extends ConfigurationClient, S extends Configuration>
void appendManagedObjectPathElement(
+ SetRelationDefinition<? super C, ? super S> r,
+ AbstractManagedObjectDefinition<C, S> d) {
+ sz--;
+
+ // The name of the managed object is determined from its type, so
+ // we don't need this argument.
+ if (isCreate && sz == 0) {
+ return;
+ }
+
+ String argName = CLIProfile.getInstance().getNamingArgument(r);
+ StringArgument arg;
+
+ try {
+ arg =
+ new StringArgument(argName, null, argName, false, true,
+ INFO_NAME_PLACEHOLDER.get(),
+ INFO_DSCFG_DESCRIPTION_NAME.get(d.getUserFriendlyName()));
+ subCommand.addArgument(arg);
+ arguments.add(arg);
+ } catch (ArgumentException e) {
+ this.e = e;
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ void appendManagedObjectPathElement(
SingletonRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d) {
sz--;
@@ -997,21 +1125,22 @@
* @param parent
* The parent managed object.
* @param r
- * The relation between the parent and the children.
+ * The relation between the parent and the children, must be
+ * a set or instantiable relation.
* @param d
* The type of child managed object to choose from.
- * @return Returns a {@link MenuResult#success()} containing the
- * name of the managed object that the user selected, or
- * {@link MenuResult#quit()}, or
- * {@link MenuResult#cancel()}, if the sub-command was run
- * interactive and the user chose to quit or cancel.
+ * @return Returns a {@link MenuResult#success()} containing the name
+ * of the managed object that the user selected, or
+ * {@link MenuResult#quit()}, or {@link MenuResult#cancel()},
+ * if the sub-command was run interactive and the user chose
+ * to quit or cancel.
* @throws CommunicationException
* If the server cannot be contacted.
* @throws ConcurrentModificationException
* If the parent managed object has been deleted.
* @throws AuthorizationException
- * If the children cannot be listed due to an
- * authorization failure.
+ * If the children cannot be listed due to an authorization
+ * failure.
* @throws CLIException
* If the user input can be read from the console or if
* there are no children.
@@ -1019,7 +1148,7 @@
protected final <C extends ConfigurationClient, S extends Configuration>
MenuResult<String> readChildName(
ConsoleApplication app, ManagedObject<?> parent,
- InstantiableRelationDefinition<C, S> r,
+ RelationDefinition<C, S> r,
AbstractManagedObjectDefinition<? extends C, ? extends S> d)
throws AuthorizationException, ConcurrentModificationException,
CommunicationException, CLIException {
@@ -1031,14 +1160,25 @@
app.println();
// Filter out advanced and hidden types if required.
- String[] childNames = parent.listChildren(r, d);
- SortedSet<String> children = new TreeSet<String>(
+ String[] childNames;
+ if (r instanceof InstantiableRelationDefinition) {
+ childNames =
+ parent.listChildren((InstantiableRelationDefinition<C,S>)r, d);
+ } else {
+ childNames = parent.listChildren((SetRelationDefinition<C,S>)r, d);
+ }
+ SortedMap<String, String> children = new TreeMap<String, String>(
String.CASE_INSENSITIVE_ORDER);
for (String childName : childNames) {
ManagedObject<?> child;
try {
- child = parent.getChild(r, childName);
+ if (r instanceof InstantiableRelationDefinition) {
+ child = parent.getChild((InstantiableRelationDefinition<C,S>)r,
+ childName);
+ } else {
+ child = parent.getChild((SetRelationDefinition<C,S>)r, childName);
+ }
ManagedObjectDefinition<?, ?> cd = child.getManagedObjectDefinition();
@@ -1051,13 +1191,18 @@
continue;
}
- children.add(childName);
+ if (r instanceof InstantiableRelationDefinition) {
+ children.put(childName, childName);
+ } else {
+ // For sets the RDN is the type string, the ufn is more friendly.
+ children.put(cd.getUserFriendlyName().toString(), childName);
+ }
} catch (DefinitionDecodingException e) {
// Add it anyway: maybe the user is trying to fix the problem.
- children.add(childName);
+ children.put(childName, childName);
} catch (ManagedObjectDecodingException e) {
// Add it anyway: maybe the user is trying to fix the problem.
- children.add(childName);
+ children.put(childName, childName);
} catch (ManagedObjectNotFoundException e) {
// Skip it - the managed object has been concurrently removed.
}
@@ -1075,7 +1220,7 @@
// Only one option available so confirm that the user wishes to
// access it.
Message msg = INFO_DSCFG_FINDER_PROMPT_SINGLE.get(
- d.getUserFriendlyName(), children.first());
+ d.getUserFriendlyName(), children.firstKey());
if (app.confirmAction(msg, true)) {
try
{
@@ -1083,7 +1228,18 @@
StringArgument arg = new StringArgument(argName, null, argName, false,
true, INFO_NAME_PLACEHOLDER.get(),
INFO_DSCFG_DESCRIPTION_NAME_CREATE.get(d.getUserFriendlyName()));
- arg.addValue(children.first());
+ if (r instanceof InstantiableRelationDefinition) {
+ arg.addValue(children.get(children.firstKey()));
+ } else {
+ // Set relation: need the short type name.
+ String longName = children.firstKey();
+ try {
+ AbstractManagedObjectDefinition<?,?> cd = d.getChild(longName);
+ arg.addValue(getShortTypeName(r.getChildDefinition(), cd));
+ } catch (IllegalArgumentException e) {
+ arg.addValue(children.get(children.firstKey()));
+ }
+ }
getCommandBuilder().addArgument(arg);
}
catch (Throwable t)
@@ -1091,7 +1247,7 @@
// Bug
new RuntimeException("Unexpected exception: "+t, t);
}
- return MenuResult.success(children.first());
+ return MenuResult.success(children.get(children.firstKey()));
} else {
return MenuResult.cancel();
}
@@ -1103,9 +1259,9 @@
builder.setPrompt(INFO_DSCFG_FINDER_PROMPT_MANY.get(d
.getUserFriendlyName()));
- for (String child : children) {
- Message option = Message.raw("%s", child);
- builder.addNumberedOption(option, MenuResult.success(child));
+ for (Map.Entry<String, String> child : children.entrySet()) {
+ Message option = Message.raw("%s", child.getKey());
+ builder.addNumberedOption(option, MenuResult.success(child.getValue()));
}
if (app.isMenuDrivenMode()) {
@@ -1121,7 +1277,18 @@
StringArgument arg = new StringArgument(argName, null, argName, false,
true, INFO_NAME_PLACEHOLDER.get(),
INFO_DSCFG_DESCRIPTION_NAME_CREATE.get(d.getUserFriendlyName()));
- arg.addValue(result.getValue());
+ if (r instanceof InstantiableRelationDefinition) {
+ arg.addValue(result.getValue());
+ } else {
+ // Set relation: need the short type name.
+ String longName = result.getValue();
+ try {
+ AbstractManagedObjectDefinition<?, ?> cd = d.getChild(longName);
+ arg.addValue(getShortTypeName(r.getChildDefinition(), cd));
+ } catch (IllegalArgumentException e) {
+ arg.addValue(children.get(result.getValue()));
+ }
+ }
getCommandBuilder().addArgument(arg);
}
catch (Throwable t)
@@ -1248,4 +1415,131 @@
}
return value;
}
+
+
+
+ /**
+ * Returns a mapping of subordinate managed object type argument
+ * values to their corresponding managed object definitions for the
+ * provided managed object definition.
+ *
+ * @param <C>
+ * The type of client configuration.
+ * @param <S>
+ * The type of server configuration.
+ * @param d
+ * The managed object definition.
+ * @return A mapping of managed object type argument values to their
+ * corresponding managed object definitions.
+ */
+ @SuppressWarnings("unchecked")
+ protected static <C extends ConfigurationClient, S extends Configuration>
+ SortedMap<String, ManagedObjectDefinition<? extends C, ? extends S>>
+ getSubTypes(AbstractManagedObjectDefinition<C, S> d) {
+ SortedMap<String, ManagedObjectDefinition<? extends C, ? extends S>> map;
+ map =
+ new TreeMap<String, ManagedObjectDefinition<? extends C, ? extends S>>();
+
+ // If the top-level definition is instantiable, we use the value
+ // "generic" or "custom".
+ if (!d.hasOption(ManagedObjectOption.HIDDEN)) {
+ if (d instanceof ManagedObjectDefinition) {
+ ManagedObjectDefinition<? extends C, ? extends S> mod =
+ (ManagedObjectDefinition<? extends C, ? extends S>) d;
+ map.put(getShortTypeName(d, mod), mod);
+ }
+ }
+
+ // Process its sub-definitions.
+ for (AbstractManagedObjectDefinition<? extends C, ? extends S> c : d
+ .getAllChildren()) {
+ if (d.hasOption(ManagedObjectOption.HIDDEN)) {
+ continue;
+ }
+
+ if (c instanceof ManagedObjectDefinition) {
+ ManagedObjectDefinition<? extends C, ? extends S> mod =
+ (ManagedObjectDefinition<? extends C, ? extends S>) c;
+ map.put(getShortTypeName(d, mod), mod);
+ }
+ }
+
+ return map;
+ }
+
+
+
+ /**
+ * Returns the type short name for a child managed object definition.
+ *
+ * @param <C>
+ * The type of client configuration.
+ * @param <S>
+ * The type of server configuration.
+ * @param d
+ * The top level parent definition.
+ * @param c
+ * The child definition.
+ * @return The type short name.
+ */
+ protected static <C extends ConfigurationClient, S extends Configuration>
+ String getShortTypeName(
+ AbstractManagedObjectDefinition<C,S> d,
+ AbstractManagedObjectDefinition<?, ?> c) {
+ if (c == d) {
+ // This is the top-level definition, so use the value "generic" or
+ // "custom".
+ if (CLIProfile.getInstance().isForCustomization(c)) {
+ return DSConfig.CUSTOM_TYPE;
+ } else {
+ return DSConfig.GENERIC_TYPE;
+ }
+ } else {
+ // It's a child definition.
+ String suffix = "-" + d.getName();
+
+ // For the type name we shorten it, if possible, by stripping
+ // off the trailing part of the name which matches the
+ // base-type.
+ String name = c.getName();
+ if (name.endsWith(suffix)) {
+ name = name.substring(0, name.length() - suffix.length());
+ }
+
+ // If this type is intended for customization, prefix it with
+ // "custom".
+ if (CLIProfile.getInstance().isForCustomization(c)) {
+ name = String.format("%s-%s", DSConfig.CUSTOM_TYPE, name);
+ }
+
+ return name;
+ }
+ }
+
+
+
+ /**
+ * Returns a usage string representing the list of possible types for
+ * the provided managed object definition.
+ *
+ * @param d
+ * The managed object definition.
+ * @return A usage string representing the list of possible types for
+ * the provided managed object definition.
+ */
+ protected static String getSubTypesUsage(
+ AbstractManagedObjectDefinition<?, ?> d) {
+ // Build the -t option usage.
+ SortedMap<String, ?> types = getSubTypes(d);
+ StringBuilder builder = new StringBuilder();
+ boolean isFirst = true;
+ for (String s : types.keySet()) {
+ if (!isFirst) {
+ builder.append(" | ");
+ }
+ builder.append(s);
+ isFirst = false;
+ }
+ return builder.toString();
+ }
}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandlerFactory.java b/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandlerFactory.java
index 202bbf9..20d5df9 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandlerFactory.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandlerFactory.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2009 Sun Microsystems, Inc.
*/
package org.opends.server.tools.dsconfig;
@@ -40,6 +40,7 @@
import org.opends.server.admin.RelationDefinition;
import org.opends.server.admin.RelationDefinitionVisitor;
import org.opends.server.admin.RelationOption;
+import org.opends.server.admin.SetRelationDefinition;
import org.opends.server.admin.SingletonRelationDefinition;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.SubCommandArgumentParser;
@@ -115,6 +116,32 @@
* {@inheritDoc}
*/
public <C extends ConfigurationClient, S extends Configuration>
+ Void visitSet(
+ SetRelationDefinition<C, S> rd, ManagedObjectPath<?, ?> p) {
+ try {
+ // Create the sub-commands.
+ createHandlers.add(CreateSubCommandHandler.create(parser, p, rd));
+ deleteHandlers.add(DeleteSubCommandHandler.create(parser, p, rd));
+ listHandlers.add(ListSubCommandHandler.create(parser, p, rd));
+ getPropHandlers.add(GetPropSubCommandHandler.create(parser, p, rd));
+ setPropHandlers.add(SetPropSubCommandHandler.create(parser, p, rd));
+
+ // Process the referenced managed object definition and its
+ // sub-types.
+ processRelation(p, rd);
+ } catch (ArgumentException e) {
+ exception = e;
+ }
+
+ return null;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
Void visitSingleton(
SingletonRelationDefinition<C, S> rd, ManagedObjectPath<?, ?> p) {
try {
@@ -135,36 +162,36 @@
}
// The set of all available sub-commands.
- private SortedSet<SubCommandHandler> allHandlers =
+ private final SortedSet<SubCommandHandler> allHandlers =
new TreeSet<SubCommandHandler>();
// The set of create-xxx available sub-commands.
- private SortedSet<CreateSubCommandHandler<?, ?>> createHandlers =
+ private final SortedSet<CreateSubCommandHandler<?, ?>> createHandlers =
new TreeSet<CreateSubCommandHandler<?, ?>>();
// The set of delete-xxx available sub-commands.
- private SortedSet<DeleteSubCommandHandler> deleteHandlers =
+ private final SortedSet<DeleteSubCommandHandler> deleteHandlers =
new TreeSet<DeleteSubCommandHandler>();
// Any exception that occurred whilst creating the sub-commands.
private ArgumentException exception = null;
// The set of get-xxx-prop available sub-commands.
- private SortedSet<GetPropSubCommandHandler> getPropHandlers =
+ private final SortedSet<GetPropSubCommandHandler> getPropHandlers =
new TreeSet<GetPropSubCommandHandler>();
// The help sub-command handler.
private HelpSubCommandHandler helpHandler = null;
// The set of list-xxx available sub-commands.
- private SortedSet<ListSubCommandHandler> listHandlers =
+ private final SortedSet<ListSubCommandHandler> listHandlers =
new TreeSet<ListSubCommandHandler>();
// The sub-command argument parser.
private final SubCommandArgumentParser parser;
// The set of set-xxx-prop available sub-commands.
- private SortedSet<SetPropSubCommandHandler> setPropHandlers =
+ private final SortedSet<SetPropSubCommandHandler> setPropHandlers =
new TreeSet<SetPropSubCommandHandler>();
// The relation visitor.
@@ -327,6 +354,27 @@
+ // Process a set relation.
+ private <C extends ConfigurationClient, S extends Configuration>
+ void processRelation(
+ ManagedObjectPath<?, ?> path, SetRelationDefinition<C, S> r) {
+ AbstractManagedObjectDefinition<C, S> d = r.getChildDefinition();
+
+ // Process all relations associated directly with this
+ // definition.
+ helpHandler.registerManagedObjectDefinition(d);
+ processPath(path.child(r, d));
+
+ // Now process relations associated with derived definitions.
+ for (AbstractManagedObjectDefinition<? extends C, ? extends S> c : d
+ .getAllChildren()) {
+ helpHandler.registerManagedObjectDefinition(c);
+ processPath(path.child(r, c));
+ }
+ }
+
+
+
// Process a singleton relation.
private <C extends ConfigurationClient, S extends Configuration>
void processRelation(
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java
index e837e7e..b7939d1 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
@@ -99,7 +99,7 @@
* {@inheritDoc}
*/
@Override
- public String getInstantiableRelationChildRDNType(
+ public String getRelationChildRDNType(
InstantiableRelationDefinition<?, ?> r) {
if (r == TestCfg.getTestOneToManyParentRelationDefinition()
|| r == TestParentCfgDefn.getInstance()
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/ANDConnectionCriteriaTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/ANDConnectionCriteriaTest.java
new file mode 100644
index 0000000..aa48391
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/ANDConnectionCriteriaTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.opends.server.DirectoryServerTestCase;
+import org.opends.server.TestCaseUtils;
+import org.opends.server.api.ClientConnection;
+import org.opends.server.protocols.internal.InternalClientConnection;
+import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.DN;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Unit tests for ANDConnectionCriteria.
+ */
+public class ANDConnectionCriteriaTest extends DirectoryServerTestCase
+{
+ /**
+ * Sets up the environment for performing the tests in this suite.
+ *
+ * @throws Exception
+ * if the environment could not be set up.
+ */
+ @BeforeClass
+ public void setUp() throws Exception
+ {
+ TestCaseUtils.startServer();
+ }
+
+
+
+ /**
+ * Returns test data for the following test cases.
+ *
+ * @return The test data for the following test cases.
+ */
+ @DataProvider(name = "testData")
+ public Object[][] createTestData()
+ {
+ return new Object[][] {
+ { Arrays.<ConnectionCriteria> asList(), true },
+ { Arrays.asList(ConnectionCriteria.TRUE), true },
+ {
+ Arrays.asList(ConnectionCriteria.TRUE,
+ ConnectionCriteria.TRUE), true },
+ { Arrays.asList(ConnectionCriteria.FALSE), false },
+ {
+ Arrays.asList(ConnectionCriteria.TRUE,
+ ConnectionCriteria.FALSE), false },
+ {
+ Arrays.asList(ConnectionCriteria.FALSE,
+ ConnectionCriteria.TRUE), false },
+ {
+ Arrays.asList(ConnectionCriteria.FALSE,
+ ConnectionCriteria.FALSE), false }, };
+ }
+
+
+
+ /**
+ * Tests the matches method.
+ *
+ * @param subCriteria
+ * The sub criteria.
+ * @param expectedResult
+ * The expected result.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @Test(dataProvider = "testData")
+ public void testMatches(Collection<ConnectionCriteria> subCriteria,
+ boolean expectedResult) throws Exception
+ {
+ ANDConnectionCriteria criteria =
+ new ANDConnectionCriteria(subCriteria);
+ ClientConnection connection =
+ new InternalClientConnection(DN.NULL_DN);
+ Assert.assertEquals(criteria.matches(connection), expectedResult);
+ }
+
+
+
+ /**
+ * Tests the willMatchAfterBind method.
+ *
+ * @param subCriteria
+ * The sub criteria.
+ * @param expectedResult
+ * The expected result.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @Test(dataProvider = "testData")
+ public void testWillMatchAfterBind(
+ Collection<ConnectionCriteria> subCriteria, boolean expectedResult)
+ throws Exception
+ {
+ ANDConnectionCriteria criteria =
+ new ANDConnectionCriteria(subCriteria);
+ ClientConnection connection =
+ new InternalClientConnection(DN.NULL_DN);
+ Assert.assertEquals(criteria.willMatchAfterBind(connection,
+ DN.NULL_DN, AuthenticationType.SIMPLE, false), expectedResult);
+ }
+
+}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/AuthMethodConnectionCriteriaTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/AuthMethodConnectionCriteriaTest.java
new file mode 100644
index 0000000..501439c
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/AuthMethodConnectionCriteriaTest.java
@@ -0,0 +1,202 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+
+import org.opends.server.DirectoryServerTestCase;
+import org.opends.server.TestCaseUtils;
+import org.opends.server.admin.std.meta.NetworkGroupCfgDefn.AllowedAuthMethod;
+import org.opends.server.api.ClientConnection;
+import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.DN;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Unit tests for AuthMethodConnectionCriteria.
+ */
+public class AuthMethodConnectionCriteriaTest extends
+ DirectoryServerTestCase
+{
+
+ /**
+ * Sets up the environment for performing the tests in this suite.
+ *
+ * @throws Exception
+ * if the environment could not be set up.
+ */
+ @BeforeClass
+ public void setUp() throws Exception
+ {
+ TestCaseUtils.startServer();
+ }
+
+
+
+ /**
+ * Returns test data for the following test cases.
+ *
+ * @return The test data for the following test cases.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @DataProvider(name = "testData")
+ public Object[][] createTestData() throws Exception
+ {
+ return new Object[][] {
+ { AllowedAuthMethod.ANONYMOUS,
+ Collections.singleton(AllowedAuthMethod.ANONYMOUS), true },
+ { AllowedAuthMethod.ANONYMOUS,
+ Collections.singleton(AllowedAuthMethod.SIMPLE), false },
+ { AllowedAuthMethod.ANONYMOUS,
+ Collections.singleton(AllowedAuthMethod.SASL), false },
+ { AllowedAuthMethod.SIMPLE,
+ Collections.singleton(AllowedAuthMethod.ANONYMOUS), false },
+ { AllowedAuthMethod.SIMPLE,
+ Collections.singleton(AllowedAuthMethod.SIMPLE), true },
+ { AllowedAuthMethod.SIMPLE,
+ Collections.singleton(AllowedAuthMethod.SASL), false },
+ { AllowedAuthMethod.SASL,
+ Collections.singleton(AllowedAuthMethod.ANONYMOUS), false },
+ { AllowedAuthMethod.SASL,
+ Collections.singleton(AllowedAuthMethod.SIMPLE), false },
+ { AllowedAuthMethod.SASL,
+ Collections.singleton(AllowedAuthMethod.SASL), true },
+ { AllowedAuthMethod.ANONYMOUS,
+ EnumSet.noneOf(AllowedAuthMethod.class), false },
+ { AllowedAuthMethod.SIMPLE,
+ EnumSet.noneOf(AllowedAuthMethod.class), false },
+ { AllowedAuthMethod.SASL,
+ EnumSet.noneOf(AllowedAuthMethod.class), false },
+ { AllowedAuthMethod.ANONYMOUS,
+ EnumSet.allOf(AllowedAuthMethod.class), true },
+ { AllowedAuthMethod.SIMPLE,
+ EnumSet.allOf(AllowedAuthMethod.class), true },
+ { AllowedAuthMethod.SASL,
+ EnumSet.allOf(AllowedAuthMethod.class), true }, };
+ }
+
+
+
+ /**
+ * Tests the matches method.
+ *
+ * @param clientAuthMethod
+ * The client authentication method.
+ * @param allowedAuthMethods
+ * The set of allowed authentication methods.
+ * @param expectedResult
+ * The expected result.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @Test(dataProvider = "testData")
+ public void testMatches(AllowedAuthMethod clientAuthMethod,
+ Collection<AllowedAuthMethod> allowedAuthMethods,
+ boolean expectedResult) throws Exception
+ {
+ DN bindDN;
+
+ if (clientAuthMethod == AllowedAuthMethod.ANONYMOUS)
+ {
+ bindDN = DN.nullDN();
+ }
+ else
+ {
+ bindDN =
+ DN.decode("cn=Directory Manager, cn=Root DNs, cn=config");
+ }
+
+ ClientConnection client =
+ new MockClientConnection(12345, false, bindDN, clientAuthMethod);
+
+ AuthMethodConnectionCriteria criteria =
+ new AuthMethodConnectionCriteria(allowedAuthMethods);
+ Assert.assertEquals(criteria.matches(client), expectedResult);
+ }
+
+
+
+ /**
+ * Tests the willMatchAfterBind method.
+ *
+ * @param clientAuthMethod
+ * The client authentication method.
+ * @param allowedAuthMethods
+ * The set of allowed authentication methods.
+ * @param expectedResult
+ * The expected result.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @Test(dataProvider = "testData")
+ public void testWillMatchAfterBind(
+ AllowedAuthMethod clientAuthMethod,
+ Collection<AllowedAuthMethod> allowedAuthMethods,
+ boolean expectedResult) throws Exception
+ {
+ ClientConnection client =
+ new MockClientConnection(12345, false, DN.nullDN(),
+ AllowedAuthMethod.ANONYMOUS);
+
+ AuthenticationType authType;
+ DN bindDN;
+
+ switch (clientAuthMethod)
+ {
+ case ANONYMOUS:
+ authType = null;
+ bindDN = DN.nullDN();
+ break;
+ case SIMPLE:
+ authType = AuthenticationType.SIMPLE;
+ bindDN =
+ DN.decode("cn=Directory Manager, cn=Root DNs, cn=config");
+ break;
+ default: // SASL
+ authType = AuthenticationType.SASL;
+ bindDN =
+ DN.decode("cn=Directory Manager, cn=Root DNs, cn=config");
+ break;
+ }
+
+ AuthMethodConnectionCriteria criteria =
+ new AuthMethodConnectionCriteria(allowedAuthMethods);
+ Assert.assertEquals(criteria.willMatchAfterBind(client, bindDN,
+ authType, false), expectedResult);
+ }
+
+}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/BindDNConnectionCriteriaTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/BindDNConnectionCriteriaTest.java
new file mode 100644
index 0000000..b8b0afa
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/BindDNConnectionCriteriaTest.java
@@ -0,0 +1,156 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opends.server.DirectoryServerTestCase;
+import org.opends.server.TestCaseUtils;
+import org.opends.server.admin.std.meta.NetworkGroupCfgDefn.AllowedAuthMethod;
+import org.opends.server.api.ClientConnection;
+import org.opends.server.authorization.dseecompat.PatternDN;
+import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.DN;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Unit tests for BindDNConnectionCriteria.
+ */
+public class BindDNConnectionCriteriaTest extends
+ DirectoryServerTestCase
+{
+
+ /**
+ * Sets up the environment for performing the tests in this suite.
+ *
+ * @throws Exception
+ * if the environment could not be set up.
+ */
+ @BeforeClass
+ public void setUp() throws Exception
+ {
+ TestCaseUtils.startServer();
+ }
+
+
+
+ /**
+ * Returns test data for the following test cases.
+ *
+ * @return The test data for the following test cases.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @DataProvider(name = "testData")
+ public Object[][] createTestData() throws Exception
+ {
+ DN anonymousUser = DN.nullDN();
+ DN rootUser =
+ DN.decode("cn=Directory Manager, cn=Root DNs, cn=config");
+ PatternDN rootMatch = PatternDN.decode("*, cn=Root DNs, cn=config");
+ PatternDN rootNoMatch =
+ PatternDN.decode("cn=Dirx*, cn=Root DNs, cn=config");
+
+ return new Object[][] {
+ { anonymousUser, Collections.<PatternDN> emptySet(), false },
+ { rootUser, Collections.<PatternDN> emptySet(), false },
+ { anonymousUser, Collections.singleton(rootMatch), false },
+ { rootUser, Collections.singleton(rootMatch), true },
+ { anonymousUser, Collections.singleton(rootNoMatch), false },
+ { rootUser, Collections.singleton(rootNoMatch), false },
+ { anonymousUser, Arrays.asList(rootMatch, rootNoMatch), false },
+ { rootUser, Arrays.asList(rootMatch, rootNoMatch), true }, };
+ }
+
+
+
+ /**
+ * Tests the matches method.
+ *
+ * @param clientBindDN
+ * The client bind DN.
+ * @param allowedDNPatterns
+ * The set of allowed DN patterns.
+ * @param expectedResult
+ * The expected result.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @Test(dataProvider = "testData")
+ public void testMatches(DN clientBindDN,
+ Collection<PatternDN> allowedDNPatterns, boolean expectedResult)
+ throws Exception
+ {
+ ClientConnection client =
+ new MockClientConnection(12345, false, clientBindDN,
+ AllowedAuthMethod.SIMPLE);
+
+ BindDNConnectionCriteria criteria =
+ BindDNConnectionCriteria.create(allowedDNPatterns);
+ Assert.assertEquals(criteria.matches(client), expectedResult);
+ }
+
+
+
+ /**
+ * Tests the willMatchAfterBind method.
+ *
+ * @param clientBindDN
+ * The client bind DN.
+ * @param allowedDNPatterns
+ * The set of allowed DN patterns.
+ * @param expectedResult
+ * The expected result.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @Test(dataProvider = "testData")
+ public void testWillMatchAfterBind(DN clientBindDN,
+ Collection<PatternDN> allowedDNPatterns, boolean expectedResult)
+ throws Exception
+ {
+ ClientConnection client =
+ new MockClientConnection(12345, false, DN.nullDN(),
+ AllowedAuthMethod.ANONYMOUS);
+
+ BindDNConnectionCriteria criteria =
+ BindDNConnectionCriteria.create(allowedDNPatterns);
+ Assert
+ .assertEquals(criteria.willMatchAfterBind(client, clientBindDN,
+ AuthenticationType.SIMPLE, false), expectedResult);
+ }
+
+}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/IPConnectionCriteriaTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/IPConnectionCriteriaTest.java
new file mode 100644
index 0000000..0cd08c0
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/IPConnectionCriteriaTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opends.server.DirectoryServerTestCase;
+import org.opends.server.TestCaseUtils;
+import org.opends.server.admin.std.meta.NetworkGroupCfgDefn.AllowedAuthMethod;
+import org.opends.server.api.ClientConnection;
+import org.opends.server.types.AddressMask;
+import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.DN;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Unit tests for IPConnectionCriteria.
+ */
+public class IPConnectionCriteriaTest extends DirectoryServerTestCase
+{
+
+ /**
+ * Sets up the environment for performing the tests in this suite.
+ *
+ * @throws Exception
+ * if the environment could not be set up.
+ */
+ @BeforeClass
+ public void setUp() throws Exception
+ {
+ TestCaseUtils.startServer();
+ }
+
+
+
+ /**
+ * Returns test data for the following test cases.
+ *
+ * @return The test data for the following test cases.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @DataProvider(name = "testData")
+ public Object[][] createTestData() throws Exception
+ {
+ AddressMask matchAnything = AddressMask.decode("*.*.*.*");
+ AddressMask matchNothing = AddressMask.decode("0.0.0.0");
+ ClientConnection client =
+ new MockClientConnection(12345, false, DN.nullDN(),
+ AllowedAuthMethod.ANONYMOUS);
+
+ Collection<AddressMask> emptyMasks = Collections.emptySet();
+
+ return new Object[][] {
+ { emptyMasks, emptyMasks, client, true },
+
+ { Collections.singleton(matchAnything), emptyMasks, client,
+ true },
+ { emptyMasks, Collections.singleton(matchAnything), client,
+ false },
+ { Collections.singleton(matchAnything),
+ Collections.singleton(matchAnything), client, false },
+
+ { Collections.singleton(matchNothing), emptyMasks, client,
+ false },
+ { emptyMasks, Collections.singleton(matchNothing), client, true },
+ { Collections.singleton(matchNothing),
+ Collections.singleton(matchNothing), client, false }, };
+ }
+
+
+
+ /**
+ * Tests the matches method.
+ *
+ * @param allowedClients
+ * The set of allowed client address masks.
+ * @param deniedClients
+ * The set of denied client address masks.
+ * @param client
+ * The test client.
+ * @param expectedResult
+ * The expected result.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @Test(dataProvider = "testData")
+ public void testMatches(Collection<AddressMask> allowedClients,
+ Collection<AddressMask> deniedClients, ClientConnection client,
+ boolean expectedResult) throws Exception
+ {
+ IPConnectionCriteria criteria =
+ new IPConnectionCriteria(allowedClients, deniedClients);
+ Assert.assertEquals(criteria.matches(client), expectedResult);
+ }
+
+
+
+ /**
+ * Tests the willMatchAfterBind method.
+ *
+ * @param allowedClients
+ * The set of allowed client address masks.
+ * @param deniedClients
+ * The set of denied client address masks.
+ * @param client
+ * The test client.
+ * @param expectedResult
+ * The expected result.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @Test(dataProvider = "testData")
+ public void testWillMatchAfterBind(
+ Collection<AddressMask> allowedClients,
+ Collection<AddressMask> deniedClients, ClientConnection client,
+ boolean expectedResult) throws Exception
+ {
+ IPConnectionCriteria criteria =
+ new IPConnectionCriteria(allowedClients, deniedClients);
+ Assert.assertEquals(criteria.willMatchAfterBind(client, DN.NULL_DN,
+ AuthenticationType.SIMPLE, false), expectedResult);
+ }
+
+}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockClientConnection.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockClientConnection.java
new file mode 100644
index 0000000..63a9776
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockClientConnection.java
@@ -0,0 +1,374 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.util.Collection;
+
+import org.opends.messages.Message;
+import org.opends.server.admin.std.meta.NetworkGroupCfgDefn.AllowedAuthMethod;
+import org.opends.server.api.ClientConnection;
+import org.opends.server.api.ConnectionHandler;
+import org.opends.server.api.ConnectionSecurityProvider;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.SearchOperation;
+import org.opends.server.protocols.asn1.ASN1OctetString;
+import org.opends.server.types.AuthenticationInfo;
+import org.opends.server.types.ByteString;
+import org.opends.server.types.CancelRequest;
+import org.opends.server.types.CancelResult;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.DisconnectReason;
+import org.opends.server.types.Entry;
+import org.opends.server.types.IntermediateResponse;
+import org.opends.server.types.Operation;
+import org.opends.server.types.SearchResultEntry;
+import org.opends.server.types.SearchResultReference;
+
+
+
+/**
+ * A mock connection for connection criteria testing.
+ */
+public final class MockClientConnection extends ClientConnection
+{
+ private final int clientPort;
+
+ private final boolean isSecure;
+
+ private final AuthenticationInfo authInfo;
+
+
+
+ /**
+ * Creates a new mock client connection.
+ *
+ * @param clientPort
+ * The client port.
+ * @param isSecure
+ * Is the client using a secure connection.
+ * @param bindDN
+ * The client bind DN.
+ * @param authMethod
+ * The client authentication mathod.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ public MockClientConnection(int clientPort, boolean isSecure,
+ DN bindDN, AllowedAuthMethod authMethod) throws Exception
+ {
+ this.clientPort = clientPort;
+ this.isSecure = isSecure;
+
+ switch (authMethod)
+ {
+ case ANONYMOUS:
+ this.authInfo = new AuthenticationInfo();
+ break;
+ case SIMPLE:
+ Entry simpleUser = DirectoryServer.getEntry(bindDN);
+ ByteString password = new ASN1OctetString();
+ password.setValue("password");
+ this.authInfo =
+ new AuthenticationInfo(simpleUser, password, true);
+ break;
+ default: // SASL
+ Entry saslUser = DirectoryServer.getEntry(bindDN);
+ this.authInfo =
+ new AuthenticationInfo(saslUser, "external", true);
+ break;
+ }
+ }
+
+
+
+ @Override
+ public AuthenticationInfo getAuthenticationInfo()
+ {
+ return authInfo;
+ }
+
+
+
+ @Override
+ public void cancelAllOperations(CancelRequest cancelRequest)
+ {
+ // Stub.
+ }
+
+
+
+ @Override
+ public void cancelAllOperationsExcept(CancelRequest cancelRequest,
+ int messageID)
+ {
+ // Stub.
+ }
+
+
+
+ @Override
+ public CancelResult cancelOperation(int messageID,
+ CancelRequest cancelRequest)
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ @Override
+ public void disconnect(DisconnectReason disconnectReason,
+ boolean sendNotification, Message message)
+ {
+ // Stub.
+ }
+
+
+
+ @Override
+ public String getClientAddress()
+ {
+ return "127.0.0.1";
+ }
+
+
+
+ @Override
+ public int getClientPort()
+ {
+ return clientPort;
+ }
+
+
+
+ @Override
+ public ConnectionHandler<?> getConnectionHandler()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ @Override
+ public long getConnectionID()
+ {
+ // Stub.
+ return 0;
+ }
+
+
+
+ @Override
+ public ConnectionSecurityProvider getConnectionSecurityProvider()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ @Override
+ public InetAddress getLocalAddress()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ @Override
+ public String getMonitorSummary()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ @Override
+ public long getNumberOfOperations()
+ {
+ // Stub.
+ return 0;
+ }
+
+
+
+ @Override
+ public Operation getOperationInProgress(int messageID)
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ @Override
+ public Collection<Operation> getOperationsInProgress()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ @Override
+ public String getProtocol()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ @Override
+ public InetAddress getRemoteAddress()
+ {
+ try
+ {
+ return InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 });
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+
+ @Override
+ public String getSecurityMechanism()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ @Override
+ public String getServerAddress()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ @Override
+ public int getServerPort()
+ {
+ // Stub.
+ return 0;
+ }
+
+
+
+ @Override
+ public boolean isSecure()
+ {
+ return isSecure;
+ }
+
+
+
+ @Override
+ public boolean processDataRead(ByteBuffer buffer)
+ {
+ // Stub.
+ return false;
+ }
+
+
+
+ @Override
+ public boolean removeOperationInProgress(int messageID)
+ {
+ // Stub.
+ return false;
+ }
+
+
+
+ @Override
+ protected boolean sendIntermediateResponseMessage(
+ IntermediateResponse intermediateResponse)
+ {
+ // Stub.
+ return false;
+ }
+
+
+
+ @Override
+ public void sendResponse(Operation operation)
+ {
+ // Stub.
+ }
+
+
+
+ @Override
+ public void sendSearchEntry(SearchOperation searchOperation,
+ SearchResultEntry searchEntry) throws DirectoryException
+ {
+ // Stub.
+ }
+
+
+
+ @Override
+ public boolean sendSearchReference(SearchOperation searchOperation,
+ SearchResultReference searchReference) throws DirectoryException
+ {
+ // Stub.
+ return false;
+ }
+
+
+
+ @Override
+ public void setConnectionSecurityProvider(
+ ConnectionSecurityProvider securityProvider)
+ {
+ // Stub.
+ }
+
+
+
+ @Override
+ public void toString(StringBuilder buffer)
+ {
+ // Stub.
+ }
+}
\ No newline at end of file
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockRequestFilteringQOSPolicyCfg.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockRequestFilteringQOSPolicyCfg.java
new file mode 100644
index 0000000..ea5f73b
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockRequestFilteringQOSPolicyCfg.java
@@ -0,0 +1,189 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.core.networkgroups;
+
+
+
+import java.util.Collections;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.std.meta.RequestFilteringQOSPolicyCfgDefn.AllowedOperations;
+import org.opends.server.admin.std.meta.RequestFilteringQOSPolicyCfgDefn.AllowedSearchScopes;
+import org.opends.server.admin.std.server.QOSPolicyCfg;
+import org.opends.server.admin.std.server.RequestFilteringQOSPolicyCfg;
+import org.opends.server.types.DN;
+
+
+
+/**
+ * Stub configuration used in tests.
+ */
+public abstract class MockRequestFilteringQOSPolicyCfg implements
+ RequestFilteringQOSPolicyCfg
+{
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void addRequestFilteringChangeListener(
+ ConfigurationChangeListener<RequestFilteringQOSPolicyCfg> listener)
+ {
+ // Stub.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final Class<? extends RequestFilteringQOSPolicyCfg> configurationClass()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getJavaClass()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void removeRequestFilteringChangeListener(
+ ConfigurationChangeListener<RequestFilteringQOSPolicyCfg> listener)
+ {
+ // Stub.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void addChangeListener(
+ ConfigurationChangeListener<QOSPolicyCfg> listener)
+ {
+ // Stub.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void removeChangeListener(
+ ConfigurationChangeListener<QOSPolicyCfg> listener)
+ {
+ // Stub.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final DN dn()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public SortedSet<String> getAllowedAttributes()
+ {
+ return Collections.unmodifiableSortedSet(new TreeSet<String>());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public SortedSet<AllowedOperations> getAllowedOperations()
+ {
+ return Collections
+ .unmodifiableSortedSet(new TreeSet<AllowedOperations>());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public SortedSet<AllowedSearchScopes> getAllowedSearchScopes()
+ {
+ return Collections
+ .unmodifiableSortedSet(new TreeSet<AllowedSearchScopes>());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public SortedSet<DN> getAllowedSubtrees()
+ {
+ return Collections.unmodifiableSortedSet(new TreeSet<DN>());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public SortedSet<String> getProhibitedAttributes()
+ {
+ return Collections.unmodifiableSortedSet(new TreeSet<String>());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public SortedSet<DN> getProhibitedSubtrees()
+ {
+ return Collections.unmodifiableSortedSet(new TreeSet<DN>());
+ }
+
+}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockResourceLimitsQOSPolicyCfg.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockResourceLimitsQOSPolicyCfg.java
new file mode 100644
index 0000000..3485165
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockResourceLimitsQOSPolicyCfg.java
@@ -0,0 +1,191 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.core.networkgroups;
+
+
+
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.std.server.QOSPolicyCfg;
+import org.opends.server.admin.std.server.ResourceLimitsQOSPolicyCfg;
+import org.opends.server.types.DN;
+
+
+
+/**
+ * Stub configuration used in tests.
+ */
+public abstract class MockResourceLimitsQOSPolicyCfg implements
+ ResourceLimitsQOSPolicyCfg
+{
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void addChangeListener(
+ ConfigurationChangeListener<QOSPolicyCfg> listener)
+ {
+ // Stub.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void removeChangeListener(
+ ConfigurationChangeListener<QOSPolicyCfg> listener)
+ {
+ // Stub.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final DN dn()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void addResourceLimitsChangeListener(
+ ConfigurationChangeListener<ResourceLimitsQOSPolicyCfg> listener)
+ {
+ // Stub.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final Class<? extends ResourceLimitsQOSPolicyCfg> configurationClass()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void removeResourceLimitsChangeListener(
+ ConfigurationChangeListener<ResourceLimitsQOSPolicyCfg> listener)
+ {
+ // Stub.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getJavaClass()
+ {
+ // Stub.
+ return null;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getMaxConcurrentOpsPerConnection()
+ {
+ return 0;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getMaxConnections()
+ {
+ return 0;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getMaxConnectionsFromSameIP()
+ {
+ return 0;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getMaxOpsPerConnection()
+ {
+ return 0;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getMinSubstringLength()
+ {
+ return 0;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public Integer getSizeLimit()
+ {
+ return null;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public Long getTimeLimit()
+ {
+ return null;
+ }
+
+}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
index bb043dd..ae3775b 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
@@ -22,22 +22,24 @@
* CDDL HEADER END
*
*
- * Copyright 2006-2008 Sun Microsystems, Inc.
+ * Copyright 2006-2009 Sun Microsystems, Inc.
*/
package org.opends.server.core.networkgroups;
-import static org.opends.messages.CoreMessages.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.opends.server.config.ConfigConstants.DN_BACKEND_BASE;
import java.util.ArrayList;
+import java.util.Collections;
+
+import static org.opends.messages.CoreMessages.*;
import org.opends.server.TestCaseUtils;
import org.opends.server.DirectoryServerTestCase;
-import org.opends.server.admin.std.meta.NetworkGroupCriteriaCfgDefn.AllowedAuthMethod;
+import org.opends.server.admin.std.meta.NetworkGroupCfgDefn.AllowedAuthMethod;
import org.opends.server.api.ClientConnection;
import org.opends.server.core.*;
import org.opends.server.extensions.NullConnectionSecurityProvider;
@@ -51,6 +53,7 @@
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
+import org.opends.server.types.InitializationException;
import org.opends.server.types.Modification;
import org.opends.server.types.ModificationType;
import org.opends.server.types.ResultCode;
@@ -461,7 +464,7 @@
String networkGroupID,
DN workflowBaseDN
)
- throws DirectoryException
+ throws Exception
{
// Create and register the network group with the server.
NetworkGroup networkGroup = new NetworkGroup(networkGroupID);
@@ -474,10 +477,10 @@
{
networkGroup.register();
}
- catch (DirectoryException de)
+ catch (InitializationException e)
{
exceptionRaised = true;
- assertEquals(de.getMessageObject().getDescriptor(),
+ assertEquals(e.getMessageObject().getDescriptor(),
ERR_REGISTER_NETWORK_GROUP_ALREADY_EXISTS);
}
assertEquals(exceptionRaised, true);
@@ -552,7 +555,7 @@
// Dump the default network group
dump(adminNG, "adminNetworkGroup> ");
-
+
// let's get the internal network group -- it should always exist
NetworkGroup internalNG = NetworkGroup.getInternalNetworkGroup();
assertNotNull(internalNG);
@@ -592,7 +595,7 @@
DN subordinate2,
DN subordinate3,
DN unrelatedDN
- ) throws DirectoryException
+ ) throws Exception
{
// The network group identifier is always the same for this test.
String networkGroupID = "Network Group for test2";
@@ -758,55 +761,86 @@
String networkGroupID,
DN workflowBaseDN,
int priority,
- int maxConnections,
- int maxConnectionsFromSameClient,
- int maxOpsPerConn,
- int maxConcurrentOpsPerConn,
- int searchTimeLimit,
- int searchSizeLimit,
- int minSubstringLength
+ final int maxConnections,
+ final int maxConnectionsFromSameClient,
+ final int maxOpsPerConn,
+ final int maxConcurrentOpsPerConn,
+ final int searchTimeLimit,
+ final int searchSizeLimit,
+ final int minSubstringLength
)
- throws DirectoryException
+ throws Exception
{
// Create and register the network group with the server.
- NetworkGroup networkGroup = new NetworkGroup(networkGroupID);
- networkGroup.register();
+ TestCaseUtils.dsconfig(
+ "set-global-configuration-prop",
+ "--set", "workflow-configuration-mode:manual");
- networkGroup.setNetworkGroupPriority(priority);
+ try
+ {
+ TestCaseUtils.dsconfig(
+ "create-network-group",
+ "--group-name", networkGroupID,
+ "--set", "enabled:true",
+ "--set", "priority:" + priority);
- // Create a workflow -- the workflow ID is the string representation
- // of the workflow base DN.
- WorkflowElement<?> nullWE = null;
- WorkflowImpl workflow = new WorkflowImpl(
- workflowBaseDN.toString(), workflowBaseDN, null, nullWE);
+ try
+ {
+ // Ensure that the network group was created ok.
+ NetworkGroup networkGroup = NetworkGroup.getNetworkGroup(networkGroupID);
+ assertNotNull(networkGroup, "The network group does not seem to be registered.");
- // Register the workflow with the network group.
- networkGroup.registerWorkflow(workflow);
+ TestCaseUtils.dsconfig(
+ "create-network-group-qos-policy",
+ "--group-name", networkGroupID,
+ "--type", "resource-limits",
+ "--set", "max-concurrent-ops-per-connection:" + maxConcurrentOpsPerConn,
+ "--set", "max-connections:" + maxConnections,
+ "--set", "max-connections-from-same-ip:" + maxConnectionsFromSameClient,
+ "--set", "max-ops-per-connection:" + maxOpsPerConn,
+ "--set", "min-substring-length:" + minSubstringLength,
+ "--set", "size-limit:" + searchSizeLimit,
+ "--set", "time-limit:" + searchTimeLimit + "s");
- // Create the resource limits
- ResourceLimits limits = new ResourceLimits(null);
- limits.setMaxConnections(maxConnections);
- limits.setMaxConnectionsFromSameIP(maxConnectionsFromSameClient);
- limits.setMaxOpsPerConnection(maxOpsPerConn);
- limits.setMaxConcurrentOpsPerConnection(maxConcurrentOpsPerConn);
- limits.setSearchTimeLimit(searchTimeLimit);
- limits.setSearchSizeLimit(searchSizeLimit);
- limits.setMinSearchSubstringLength(minSubstringLength);
+ // Check that the policy was created.
+ ResourceLimitsPolicy policy = networkGroup.getNetworkGroupQOSPolicy(ResourceLimitsPolicy.class);
+ assertNotNull(policy, "The policy was not registered.");
- // Associate the resource limits to the network group
- networkGroup.setResourceLimits(limits);
+ // Check the resource limits are set properly.
+ assertEquals(policy.getTimeLimit(), searchTimeLimit);
+ assertEquals(policy.getSizeLimit(), searchSizeLimit);
+ assertEquals(policy.getMinSubstring(), minSubstringLength);
- // Check the resource limits
- assertEquals(networkGroup.getSearchDurationLimit(), searchTimeLimit);
- assertEquals(networkGroup.getSearchSizeLimit(), searchSizeLimit);
- assertEquals(networkGroup.getMinSubstring(), minSubstringLength);
+ assertEquals(networkGroup.getTimeLimit(), searchTimeLimit);
+ assertEquals(networkGroup.getSizeLimit(), searchSizeLimit);
+ assertEquals(networkGroup.getMinSubstring(), minSubstringLength);
- // Clean the network group
- networkGroup.deregisterWorkflow(workflow.getWorkflowId());
- networkGroup.deregister();
+ TestCaseUtils.dsconfig(
+ "delete-network-group-qos-policy",
+ "--group-name", networkGroupID,
+ "--policy-type", "resource-limits");
+
+ // Check that the policy was removed.
+ policy = networkGroup.getNetworkGroupQOSPolicy(ResourceLimitsPolicy.class);
+ assertNull(policy, "The policy was not deregistered.");
+ }
+ finally
+ {
+ // The policy will get removed by this as well.
+ TestCaseUtils.dsconfig("delete-network-group", "--group-name",
+ networkGroupID);
+ }
+ }
+ finally
+ {
+ TestCaseUtils.dsconfig(
+ "set-global-configuration-prop",
+ "--set", "workflow-configuration-mode:auto");
+ }
}
+
/**
* Tests the mechanism to attribute a network group to a client connection,
* comparing the priority.
@@ -820,7 +854,7 @@
DN dn2,
int prio2
)
- throws DirectoryException
+ throws Exception
{
// Create and register the network group with the server.
NetworkGroup networkGroup1 = new NetworkGroup(ng1);
@@ -872,39 +906,36 @@
int prio1,
int prio2,
int prio3)
- throws DirectoryException
+ throws Exception
{
// Create a AuthMethodCriteria for anonymous connections
- AuthMethodCriteria authCriteria1 = new AuthMethodCriteria();
- authCriteria1.addAuthMethod(AllowedAuthMethod.ANONYMOUS);
- NetworkGroupCriteria criteria1 = new NetworkGroupCriteria(null);
- criteria1.setAuthMethodCriteria(authCriteria1);
+ AuthMethodConnectionCriteria authCriteria1 =
+ new AuthMethodConnectionCriteria(Collections
+ .singleton(AllowedAuthMethod.ANONYMOUS));
// Create a AuthMethodCriteria for simple bind connections
- AuthMethodCriteria authCriteria2 = new AuthMethodCriteria();
- authCriteria2.addAuthMethod(AllowedAuthMethod.SIMPLE);
- NetworkGroupCriteria criteria2 = new NetworkGroupCriteria(null);
- criteria2.setAuthMethodCriteria(authCriteria2);
+ AuthMethodConnectionCriteria authCriteria2 =
+ new AuthMethodConnectionCriteria(Collections
+ .singleton(AllowedAuthMethod.SIMPLE));
// Create a AuthMethodCriteria for sasl connections
- AuthMethodCriteria authCriteria3 = new AuthMethodCriteria();
- authCriteria3.addAuthMethod(AllowedAuthMethod.SASL);
- NetworkGroupCriteria criteria3 = new NetworkGroupCriteria(null);
- criteria3.setAuthMethodCriteria(authCriteria3);
+ AuthMethodConnectionCriteria authCriteria3 =
+ new AuthMethodConnectionCriteria(Collections
+ .singleton(AllowedAuthMethod.SASL));
// Create and register the network group with the server.
NetworkGroup networkGroup1 = new NetworkGroup("anonymous_group");
networkGroup1.register();
- networkGroup1.setCriteria(criteria1);
+ networkGroup1.setConnectionCriteria(authCriteria1);
networkGroup1.setNetworkGroupPriority(prio1);
NetworkGroup networkGroup2 = new NetworkGroup("simplebind_group");
networkGroup2.register();
- networkGroup2.setCriteria(criteria2);
+ networkGroup2.setConnectionCriteria(authCriteria2);
networkGroup2.setNetworkGroupPriority(prio2);
NetworkGroup networkGroup3 = new NetworkGroup("sasl_group");
networkGroup3.register();
- networkGroup3.setCriteria(criteria3);
+ networkGroup3.setConnectionCriteria(authCriteria3);
networkGroup3.setNetworkGroupPriority(prio3);
// Create a new client connection, with anonymous authentication
@@ -943,18 +974,17 @@
public void testNetworkGroupBindDnCriteria(
String bindDnFilter,
boolean match)
- throws DirectoryException
+ throws Exception
{
// Create a BindDnFilterCriteria
- BindDnCriteria bindCriteria = new BindDnCriteria();
- bindCriteria.addBindDnFilter(bindDnFilter);
- NetworkGroupCriteria criteria = new NetworkGroupCriteria(null);
- criteria.setBindDnCriteria(bindCriteria);
+ BindDNConnectionCriteria bindCriteria =
+ BindDNConnectionCriteria.decode(Collections
+ .singleton(bindDnFilter));
// Create and register the network group with the server.
NetworkGroup networkGroup = new NetworkGroup("bindfilter_group");
networkGroup.register();
- networkGroup.setCriteria(criteria);
+ networkGroup.setConnectionCriteria(bindCriteria);
NetworkGroup defaultNg = NetworkGroup.getDefaultNetworkGroup();
@@ -1000,17 +1030,16 @@
*/
@Test (groups = "virtual")
public void testNetworkGroupSecurityCriteria()
- throws DirectoryException
+ throws Exception
{
// Create a SecurityCriteria
- SecurityCriteria secCriteria = new SecurityCriteria(true);
- NetworkGroupCriteria criteria = new NetworkGroupCriteria(null);
- criteria.setSecurityCriteria(secCriteria);
+ SecurityConnectionCriteria secCriteria =
+ SecurityConnectionCriteria.SECURITY_REQUIRED;
// Create and register the network group with the server.
NetworkGroup networkGroup = new NetworkGroup("secured_group");
networkGroup.register();
- networkGroup.setCriteria(criteria);
+ networkGroup.setConnectionCriteria(secCriteria);
NetworkGroup defaultNg = NetworkGroup.getDefaultNetworkGroup();
@@ -1029,8 +1058,8 @@
assertEquals(ng, defaultNg);
// now change the criteria (security not mandatory)
- secCriteria = new SecurityCriteria(false);
- criteria.setSecurityCriteria(secCriteria);
+ secCriteria = SecurityConnectionCriteria.SECURITY_NOT_REQUIRED;
+ networkGroup.setConnectionCriteria(secCriteria);
// connection1 should match the networkGroup, even though it is not
// secured
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyTest.java
index 80ec06d..3a2b674 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyTest.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/RequestFilteringPolicyTest.java
@@ -22,21 +22,20 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2009 Sun Microsystems, Inc.
*/
package org.opends.server.core.networkgroups;
import java.util.ArrayList;
-import java.util.Set;
+import java.util.Collections;
+import java.util.SortedSet;
import java.util.TreeSet;
import org.opends.messages.Message;
import org.opends.server.DirectoryServerTestCase;
import org.opends.server.TestCaseUtils;
-import org.opends.server.admin.std.meta.
- NetworkGroupRequestFilteringPolicyCfgDefn.AllowedOperations;
-import org.opends.server.admin.std.meta.
- NetworkGroupRequestFilteringPolicyCfgDefn.AllowedSearchScopes;
+import org.opends.server.admin.std.meta.RequestFilteringQOSPolicyCfgDefn.AllowedOperations;
+import org.opends.server.admin.std.meta.RequestFilteringQOSPolicyCfgDefn.AllowedSearchScopes;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPFilter;
@@ -45,7 +44,6 @@
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
-import org.opends.server.types.LDAPException;
import org.opends.server.types.Modification;
import org.opends.server.types.ModificationType;
import org.opends.server.types.OperationType;
@@ -275,6 +273,8 @@
@DataProvider (name = "ComplexSubtreesSet")
public Object[][] initComplexSubtreesSet() throws DirectoryException
{
+ TreeSet<DN> subtrees_empty = new TreeSet<DN>();
+
TreeSet<DN> subtrees_root = new TreeSet<DN>();
subtrees_root.add(DN.decode("dc=example,dc=com"));
@@ -289,8 +289,8 @@
{subtrees_root, subtrees_people, "dc=example,dc=com", true},
{subtrees_root, subtrees_people, "ou=people,dc=example,dc=com", false},
{subtrees_root, subtrees_entry, "ou=people,dc=example,dc=com", true},
- {null, subtrees_people, "dc=example,dc=com", true},
- {null, subtrees_people, "ou=people,dc=example,dc=com", false}
+ {subtrees_empty, subtrees_people, "dc=example,dc=com", true},
+ {subtrees_empty, subtrees_people, "ou=people,dc=example,dc=com", false}
};
return myData;
}
@@ -352,14 +352,23 @@
*/
@Test (dataProvider = "AllowedAttributesSet", groups = "virtual")
public void testAllowedAttributes(
- Set<String> allowedAttributes,
+ final SortedSet<String> allowedAttributes,
String searchFilter,
boolean success)
- throws DirectoryException, LDAPException
+ throws Exception
{
ArrayList<Message> messages = new ArrayList<Message>();
- RequestFilteringPolicy policy = new RequestFilteringPolicy(null);
- policy.setAllowedAttributes(allowedAttributes);
+
+ RequestFilteringPolicyFactory factory = new RequestFilteringPolicyFactory();
+ RequestFilteringPolicy policy = factory.createQOSPolicy(new MockRequestFilteringQOSPolicyCfg() {
+
+ @Override
+ public SortedSet<String> getAllowedAttributes()
+ {
+ return Collections.unmodifiableSortedSet(allowedAttributes);
+ }
+
+ });
InternalClientConnection conn = new InternalClientConnection(DN.NULL_DN);
InternalSearchOperation search = conn.processSearch(
@@ -367,7 +376,7 @@
SearchScope.BASE_OBJECT,
LDAPFilter.decode(searchFilter).toSearchFilter());
- boolean check = policy.checkPolicy(search, messages);
+ boolean check = policy.isAllowed(search, messages);
if (success) {
assertTrue(check);
} else {
@@ -380,14 +389,23 @@
*/
@Test (dataProvider = "ProhibitedAttributesSet", groups = "virtual")
public void testProhibitedAttributes(
- Set<String> prohibitedAttributes,
+ final SortedSet<String> prohibitedAttributes,
String searchFilter,
boolean success)
- throws DirectoryException, LDAPException
+ throws Exception
{
ArrayList<Message> messages = new ArrayList<Message>();
- RequestFilteringPolicy policy = new RequestFilteringPolicy(null);
- policy.setProhibitedAttributes(prohibitedAttributes);
+
+ RequestFilteringPolicyFactory factory = new RequestFilteringPolicyFactory();
+ RequestFilteringPolicy policy = factory.createQOSPolicy(new MockRequestFilteringQOSPolicyCfg() {
+
+ @Override
+ public SortedSet<String> getProhibitedAttributes()
+ {
+ return Collections.unmodifiableSortedSet(prohibitedAttributes);
+ }
+
+ });
InternalClientConnection conn = new InternalClientConnection(DN.NULL_DN);
InternalSearchOperation search = conn.processSearch(
@@ -395,7 +413,7 @@
SearchScope.BASE_OBJECT,
LDAPFilter.decode(searchFilter).toSearchFilter());
- boolean check = policy.checkPolicy(search, messages);
+ boolean check = policy.isAllowed(search, messages);
if (success) {
assertTrue(check);
} else {
@@ -408,14 +426,23 @@
*/
@Test (dataProvider = "AllowedSearchScopesSet", groups = "virtual")
public void testAllowedSearchScopes(
- Set<AllowedSearchScopes> allowedScopes,
+ final SortedSet<AllowedSearchScopes> allowedScopes,
SearchScope searchScope,
boolean success)
- throws DirectoryException, LDAPException
+ throws Exception
{
ArrayList<Message> messages = new ArrayList<Message>();
- RequestFilteringPolicy policy = new RequestFilteringPolicy(null);
- policy.setAllowedSearchScopes(allowedScopes);
+
+ RequestFilteringPolicyFactory factory = new RequestFilteringPolicyFactory();
+ RequestFilteringPolicy policy = factory.createQOSPolicy(new MockRequestFilteringQOSPolicyCfg() {
+
+ @Override
+ public SortedSet<AllowedSearchScopes> getAllowedSearchScopes()
+ {
+ return Collections.unmodifiableSortedSet(allowedScopes);
+ }
+
+ });
InternalClientConnection conn = new InternalClientConnection(DN.NULL_DN);
InternalSearchOperation search = conn.processSearch(
@@ -423,7 +450,7 @@
searchScope,
LDAPFilter.decode("objectclass=*").toSearchFilter());
- boolean check = policy.checkPolicy(search, messages);
+ boolean check = policy.isAllowed(search, messages);
if (success) {
assertTrue(check);
} else {
@@ -436,14 +463,23 @@
*/
@Test (dataProvider = "AllowedSubtreesSet", groups = "virtual")
public void testAllowedSubtrees(
- Set<DN> allowedSubtrees,
+ final SortedSet<DN> allowedSubtrees,
String searchSubtree,
boolean success)
- throws DirectoryException, LDAPException
+ throws Exception
{
ArrayList<Message> messages = new ArrayList<Message>();
- RequestFilteringPolicy policy = new RequestFilteringPolicy(null);
- policy.setAllowedSubtrees(allowedSubtrees);
+
+ RequestFilteringPolicyFactory factory = new RequestFilteringPolicyFactory();
+ RequestFilteringPolicy policy = factory.createQOSPolicy(new MockRequestFilteringQOSPolicyCfg() {
+
+ @Override
+ public SortedSet<DN> getAllowedSubtrees()
+ {
+ return Collections.unmodifiableSortedSet(allowedSubtrees);
+ }
+
+ });
InternalClientConnection conn = new InternalClientConnection(DN.NULL_DN);
InternalSearchOperation search = conn.processSearch(
@@ -451,7 +487,7 @@
SearchScope.WHOLE_SUBTREE,
LDAPFilter.decode("objectclass=*").toSearchFilter());
- boolean check = policy.checkPolicy(search, messages);
+ boolean check = policy.isAllowed(search, messages);
if (success) {
assertTrue(check);
} else {
@@ -464,14 +500,23 @@
*/
@Test (dataProvider = "ProhibitedSubtreesSet", groups = "virtual")
public void testProhibitedSubtrees(
- Set<DN> prohibitedSubtrees,
+ final SortedSet<DN> prohibitedSubtrees,
String searchSubtree,
boolean success)
- throws DirectoryException, LDAPException
+ throws Exception
{
ArrayList<Message> messages = new ArrayList<Message>();
- RequestFilteringPolicy policy = new RequestFilteringPolicy(null);
- policy.setProhibitedSubtrees(prohibitedSubtrees);
+
+ RequestFilteringPolicyFactory factory = new RequestFilteringPolicyFactory();
+ RequestFilteringPolicy policy = factory.createQOSPolicy(new MockRequestFilteringQOSPolicyCfg() {
+
+ @Override
+ public SortedSet<DN> getProhibitedSubtrees()
+ {
+ return Collections.unmodifiableSortedSet(prohibitedSubtrees);
+ }
+
+ });
InternalClientConnection conn = new InternalClientConnection(DN.NULL_DN);
InternalSearchOperation search = conn.processSearch(
@@ -479,7 +524,7 @@
SearchScope.WHOLE_SUBTREE,
LDAPFilter.decode("objectclass=*").toSearchFilter());
- boolean check = policy.checkPolicy(search, messages);
+ boolean check = policy.isAllowed(search, messages);
if (success) {
assertTrue(check);
} else {
@@ -492,16 +537,30 @@
*/
@Test (dataProvider = "ComplexSubtreesSet", groups = "virtual")
public void testComplexSubtrees(
- Set<DN> allowedSubtrees,
- Set<DN> prohibitedSubtrees,
+ final SortedSet<DN> allowedSubtrees,
+ final SortedSet<DN> prohibitedSubtrees,
String searchSubtree,
boolean success)
- throws DirectoryException, LDAPException
+ throws Exception
{
ArrayList<Message> messages = new ArrayList<Message>();
- RequestFilteringPolicy policy = new RequestFilteringPolicy(null);
- policy.setAllowedSubtrees(allowedSubtrees);
- policy.setProhibitedSubtrees(prohibitedSubtrees);
+
+ RequestFilteringPolicyFactory factory = new RequestFilteringPolicyFactory();
+ RequestFilteringPolicy policy = factory.createQOSPolicy(new MockRequestFilteringQOSPolicyCfg() {
+
+ @Override
+ public SortedSet<DN> getAllowedSubtrees()
+ {
+ return Collections.unmodifiableSortedSet(allowedSubtrees);
+ }
+
+ @Override
+ public SortedSet<DN> getProhibitedSubtrees()
+ {
+ return Collections.unmodifiableSortedSet(prohibitedSubtrees);
+ }
+
+ });
InternalClientConnection conn = new InternalClientConnection(DN.NULL_DN);
InternalSearchOperation search = conn.processSearch(
@@ -509,7 +568,7 @@
SearchScope.WHOLE_SUBTREE,
LDAPFilter.decode("objectclass=*").toSearchFilter());
- boolean check = policy.checkPolicy(search, messages);
+ boolean check = policy.isAllowed(search, messages);
if (success) {
assertTrue(check);
} else {
@@ -522,14 +581,23 @@
*/
@Test (dataProvider = "AllowedOperationsSet", groups = "virtual")
public void testAllowedOperations(
- Set<AllowedOperations> allowedOps,
+ final SortedSet<AllowedOperations> allowedOps,
OperationType type,
boolean success)
- throws DirectoryException, LDAPException, Exception
+ throws Exception
{
ArrayList<Message> messages = new ArrayList<Message>();
- RequestFilteringPolicy policy = new RequestFilteringPolicy(null);
- policy.setAllowedOperations(allowedOps);
+
+ RequestFilteringPolicyFactory factory = new RequestFilteringPolicyFactory();
+ RequestFilteringPolicy policy = factory.createQOSPolicy(new MockRequestFilteringQOSPolicyCfg() {
+
+ @Override
+ public SortedSet<AllowedOperations> getAllowedOperations()
+ {
+ return Collections.unmodifiableSortedSet(allowedOps);
+ }
+
+ });
InternalClientConnection conn = new InternalClientConnection(DN.NULL_DN);
PreParseOperation op = null;
@@ -583,7 +651,7 @@
return;
}
- boolean check = policy.checkPolicy(op, messages);
+ boolean check = policy.isAllowed(op, messages);
if (success) {
assertTrue(check);
} else {
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/ResourceLimitsTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyTest.java
similarity index 74%
rename from opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/ResourceLimitsTest.java
rename to opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyTest.java
index 86ff103..1a9e55c 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/ResourceLimitsTest.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyTest.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2006-2008 Sun Microsystems, Inc.
+ * Copyright 2006-2009 Sun Microsystems, Inc.
*/
package org.opends.server.core.networkgroups;
@@ -35,8 +35,6 @@
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.types.DN;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.LDAPException;
import org.opends.server.types.SearchScope;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
@@ -49,7 +47,7 @@
/*
* This set of tests test the resource limits.
*/
-public class ResourceLimitsTest extends DirectoryServerTestCase {
+public class ResourceLimitsPolicyTest extends DirectoryServerTestCase {
//===========================================================================
//
// B E F O R E C L A S S
@@ -115,29 +113,42 @@
/**
* Tests the max number of connections resource limit.
- * @throws DirectoryException when there was a problem creating the connection
+ * @throws Exception If the test failed unexpectedly.
*/
@Test (groups = "virtual")
public void testMaxNumberOfConnections()
- throws DirectoryException
+ throws Exception
{
ArrayList<Message> messages = new ArrayList<Message>();
- ResourceLimits limits = new ResourceLimits(null);
- limits.setMaxConnections(1);
+
+ ResourceLimitsPolicyFactory factory =
+ new ResourceLimitsPolicyFactory();
+ ResourceLimitsPolicy limits =
+ factory
+ .createQOSPolicy(new MockResourceLimitsQOSPolicyCfg()
+ {
+
+ @Override
+ public int getMaxConnections()
+ {
+ return 1;
+ }
+
+ });
InternalClientConnection conn1 = new InternalClientConnection(DN.NULL_DN);
limits.addConnection(conn1);
- boolean check = limits.checkLimits(conn1, null, true, messages);
+ boolean check = limits.isAllowed(conn1, null, true, messages);
assertTrue(check);
InternalClientConnection conn2 = new InternalClientConnection(DN.NULL_DN);
limits.addConnection(conn2);
- check = limits.checkLimits(conn2, null, true, messages);
+ check = limits.isAllowed(conn2, null, true, messages);
assertFalse(check);
limits.removeConnection(conn1);
- check = limits.checkLimits(conn2, null, true, messages);
+ check = limits.isAllowed(conn2, null, true, messages);
assertTrue(check);
limits.removeConnection(conn2);
@@ -145,29 +156,42 @@
/**
* Tests the max number of connections from same IP resource limit.
- * @throws DirectoryException when there was a problem creating the connection
+ * @throws Exception If the test failed unexpectedly.
*/
@Test (groups = "virtual")
public void testMaxNumberOfConnectionsFromSameIp()
- throws DirectoryException
+ throws Exception
{
ArrayList<Message> messages = new ArrayList<Message>();
- ResourceLimits limits = new ResourceLimits(null);
- limits.setMaxConnectionsFromSameIP(1);
+
+ ResourceLimitsPolicyFactory factory =
+ new ResourceLimitsPolicyFactory();
+ ResourceLimitsPolicy limits =
+ factory
+ .createQOSPolicy(new MockResourceLimitsQOSPolicyCfg()
+ {
+
+ @Override
+ public int getMaxConnectionsFromSameIP()
+ {
+ return 1;
+ }
+
+ });
InternalClientConnection conn1 = new InternalClientConnection(DN.NULL_DN);
limits.addConnection(conn1);
- boolean check = limits.checkLimits(conn1, null, true, messages);
+ boolean check = limits.isAllowed(conn1, null, true, messages);
assertTrue(check);
InternalClientConnection conn2 = new InternalClientConnection(DN.NULL_DN);
limits.addConnection(conn2);
- check = limits.checkLimits(conn2, null, true, messages);
+ check = limits.isAllowed(conn2, null, true, messages);
assertFalse(check);
limits.removeConnection(conn1);
- check = limits.checkLimits(conn2, null, true, messages);
+ check = limits.isAllowed(conn2, null, true, messages);
assertTrue(check);
limits.removeConnection(conn2);
@@ -178,19 +202,31 @@
* @param minLength minimum search filter substring length
* @param searchFilter the search filter to test
* @param success boolean indicating the expected result
- * @throws DirectoryException when there was a problem creating the connection
- * @throws LDAPException when there was a problem decoding the filter
+ * @throws Exception If the test failed unexpectedly.
*/
@Test (dataProvider = "SearchFilterSet", groups = "virtual")
public void testMinSubstringLength(
- int minLength,
+ final int minLength,
String searchFilter,
boolean success)
- throws DirectoryException, LDAPException
+ throws Exception
{
List<Message> messages = new ArrayList<Message>();
- ResourceLimits limits = new ResourceLimits(null);
- limits.setMinSearchSubstringLength(minLength);
+
+ ResourceLimitsPolicyFactory factory =
+ new ResourceLimitsPolicyFactory();
+ ResourceLimitsPolicy limits =
+ factory
+ .createQOSPolicy(new MockResourceLimitsQOSPolicyCfg()
+ {
+
+ @Override
+ public int getMinSubstringLength()
+ {
+ return minLength;
+ }
+
+ });
InternalClientConnection conn1 = new InternalClientConnection(DN.NULL_DN);
limits.addConnection(conn1);
@@ -200,7 +236,7 @@
SearchScope.BASE_OBJECT,
LDAPFilter.decode(searchFilter).toSearchFilter());
- boolean check = limits.checkLimits(conn1, search, true, messages);
+ boolean check = limits.isAllowed(conn1, search, true, messages);
if (success) {
assertTrue(check);
} else {
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/SecurityConnectionCriteriaTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/SecurityConnectionCriteriaTest.java
new file mode 100644
index 0000000..6525955
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/SecurityConnectionCriteriaTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.core.networkgroups;
+
+
+
+import org.opends.server.DirectoryServerTestCase;
+import org.opends.server.TestCaseUtils;
+import org.opends.server.admin.std.meta.NetworkGroupCfgDefn.AllowedAuthMethod;
+import org.opends.server.api.ClientConnection;
+import org.opends.server.types.AuthenticationType;
+import org.opends.server.types.DN;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Unit tests for ProtocolConnectionCriteria.
+ */
+public class SecurityConnectionCriteriaTest extends
+ DirectoryServerTestCase
+{
+
+ /**
+ * Sets up the environment for performing the tests in this suite.
+ *
+ * @throws Exception
+ * if the environment could not be set up.
+ */
+ @BeforeClass
+ public void setUp() throws Exception
+ {
+ TestCaseUtils.startServer();
+ }
+
+
+
+ /**
+ * Returns test data for the following test cases.
+ *
+ * @return The test data for the following test cases.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @DataProvider(name = "testData")
+ public Object[][] createTestData() throws Exception
+ {
+ return new Object[][] {
+ { false, SecurityConnectionCriteria.SECURITY_NOT_REQUIRED, true },
+ { false, SecurityConnectionCriteria.SECURITY_REQUIRED, false },
+ { true, SecurityConnectionCriteria.SECURITY_NOT_REQUIRED, true },
+ { true, SecurityConnectionCriteria.SECURITY_REQUIRED, true }, };
+ }
+
+
+
+ /**
+ * Tests the matches method.
+ *
+ * @param isSecure
+ * Indicates if the client is using a secured connection.
+ * @param criteria
+ * The security criteria.
+ * @param expectedResult
+ * The expected result.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @Test(dataProvider = "testData")
+ public void testMatches(boolean isSecure,
+ SecurityConnectionCriteria criteria, boolean expectedResult)
+ throws Exception
+ {
+ ClientConnection client =
+ new MockClientConnection(12345, isSecure, DN.nullDN(),
+ AllowedAuthMethod.ANONYMOUS);
+
+ Assert.assertEquals(criteria.matches(client), expectedResult);
+ }
+
+
+
+ /**
+ * Tests the willMatchAfterBind method.
+ *
+ * @param isSecure
+ * Indicates if the client is using a secured connection.
+ * @param criteria
+ * The security criteria.
+ * @param expectedResult
+ * The expected result.
+ * @throws Exception
+ * If an unexpected exception occurred.
+ */
+ @Test(dataProvider = "testData")
+ public void testWillMatchAfterBind(boolean isSecure,
+ SecurityConnectionCriteria criteria, boolean expectedResult)
+ throws Exception
+ {
+ ClientConnection client =
+ new MockClientConnection(12345, false, DN.nullDN(),
+ AllowedAuthMethod.ANONYMOUS);
+
+ Assert.assertEquals(criteria.willMatchAfterBind(client,
+ DN.nullDN(), AuthenticationType.SIMPLE, isSecure),
+ expectedResult);
+ }
+
+}
--
Gitblit v1.10.0