From 801fa1c00effec79421fbf68ad88fc6163fd3c34 Mon Sep 17 00:00:00 2001
From: Fabio Pistolesi <fabio.pistolesi@forgerock.com>
Date: Thu, 24 Nov 2016 16:24:46 +0000
Subject: [PATCH] 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

---
 opendj-server-legacy/src/messages/org/opends/messages/backend.properties                                                                   |    6 
 opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/ReplicationServiceDiscoveryMechanismConfiguration.xml |  149 ++++++++
 opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java                                                             |   25 +
 opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryMechanismConfigManager.java                                 |  164 +++++++++
 opendj-server-legacy/src/main/java/org/opends/server/discovery/package-info.java                                                           |   20 +
 opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java                                                               |   29 +
 opendj-server-legacy/resource/schema/02-config.ldif                                                                                        |  143 ++++++++
 opendj-server-legacy/resource/config/config.ldif                                                                                           |    5 
 opendj-server-legacy/src/main/java/org/opends/server/config/ConfigConstants.java                                                           |    7 
 opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/RootConfiguration.xml                                 |    9 
 opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryMechanism.java                                              |   79 ++++
 opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/StaticServiceDiscoveryMechanismConfiguration.xml      |  140 ++++++++
 opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryChangeListener.java                                         |   30 +
 opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/ServiceDiscoveryMechanismConfiguration.xml            |  159 +++++++++
 14 files changed, 963 insertions(+), 2 deletions(-)

diff --git a/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/ReplicationServiceDiscoveryMechanismConfiguration.xml b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/ReplicationServiceDiscoveryMechanismConfiguration.xml
new file mode 100644
index 0000000..a812124
--- /dev/null
+++ b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/ReplicationServiceDiscoveryMechanismConfiguration.xml
@@ -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>
diff --git a/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/RootConfiguration.xml b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/RootConfiguration.xml
index 003307a..da5d925 100644
--- a/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/RootConfiguration.xml
+++ b/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>
diff --git a/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/ServiceDiscoveryMechanismConfiguration.xml b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/ServiceDiscoveryMechanismConfiguration.xml
new file mode 100644
index 0000000..6227068
--- /dev/null
+++ b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/ServiceDiscoveryMechanismConfiguration.xml
@@ -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>
diff --git a/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/StaticServiceDiscoveryMechanismConfiguration.xml b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/StaticServiceDiscoveryMechanismConfiguration.xml
new file mode 100644
index 0000000..9bd103c
--- /dev/null
+++ b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/StaticServiceDiscoveryMechanismConfiguration.xml
@@ -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>
diff --git a/opendj-server-legacy/resource/config/config.ldif b/opendj-server-legacy/resource/config/config.ldif
index 1693b9b..87209a9 100644
--- a/opendj-server-legacy/resource/config/config.ldif
+++ b/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
diff --git a/opendj-server-legacy/resource/schema/02-config.ldif b/opendj-server-legacy/resource/schema/02-config.ldif
index 9196f03..1f7ba43 100644
--- a/opendj-server-legacy/resource/schema/02-config.ldif
+++ b/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' )
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/config/ConfigConstants.java b/opendj-server-legacy/src/main/java/org/opends/server/config/ConfigConstants.java
index 36cfe14..69303d2 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/config/ConfigConstants.java
+++ b/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.
    */
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
index c420850..db84e6a 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
+++ b/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();
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java b/opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java
index dc6cb11..e0aa1fa 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java
+++ b/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);
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryChangeListener.java b/opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryChangeListener.java
new file mode 100644
index 0000000..fb62f0f
--- /dev/null
+++ b/opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryChangeListener.java
@@ -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);
+}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryMechanism.java b/opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryMechanism.java
new file mode 100644
index 0000000..2c3e99b
--- /dev/null
+++ b/opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryMechanism.java
@@ -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);
+}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryMechanismConfigManager.java b/opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryMechanismConfigManager.java
new file mode 100644
index 0000000..6aa1285
--- /dev/null
+++ b/opendj-server-legacy/src/main/java/org/opends/server/discovery/ServiceDiscoveryMechanismConfigManager.java
@@ -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);
+  }
+}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/discovery/package-info.java b/opendj-server-legacy/src/main/java/org/opends/server/discovery/package-info.java
new file mode 100644
index 0000000..bf16bb5
--- /dev/null
+++ b/opendj-server-legacy/src/main/java/org/opends/server/discovery/package-info.java
@@ -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;
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/backend.properties b/opendj-server-legacy/src/messages/org/opends/messages/backend.properties
index ac5db33..7337a24 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/backend.properties
+++ b/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. 
\ No newline at end of file
+ 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

--
Gitblit v1.10.0