| | |
| | | import java.util.*; |
| | | import java.util.concurrent.CopyOnWriteArraySet; |
| | | import java.util.concurrent.atomic.AtomicBoolean; |
| | | import java.util.concurrent.atomic.AtomicReference; |
| | | |
| | | import org.opends.messages.Category; |
| | | import org.opends.messages.Message; |
| | | import org.opends.messages.Severity; |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import org.opends.server.admin.std.meta.ReplicationServerCfgDefn.ReplicationDBImplementation; |
| | | import org.opends.server.admin.std.meta.VirtualAttributeCfgDefn.ConflictBehavior; |
| | |
| | | import org.opends.server.backends.ChangelogBackend; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.core.WorkflowImpl; |
| | | import org.opends.server.core.networkgroups.NetworkGroup; |
| | | import org.opends.server.loggers.debug.DebugLogger; |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | | import org.opends.server.replication.common.*; |
| | |
| | | import org.opends.server.replication.server.changelog.je.JEChangelogDB; |
| | | import org.opends.server.replication.service.DSRSShutdownSync; |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.util.ServerConstants; |
| | | import org.opends.server.util.StaticUtils; |
| | | import org.opends.server.workflowelement.externalchangelog.ECLWorkflowElement; |
| | | |
| | | import static org.opends.messages.ConfigMessages.*; |
| | | import static org.opends.messages.ReplicationMessages.*; |
| | |
| | | /** The tracer object for the debug logger. */ |
| | | private static final DebugTracer TRACER = getTracer(); |
| | | |
| | | private static final String eclWorkflowID = |
| | | "External Changelog Workflow ID"; |
| | | private ECLWorkflowElement eclwe; |
| | | private final AtomicReference<WorkflowImpl> eclWorkflowImpl = |
| | | new AtomicReference<WorkflowImpl>(); |
| | | |
| | | /** |
| | | * This is required for unit testing, so that we can keep track of all the |
| | | * replication servers which are running in the VM. |
| | |
| | | this.config = cfg; |
| | | this.dsrsShutdownSync = dsrsShutdownSync; |
| | | this.domainPredicate = predicate; |
| | | |
| | | enableExternalChangeLog(); |
| | | ReplicationDBImplementation dbImpl = cfg.getReplicationDBImplementation(); |
| | | if (DebugLogger.debugEnabled()) |
| | | { |
| | |
| | | initialize(); |
| | | cfg.addChangeListener(this); |
| | | |
| | | // TODO : uncomment to branch changelog backend |
| | | //enableExternalChangeLog(); |
| | | |
| | | localPorts.add(getReplicationPort()); |
| | | |
| | | // Keep track of this new instance |
| | |
| | | listenThread = new ReplicationServerListenThread(this); |
| | | listenThread.start(); |
| | | |
| | | // Creates the ECL workflow elem so that DS (LDAPReplicationDomain) |
| | | // can know me and really enableECL. |
| | | if (WorkflowImpl.getWorkflow(eclWorkflowID) != null) |
| | | { |
| | | // Already done. Nothing to do |
| | | return; |
| | | } |
| | | eclwe = new ECLWorkflowElement(this); |
| | | |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugInfo("RS " + getMonitorInstanceName() |
| | |
| | | Message message = ERR_COULD_NOT_BIND_CHANGELOG.get( |
| | | getReplicationPort(), e.getMessage()); |
| | | logError(message); |
| | | } catch (DirectoryException e) |
| | | { |
| | | //FIXME:DirectoryException is raised by initializeECL => fix err msg |
| | | Message message = Message.raw(Category.SYNC, Severity.SEVERE_ERROR, |
| | | "Directory Exception raised by ECL initialization: " + e.getMessage()); |
| | | logError(message); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Enable the ECL access by creating a dedicated workflow element. |
| | | * @throws DirectoryException when an error occurs. |
| | | */ |
| | | public void enableECL() throws DirectoryException |
| | | { |
| | | if (eclWorkflowImpl.get() != null) |
| | | { |
| | | // ECL is already enabled, do nothing |
| | | return; |
| | | } |
| | | |
| | | // Create the workflow for the base DN |
| | | // and register the workflow with the server. |
| | | final DN dn = DN.decode(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT); |
| | | final WorkflowImpl workflowImpl = new WorkflowImpl(eclWorkflowID, dn, |
| | | eclwe.getWorkflowElementID(), eclwe); |
| | | if (!eclWorkflowImpl.compareAndSet(null, workflowImpl)) |
| | | { |
| | | // ECL is being enabled, do nothing |
| | | return; |
| | | } |
| | | |
| | | workflowImpl.register(); |
| | | |
| | | NetworkGroup.getDefaultNetworkGroup().registerWorkflow(workflowImpl); |
| | | |
| | | // FIXME:ECL should the ECL Workflow be registered in admin and internal |
| | | // network groups? |
| | | NetworkGroup.getAdminNetworkGroup().registerWorkflow(workflowImpl); |
| | | NetworkGroup.getInternalNetworkGroup().registerWorkflow(workflowImpl); |
| | | |
| | | registerVirtualAttributeRules(); |
| | | } |
| | | |
| | | /** |
| | | * Enable the external changelog if it is not already enabled. |
| | | * <p> |
| | | * The external changelog is provided by the changelog backend. |
| | |
| | | } |
| | | } |
| | | |
| | | private void shutdownECL() |
| | | { |
| | | WorkflowImpl eclwf = (WorkflowImpl) WorkflowImpl.getWorkflow(eclWorkflowID); |
| | | // do it only if not already done by another RS (unit test case) |
| | | if (eclwf != null) |
| | | { |
| | | // FIXME:ECL should the ECL Workflow be registered in admin and internal |
| | | // network groups? |
| | | NetworkGroup.getInternalNetworkGroup().deregisterWorkflow(eclWorkflowID); |
| | | NetworkGroup.getAdminNetworkGroup().deregisterWorkflow(eclWorkflowID); |
| | | |
| | | NetworkGroup.getDefaultNetworkGroup().deregisterWorkflow(eclWorkflowID); |
| | | |
| | | deregisterVirtualAttributeRules(); |
| | | |
| | | eclwf.deregister(); |
| | | eclwf.finalizeWorkflow(); |
| | | } |
| | | |
| | | eclwe = (ECLWorkflowElement) DirectoryServer |
| | | .getWorkflowElement("EXTERNAL CHANGE LOG"); |
| | | if (eclwe != null) |
| | | { |
| | | DirectoryServer.deregisterWorkflowElement(eclwe); |
| | | eclwe.finalizeWorkflowElement(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the ReplicationServerDomain associated to the base DN given in |
| | | * parameter. |
| | |
| | | domain.shutdown(); |
| | | } |
| | | |
| | | // TODO : switch to second method when changelog backend is branched |
| | | shutdownECL(); |
| | | //shutdownExternalChangelog(); |
| | | shutdownExternalChangelog(); |
| | | |
| | | try |
| | | { |