mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Fabio Pistolesi
24.47.2016 801fa1c00effec79421fbf68ad88fc6163fd3c34
OPENDJ-3419 Introduce Service Discovery Mechanism and related configuration manager
OPENDJ-3420 Introduce server group mechanism configuration for manually configured servers
OPENDJ-3421 Introduce server group mechanism configuration for querying a replication topology

Add the Service Discovery Mechanism layer and its configuration manager, initialized at server startup.
Add the configuration definitions for individual service discovery mechanisms.
7 files added
7 files modified
965 ■■■■■ changed files
opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/ReplicationServiceDiscoveryMechanismConfiguration.xml 149 ●●●●● patch | view | raw | blame | history
opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/RootConfiguration.xml 9 ●●●●● patch | view | raw | blame | history
opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/ServiceDiscoveryMechanismConfiguration.xml 159 ●●●●● patch | view | raw | blame | history
opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/StaticServiceDiscoveryMechanismConfiguration.xml 140 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/resource/config/config.ldif 5 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/resource/schema/02-config.ldif 143 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/config/ConfigConstants.java 7 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java 25 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java 29 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryChangeListener.java 30 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryMechanism.java 79 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryMechanismConfigManager.java 164 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/discovery/package-info.java 20 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/messages/org/opends/messages/backend.properties 6 ●●●● patch | view | raw | blame | history
opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/ReplicationServiceDiscoveryMechanismConfiguration.xml
New file
@@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  The contents of this file are subject to the terms of the Common Development and
  Distribution License (the License). You may not use this file except in compliance with the
  License.
  You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
  specific language governing permission and limitations under the License.
  When distributing Covered Software, include this CDDL Header Notice in each file and include
  the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
  Header, with the fields enclosed by brackets [] replaced by your own identifying
  information: "Portions Copyright [year] [name of copyright owner]".
  Copyright 2016 ForgeRock AS.
  ! -->
<adm:managed-object name="replication-service-discovery-mechanism"
                    plural-name="replication-service-discovery-mechanisms"
                    extends="service-discovery-mechanism"
                    package="org.forgerock.opendj.server.config"
                    xmlns:adm="http://opendj.forgerock.org/admin"
                    xmlns:ldap="http://opendj.forgerock.org/admin-ldap"
                    xmlns:cli="http://opendj.forgerock.org/admin-cli">
  <adm:synopsis>
    A <adm:user-friendly-name/> returns the set of directory servers participating in a
    replication topology.
  </adm:synopsis>
  <adm:description>
    The <adm:user-friendly-name/> specifies the replication servers
    whose configuration is periodically read to discover available replicas.
  </adm:description>
  <adm:property-override name="java-class" advanced="true">
    <adm:default-behavior>
      <adm:defined>
        <adm:value>
          org.opends.server.backends.proxy.ReplicationServiceDiscoveryMechanism
        </adm:value>
      </adm:defined>
    </adm:default-behavior>
  </adm:property-override>
  <adm:profile name="ldap">
    <ldap:object-class>
      <ldap:name>ds-cfg-replication-server-discovery-mechanism</ldap:name>
      <ldap:superior>ds-cfg-service-discovery-mechanism</ldap:superior>
    </ldap:object-class>
  </adm:profile>
  <adm:property name="primary-group-id">
    <adm:synopsis>
      Replication domain group ID of preferred directory server replicas.
    </adm:synopsis>
    <adm:syntax>
      <adm:integer />
    </adm:syntax>
    <adm:description>
      Directory server replicas with this replication domain group ID
      will be preferred over other directory server replicas.
      Secondary server replicas will only be used when all primary server replicas
      become unavailable.
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          All the server replicas will be treated the same.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-primary-group-id</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="replication-server" multi-valued="true" mandatory="true">
    <adm:synopsis>
      Specifies the list of replication servers to contact periodically when discovering server replicas.
    </adm:synopsis>
    <adm:syntax>
      <adm:string>
        <adm:pattern>
          <adm:regex>^.+:[0-9]+$</adm:regex>
          <adm:usage>HOST:PORT</adm:usage>
          <adm:synopsis>
            A host name followed by a ":" and a port number.
          </adm:synopsis>
        </adm:pattern>
      </adm:string>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-replication-server</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="bind-dn" mandatory="true">
    <adm:synopsis>
      The bind DN for periodically reading replication server configurations
    </adm:synopsis>
    <adm:description>
      The bind DN must be present on all replication servers and directory servers,
      it must be able to read the server configuration.
    </adm:description>
    <adm:syntax>
      <adm:dn/>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-bind-dn</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="bind-password" mandatory="true">
    <adm:synopsis>
      The bind password for periodically reading replication server configurations
    </adm:synopsis>
    <adm:description>
      The bind password must be the same on all replication and directory servers
    </adm:description>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-bind-password</ldap:name>
      </ldap:attribute>
    </adm:profile>
    <adm:syntax>
      <adm:password/>
    </adm:syntax>
  </adm:property>
  <adm:property name="discovery-interval">
    <adm:synopsis>
      Interval between two replication server configuration discovery queries.
    </adm:synopsis>
    <adm:description>
      Specifies how frequently to query a replication server configuration
      in order to discover information about available directory server replicas.
    </adm:description>
    <adm:syntax>
      <adm:duration base-unit="s" lower-limit="1s"/>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-discovery-interval</ldap:name>
      </ldap:attribute>
    </adm:profile>
    <adm:default-behavior>
      <adm:defined>
        <adm:value>60s</adm:value>
      </adm:defined>
    </adm:default-behavior>
  </adm:property>
</adm:managed-object>
opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/RootConfiguration.xml
@@ -266,6 +266,12 @@
      </cli:relation>
    </adm:profile>
  </adm:relation>
  <adm:relation name="service-discovery-mechanism">
    <adm:one-to-many />
    <adm:profile name="ldap">
      <ldap:rdn-sequence>cn=Service Discovery Mechanisms,cn=config</ldap:rdn-sequence>
    </adm:profile>
  </adm:relation>
  <adm:relation name="root-dn">
    <adm:one-to-one />
    <adm:profile name="ldap">
@@ -442,4 +448,7 @@
  <adm:tag-definition name="core-server">
    <adm:synopsis>Core server</adm:synopsis>
  </adm:tag-definition>
  <adm:tag-definition name="service-discovery">
    <adm:synopsis>Service Discovery Mechanism</adm:synopsis>
  </adm:tag-definition>
</adm:root-managed-object>
opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/ServiceDiscoveryMechanismConfiguration.xml
New file
@@ -0,0 +1,159 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  The contents of this file are subject to the terms of the Common Development and
  Distribution License (the License). You may not use this file except in compliance with the
  License.
  You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
  specific language governing permission and limitations under the License.
  When distributing Covered Software, include this CDDL Header Notice in each file and include
  the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
  Header, with the fields enclosed by brackets [] replaced by your own identifying
  information: "Portions Copyright [year] [name of copyright owner]".
  Copyright 2016 ForgeRock AS.
  ! -->
<adm:managed-object name="service-discovery-mechanism" plural-name="service-discovery-mechanisms"
                    package="org.forgerock.opendj.server.config"
                    xmlns:adm="http://opendj.forgerock.org/admin"
                    xmlns:ldap="http://opendj.forgerock.org/admin-ldap"
                    xmlns:cli="http://opendj.forgerock.org/admin-cli">
  <adm:synopsis>
     A <adm:user-friendly-name/> identifies a set of LDAP servers for load balancing
  </adm:synopsis>
  <adm:profile name="ldap">
    <ldap:object-class>
      <ldap:name>ds-cfg-service-discovery-mechanism</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.backends.proxy.ServiceDiscoveryMechanism</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:tag name="service-discovery"/>
  <adm:property-reference name="use-ssl"/>
  <adm:property name="use-start-tls">
    <adm:synopsis>
      Indicates whether the <adm:user-friendly-name/> should use Start TLS.
    </adm:synopsis>
    <adm:description>
      If enabled, the <adm:user-friendly-name/> will use Start TLS to encrypt communication with remote servers.
    </adm:description>
    <adm:requires-admin-action>
      <adm:component-restart/>
    </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-use-start-tls</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property-reference name="ssl-cert-nickname"/>
  <adm:property name="key-manager-provider">
    <adm:synopsis>
      Specifies the name of the key manager that should be used with this <adm:user-friendly-name/>.
    </adm:synopsis>
    <adm:requires-admin-action>
      <adm:none>
        <adm:synopsis>
          Changes to this property take effect immediately, but
          only for subsequent attempts to access the key manager
          provider for associated client connections.
        </adm:synopsis>
      </adm:none>
    </adm:requires-admin-action>
    <adm:default-behavior>
      <adm:undefined/>
    </adm:default-behavior>
    <adm:syntax>
      <adm:aggregation relation-name="key-manager-provider" parent-path="/">
        <adm:constraint>
          <adm:synopsis>
            The referenced key manager provider must be enabled when
            the <adm:user-friendly-name/> is enabled and configured to use SSL or StartTLS.
          </adm:synopsis>
          <adm:target-needs-enabling-condition>
            <adm:or>
              <adm:contains property="use-ssl" value="true"/>
              <adm:contains property="use-start-tls" value="true"/>
            </adm:or>
          </adm:target-needs-enabling-condition>
        </adm:constraint>
      </adm:aggregation>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-key-manager-provider</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="trust-manager-provider">
    <adm:synopsis>
      Specifies the name of the trust manager that should be used with
      the <adm:user-friendly-name/>.
    </adm:synopsis>
    <adm:requires-admin-action>
      <adm:none>
        <adm:synopsis>
          Changes to this property take effect immediately, but
          only for subsequent attempts to access the trust manager
          provider for associated client connections.
        </adm:synopsis>
      </adm:none>
    </adm:requires-admin-action>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Use the trust manager provided by the JVM.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:aggregation relation-name="trust-manager-provider"
                       parent-path="/">
        <adm:constraint>
          <adm:synopsis>
            The referenced trust manager provider must be enabled when the
            <adm:user-friendly-name/> is enabled and configured to use SSL or StartTLS.
          </adm:synopsis>
          <adm:target-needs-enabling-condition>
            <adm:or>
              <adm:contains property="use-ssl" value="true"/>
              <adm:contains property="use-start-tls" value="true"/>
            </adm:or>
          </adm:target-needs-enabling-condition>
        </adm:constraint>
      </adm:aggregation>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-trust-manager-provider</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
</adm:managed-object>
opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/StaticServiceDiscoveryMechanismConfiguration.xml
New file
@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  The contents of this file are subject to the terms of the Common Development and
  Distribution License (the License). You may not use this file except in compliance with the
  License.
  You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
  specific language governing permission and limitations under the License.
  When distributing Covered Software, include this CDDL Header Notice in each file and include
  the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
  Header, with the fields enclosed by brackets [] replaced by your own identifying
  information: "Portions Copyright [year] [name of copyright owner]".
  Copyright 2016 ForgeRock AS.
  ! -->
<adm:managed-object name="static-service-discovery-mechanism" plural-name="static-service-discovery-mechanisms"
                    extends="service-discovery-mechanism"
                    package="org.forgerock.opendj.server.config"
                    xmlns:adm="http://opendj.forgerock.org/admin"
                    xmlns:ldap="http://opendj.forgerock.org/admin-ldap"
                    xmlns:cli="http://opendj.forgerock.org/admin-cli">
  <adm:synopsis>
    A <adm:user-friendly-name/> returns a fixed list of LDAP directory servers.
  </adm:synopsis>
  <adm:description>
    A change in configuration to any of the specified directory servers must be manually applied on all
    <adm:user-friendly-plural-name/> that reference it.
  </adm:description>
  <adm:property-override name="java-class" advanced="true">
    <adm:default-behavior>
      <adm:defined>
        <adm:value>
          org.opends.server.backends.proxy.StaticServiceDiscoveryMechanism
        </adm:value>
      </adm:defined>
    </adm:default-behavior>
  </adm:property-override>
  <adm:profile name="ldap">
    <ldap:object-class>
      <ldap:name>ds-cfg-static-server-discovery-mechanism</ldap:name>
      <ldap:superior>ds-cfg-service-discovery-mechanism</ldap:superior>
    </ldap:object-class>
  </adm:profile>
  <adm:property name="primary-server" multi-valued="true">
    <adm:synopsis>
      Specifies a list of servers that will be used in preference to secondary servers when available.
    </adm:synopsis>
    <adm:syntax>
      <adm:string>
        <adm:pattern>
          <adm:regex>^.+:[0-9]+$</adm:regex>
          <adm:usage>HOST:PORT</adm:usage>
          <adm:synopsis>
            A host name followed by a ":" and a port number.
          </adm:synopsis>
        </adm:pattern>
      </adm:string>
    </adm:syntax>
    <adm:default-behavior>
      <adm:undefined/>
    </adm:default-behavior>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-primary-server</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="secondary-server" multi-valued="true">
    <adm:synopsis>
      Specifies a list of servers that will be used in place of primary servers when all primary servers
      are unavailable.
    </adm:synopsis>
    <adm:syntax>
      <adm:string>
      <adm:pattern>
        <adm:regex>^.+:[0-9]+$</adm:regex>
          <adm:usage>HOST:PORT</adm:usage>
          <adm:synopsis>
            A host name followed by a ":" and a port number.
          </adm:synopsis>
        </adm:pattern>
      </adm:string>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-secondary-server</ldap:name>
      </ldap:attribute>
    </adm:profile>
    <adm:default-behavior>
      <adm:undefined/>
    </adm:default-behavior>
  </adm:property>
  <adm:property name="discovery-interval">
    <adm:synopsis>
      Interval between two server configuration discovery executions.
    </adm:synopsis>
    <adm:description>
      Specifies how frequently to read the configuration of the servers
      in order to discover their new information.
    </adm:description>
    <adm:syntax>
      <adm:duration base-unit="s" lower-limit="1s"/>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-discovery-interval</ldap:name>
      </ldap:attribute>
    </adm:profile>
    <adm:default-behavior>
      <adm:defined>
        <adm:value>60s</adm:value>
      </adm:defined>
    </adm:default-behavior>
  </adm:property>
  <!-- Unused for the time being, space holder for future reference.
  Comment from PR:
  Should you enumerate which operations in the description?
  (For example, is bind considered to be a write operation? Or a read operation,
   with a write operation as a possible side effect?)
  <adm:property name="read-only-server" multi-valued="true" hidden="true">
    <adm:synopsis>The list of servers for read operations only</adm:synopsis>
    <adm:syntax>
      <adm:string/>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-read-only-server</ldap:name>
      </ldap:attribute>
    </adm:profile>
    <adm:default-behavior>
      <adm:undefined/>
    </adm:default-behavior>
  </adm:property>
  -->
</adm:managed-object>
opendj-server-legacy/resource/config/config.ldif
@@ -1492,6 +1492,11 @@
ds-cfg-enabled: true
ds-cfg-identity-mapper: cn=Exact Match,cn=Identity Mappers,cn=config
dn: cn=Service Discovery Mechanisms,cn=config
objectClass: top
objectClass: ds-cfg-branch
cn: Service Discovery Mechanisms
dn: cn=Synchronization Providers,cn=config
objectClass: top
objectClass: ds-cfg-branch
opendj-server-legacy/resource/schema/02-config.ldif
@@ -3997,12 +3997,106 @@
  EQUALITY booleanMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
  SINGLE-VALUE
  X-ORIGIN 'OpenDS Directory Server' )
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.202
  NAME 'ds-cfg-indexed-field'
  EQUALITY caseExactMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.203
  NAME 'ds-cfg-primary-server'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.204
  NAME 'ds-cfg-secondary-server'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.206
  NAME 'ds-cfg-service-discovery'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.207
  NAME 'ds-cfg-discovery-interval'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.208
  NAME 'ds-cfg-use-start-tls'
  EQUALITY booleanMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.209
  NAME 'ds-cfg-proxy-password'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.210
  NAME 'ds-cfg-load-balancing-algorithm'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.211
  NAME 'ds-cfg-proxy-route-all'
  EQUALITY booleanMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.212
  NAME 'ds-cfg-primary-group-id'
  EQUALITY integerMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.213
  NAME 'ds-cfg-monitoring-timeout'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.214
  NAME 'ds-cfg-connection-pool-idle-timeout'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.215
  NAME 'ds-cfg-connection-pool-min-size'
  EQUALITY integerMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.216
  NAME 'ds-cfg-connection-pool-max-size'
  EQUALITY integerMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.217
  NAME 'ds-cfg-proxy-dn'
  EQUALITY distinguishedNameMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.218
  NAME 'ds-cfg-load-balancing-affinity-rdn-count'
  EQUALITY integerMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.219
  NAME 'ds-cfg-bind-dn'
  EQUALITY distinguishedNameMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.220
  NAME 'ds-cfg-bind-password'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.1
  NAME 'ds-cfg-access-control-handler'
  SUP top
@@ -6109,3 +6203,50 @@
  STRUCTURAL
  MUST ( ds-cfg-writability-mode )
  X-ORIGIN 'OpenDJ Directory Server' )
objectClasses: ( 1.3.6.1.4.1.36733.2.1.2.55
  NAME 'ds-cfg-proxy-backend'
  SUP ds-cfg-backend
  STRUCTURAL
  MUST ( ds-cfg-base-dn $
         ds-cfg-service-discovery-mechanism )
  MAY ( ds-cfg-proxy-route-all $
        ds-cfg-proxy-dn $
        ds-cfg-proxy-password $
        ds-cfg-load-balancing-algorithm $
        ds-cfg-load-balancing-affinity-rdn-count $
        ds-cfg-connection-timeout $
        ds-cfg-monitoring-timeout $
        ds-cfg-monitoring-period $
        ds-cfg-connection-pool-idle-timeout $
        ds-cfg-connection-pool-min-size $
        ds-cfg-connection-pool-max-size )
  X-ORIGIN 'OpenDJ Directory Server' )
objectClasses: ( 1.3.6.1.4.1.36733.2.1.2.56
  NAME 'ds-cfg-service-discovery-mechanism'
  SUP top
  STRUCTURAL
  MUST ds-cfg-java-class
  MAY ( ds-cfg-use-ssl $
        ds-cfg-use-start-tls $
        ds-cfg-ssl-cert-nickname $
        ds-cfg-trust-manager-provider $
        ds-cfg-key-manager-provider )
  X-ORIGIN 'OpenDJ Directory Server' )
objectClasses: ( 1.3.6.1.4.1.36733.2.1.2.57
  NAME 'ds-cfg-static-service-discovery-mechanism'
  SUP ds-cfg-service-discovery-mechanism
  STRUCTURAL
  MAY ( ds-cfg-primary-server $
        ds-cfg-secondary-server $
        ds-cfg-discovery-interval )
  X-ORIGIN 'OpenDJ Directory Server' )
objectClasses: ( 1.3.6.1.4.1.36733.2.1.2.58
  NAME 'ds-cfg-replication-service-discovery-mechanism'
  SUP ds-cfg-service-discovery-mechanism
  STRUCTURAL
  MAY ( ds-cfg-primary-group-id $
        ds-cfg-replication-server $
        ds-cfg-bind-dn $
        ds-cfg-bind-password $
        ds-cfg-discovery-interval )
  X-ORIGIN 'OpenDJ Directory Server' )
opendj-server-legacy/src/main/java/org/opends/server/config/ConfigConstants.java
@@ -3034,6 +3034,13 @@
  /**
   * The DN of the entry that will serve as the base for all Directory Server
   * service discovery mechanisms, used by proxy.
   */
  public static final String DN_SERVICE_DISCOVERY_BASE = "Service Discovery Mechanisms" + DN_CONFIG_ROOT;
  /**
   * The DN of the entry that will serve as the base for the configuration for
   * all Directory Server synchronization providers.
   */
opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
@@ -116,6 +116,7 @@
import org.opends.server.controls.PasswordPolicyResponseControl;
import org.opends.server.crypto.CryptoManagerImpl;
import org.opends.server.crypto.CryptoManagerSync;
import org.opends.server.discovery.ServiceDiscoveryMechanismConfigManager;
import org.opends.server.extensions.DiskSpaceMonitor;
import org.opends.server.extensions.JMXAlertHandler;
import org.opends.server.loggers.AccessLogger;
@@ -543,6 +544,7 @@
  private Router httpRouter;
  private CronExecutorService cronExecutorService;
  private ServiceDiscoveryMechanismConfigManager serviceDiscoveryMechanismConfigManager;
  /** Class that prints the version of OpenDJ server to System.out. */
  public static final class DirectoryServerVersionHandler implements com.forgerock.opendj.cli.VersionHandler
@@ -970,6 +972,23 @@
      return directoryServer.coreConfigManager;
    }
    @Override
    public ServiceDiscoveryMechanismConfigManager getServiceDiscoveryMechanismConfigManager()
    {
      return directoryServer.serviceDiscoveryMechanismConfigManager;
    }
    @Override
    public KeyManagerProvider<?> getKeyManagerProvider(DN keyManagerProviderDN)
    {
      return DirectoryServer.getKeyManagerProvider(keyManagerProviderDN);
    }
    @Override
    public TrustManagerProvider<?> getTrustManagerProvider(DN trustManagerProviderDN)
    {
      return DirectoryServer.getTrustManagerProvider(trustManagerProviderDN);
    }
  }
  /**
@@ -1438,6 +1457,10 @@
      // decode encrypted data in the backend by reading them from the trust store.
      new CryptoManagerSync();
      // Proxy needs discovery services to be already initialized.
      serviceDiscoveryMechanismConfigManager = new ServiceDiscoveryMechanismConfigManager(serverContext);
      serviceDiscoveryMechanismConfigManager.initializeServiceDiscoveryMechanismConfigManager();
      initializeRemainingBackends();
      // Check for and initialize user configured entry cache if any.
@@ -4277,6 +4300,8 @@
      ec.finalizeEntryCache();
    }
    directoryServer.serviceDiscoveryMechanismConfigManager.finalize();
    // Release exclusive lock held on server.lock file
    try {
        String serverLockFileName = LockFileManager.getServerLockFileName();
opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java
@@ -19,8 +19,12 @@
import org.forgerock.http.routing.Router;
import org.forgerock.opendj.config.server.ServerManagementContext;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.server.config.server.RootCfg;
import org.opends.server.api.KeyManagerProvider;
import org.opends.server.api.TrustManagerProvider;
import org.opends.server.discovery.ServiceDiscoveryMechanismConfigManager;
import org.opends.server.extensions.DiskSpaceMonitor;
import org.opends.server.loggers.CommonAudit;
import org.opends.server.schema.SchemaHandler;
@@ -116,6 +120,13 @@
  CommonAudit getCommonAudit();
  /**
   * Returns the Service Discovery Mechanism Config Manager.
   *
   * @return the Service Discovery Mechanism Config Manager
   */
  ServiceDiscoveryMechanismConfigManager getServiceDiscoveryMechanismConfigManager();
  /**
   * Returns the logger config manager.
   *
   * @return the logger config manager
@@ -149,4 +160,22 @@
   * @return core configuration manager
   */
  CoreConfigManager getCoreConfigManager();
  /**
   * Returns the key manager provider matching the provided DN.
   *
   * @param keyManagerProviderDN
   *          the DN of the key manager provider
   * @return the key manager provider, or {@code null} if none match
   */
  KeyManagerProvider<?> getKeyManagerProvider(DN keyManagerProviderDN);
  /**
   * Returns the trust manager provider matching the provided DN.
   *
   * @param trustManagerProviderDN
   *          the DN of the trust manager provider
   * @return the trust manager provider, or {@code null} if none match
   */
  TrustManagerProvider<?> getTrustManagerProvider(DN trustManagerProviderDN);
}
opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryChangeListener.java
New file
@@ -0,0 +1,30 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2016 ForgeRock AS.
 */
package org.opends.server.discovery;
/**
 * This interface defines the methods that a Service Discovery consumer
 * should implement if it wishes to be notified of changes in the service.
 */
public interface ServiceDiscoveryChangeListener
{
  /**
   * A change in the service, configuration or other, was detected.
   *
   * @param changedService the Service Discovery Mechanism who detected a change
   */
  void serviceChanged(ServiceDiscoveryMechanism<?> changedService);
}
opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryMechanism.java
New file
@@ -0,0 +1,79 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2016 ForgeRock AS.
 */
package org.opends.server.discovery;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.server.config.server.ServiceDiscoveryMechanismCfg;
import org.opends.server.core.ServerContext;
import java.util.List;
/**
 * Maintains a set of {@code Partition}s keeping it up to date according to a specific
 * discovery mechanism.
 *
 * @param <C> the configuration for the Service Discovery
 */
public interface ServiceDiscoveryMechanism<C extends ServiceDiscoveryMechanismCfg>
{
  /**
   * Returns the name of the mechanism.
   *
   * @return the name of the mechanism
   */
  String getName();
  /**
   * Returns whether the provided configuration is correct for the mechanism.
   * It should be possible to call this method on an uninitialized mechanism to check
   * the configuration for correctness.
   *
   * @param configuration the configuration to check
   * @param unacceptableReasons the list of reasons the configuration is not acceptable
   * @param serverContext the server context of this Directory Server instance
   * @return if the provided configuration is correct for the mechanism.
   */
  boolean isConfigurationAcceptable(C configuration,
      List<LocalizableMessage> unacceptableReasons, ServerContext serverContext);
  /**
   * Initializes the mechanism with the provided configuration.
   *
   * @param configuration the configuration for initialization
   * @param serverContext the server context for this Directory Server instance
   */
  void initializeMechanism(C configuration, ServerContext serverContext);
  /**
   * Frees any resources in use, mechanism will not be used anymore afterwards.
   */
  void finalizeMechanism();
  /**
   * Registers a listener to be notified when changes in the service occur.
   *
   * @param listener the listener to register for notifications
   * @return true if registration was successful
   */
  boolean registerChangeListener(ServiceDiscoveryChangeListener listener);
  /**
   * De-registers a listener from notifications on service changes.
   *
   * @param listener the listener to de-register
   */
  void deregisterChangeListener(ServiceDiscoveryChangeListener listener);
}
opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryMechanismConfigManager.java
New file
@@ -0,0 +1,164 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2016 ForgeRock AS.
 */
package org.opends.server.discovery;
import static org.opends.messages.BackendMessages.*;
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.config.server.ConfigChangeResult;
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.config.server.ConfigurationAddListener;
import org.forgerock.opendj.config.server.ConfigurationDeleteListener;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.server.config.server.RootCfg;
import org.forgerock.opendj.server.config.server.ServiceDiscoveryMechanismCfg;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ServerContext;
/**
 * Manages configuration additions and deletions of service discovery mechanisms in the server configuration.
 */
public class ServiceDiscoveryMechanismConfigManager implements
    ConfigurationAddListener<ServiceDiscoveryMechanismCfg>,
    ConfigurationDeleteListener<ServiceDiscoveryMechanismCfg>
{
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
  private final Map<String, ServiceDiscoveryMechanism<?>> serviceDiscoveryMechanisms = new ConcurrentHashMap<>();
  private final ServerContext serverContext;
  /**
   * Declares a new Configuration Manager for this Directory Server.
   *
   * @param serverContext the current directory server context
   */
  public ServiceDiscoveryMechanismConfigManager(ServerContext serverContext)
  {
    this.serverContext = serverContext;
  }
  /**
   * Initializes the Mechanism Configuration Manager and its configuration at startup.
   * Registers itself as a service in the directory server instance.
   */
  public void initializeServiceDiscoveryMechanismConfigManager()
  {
    RootCfg root = serverContext.getRootConfig();
    for (String mechanism : root.listServiceDiscoveryMechanisms())
    {
      try
      {
        ServiceDiscoveryMechanismCfg configuration = root.getServiceDiscoveryMechanism(mechanism);
        serviceDiscoveryMechanisms.put(configuration.name(), loadAndInitializeMechanism(configuration));
      }
      catch (Exception e)
      {
        logger.error(ERR_SERVICE_DISCOVERY_CONFIG_MANAGER_INIT_MECHANISM.get(
            mechanism, stackTraceToSingleLineString(e)));
      }
    }
    try
    {
      root.addServiceDiscoveryMechanismAddListener(this);
      root.addServiceDiscoveryMechanismDeleteListener(this);
    }
    catch (ConfigException e)
    {
      logger.error(ERR_SERVICE_DISCOVERY_CONFIG_MANAGER_LISTENER.get(stackTraceToSingleLineString(e)));
    }
  }
  ServiceDiscoveryMechanism<?> getMechanism(String name)
  {
    return serviceDiscoveryMechanisms.get(name);
  }
  @Override
  public boolean isConfigurationAddAcceptable(ServiceDiscoveryMechanismCfg configuration,
      List<LocalizableMessage> unacceptableReasons)
  {
    try
    {
      ServiceDiscoveryMechanism newMechanism = loadAndInitializeMechanism(configuration);
      return newMechanism.isConfigurationAcceptable(configuration, unacceptableReasons, serverContext);
    }
    catch (Exception e)
    {
      unacceptableReasons.add(ERR_SERVICE_DISCOVERY_CONFIG_MANAGER_ADD_MECHANISM.get(
          configuration.name(), stackTraceToSingleLineString(e)));
      return false;
    }
  }
  @Override
  public ConfigChangeResult applyConfigurationAdd(ServiceDiscoveryMechanismCfg configuration)
  {
    ConfigChangeResult ccr = new ConfigChangeResult();
    try
    {
      serviceDiscoveryMechanisms.put(configuration.name(), loadAndInitializeMechanism(configuration));
    }
    catch (Exception e)
    {
      ccr.setResultCode(ResultCode.OTHER);
      ccr.addMessage(ERR_SERVICE_DISCOVERY_CONFIG_MANAGER_ADD_MECHANISM.get(
          configuration.name(), stackTraceToSingleLineString(e)));
    }
    return ccr;
  }
  @SuppressWarnings({ "rawtypes", "unchecked" })
  private ServiceDiscoveryMechanism loadAndInitializeMechanism(ServiceDiscoveryMechanismCfg cfg) throws Exception
  {
    final ServiceDiscoveryMechanism newMechanism =
        ((Class<ServiceDiscoveryMechanism>) DirectoryServer.loadClass(cfg.getJavaClass())).newInstance();
    newMechanism.initializeMechanism(cfg, serverContext);
    return newMechanism;
  }
  @Override
  public boolean isConfigurationDeleteAcceptable(ServiceDiscoveryMechanismCfg configuration,
      List<LocalizableMessage> unacceptableReasons)
  {
    return true;
  }
  @Override
  public ConfigChangeResult applyConfigurationDelete(ServiceDiscoveryMechanismCfg configuration)
  {
    serviceDiscoveryMechanisms.remove(configuration.name()).finalizeMechanism();
    return new ConfigChangeResult();
  }
  /**
   * Finalize all service discovery mechanism for shutdown.
   */
  public void finalize()
  {
    for (ServiceDiscoveryMechanism<?> service : serviceDiscoveryMechanisms.values())
    {
      service.finalizeMechanism();
    }
    serverContext.getRootConfig().removeServiceDiscoveryMechanismAddListener(this);
    serverContext.getRootConfig().removeServiceDiscoveryMechanismDeleteListener(this);
  }
}
opendj-server-legacy/src/main/java/org/opends/server/discovery/package-info.java
New file
@@ -0,0 +1,20 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2016 ForgeRock AS.
 */
/**
 * Contains the Service Discovery Mechanisms and APIs.
 */
@org.opends.server.types.PublicAPI(stability=org.opends.server.types.StabilityLevel.PRIVATE)
package org.opends.server.discovery;
opendj-server-legacy/src/messages/org/opends/messages/backend.properties
@@ -1099,4 +1099,8 @@
 copies of entry '%s'
ERR_ROOTDSE_NOT_SUPPORTED_SCOPE_610=Unwilling to perform a search \
 (connection ID %d, operation ID %d) with a scope of "%s" in the root DSE \
 backend. Only the BASE scope is supported for the root DSE backend.
 backend. Only the BASE scope is supported for the root DSE backend.
ERR_SERVICE_DISCOVERY_CONFIG_MANAGER_ADD_MECHANISM_611=An error occurred while adding \
 Service Discovery Mechanism '%s' : %s
ERR_SERVICE_DISCOVERY_CONFIG_MANAGER_INIT_MECHANISM_614=Service Discovery Mechanism '%s' initialization failed : %s
ERR_SERVICE_DISCOVERY_CONFIG_MANAGER_LISTENER_615=Registering Service Discovery Manager's listener failed : %s