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

gbellato
26.17.2007 d5193b4f72a86a30a116b4629d1db5231dd42992
This commit allows to complete issues 504, 505 and 507 by using the new
import/export/backup/restore interface to get notifications of import
and restore and then resynchronize the server approprietely.

It was necessary to move the call to the import and restore listeners in the
import and restore task implementations because these calls were made too
late and the backend that were given in parameter were already invalid when
the listeners are called.

This code is already covered by the ReSyncTest.java
6 files modified
229 ■■■■■ changed files
opends/src/server/org/opends/server/synchronization/plugin/MultimasterSynchronization.java 177 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tasks/ImportTask.java 13 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tasks/RestoreTask.java 13 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/ReSyncTest.java 23 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SchemaSynchronizationTest.java 1 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/StressTest.java 2 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/synchronization/plugin/MultimasterSynchronization.java
@@ -30,9 +30,14 @@
import java.util.List;
import java.util.Map;
import org.opends.server.api.Backend;
import org.opends.server.api.BackupTaskListener;
import org.opends.server.api.ConfigAddListener;
import org.opends.server.api.ConfigChangeListener;
import org.opends.server.api.ConfigDeleteListener;
import org.opends.server.api.ExportTaskListener;
import org.opends.server.api.ImportTaskListener;
import org.opends.server.api.RestoreTaskListener;
import org.opends.server.api.SynchronizationProvider;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
@@ -47,8 +52,12 @@
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.Operation;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.Modification;
import org.opends.server.types.RestoreConfig;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SynchronizationProviderResult;
@@ -63,7 +72,10 @@
 * as pre-op, conflictRsolution, and post-op.
 */
public class MultimasterSynchronization extends SynchronizationProvider
       implements ConfigAddListener, ConfigDeleteListener, ConfigChangeListener
       implements ConfigAddListener, ConfigDeleteListener, ConfigChangeListener,
       BackupTaskListener, RestoreTaskListener, ImportTaskListener,
       ExportTaskListener
{
  static String CHANGELOG_DN = "cn=Changelog Server," +
    "cn=Multimaster Synchronization, cn=Synchronization Providers, cn=config";
@@ -131,6 +143,11 @@
    {
      processSchemaChange(offlineSchemaChanges);
    }
    DirectoryServer.registerBackupTaskListener(this);
    DirectoryServer.registerRestoreTaskListener(this);
    DirectoryServer.registerExportTaskListener(this);
    DirectoryServer.registerImportTaskListener(this);
  }
  /**
@@ -453,6 +470,11 @@
    // shutdown the Changelog Service if necessary
    if (changelog != null)
      changelog.shutdown();
    DirectoryServer.deregisterBackupTaskListener(this);
    DirectoryServer.deregisterRestoreTaskListener(this);
    DirectoryServer.deregisterExportTaskListener(this);
    DirectoryServer.deregisterImportTaskListener(this);
  }
  /**
@@ -504,51 +526,6 @@
    return;
  }
  /**
   * Handle a Notification of restore start from the core server.
   *
   * @param dn The baseDn of the restore.
   */
  public static void notificationRestoreStart(DN dn)
  {
    SynchronizationDomain domain = findDomain(dn, null);
    domain.disable();
  }
  /**
   * Handle a Notification of restore end from the core server.
   *
   * @param dn The baseDn of the restore.
   */
  public static void notificationRestoreEnd(DN dn)
  {
    SynchronizationDomain domain = findDomain(dn, null);
    domain.enable();
  }
  /**
   * Handle a Notification of backup start from the core server.
   *
   * @param dn The baseDn of the backup.
   */
  public static void notificationBackupStart(DN dn)
  {
    SynchronizationDomain domain = findDomain(dn, null);
    domain.backupStart();
  }
  /**
   * Handle a Notification of backup end from the core server.
   *
   * @param dn The baseDn of the backup.
   */
  public static void notificationBackupEnd(DN dn)
  {
    SynchronizationDomain domain = findDomain(dn, null);
    domain.backupEnd();
  }
  /**
   * This method is called whenever the server detects a modification
   * of the schema done by directly modifying the backing files
@@ -566,6 +543,114 @@
    if (domain != null)
      domain.synchronizeModifications(modifications);
  }
  /**
   * {@inheritDoc}
   */
  public void processBackupBegin(Backend backend, BackupConfig config)
  {
    for (DN dn : backend.getBaseDNs())
    {
      SynchronizationDomain domain = findDomain(dn, null);
      if (domain != null)
        domain.backupStart();
    }
  }
  /**
   * {@inheritDoc}
   */
  public void processBackupEnd(Backend backend, BackupConfig config,
                               boolean successful)
  {
    for (DN dn : backend.getBaseDNs())
    {
      SynchronizationDomain domain = findDomain(dn, null);
      if (domain != null)
        domain.backupEnd();
    }
  }
  /**
   * {@inheritDoc}
   */
  public void processRestoreBegin(Backend backend, RestoreConfig config)
  {
    for (DN dn : backend.getBaseDNs())
    {
      SynchronizationDomain domain = findDomain(dn, null);
      if (domain != null)
        domain.disable();
    }
  }
  /**
   * {@inheritDoc}
   */
  public void processRestoreEnd(Backend backend, RestoreConfig config,
                                boolean successful)
  {
    for (DN dn : backend.getBaseDNs())
    {
      SynchronizationDomain domain = findDomain(dn, null);
      if (domain != null)
        domain.enable();
    }
  }
  /**
   * {@inheritDoc}
   */
  public void processImportBegin(Backend backend, LDIFImportConfig config)
  {
    for (DN dn : backend.getBaseDNs())
    {
      SynchronizationDomain domain = findDomain(dn, null);
      if (domain != null)
        domain.disable();
    }
  }
  /**
   * {@inheritDoc}
   */
  public void processImportEnd(Backend backend, LDIFImportConfig config,
                               boolean successful)
  {
    for (DN dn : backend.getBaseDNs())
    {
      SynchronizationDomain domain = findDomain(dn, null);
      if (domain != null)
        domain.enable();
    }
  }
  /**
   * {@inheritDoc}
   */
  public void processExportBegin(Backend backend, LDIFExportConfig config)
  {
    for (DN dn : backend.getBaseDNs())
    {
      SynchronizationDomain domain = findDomain(dn, null);
      if (domain != null)
        domain.backupStart();
    }
  }
  /**
   * {@inheritDoc}
   */
  public void processExportEnd(Backend backend, LDIFExportConfig config,
                               boolean successful)
  {
    for (DN dn : backend.getBaseDNs())
    {
      SynchronizationDomain domain = findDomain(dn, null);
      if (domain != null)
        domain.backupEnd();
    }
  }
}
opends/src/server/org/opends/server/tasks/ImportTask.java
@@ -32,7 +32,6 @@
import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import org.opends.server.types.DebugLogLevel;
import static org.opends.server.loggers.Error.logError;
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.core.DirectoryServer.getAttributeType;
@@ -473,6 +472,11 @@
    DN[] baseDNs = new DN[defaultIncludeBranches.size()];
    defaultIncludeBranches.toArray(baseDNs);
    // Notify the task listeners that an import is going to start
    // this must be done before disabling the backend to allow
    // listeners to get access to the backend configuration
    // and to take appropriate actions.
    DirectoryServer.notifyImportBeginning(backend, importConfig);
    // Disable the backend.
    try
@@ -528,9 +532,7 @@
      // Launch the import.
      try
      {
        DirectoryServer.notifyImportBeginning(backend, importConfig);
        backend.importLDIF(configEntry, baseDNs, importConfig);
        DirectoryServer.notifyImportEnded(backend, importConfig, true);
      }
      catch (DirectoryException de)
      {
@@ -600,6 +602,10 @@
      try
      {
        TaskUtils.setBackendEnabled(configEntry, true);
        // It is necessary to retrieve the backend structure again
        // because disabling and enabling it again may have resulted
        // in a new backend being registered to the server.
        backend = DirectoryServer.getBackend(backendID);
      }
      catch (DirectoryException e)
      {
@@ -612,6 +618,7 @@
                 e.getErrorMessage(), e.getErrorMessageID());
        return TaskState.STOPPED_BY_ERROR;
      }
      DirectoryServer.notifyImportEnded(backend, importConfig, true);
    }
opends/src/server/org/opends/server/tasks/RestoreTask.java
@@ -289,6 +289,11 @@
    RestoreConfig restoreConfig = new RestoreConfig(backupDir, backupID,
                                                    verifyOnly);
    // Notify the task listeners that a restore is going to start
    // this must be done before disabling the backend to allow
    // listener to get access to the backend configuration
    // and to take appropriate actions.
    DirectoryServer.notifyRestoreBeginning(backend, restoreConfig);
    // Disable the backend.
    try
@@ -307,7 +312,6 @@
      return TaskState.STOPPED_BY_ERROR;
    }
    // From here we must make sure to re-enable the backend before returning.
    boolean errorsEncountered = false;
    try
@@ -321,9 +325,7 @@
          // Perform the restore.
          try
          {
            DirectoryServer.notifyRestoreBeginning(backend, restoreConfig);
            backend.restoreBackup(configEntry, restoreConfig);
            DirectoryServer.notifyRestoreEnded(backend, restoreConfig, true);
          }
          catch (DirectoryException de)
          {
@@ -362,6 +364,10 @@
      try
      {
        TaskUtils.setBackendEnabled(configEntry, true);
        // it is necessary to retrieve the backend structure again
        // because disabling and enabling it again may have resulted
        // in a new backend being registered to the server.
        backend = DirectoryServer.getBackend(backendID);
      }
      catch (DirectoryException e)
      {
@@ -374,6 +380,7 @@
                 e.getErrorMessage(), e.getErrorMessageID());
        errorsEncountered = true;
      }
      DirectoryServer.notifyRestoreEnded(backend, restoreConfig, true);
    }
    if (errorsEncountered)
opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/ReSyncTest.java
@@ -42,7 +42,6 @@
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.schema.DirectoryStringSyntax;
import org.opends.server.synchronization.plugin.MultimasterSynchronization;
import org.opends.server.types.AttributeType;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
@@ -169,10 +168,6 @@
    // we do test something.
    connection.processDelete(DN.decode("dc=foo, dc=example,dc=com"));
    MultimasterSynchronization.notificationBackupStart(
        DN.decode("dc=example,dc=com")); // TEMPORARY UNTIL core server
                                        // sends a notification
    task("dn: ds-task-id=" + UUID.randomUUID()
        +  ",cn=Scheduled Tasks,cn=Tasks\n"
        + "objectclass: top\n"
@@ -185,9 +180,6 @@
    addEntry("dn: dc=foo, dc=example,dc=com\n"
        + "objectClass: top\n" + "objectClass: domain\n");
    MultimasterSynchronization.notificationRestoreStart(
        DN.decode("dc=example,dc=com"));// TEMPORARY UNTIL core server
                                       //  sends a notification
    task("dn: ds-task-id=" + UUID.randomUUID()
        + ",cn=Scheduled Tasks,cn=Tasks\n"
        + "objectclass: top\n"
@@ -197,10 +189,6 @@
        + "ds-backup-directory-path: bak" + File.separator
        + "userRoot\n");
    MultimasterSynchronization.notificationRestoreEnd(
        DN.decode("dc=example,dc=com"));// TEMPORARY UNTIL core server
                                       // sends a notification
   if (getEntry(DN.decode("dc=foo, dc=example,dc=com"), 30000, true) == null)
     fail("The Directory has not been resynchronized after the restore.");
@@ -224,10 +212,6 @@
    // we do test something.
    connection.processDelete(DN.decode("dc=foo, dc=example,dc=com"));
    MultimasterSynchronization.notificationBackupStart(
        DN.decode("dc=example,dc=com")); // TEMPORARY UNTIL core server
                                        // sends a notification
    String buildRoot = System.getProperty(TestCaseUtils.PROPERTY_BUILD_ROOT);
    String path = buildRoot + File.separator + "build" +
                  File.separator + "unit-tests" + File.separator +
@@ -245,9 +229,6 @@
    addEntry("dn: dc=foo, dc=example,dc=com\n"
        + "objectClass: top\n" + "objectClass: domain\n");
    MultimasterSynchronization.notificationRestoreStart(
        DN.decode("dc=example,dc=com"));// TEMPORARY UNTIL core server
                                       //  sends a notification
    task("dn: ds-task-id=" + UUID.randomUUID()
        + ",cn=Scheduled Tasks,cn=Tasks\n"
        + "objectclass: top\n"
@@ -258,10 +239,6 @@
        + "ds-task-import-ldif-file: " + path + "\n"
        + "ds-task-import-reject-file: " + path + "reject\n");
    MultimasterSynchronization.notificationRestoreEnd(
        DN.decode("dc=example,dc=com"));// TEMPORARY UNTIL core server
                                       //  sends a notification
   if (getEntry(DN.decode("dc=foo, dc=example,dc=com"), 30000, true) == null)
     fail("The Directory has not been resynchronized after the restore.");
  }
opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SchemaSynchronizationTest.java
@@ -46,7 +46,6 @@
import org.opends.server.protocols.ldap.LDAPModification;
import org.opends.server.synchronization.common.ChangeNumberGenerator;
import org.opends.server.synchronization.plugin.ChangelogBroker;
import org.opends.server.synchronization.plugin.MultimasterSynchronization;
import org.opends.server.synchronization.protocol.ModifyMsg;
import org.opends.server.synchronization.protocol.SynchronizationMessage;
import org.opends.server.types.Attribute;
opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/StressTest.java
@@ -32,14 +32,12 @@
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import org.opends.server.TestCaseUtils;
import org.opends.server.TestErrorLogger;
import org.opends.server.api.MonitorProvider;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;