From 4fe72a4bef946169b0f50bc05bd9dc3b4b1131d3 Mon Sep 17 00:00:00 2001
From: pgamba <pgamba@localhost>
Date: Fri, 14 Aug 2009 12:37:19 +0000
Subject: [PATCH] Support for External change log compatible with draft-good-ldap-changelog-04.txt , March 2003
---
opends/src/server/org/opends/server/replication/server/ReplicationServer.java | 143 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 141 insertions(+), 2 deletions(-)
diff --git a/opends/src/server/org/opends/server/replication/server/ReplicationServer.java b/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
index 77d068f..0b2ae52 100644
--- a/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
+++ b/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
@@ -42,6 +42,7 @@
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -67,6 +68,7 @@
import org.opends.server.core.networkgroups.NetworkGroup;
import org.opends.server.loggers.LogLevel;
import org.opends.server.loggers.debug.DebugTracer;
+import org.opends.server.replication.common.ChangeNumber;
import org.opends.server.replication.common.ExternalChangeLogSession;
import org.opends.server.replication.protocol.ProtocolSession;
import org.opends.server.replication.protocol.ReplServerStartMsg;
@@ -164,6 +166,13 @@
// the DS in DEGRADED_STATUS. If value is 0, status analyzer is disabled
private int degradedStatusThreshold = 5000;
+ // The handler of the draft change numbers database, the database used to
+ // store the relation between a draft change number ('seqnum') and the
+ // associated cookie.
+ private DraftCNDbHandler draftCNDbHandler;
+ // The last value generated of the draft change number.
+ private int lastGeneratedDraftCN = 0;
+
/**
* The tracer object for the debug logger.
*/
@@ -1154,7 +1163,7 @@
* Returns null if none.
* @return the iterator.
*/
- public Iterator<ReplicationServerDomain> getCacheIterator()
+ public Iterator<ReplicationServerDomain> getDomainIterator()
{
if (!baseDNs.isEmpty())
return baseDNs.values().iterator();
@@ -1167,7 +1176,7 @@
*/
public void clearDb()
{
- Iterator<ReplicationServerDomain> rcachei = getCacheIterator();
+ Iterator<ReplicationServerDomain> rcachei = getDomainIterator();
if (rcachei != null)
{
while (rcachei.hasNext())
@@ -1445,4 +1454,134 @@
return false;
}
}
+
+ private ArrayList<String> excludedServiceIDs;
+ /**
+ * Excluded a list of domain from eligibility computation.
+ * @param excludedServiceIDs the provided list of serviceIDs excluded from
+ * the computation of eligibleCN.
+ */
+ public void disableEligibility(ArrayList<String> excludedServiceIDs)
+ {
+ this.excludedServiceIDs = excludedServiceIDs;
+ }
+
+ /**
+ * Returns the eligible CN cross domains - relies on the eligible CN from
+ * each domain.
+ * @return the cross domain eligible CN.
+ */
+ public ChangeNumber getEligibleCN()
+ {
+ String debugLog = "";
+
+ // traverse the domains and get the eligible CN from each domain
+ // store the oldest one as the cross domain eligible CN
+ ChangeNumber eligibleCN = null;
+ Iterator<ReplicationServerDomain> rsdi = this.getDomainIterator();
+ if (rsdi != null)
+ {
+ while (rsdi.hasNext())
+ {
+ ReplicationServerDomain domain = rsdi.next();
+
+ if (excludedServiceIDs.contains(domain.getBaseDn()))
+ {
+ continue;
+ }
+
+ ChangeNumber domainEligibleCN = domain.getEligibleCN();
+ String dates = "";
+ if (domainEligibleCN != null)
+ {
+ if ((eligibleCN == null) || (domainEligibleCN.older(eligibleCN)))
+ {
+ eligibleCN = domainEligibleCN;
+ }
+ dates = new Date(domainEligibleCN.getTime()).toString();
+ }
+ debugLog += "[dn=" + domain.getBaseDn()
+ + "] [eligibleCN=" + domainEligibleCN + ", " + dates + "]";
+ }
+ }
+
+ if (eligibleCN==null)
+ {
+ eligibleCN = new ChangeNumber(0,0,(short)0);
+ }
+
+ if (debugEnabled())
+ TRACER.debugInfo("In " + this +
+ " getEligibleCN() ends with " +
+ " the following domainEligibleCN for each domain :" + debugLog +
+ " thus CrossDomainEligibleCN=" + eligibleCN +
+ " ts=" +
+ (eligibleCN!=null?
+ new Date(eligibleCN.getTime()).toString(): null));
+
+ return eligibleCN;
+ }
+
+ /**
+ * Get or create a handler on a Db on DraftCN for external changelog.
+ * @return the handler.
+ * @throws DirectoryException when needed.
+ */
+ public synchronized DraftCNDbHandler getDraftCNDbHandler()
+ throws DirectoryException
+ {
+ try
+ {
+ if (draftCNDbHandler == null)
+ {
+ draftCNDbHandler = new DraftCNDbHandler(this, this.dbEnv);
+ if (draftCNDbHandler == null)
+ return null;
+ this.lastGeneratedDraftCN = getLastDraftChangeNumber();
+ }
+ return draftCNDbHandler;
+ }
+ catch (Exception e)
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ MessageBuilder mb = new MessageBuilder();
+ mb.append(ERR_DRAFT_CHANGENUMBER_DATABASE.get(""));
+ throw new DirectoryException(ResultCode.OPERATIONS_ERROR,
+ mb.toMessage(), e);
+ }
+ }
+
+ /**
+ * Get the value of the first draft change number, 0 when db is empty.
+ * @return the first value.
+ */
+ public int getFirstDraftChangeNumber()
+ {
+ int first=0;
+ if (draftCNDbHandler != null)
+ first = draftCNDbHandler.getFirstKey();
+ return first;
+ }
+
+ /**
+ * Get the value of the last draft change number, 0 when db is empty.
+ * @return the last value.
+ */
+ public int getLastDraftChangeNumber()
+ {
+ int last=0;
+ if (draftCNDbHandler != null)
+ last = draftCNDbHandler.getLastKey();
+ return last;
+ }
+
+ /**
+ * Generate a new Draft ChangeNumber.
+ * @return The generated Draft ChangeNUmber
+ */
+ synchronized public int getNewDraftCN()
+ {
+ return ++lastGeneratedDraftCN;
+ }
+
}
--
Gitblit v1.10.0