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

pgamba
10.52.2009 6401e69f22f9b5044c53bbdb4051851cb0f4cd7a
Fix#4262 ECL One should be able to disable ECL for each domain
3 files added
17 files modified
985 ■■■■ changed files
opends/resource/admin/abbreviations.xsl 1 ●●●● patch | view | raw | blame | history
opends/resource/schema/02-config.ldif 11 ●●●● patch | view | raw | blame | history
opends/src/admin/defn/org/opends/server/admin/std/ExternalChangelogDomainConfiguration.xml 80 ●●●●● patch | view | raw | blame | history
opends/src/admin/defn/org/opends/server/admin/std/ReplicationDomainConfiguration.xml 51 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/common/FirstChangeNumberVirtualAttributeProvider.java 2 ●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/common/LastChangeNumberVirtualAttributeProvider.java 2 ●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/common/LastCookieVirtualProvider.java 2 ●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/plugin/ExternalChangelogDomain.java 178 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java 123 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java 23 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/service/ReplicationBroker.java 5 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/service/ReplicationDomain.java 10 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java 2 ●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java 57 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/GenerationIdTest.java 88 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ProtocolWindowTest.java 1 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ReplicationTestCase.java 89 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/DomainFakeCfg.java 99 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/ExternalChangelogDomainFakeCfg.java 154 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/MonitorTest.java 7 ●●●● patch | view | raw | blame | history
opends/resource/admin/abbreviations.xsl
@@ -53,6 +53,7 @@
              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 = 'qos'
              or $value = 'ecl'
             "/>
  </xsl:template>
</xsl:stylesheet>
opends/resource/schema/02-config.ldif
@@ -3026,8 +3026,7 @@
        ds-cfg-fractional-exclude $
        ds-cfg-fractional-include $
        ds-cfg-solve-conflicts $
        ds-cfg-changetime-heartbeat-interval $
        ds-cfg-ecl-include )
        ds-cfg-changetime-heartbeat-interval )
  X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.58
  NAME 'ds-cfg-length-based-password-validator'
@@ -4144,4 +4143,12 @@
  STRUCTURAL
  MAY ( ds-cfg-num-worker-threads )
  X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.234
  NAME 'ds-cfg-external-changelog-domain'
  SUP top
  STRUCTURAL
  MUST ( cn $
         ds-cfg-enabled )
  MAY  ( ds-cfg-ecl-include )
  X-ORIGIN 'OpenDS Directory Server' )
opends/src/admin/defn/org/opends/server/admin/std/ExternalChangelogDomainConfiguration.xml
New file
@@ -0,0 +1,80 @@
<?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="external-changelog-domain"
  plural-name="external-changelog-domains"
  package="org.opends.server.admin.std"
  xmlns:adm="http://www.opends.org/admin"
  xmlns:ldap="http://www.opends.org/admin-ldap"
  xmlns:cli="http://www.opends.org/admin-cli">
  <adm:synopsis>
    The
    <adm:user-friendly-name />
    provides configuration of the external changelog for the replication domain.
  </adm:synopsis>
  <adm:profile name="ldap">
    <ldap:object-class>
      <ldap:name>ds-cfg-external-changelog-domain</ldap:name>
      <ldap:superior>top</ldap:superior>
    </ldap:object-class>
  </adm:profile>
  <adm:property name="enabled" mandatory="true">
    <adm:synopsis>
      Indicates whether the
      <adm:user-friendly-name />
      is enabled.
    </adm:synopsis>
    <adm:syntax>
      <adm:boolean />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-enabled</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="ecl-include" multi-valued="true" mandatory="false">
    <adm:synopsis>
      Allows to include some target entry attributes in the external changelog.
    </adm:synopsis>
    <adm:description>
      Specifies an attribute that will be included in every External Change Log
      entry related to this replication domain.
    </adm:description>
    <adm:default-behavior>
      <adm:undefined/>
    </adm:default-behavior>
    <adm:syntax>
      <adm:attribute-type />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-ecl-include</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
</adm:managed-object>
opends/src/admin/defn/org/opends/server/admin/std/ReplicationDomainConfiguration.xml
@@ -43,6 +43,14 @@
      <ldap:superior>top</ldap:superior>
    </ldap:object-class>
  </adm:profile>
  <adm:relation name="external-changelog-domain">
    <adm:one-to-one />
    <adm:profile name="ldap">
      <ldap:rdn-sequence>
        cn=External ChangeLog
      </ldap:rdn-sequence>
    </adm:profile>
  </adm:relation>
  <adm:property name="replication-server" multi-valued="true"
    mandatory="true">
    <adm:synopsis>
@@ -487,47 +495,4 @@
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="ecl-include" multi-valued="true" mandatory="false">
    <adm:synopsis>
      Allows to include some target entry attributes in the ECL.
    </adm:synopsis>
    <adm:description>
      Specifies an attribute that will be included in every External Change Log
      entry related to this replication domain.
    </adm:description>
    <adm:default-behavior>
      <adm:undefined/>
    </adm:default-behavior>
    <adm:syntax>
      <adm:string>
        <adm:pattern>
          <!-- This java regex is mostly derived from keystring BNF definition
          that can be found in RFC 2252, section "4.1. Common Encoding Aspects".
          This can be read as: (oid|\*):oid(,oid)*+
          -->
          <adm:regex>^((([a-zA-Z]([a-zA-Z]|[0-9]|-|;)*+)|(0|([1-9]([0-9])*+))(\\.(0|([1-9]([0-9])*+)))*+)|\\*):(([a-zA-Z]([a-zA-Z]|[0-9]|-|;)*+)|(0|([1-9]([0-9])*+))(\\.(0|([1-9]([0-9])*+)))*+)(,(([a-zA-Z]([a-zA-Z]|[0-9]|-|;)*+)|(0|([1-9]([0-9])*+))(\\.(0|([1-9]([0-9])*+)))*+))*+$</adm:regex>
          <adm:usage>Syntax:
          className:attributeName[,attributeName]
          or
          *:attributeName[,attributeName].
          Note that any class (className) or attribute (attributeName) definition can be replaced with its OID definition.
          Examples:
          inetOrgPerson:photo,jpegPhoto : 'photo' and 'jpegPhoto' attributes of any entry of type 'inetOrgPerson' class.
          This can also be 2.16.840.1.113730.3.2.2:0.9.2342.19200300.100.1.7,0.9.2342.19200300.100.1.60 or a mix.
          *:jpegPhoto : the 'jpegPhoto' attribute of any entry that has this attribute.
          This can also be *:0.9.2342.19200300.100.1.60
          </adm:usage>
          <adm:synopsis>
            Defines attribute(s) of one particular class or of all possible
            classes, to exclude from the replication.
          </adm:synopsis>
        </adm:pattern>
      </adm:string>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-ecl-include</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
</adm:managed-object>
opends/src/server/org/opends/server/replication/common/FirstChangeNumberVirtualAttributeProvider.java
@@ -134,7 +134,7 @@
      {
        // Set a list of excluded domains (also exclude 'cn=changelog' itself)
        ArrayList<String> excludedDomains =
          MultimasterReplication.getPrivateDomains();
          MultimasterReplication.getECLDisabledDomains();
        if (!excludedDomains.contains(
            ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT))
          excludedDomains.add(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT);
opends/src/server/org/opends/server/replication/common/LastChangeNumberVirtualAttributeProvider.java
@@ -134,7 +134,7 @@
      {
        // Set a list of excluded domains (also exclude 'cn=changelog' itself)
        ArrayList<String> excludedDomains =
          MultimasterReplication.getPrivateDomains();
          MultimasterReplication.getECLDisabledDomains();
        if (!excludedDomains.contains(
            ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT))
          excludedDomains.add(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT);
opends/src/server/org/opends/server/replication/common/LastCookieVirtualProvider.java
@@ -137,7 +137,7 @@
      {
        // Set a list of excluded domains (also exclude 'cn=changelog' itself)
        ArrayList<String> excludedDomains =
          MultimasterReplication.getPrivateDomains();
          MultimasterReplication.getECLDisabledDomains();
        if (!excludedDomains.contains(
            ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT))
          excludedDomains.add(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT);
opends/src/server/org/opends/server/replication/plugin/ExternalChangelogDomain.java
New file
@@ -0,0 +1,178 @@
/*
 * 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 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.replication.plugin;
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.server.ExternalChangelogDomainCfg;
import org.opends.server.types.AttributeType;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DN;
import org.opends.server.types.ResultCode;
/**
 * This class specifies the external changelog feature for a replication
 * domain.
 */
public class ExternalChangelogDomain
  implements ConfigurationAddListener<ExternalChangelogDomainCfg>,
             ConfigurationDeleteListener<ExternalChangelogDomainCfg>,
             ConfigurationChangeListener<ExternalChangelogDomainCfg>
{
  LDAPReplicationDomain domain;
  boolean isEnabled;
  /**
   * Constructor from a provided LDAPReplicationDomain.
   * @param domain The provided domain.
   * @param configuration The external changelog configuration.
   */
  public ExternalChangelogDomain(LDAPReplicationDomain domain,
      ExternalChangelogDomainCfg configuration)
  {
    this.domain =domain;
    this.isEnabled = configuration.isEnabled();
    configuration.addChangeListener(this);
    if (configuration.getECLInclude() != null)
      for (AttributeType eclInclude : configuration.getECLInclude())
        domain.addEclInclude(eclInclude.getNormalizedPrimaryName());
  }
  /**
   * {@inheritDoc}
   */
  public ConfigChangeResult applyConfigurationAdd(
      ExternalChangelogDomainCfg configuration)
  {
    try
    {
      if (domain==null)
      {
        DN rdns = DN.decode(
            configuration.dn().getParent().getRDN().getAttributeValue(0).
            getNormalizedValue());
        domain = MultimasterReplication.findDomain(rdns, null);
      }
    }
    catch (Exception e)
    {
      return new ConfigChangeResult(ResultCode.CONSTRAINT_VIOLATION, false);
    }
    this.isEnabled = configuration.isEnabled();
    if (configuration.getECLInclude() != null)
      for (AttributeType eclInclude : configuration.getECLInclude())
        domain.addEclInclude(eclInclude.getNormalizedPrimaryName());
    return new ConfigChangeResult(ResultCode.SUCCESS, false);
  }
  /**
   * {@inheritDoc}
   */
  public ConfigChangeResult applyConfigurationChange(
      ExternalChangelogDomainCfg configuration)
  {
    try
    {
      if (domain==null)
      {
        DN rdns = DN.decode(
            configuration.dn().getParent().getRDN().getAttributeValue(0).
              getNormalizedValue());
        domain = MultimasterReplication.findDomain(rdns, null);
      }
      this.isEnabled = configuration.isEnabled();
      if (configuration.getECLInclude() != null)
        for (AttributeType eclInclude : configuration.getECLInclude())
          domain.addEclInclude(eclInclude.getNormalizedPrimaryName());
      return new ConfigChangeResult(ResultCode.SUCCESS, false);
    }
    catch (Exception e)
    {
      return new ConfigChangeResult(ResultCode.CONSTRAINT_VIOLATION, false);
    }
  }
  /**
   * {@inheritDoc}
   */
  public boolean isConfigurationAddAcceptable(
      ExternalChangelogDomainCfg configuration,
      List<Message> unacceptableReasons)
  {
    return true;
  }
  /**
   * {@inheritDoc}
   */
  public boolean isConfigurationChangeAcceptable(
      ExternalChangelogDomainCfg configuration,
      List<Message> unacceptableReasons)
  {
    return true;
  }
  /**
   * {@inheritDoc}
   */
  public boolean isConfigurationDeleteAcceptable(
      ExternalChangelogDomainCfg configuration,
      List<Message> unacceptableReasons)
  {
    return true;
  }
  /**
   * {@inheritDoc}
   */
  public ConfigChangeResult applyConfigurationDelete(
      ExternalChangelogDomainCfg configuration)
  {
    // nothing to do
    return new ConfigChangeResult(ResultCode.SUCCESS, false);
  }
  /**
   * Specifies whether this domain is enabled/disabled regarding the ECL.
   * @return enabled/disabled for the ECL.
   */
  boolean isEnabled()
  {
    return this.isEnabled;
  }
}
opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java
@@ -41,6 +41,7 @@
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
@@ -66,7 +67,9 @@
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.meta.ReplicationDomainCfgDefn.AssuredType;
import org.opends.server.admin.std.meta.ReplicationDomainCfgDefn.*;
import org.opends.server.admin.std.server.ExternalChangelogDomainCfg;
import org.opends.server.admin.std.server.ReplicationDomainCfg;
import org.opends.server.api.AlertGenerator;
import org.opends.server.api.Backend;
@@ -157,6 +160,7 @@
import org.opends.server.types.operation.PreOperationModifyDNOperation;
import org.opends.server.types.operation.PreOperationModifyOperation;
import org.opends.server.types.operation.PreOperationOperation;
import org.opends.server.util.LDIFReader;
import org.opends.server.workflowelement.externalchangelog.ECLWorkflowElement;
import org.opends.server.workflowelement.localbackend.*;
@@ -256,6 +260,7 @@
   * The DN of the configuration entry of this domain.
   */
  private final DN configDn;
  private ExternalChangelogDomain eclDomain;
  /**
   * A boolean indicating if the thread used to save the persistentServerState
@@ -432,7 +437,7 @@
    setGroupId((byte)configuration.getGroupId());
    setURLs(configuration.getReferralsUrl());
    setCfgEclInclude(configuration.getEclInclude());
    createECLDomainCfg(configuration);
    /*
     * Modify conflicts are solved for all suffixes but the schema suffix
@@ -2305,6 +2310,15 @@
  }
  /**
   * Delete this ReplicationDomain.
   */
  public void delete()
  {
    shutdown();
    removeECLDomainCfg();
  }
  /**
   * Shutdown this ReplicationDomain.
   */
  public void shutdown()
@@ -4093,6 +4107,15 @@
      solveConflictFlag = configuration.isSolveConflicts();
    }
    try
    {
      createECLDomainCfg(configuration);
    }
    catch(Exception e)
    {
      return new ConfigChangeResult(ResultCode.OTHER, false);
    }
    return new ConfigChangeResult(ResultCode.SUCCESS, false);
  }
@@ -4166,6 +4189,94 @@
  /**
   * Remove from this domain configuration, the configuration of the
   * external change log.
   */
  public void removeECLDomainCfg()
  {
    try
    {
      DN eclConfigEntryDN = DN.decode(
          "cn=external changeLog," + configDn);
      if (DirectoryServer.getConfigHandler().entryExists(eclConfigEntryDN))
      {
        DirectoryServer.getConfigHandler().deleteEntry(eclConfigEntryDN, null);
      }
    }
    catch(Exception e)
    {
      TRACER.debugCaught(DebugLogLevel.ERROR, e);
      MessageBuilder mb = new MessageBuilder();
      mb.append(e.getMessage());
      Message msg = ERR_CHECK_CREATE_REPL_BACKEND_FAILED.get(mb.toString());
      logError(msg);
    }
  }
  /**
   * Create the ECl configuration.
   * @param  configuration The provided configuration.
   * @throws ConfigException a.
   */
  public void createECLDomainCfg(ReplicationDomainCfg configuration)
  throws ConfigException
  {
    // create the ecl config if it does not exist
    // There may ot be any config entry related to this domain in some
    // unit test cases
    try
    {
      ExternalChangelogDomainCfg eclDomCfg = null;
      if (DirectoryServer.getConfigHandler().entryExists(configDn))
      {
        try
        { eclDomCfg = configuration.getExternalChangelogDomain();
        }catch(Exception e) {}
        if (eclDomCfg==null)
        {
          DN eclConfigEntryDN = DN.decode("cn=external changelog," + configDn);
          if (!DirectoryServer.getConfigHandler().entryExists(eclConfigEntryDN))
          {
            String ldif = makeLdif(
                "dn: cn=external changelog," + configDn,
                "objectClass: top",
                "objectClass: ds-cfg-external-changelog-domain",
                "cn: external changelog",
                "ds-cfg-enabled: " + (!getBackend().isPrivateBackend()));
            LDIFImportConfig ldifImportConfig = new LDIFImportConfig(
                new StringReader(ldif));
            LDIFReader reader = new LDIFReader(ldifImportConfig);
            Entry eclEntry = reader.readEntry();
            DirectoryServer.getConfigHandler().addEntry(eclEntry, null);
            ldifImportConfig.close();
          }
        }
      }
      eclDomCfg = configuration.getExternalChangelogDomain();
      eclDomain = new ExternalChangelogDomain(this, eclDomCfg);
    }
    catch(Exception de)
    {
      throw new ConfigException(
            NOTE_ERR_UNABLE_TO_ENABLE_ECL.get(
                "Replication Domain on" + baseDn,
                de.getMessage() + " " + de.getCause().getMessage()), de);
    }
  }
  private static String makeLdif(String... lines)
  {
    StringBuilder buffer = new StringBuilder();
    for (String line : lines) {
      buffer.append(line).append(EOL);
    }
    // Append an extra line so we can append LDIF Strings.
    buffer.append(EOL);
    return buffer.toString();
  }
  /**
   * {@inheritDoc}
   */
  @Override
@@ -4197,7 +4308,6 @@
      }
      catch(DirectoryException de)
      {
        //FIXME:DirectoryException is raised by initializeECL => fix err msg
        Message message =
          NOTE_ERR_UNABLE_TO_ENABLE_ECL.get(
              "Replication Domain on" + baseDn,
@@ -5080,4 +5190,13 @@
      return true;
    }
  }
  /**
   * Specifies whether this domain is enabled/disabled regarding the ECL.
   * @return enabled/disabled for the ECL.
   */
  public boolean isECLEnabled()
  {
    return this.eclDomain.isEnabled();
  }
}
opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java
@@ -36,6 +36,7 @@
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
import org.opends.messages.Message;
import org.opends.server.admin.server.ConfigurationAddListener;
import org.opends.server.admin.server.ConfigurationChangeListener;
@@ -195,7 +196,7 @@
      ReplicationDomainCfg configuration)
      throws ConfigException
  {
    LDAPReplicationDomain domain;
    LDAPReplicationDomain domain = null;
    try
    {
      domain = new LDAPReplicationDomain(configuration, updateToReplayQueue);
@@ -208,14 +209,14 @@
      }
      domains.put(domain.getBaseDN(), domain);
      return domain;
    }
    catch (ConfigException e)
    {
      logError(ERR_COULD_NOT_START_REPLICATION.get(
          configuration.dn().toString(), e.getLocalizedMessage()));
      return null;
          configuration.dn().toString(), e.getLocalizedMessage()
          + " " + stackTraceToSingleLineString(e)));
    }
    return domain;
  }
  /**
@@ -251,7 +252,7 @@
    LDAPReplicationDomain domain = domains.remove(dn);
    if (domain != null)
      domain.shutdown();
      domain.delete();
    // No replay threads running if no replication need
    if (domains.size() == 0) {
@@ -822,18 +823,16 @@
   * Gets the baseDn of the domains that have a private backend.
   * @return The private baseDN.
   */
  public static ArrayList<String> getPrivateDomains()
  public static ArrayList<String> getECLDisabledDomains()
  {
    ArrayList<String> privateDNs = new ArrayList<String>();
    ArrayList<String> disabledServiceIDs = new ArrayList<String>();
    for (LDAPReplicationDomain domain : domains.values())
    {
      Backend b = domain.getBackend();
      if (b != null)
        if (b.isPrivateBackend())
          privateDNs.add(domain.getBaseDN().toNormalizedString());
      if (!domain.isECLEnabled())
        disabledServiceIDs.add(domain.getBaseDN().toNormalizedString());
    }
    return privateDNs;
    return disabledServiceIDs;
  }
  /**
opends/src/server/org/opends/server/replication/service/ReplicationBroker.java
@@ -2502,11 +2502,6 @@
          domain.addEclInclude(attr);
        }
      }
      if (debugEnabled())
      {
        TRACER.debugInfo("domain: " + domain.getServiceID() +
            " EclIncludes" + domain.getEclInclude());
      }
    }
  }
  /**
opends/src/server/org/opends/server/replication/service/ReplicationDomain.java
@@ -2909,14 +2909,4 @@
  {
    return eClIncludes;
  }
  /**
   * Set the list of attributes to include in the ECL.
   * @param eclIncludes The list of attributes.
   */
  protected void setCfgEclInclude(Set<String> eclIncludes)
  {
    this.cfgEclIncludes = eclIncludes;
    this.eClIncludes = eclIncludes;
  }
}
opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java
@@ -248,7 +248,7 @@
      // Set a list of excluded domains (also exclude 'cn=changelog' itself)
      ArrayList<String> excludedDomains =
        MultimasterReplication.getPrivateDomains();
        MultimasterReplication.getECLDisabledDomains();
      if (!excludedDomains.contains(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT))
        excludedDomains.add(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT);
      startECLSessionMsg.setExcludedDNs(excludedDomains);
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java
@@ -89,6 +89,7 @@
import org.opends.server.replication.common.MultiDomainServerState;
import org.opends.server.replication.common.ServerState;
import org.opends.server.replication.plugin.DomainFakeCfg;
import org.opends.server.replication.plugin.ExternalChangelogDomainFakeCfg;
import org.opends.server.replication.plugin.LDAPReplicationDomain;
import org.opends.server.replication.plugin.MultimasterReplication;
import org.opends.server.replication.protocol.AddMsg;
@@ -111,6 +112,7 @@
import org.opends.server.types.AbstractOperation;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeBuilder;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.Attributes;
import org.opends.server.types.ByteString;
@@ -230,17 +232,17 @@
      fail("Ending test " +  " with exception:"
          +  stackTraceToSingleLineString(de));
    }
    // Test all types of ops.  
    ECLAllOps(); // Do not clean the db for the next test
    // First and last should be ok whenever a request has been done or not
    // in compat mode.
    ECLCompatTestLimits(1,4,true);replicationServer.clearDb();
    // Test with a mix of domains, a mix of DSes
    ECLTwoDomains(); replicationServer.clearDb();
    // Write changes and read ECL from start
    int ts = ECLCompatWriteReadAllOps(1);
@@ -657,13 +659,20 @@
      // Add the root entry in the backend
      Backend backend2 = initializeTestBackend(false, TEST_ROOT_DN_STRING2,
          TEST_BACKEND_ID2);
      backend2.setPrivateBackend(true);
      DN baseDn2 = DN.decode(TEST_ROOT_DN_STRING2);
      SortedSet<String> replServers = new TreeSet<String>();
      replServers.add("localhost:"+replicationServerPort);
      DomainFakeCfg domainConf =
        new DomainFakeCfg(baseDn2,  1602, replServers);
      LDAPReplicationDomain domain2 = MultimasterReplication.createNewDomain(domainConf);
      ExternalChangelogDomainFakeCfg eclCfg =
        new ExternalChangelogDomainFakeCfg(true, null);
      domainConf.setExternalChangelogDomain(eclCfg);
      LDAPReplicationDomain domain2 =
        MultimasterReplication.createNewDomain(domainConf);
      domain2.start();
      sleep(1000);
      Entry e = createEntry(baseDn2);
      addEntry(e);
@@ -716,11 +725,11 @@
          //}
        }
      }
      //
      // Set the backend private and do again a search on ECL that should
      // now not return the entry
      //
      domain2.getBackend().setPrivateBackend(true);
      eclCfg =
        new ExternalChangelogDomainFakeCfg(false, null);
      domainConf.setExternalChangelogDomain(eclCfg);
      domain2.applyConfigurationChange(domainConf);
      debugInfo(tn, "Search with cookie=" + cookie);
      searchOp = connection.processSearch(
@@ -739,8 +748,8 @@
      waitOpResult(searchOp, ResultCode.SUCCESS);
      entries = searchOp.getSearchEntries();
      assertTrue(entries != null);
      assertTrue(entries.size()==1);
      assertTrue(entries != null, "Entries returned when test2 is ECL disabled.");
      assertTrue(entries.size()==1, "#Entry="+entries.size()+"when expected is 1");
      if (entries != null)
        for (SearchResultEntry resultEntry : entries)
        {
@@ -3514,9 +3523,13 @@
      replServers.add("localhost:"+replicationServerPort);
      DomainFakeCfg domainConf =
        new DomainFakeCfg(baseDn2, 1702, replServers);
      SortedSet<String> includeAttributes = new TreeSet<String>();
      includeAttributes.add("sn");
      domainConf.setEclIncludes(includeAttributes);
      // SortedSet<String> includeAttributes = new TreeSet<String>();
      // includeAttributes.add("sn");
      SortedSet<AttributeType> eclInclude = new TreeSet<AttributeType>();
      eclInclude.add(DirectoryServer.getAttributeType("sn"));
      ExternalChangelogDomainFakeCfg eclCfg =
        new ExternalChangelogDomainFakeCfg(true, eclInclude);
      domainConf.setExternalChangelogDomain(eclCfg);
      domain2 = MultimasterReplication.createNewDomain(domainConf);
      domain2.start();
@@ -3525,17 +3538,21 @@
      baseDn3 = DN.decode(TEST_ROOT_DN_STRING3);
      domainConf =
        new DomainFakeCfg(baseDn3, 1703, replServers);
      includeAttributes = new TreeSet<String>();
      includeAttributes.add("objectclass");
      domainConf.setEclIncludes(includeAttributes);
      eclInclude = new TreeSet<AttributeType>();
      eclInclude.add(DirectoryServer.getAttributeType("objectclass"));
      eclCfg =
        new ExternalChangelogDomainFakeCfg(true, eclInclude);
      domainConf.setExternalChangelogDomain(eclCfg);
      domain3 = MultimasterReplication.createNewDomain(domainConf);
      domain3.start();
      domainConf =
        new DomainFakeCfg(baseDn2, 1704, replServers);
      includeAttributes = new TreeSet<String>();
      includeAttributes.add("cn");
      domainConf.setEclIncludes(includeAttributes);
      eclInclude = new TreeSet<AttributeType>();
      eclInclude.add(DirectoryServer.getAttributeType("cn"));
      eclCfg =
        new ExternalChangelogDomainFakeCfg(true, eclInclude);
      domainConf.setExternalChangelogDomain(eclCfg);
      domain21 = MultimasterReplication.createNewDomain(domainConf);
      domain21.start();
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/GenerationIdTest.java
@@ -26,6 +26,8 @@
 */
package org.opends.server.replication;
import static org.opends.server.TestCaseUtils.TEST_BACKEND_ID;
import static org.opends.server.TestCaseUtils.TEST_ROOT_DN_STRING;
import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
@@ -54,7 +56,6 @@
import org.opends.server.core.DirectoryServer;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.replication.service.ReplicationBroker;
import org.opends.server.replication.common.ChangeNumberGenerator;
import org.opends.server.replication.common.ServerStatus;
import org.opends.server.replication.plugin.LDAPReplicationDomain;
@@ -69,10 +70,12 @@
import org.opends.server.replication.server.ReplServerFakeConfiguration;
import org.opends.server.replication.server.ReplicationBackend;
import org.opends.server.replication.server.ReplicationServer;
import org.opends.server.replication.service.ReplicationBroker;
import org.opends.server.tasks.LdifFileWriter;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.ResultCode;
@@ -81,7 +84,6 @@
import org.opends.server.types.SearchScope;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.opends.server.TestCaseUtils.*;
/**
 * Tests contained here:
@@ -117,7 +119,6 @@
  private ReplicationServer replServer2 = null;
  private ReplicationServer replServer3 = null;
  private boolean emptyOldChanges = true;
  LDAPReplicationDomain replDomain = null;
  private Entry taskInitRemoteS2;
  SocketSession ssSession = null;
  boolean ssShutdownRequested = false;
@@ -440,12 +441,21 @@
        "Unable to add the synchronized server");
      configEntryList.add(synchroServerEntry.getDN());
      replDomain = LDAPReplicationDomain.retrievesReplicationDomain(baseDn);
      if (replDomain != null)
      int waitCo=0;
      LDAPReplicationDomain doToco=null;
      while(waitCo<30)
      {
        debugInfo("ReplicationDomain: Import/Export is running ? " + replDomain.ieRunning());
        doToco =
          LDAPReplicationDomain.retrievesReplicationDomain(baseDn);
        if ((doToco!=null) && (doToco.isConnected()))
          break;
        Thread.sleep(200);
        waitCo++;
      }
      assertTrue(doToco.isConnected(), "not connected after #attempt="+waitCo);
      if (doToco != null)
      {
        debugInfo("ReplicationDomain: Import/Export is running ? " + doToco.ieRunning());
      }
    }
    catch(Exception e)
@@ -469,6 +479,14 @@
      assertTrue(synchroServerEntry != null);
      DN synchroServerDN = DN.decode(synchroServerStringDN);
      Entry ecle;
      ecle = DirectoryServer.getConfigHandler().getEntry(
          DN.decode("cn=external changelog," + synchroServerStringDN));
      if (ecle!=null)
      {
        DirectoryServer.getConfigHandler().deleteEntry(ecle.getDN(), null);
      }
      DirectoryServer.getConfigHandler().deleteEntry(synchroServerDN, null);
      assertTrue(DirectoryServer.getConfigEntry(synchroServerEntry.getDN()) ==
        null,
@@ -477,6 +495,23 @@
      configEntryList.remove(configEntryList.indexOf(synchroServerDN));
      LDAPReplicationDomain replDomainToDis = null;
      try
      {
        int waitCo=0;
        while(waitCo<30)
        {
          replDomainToDis =
            LDAPReplicationDomain.retrievesReplicationDomain(baseDn);
          Thread.sleep(200);
          waitCo++;
        }
        assert(replDomainToDis==null);
      }
      catch (DirectoryException e)
      {
        // success
      }
    }
    catch(Exception e)
    {
@@ -703,7 +738,6 @@
      // To search the replication server db later in these tests, we need
      // to attach the search backend to the replication server just created.
      Thread.sleep(500);
      ReplicationBackend b =
        (ReplicationBackend)DirectoryServer.getBackend("replicationChanges");
      b.setServer(replServer1);
@@ -829,7 +863,6 @@
      // To search the replication server db later in these tests, we need
      // to attach the search backend to the replication server just created.
      Thread.sleep(500);
      b = (ReplicationBackend)DirectoryServer.getBackend("replicationChanges");
      b.setServer(replServer1);
@@ -1012,7 +1045,6 @@
      addTask(taskReset, ResultCode.SUCCESS, null);
      waitTaskState(taskReset, TaskState.COMPLETED_SUCCESSFULLY, null);
      Thread.sleep(200);
      debugInfo("Verify that RS1 has still the right genID");
      assertEquals(replServer1.getGenerationId(baseDn.toNormalizedString()), rgenId);
@@ -1126,9 +1158,18 @@
      debugInfo("Connecting DS to replServer1");
      connectServer1ToChangelog(changelog1ID);
      Thread.sleep(1500);
      debugInfo("Expect genId are set in all replServers.");
      int waitRes=0;
      while(waitRes<100)
      {
        if ((replServer1.getGenerationId(baseDn.toNormalizedString())==EMPTY_DN_GENID)
          && (replServer2.getGenerationId(baseDn.toNormalizedString())==EMPTY_DN_GENID)
          && (replServer3.getGenerationId(baseDn.toNormalizedString())==EMPTY_DN_GENID))
          break;
        waitRes++;
        Thread.sleep(100);
      }
      assertEquals(replServer1.getGenerationId(baseDn.toNormalizedString()), EMPTY_DN_GENID,
        " in replServer1");
      assertEquals(replServer2.getGenerationId(baseDn.toNormalizedString()), EMPTY_DN_GENID,
@@ -1138,8 +1179,17 @@
      debugInfo("Disconnect DS from replServer1.");
      disconnectFromReplServer(changelog1ID);
      Thread.sleep(3000);
      waitRes=0;
      while(waitRes<100)
      {
        if ((replServer1.getGenerationId(baseDn.toNormalizedString())==-1)
          && (replServer2.getGenerationId(baseDn.toNormalizedString())==-1)
          && (replServer3.getGenerationId(baseDn.toNormalizedString())==-1))
          break;
        waitRes++;
        Thread.sleep(100);
      }
      debugInfo(
        "Expect genIds to be resetted in all servers to -1 as no more DS in topo");
      assertEquals(replServer1.getGenerationId(baseDn.toNormalizedString()), -1);
@@ -1151,12 +1201,21 @@
      debugInfo("Connecting DS to replServer2");
      connectServer1ToChangelog(changelog2ID);
      Thread.sleep(3000);
      debugInfo(
        "Expect genIds to be set in all servers based on the added entries.");
      genId = readGenIdFromSuffixRootEntry();
      assertTrue(genId != -1);
      waitRes=0;
      while(waitRes<100)
      {
        if ((replServer1.getGenerationId(baseDn.toNormalizedString())==genId)
          && (replServer2.getGenerationId(baseDn.toNormalizedString())==genId)
          && (replServer3.getGenerationId(baseDn.toNormalizedString())==genId))
          break;
        waitRes++;
        Thread.sleep(100);
      }
      assertEquals(replServer1.getGenerationId(baseDn.toNormalizedString()), genId);
      assertEquals(replServer2.getGenerationId(baseDn.toNormalizedString()), genId);
      assertEquals(replServer3.getGenerationId(baseDn.toNormalizedString()), genId);
@@ -1347,7 +1406,6 @@
      // Read generationId - should be not retrievable since no entry
      debugInfo(testCase + " Connecting DS1 to replServer1(" + changelog1ID + ")");
      connectServer1ToChangelog(changelog1ID);
      Thread.sleep(1000);
      debugInfo(testCase + " Expect genId attribute to be not retrievable");
      genId = readGenIdFromSuffixRootEntry();
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ProtocolWindowTest.java
@@ -119,6 +119,7 @@
    DirectoryServer.getConfigHandler().addEntry(repDomainEntry, null);
    assertNotNull(DirectoryServer.getConfigEntry(repDomainEntry.getDN()),
          "Unable to add the synchronized server");
    configEntryList.add(repDomainEntry.getDN());
    ReplicationBroker broker = openReplicationSession(baseDn, 12,
        WINDOW_SIZE, replServerPort, 1000, true);
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ReplicationTestCase.java
@@ -398,35 +398,43 @@
    return broker;
  }
  protected void deleteEntry(DN dn)
  {
    try
    {
    if (dn.getParent().getRDN().toString().equalsIgnoreCase("cn=domains"))
      deleteEntry(DN.decode("cn=external changelog,"+dn.toString()));
    }
    catch(Exception e)
    {}
    DeleteOperationBasis op;
    op = new DeleteOperationBasis(connection, InternalClientConnection
        .nextOperationID(), InternalClientConnection.nextMessageID(), null,
        dn);
    op.run();
    if ((op.getResultCode() != ResultCode.SUCCESS) &&
        (op.getResultCode() != ResultCode.NO_SUCH_OBJECT))
    {
      fail("Delete entry " + dn +
          " failed: " + op.getResultCode().getResultCodeName());
    }
  }
  /**
   * suppress all the config entries created by the tests in this class
   */
  protected void cleanConfigEntries()
  {
    logError(Message.raw(Category.SYNC, Severity.NOTICE,
        "ReplicationTestCase/Cleaning config entries"));
    "ReplicationTestCase/Cleaning config entries"));
    DeleteOperationBasis op;
    // Delete entries
    try
    {
      while (true)
      {
        DN dn = configEntryList.removeLast();
        logError(Message.raw(Category.SYNC, Severity.NOTICE,
                 "cleaning config entry " + dn));
        op = new DeleteOperationBasis(connection, InternalClientConnection
            .nextOperationID(), InternalClientConnection.nextMessageID(), null,
            dn);
        op.run();
        if ((op.getResultCode() != ResultCode.SUCCESS) &&
            (op.getResultCode() != ResultCode.NO_SUCH_OBJECT))
        {
          fail("ReplicationTestCase/Cleaning config entries DEL " + dn +
                   " failed: " + op.getResultCode().getResultCodeName());
        }
        deleteEntry(dn);
      }
    }
    catch (NoSuchElementException e) {
@@ -441,8 +449,8 @@
   */
  protected void cleanRealEntries()
  {
    logError(Message.raw(Category.SYNC, Severity.NOTICE,
        "ReplicationTestCase/Cleaning entries"));
    logError(Message.raw(Category.SYNC, Severity.NOTICE,
    "ReplicationTestCase/Cleaning entries"));
    DeleteOperationBasis op;
    // Delete entries
@@ -451,23 +459,7 @@
      while (true)
      {
        DN dn = entryList.removeLast();
        op = new DeleteOperationBasis(connection,
               InternalClientConnection.nextOperationID(),
               InternalClientConnection.nextMessageID(),
               null,
               dn);
        op.run();
        if ((op.getResultCode() != ResultCode.SUCCESS) &&
            (op.getResultCode() != ResultCode.NO_SUCH_OBJECT))
        {
          logError(Message.raw(Category.SYNC, Severity.NOTICE,
                   "ReplicationTestCase/Cleaning entries" +
                   "DEL " + dn +
                   " failed " + op.getResultCode().getResultCodeName()));
        }
        deleteEntry(dn);
      }
    }
    catch (NoSuchElementException e) {
@@ -1171,29 +1163,8 @@
   */
  protected void removeDomain(Entry domainCfgEntry)
  {
    DeleteOperationBasis op;
    // Delete entries
    try
    {
      DN dn = domainCfgEntry.getDN();
      logError(Message.raw(Category.SYNC, Severity.NOTICE,
        "cleaning config entry " + dn));
      op = new DeleteOperationBasis(connection, InternalClientConnection.
        nextOperationID(), InternalClientConnection.nextMessageID(), null,
        dn);
      op.run();
      if ((op.getResultCode() != ResultCode.SUCCESS) &&
        (op.getResultCode() != ResultCode.NO_SUCH_OBJECT))
      {
        fail("Deleting config entry" + dn +
          " failed: " + op.getResultCode().getResultCodeName());
      }
    } catch (NoSuchElementException e)
    {
      // done
    }
    DN dn = domainCfgEntry.getDN();
    deleteEntry(dn);
  }
  /**
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/DomainFakeCfg.java
@@ -26,17 +26,21 @@
 */
package org.opends.server.replication.plugin;
import java.util.HashSet;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import org.opends.server.admin.Configuration;
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.server.ServerManagedObject;
import org.opends.server.admin.std.meta.ReplicationDomainCfgDefn.AssuredType;
import org.opends.server.admin.std.meta.ReplicationDomainCfgDefn.IsolationPolicy;
import org.opends.server.admin.std.server.ExternalChangelogDomainCfg;
import org.opends.server.admin.std.server.ReplicationDomainCfg;
import org.opends.server.config.ConfigException;
import org.opends.server.types.AttributeType;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
@@ -69,7 +73,9 @@
  private SortedSet<String> fractionalIncludes = new TreeSet<String>();
  private SortedSet<String> eclIncludes = new TreeSet<String>();
  private ExternalChangelogDomainCfg eclCfg =
    new ExternalChangelogDomainFakeCfg(true, new TreeSet<AttributeType>());
  /**
   * Creates a new Domain with the provided information
   * (assured mode disabled, default group id)
@@ -365,8 +371,95 @@
    this.eclIncludes = attrs;
  }
 
  public SortedSet<String> getEclInclude()
  public SortedSet<String> getECLInclude()
  {
    return this.eclIncludes;
  }
  public boolean hasExternalChangelogDomain() { return true; }
  /**
   * Gets the ECL Domain if it is present.
   *
   * @return Returns the ECL Domain if it is present.
   * @throws ConfigException
   *           If the ECL Domain does not exist or it could not
   *           be successfully decoded.
   */
  public ExternalChangelogDomainCfg getExternalChangelogDomain()
  throws ConfigException
  { return eclCfg; }
  /**
   * Sets the ECL Domain if it is present.
   *
   * @return Returns the ECL Domain if it is present.
   * @throws ConfigException
   *           If the ECL Domain does not exist or it could not
   *           be successfully decoded.
   */
  public void  setExternalChangelogDomain(ExternalChangelogDomainCfg eclCfg)
  throws ConfigException
  { this.eclCfg=eclCfg;}
  /**
   * Registers to be notified when the ECL Domain is added.
   *
   * @param listener
   *          The ECL Domain configuration add listener.
   * @throws ConfigException
   *          If the add listener could not be registered.
   */
  public
  void addECLDomainAddListener(
      ConfigurationAddListener<ExternalChangelogDomainCfg> listener)
  throws ConfigException
  {}
  /**
   * Deregisters an existing ECL Domain configuration add listener.
   *
   * @param listener
   *          The ECL Domain configuration add listener.
   */
  public void removeECLDomainAddListener(
      ConfigurationAddListener<ExternalChangelogDomainCfg>
  listener)
  {}
  /**
   * Registers to be notified the ECL Domain is deleted.
   *
   * @param listener
   *          The ECL Domain configuration delete listener.
   * @throws ConfigException
   *          If the delete listener could not be registered.
   */
  public void
  addECLDomainDeleteListener(
      ConfigurationDeleteListener<ExternalChangelogDomainCfg> listener)
  throws ConfigException
  {}
  /**
   * Deregisters an existing ECL Domain configuration delete listener.
   *
   * @param listener
   *          The ECL Domain configuration delete listener.
   */
  public void
  removeECLDomainDeleteListener(
      ConfigurationDeleteListener<ExternalChangelogDomainCfg> listener)
  {}
}
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/ExternalChangelogDomainFakeCfg.java
New file
@@ -0,0 +1,154 @@
/*
 * 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-2009 Sun Microsystems, Inc.
 */
package org.opends.server.replication.plugin;
import java.util.SortedSet;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.ExternalChangelogDomainCfg;
import org.opends.server.types.AttributeType;
import org.opends.server.types.DN;
/**
 * This class implement a configuration object for the ExternalChangelog domain
 * that can be used in unit tests to instantiate ExternalChangelogDomain.
 */
public class ExternalChangelogDomainFakeCfg
  implements ExternalChangelogDomainCfg
{
  // The value of the "ecl-include" property.
  private SortedSet<AttributeType> pECLInclude;
  // The value of the "enabled" property.
  private boolean pEnabled;
  private DN pDN;
  /**
   * Creates a new Domain with the provided information
   * (assured mode disabled, default group id)
   */
  public ExternalChangelogDomainFakeCfg(boolean isEnabled,
      SortedSet<AttributeType> eCLInclude)
  {
    this.pEnabled = isEnabled;
    this.pECLInclude = eCLInclude;
  }
  /**
   * {@inheritDoc}
   */
  public Class<? extends ExternalChangelogDomainCfg> configurationClass()
  {
    return null;
  }
  /**
   * Register to be notified when this External Changelog Domain is changed.
   *
   * @param listener
   *          The External Changelog Domain configuration change listener.
   */
  public void addChangeListener(
      ConfigurationChangeListener<ExternalChangelogDomainCfg> listener)
  {}
  /**
   * Deregister an existing External Changelog Domain configuration change listener.
   *
   * @param listener
   *          The External Changelog Domain configuration change listener.
   */
  public void removeChangeListener(
      ConfigurationChangeListener<ExternalChangelogDomainCfg> listener)
  {}
  /**
   * Gets the "ecl-include" property.
   * <p>
   * Allows to include some target entry attributes in the external
   * changelog.
   * <p>
   * Specifies an attribute that will be included in every External
   * Change Log entry related to this replication domain.
   *
   * @return Returns an unmodifiable set containing the values of the "ecl-include" property.
   */
  public SortedSet<AttributeType> getECLInclude()
  {
    return this.pECLInclude;
  }
  /**
   * Set eclInclude.
   * @param eclInclude the attribute to include.
   */
  public void setECLInclude(SortedSet<AttributeType> eclInclude)
  {
    this.pECLInclude = eclInclude;
  }
  /**
   * Set enabled.
   * @param enabled a.
   */
  public void setEnable(boolean enabled)
  {
    this.pEnabled = enabled;
  }
  /**
   * Gets the "enabled" property.
   * <p>
   * Indicates whether the External Changelog Domain is enabled for
   * use.
   *
   * @return Returns the value of the "enabled" property.
   */
  public boolean isEnabled()
  {
    return this.pEnabled;
  }
  public DN dn()
  {
    return pDN;
  }
  public void setDN(DN dn)
  {
    this.pDN = dn;
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/MonitorTest.java
@@ -267,14 +267,9 @@
      SYNCHRO_PLUGIN_DN;
      // Must have called connectServer1ToChangelog previously
      assertTrue(synchroServerEntry != null);
      DN synchroServerDN = DN.decode(synchroServerStringDN);
      DirectoryServer.getConfigHandler().deleteEntry(synchroServerDN, null);
      assertTrue(DirectoryServer.getConfigEntry(synchroServerEntry.getDN()) ==
        null,
        "Unable to delete the synchronized domain");
      deleteEntry(synchroServerDN);
      synchroServerEntry = null;
      configEntryList.remove(configEntryList.indexOf(synchroServerDN));
    }