From 10b41fbd56bb15230d9070fb9eeacac4772dfe9d Mon Sep 17 00:00:00 2001
From: pgamba <pgamba@localhost>
Date: Wed, 19 Sep 2007 09:22:21 +0000
Subject: [PATCH] #793 / Ability to search the replication server db
---
opendj-sdk/opends/src/messages/messages/replication.properties | 8
opendj-sdk/opends/src/server/org/opends/server/replication/plugin/ReplicationServerListener.java | 9
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/ReplicationServerTest.java | 186 ++++++++++++++++
opendj-sdk/opends/src/server/org/opends/server/api/Backend.java | 2
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java | 3
opendj-sdk/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java | 10
opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationBackend.java | 405 +++++++++++++++++++++++++++++++-----
7 files changed, 552 insertions(+), 71 deletions(-)
diff --git a/opendj-sdk/opends/src/messages/messages/replication.properties b/opendj-sdk/opends/src/messages/messages/replication.properties
index e6226a9..aefafdf 100644
--- a/opendj-sdk/opends/src/messages/messages/replication.properties
+++ b/opendj-sdk/opends/src/messages/messages/replication.properties
@@ -229,8 +229,12 @@
testing existence or creating the replication backend : %s
SEVERE_ERR_DELETE_REPL_BACKEND_FAILED_90=An unexpected error occurred when \
deleting the replication backend : %s
-SEVERE_ERR_EXPORT_CANNOT_WRITE_ENTRY_TO_LDIF_91=An error occurred when \
- exporting to LDIF the entry %s : %s
+ SEVERE_ERR_BACKEND_EXPORT_ENTRY_91=An error occurred when \
+ exporting the entry %s : %s
SEVERE_ERR_BACKEND_CANNOT_CREATE_LDIF_WRITER_92 =An error occurred when \
creating the LDIF writer to export backend : %s
+SEVERE_ERR_BACKEND_SEARCH_ENTRY_93 =An error occurred when \
+ searching for %s : %s
+ SEVERE_ERR_REPLICATIONBACKEND_ENTRY_DOESNT_EXIST_94=Entry %s does not exist in \
+ the replication server backend
\ No newline at end of file
diff --git a/opendj-sdk/opends/src/server/org/opends/server/api/Backend.java b/opendj-sdk/opends/src/server/org/opends/server/api/Backend.java
index 4651075..da13ee7 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/api/Backend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/api/Backend.java
@@ -1056,11 +1056,9 @@
return false;
}
}
-
return true;
}
}
-
return false;
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
index 9e4b11e..b3244ac 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
@@ -782,7 +782,8 @@
Attribute ocAttr = entry.getObjectClassAttribute();
try
{
- entryToReturn.setObjectClasses(ocAttr.getValues());
+ if (ocAttr != null)
+ entryToReturn.setObjectClasses(ocAttr.getValues());
}
catch (DirectoryException e)
{
diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java b/opendj-sdk/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java
index f09fa82..d462805 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java
@@ -609,6 +609,16 @@
return;
}
+
+ /**
+ * Returns the replication server listener associated to that Multimaster
+ * Replication.
+ * @return the listener.
+ */
+ public ReplicationServerListener getReplicationServerListener()
+ {
+ return replicationServerListener;
+ }
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/plugin/ReplicationServerListener.java b/opendj-sdk/opends/src/server/org/opends/server/replication/plugin/ReplicationServerListener.java
index ccd31fc..5944004 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/plugin/ReplicationServerListener.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/plugin/ReplicationServerListener.java
@@ -137,4 +137,13 @@
{
return true;
}
+
+ /**
+ * Returns the associated Replication Server.
+ * @return The replication server.
+ */
+ public ReplicationServer getReplicationServer()
+ {
+ return replicationServer;
+ }
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationBackend.java b/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationBackend.java
index 5ce0a43..0a4596d 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationBackend.java
@@ -34,11 +34,17 @@
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
import static org.opends.server.util.StaticUtils.getExceptionMessage;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Timer;
@@ -49,6 +55,7 @@
import org.opends.server.admin.std.server.BackendCfg;
import org.opends.server.admin.std.server.JEBackendCfg;
import org.opends.server.api.Backend;
+import org.opends.server.api.SynchronizationProvider;
import org.opends.server.backends.jeb.BackupManager;
import org.opends.server.config.ConfigException;
import org.opends.server.core.AddOperation;
@@ -59,6 +66,8 @@
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.internal.InternalClientConnection;
+import org.opends.server.replication.plugin.MultimasterReplication;
+import org.opends.server.replication.plugin.ReplicationServerListener;
import org.opends.server.replication.protocol.AddMsg;
import org.opends.server.replication.protocol.DeleteMsg;
import org.opends.server.replication.protocol.ModifyDNMsg;
@@ -70,6 +79,7 @@
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.ConditionResult;
+import org.opends.server.types.Control;
import org.opends.server.types.DN;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
@@ -81,8 +91,11 @@
import org.opends.server.types.RawAttribute;
import org.opends.server.types.RestoreConfig;
import org.opends.server.types.ResultCode;
+import org.opends.server.types.SearchFilter;
+import org.opends.server.types.SearchScope;
import org.opends.server.util.AddChangeRecordEntry;
import org.opends.server.util.DeleteChangeRecordEntry;
+import org.opends.server.util.LDIFReader;
import org.opends.server.util.LDIFWriter;
import org.opends.server.util.ModifyChangeRecordEntry;
import org.opends.server.util.ModifyDNChangeRecordEntry;
@@ -357,14 +370,7 @@
public synchronized void search(SearchOperation searchOperation)
throws DirectoryException
{
- DN matchedDN = baseDNs[0];
- DN baseDN = searchOperation.getBaseDN();
- // FIXME Remove this error message or replace when implementing
- // the search.
- Message message =
- ERR_MEMORYBACKEND_ENTRY_DOESNT_EXIST.get(String.valueOf(baseDN));
- throw new DirectoryException(
- ResultCode.NO_SUCH_OBJECT, message, matchedDN, null);
+ this.searchBackend(searchOperation);
}
/**
@@ -465,7 +471,7 @@
{
for (ReplicationCache exportContainer : exportContainers)
{
- exportContainer(exportContainer, exportConfig, ldifWriter);
+ processContainer(exportContainer, exportConfig, ldifWriter, null);
}
}
finally
@@ -572,7 +578,7 @@
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- Message message = ERR_EXPORT_CANNOT_WRITE_ENTRY_TO_LDIF.get(
+ Message message = ERR_BACKEND_EXPORT_ENTRY.get(
exportContainer.getBaseDn() + "," + EXPORT_BASE_DN,
String.valueOf(e));
logError(message);
@@ -581,29 +587,35 @@
}
/**
- * Export the changes for a given ReplicationCache.
+ * Processes the changes for a given ReplicationCache.
*/
- private void exportContainer(ReplicationCache rc,
- LDIFExportConfig exportConfig, LDIFWriter ldifWriter)
+ private void processContainer(ReplicationCache rc,
+ LDIFExportConfig exportConfig, LDIFWriter ldifWriter,
+ SearchOperation searchOperation)
{
- StringBuilder buffer = new StringBuilder();
-
// Walk through the servers
for (Short serverId : rc.getServers())
{
ReplicationIterator ri = rc.getChangelogIterator(serverId,
null);
- if (ri == null)
- break;
-
- // Walk through the changes
- while (ri.getChange() != null)
+ if (ri != null)
{
- UpdateMessage msg = ri.getChange();
- exportChange(buffer, msg, exportConfig, ldifWriter);
- if (!ri.next())
- break;
+ try
+ {
+ // Walk through the changes
+ while (ri.getChange() != null)
+ {
+ UpdateMessage msg = ri.getChange();
+ processChange(msg, exportConfig, ldifWriter, searchOperation);
+ if (!ri.next())
+ break;
+ }
+ }
+ finally
+ {
+ ri.releaseCursor();
+ }
}
}
}
@@ -611,26 +623,30 @@
/**
* Export one change.
*/
- private void exportChange(StringBuilder buffer, UpdateMessage msg,
- LDIFExportConfig exportConfig, LDIFWriter ldifWriter)
+ private void processChange(UpdateMessage msg,
+ LDIFExportConfig exportConfig, LDIFWriter ldifWriter,
+ SearchOperation searchOperation)
{
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
- String dn = null;
+ Entry entry = null;
+ DN dn = null;
+
try
{
if (msg instanceof AddMsg)
{
AddMsg addMsg = (AddMsg)msg;
- AddOperation op = (AddOperation)msg.createOperation(conn);
- dn = "puid=" + addMsg.getParentUid() + "," +
- "changeNumber=" + msg.getChangeNumber().toString() + "," +
- msg.getDn() +","+ "dc=replicationChanges";
+ AddOperation addOperation = (AddOperation)msg.createOperation(conn);
+
+ dn = DN.decode("puid=" + addMsg.getParentUid() + "," +
+ "changeNumber=" + msg.getChangeNumber().toString() + "," +
+ msg.getDn() +","+ "dc=replicationChanges");
Map<AttributeType,List<Attribute>> attributes =
new HashMap<AttributeType,List<Attribute>>();
- for (RawAttribute a : op.getRawAttributes())
+ for (RawAttribute a : addOperation.getRawAttributes())
{
Attribute attr = a.toAttribute();
AttributeType attrType = attr.getAttributeType();
@@ -646,52 +662,114 @@
attrs.add(attr);
}
}
+
AddChangeRecordEntry changeRecord =
- new AddChangeRecordEntry(DN.decode(dn), attributes);
- ldifWriter.writeChangeRecord(changeRecord);
+ new AddChangeRecordEntry(dn, attributes);
+ if (exportConfig != null)
+ {
+ ldifWriter.writeChangeRecord(changeRecord);
+ }
+ else
+ {
+ Writer writer = new Writer();
+ LDIFWriter ldifWriter2 = writer.getLDIFWriter();
+ ldifWriter2.writeChangeRecord(changeRecord);
+ LDIFReader reader = writer.getLDIFReader();
+ entry = reader.readEntry();
+ }
}
else if (msg instanceof DeleteMsg)
{
DeleteMsg delMsg = (DeleteMsg)msg;
- // DN
- dn = "uuid=" + msg.getUniqueId() + "," +
- "changeNumber=" + delMsg.getChangeNumber().toString()+ "," +
- msg.getDn() +","+
- "dc=replicationChanges";
+
+ dn = DN.decode("uuid=" + msg.getUniqueId() + "," +
+ "changeNumber=" + delMsg.getChangeNumber().toString()+ "," +
+ msg.getDn() +","+ "dc=replicationChanges");
+
DeleteChangeRecordEntry changeRecord =
- new DeleteChangeRecordEntry(DN.decode(dn));
- ldifWriter.writeChangeRecord(changeRecord);
+ new DeleteChangeRecordEntry(dn);
+ if (exportConfig != null)
+ {
+ ldifWriter.writeChangeRecord(changeRecord);
+ }
+ else
+ {
+ Writer writer = new Writer();
+ LDIFWriter ldifWriter2 = writer.getLDIFWriter();
+ ldifWriter2.writeChangeRecord(changeRecord);
+ LDIFReader reader = writer.getLDIFReader();
+ entry = reader.readEntry();
+ }
}
else if (msg instanceof ModifyMsg)
{
ModifyOperation op = (ModifyOperation)msg.createOperation(conn);
- // DN
- dn = "uuid=" + msg.getUniqueId() + "," +
- "changeNumber=" + msg.getChangeNumber().toString()+ "," +
- msg.getDn() +","+
- "dc=replicationChanges";
+
+ dn = DN.decode("uuid=" + msg.getUniqueId() + "," +
+ "changeNumber=" + msg.getChangeNumber().toString()+ "," +
+ msg.getDn() +","+ "dc=replicationChanges");
op.setInternalOperation(true);
+
ModifyChangeRecordEntry changeRecord =
- new ModifyChangeRecordEntry(DN.decode(dn),
- op.getRawModifications());
- ldifWriter.writeChangeRecord(changeRecord);
+ new ModifyChangeRecordEntry(dn, op.getRawModifications());
+ if (exportConfig != null)
+ {
+ ldifWriter.writeChangeRecord(changeRecord);
+ }
+ else
+ {
+ Writer writer = new Writer();
+ LDIFWriter ldifWriter2 = writer.getLDIFWriter();
+ ldifWriter2.writeChangeRecord(changeRecord);
+ LDIFReader reader = writer.getLDIFReader();
+ entry = reader.readEntry();
+ }
}
else if (msg instanceof ModifyDNMsg)
{
ModifyDNOperation op = (ModifyDNOperation)msg.createOperation(conn);
- // DN
- dn = "uuid=" + msg.getUniqueId() + "," +
- "changeNumber=" + msg.getChangeNumber().toString()+ "," +
- msg.getDn() +","+
- "dc=replicationChanges";
+
+ dn = DN.decode("uuid=" + msg.getUniqueId() + "," +
+ "changeNumber=" + msg.getChangeNumber().toString()+ "," +
+ msg.getDn() +","+ "dc=replicationChanges");
op.setInternalOperation(true);
+
ModifyDNChangeRecordEntry changeRecord =
- new ModifyDNChangeRecordEntry(DN.decode(dn),
- op.getNewRDN(), op.deleteOldRDN(),
+ new ModifyDNChangeRecordEntry(dn, op.getNewRDN(), op.deleteOldRDN(),
op.getNewSuperior());
- ldifWriter.writeChangeRecord(changeRecord);
+
+ if (exportConfig != null)
+ {
+ ldifWriter.writeChangeRecord(changeRecord);
+ }
+ else
+ {
+ Writer writer = new Writer();
+ LDIFWriter ldifWriter2 = writer.getLDIFWriter();
+ ldifWriter2.writeChangeRecord(changeRecord);
+ LDIFReader reader = writer.getLDIFReader();
+ Entry modDNEntry = reader.readEntry();
+ entry = modDNEntry;
+ }
}
- this.exportedCount++;
+
+ if (exportConfig != null)
+ {
+ this.exportedCount++;
+ }
+ else
+ {
+ // Get the base DN, scope, and filter for the search.
+ DN searchBaseDN = searchOperation.getBaseDN();
+ SearchScope scope = searchOperation.getScope();
+ SearchFilter filter = searchOperation.getFilter();
+
+ if (entry.matchesBaseAndScope(searchBaseDN, scope) &&
+ filter.matchesEntry(entry))
+ {
+ searchOperation.returnEntry(entry, new LinkedList<Control>());
+ }
+ }
}
catch (Exception e)
{
@@ -700,10 +778,18 @@
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- Message message = ERR_EXPORT_CANNOT_WRITE_ENTRY_TO_LDIF.get(
- dn, String.valueOf(e));
+ Message message = null;
+ if (exportConfig != null)
+ {
+ message = ERR_BACKEND_EXPORT_ENTRY.get(
+ dn.toNormalizedString(), String.valueOf(e));
+ }
+ else
+ {
+ message = ERR_BACKEND_SEARCH_ENTRY.get(
+ dn.toNormalizedString(), e.getLocalizedMessage());
+ }
logError(message);
-
}
}
@@ -715,8 +801,6 @@
return false;
}
-
-
/**
* {@inheritDoc}
*/
@@ -890,4 +974,199 @@
previousTime = latestTime;
}
};
+
+ /**
+ * {@inheritDoc}
+ */
+ public synchronized void searchBackend(SearchOperation searchOperation)
+ throws DirectoryException
+ {
+ // Get the base DN, scope, and filter for the search.
+ DN searchBaseDN = searchOperation.getBaseDN();
+ DN baseDN;
+ ArrayList<ReplicationCache> searchContainers =
+ new ArrayList<ReplicationCache>();
+
+ if (server==null)
+ {
+ server = retrievesReplicationServer();
+
+ if (server == null)
+ {
+ Message message = ERR_REPLICATIONBACKEND_ENTRY_DOESNT_EXIST.
+ get(String.valueOf(searchBaseDN));
+ throw new DirectoryException(
+ ResultCode.NO_SUCH_OBJECT, message, null, null);
+ }
+ }
+
+ // Make sure the base entry exists if it's supposed to be in this backend.
+ if (!handlesEntry(searchBaseDN))
+ {
+ DN matchedDN = searchBaseDN.getParentDNInSuffix();
+ while (matchedDN != null)
+ {
+ if (handlesEntry(matchedDN))
+ {
+ break;
+ }
+ matchedDN = matchedDN.getParentDNInSuffix();
+ }
+
+ Message message = ERR_REPLICATIONBACKEND_ENTRY_DOESNT_EXIST.
+ get(String.valueOf(searchBaseDN));
+ throw new DirectoryException(
+ ResultCode.NO_SUCH_OBJECT, message, matchedDN, null);
+ }
+
+ // Walk through all entries and send the ones that match.
+ Iterator<ReplicationCache> rcachei = server.getCacheIterator();
+ if (rcachei != null)
+ {
+ while (rcachei.hasNext())
+ {
+ ReplicationCache rc = rcachei.next();
+
+ // Skip containers that are not covered by the include branches.
+ baseDN = DN.decode(rc.getBaseDn().toString() + "," + EXPORT_BASE_DN);
+
+ if (searchBaseDN.isDescendantOf(baseDN) ||
+ searchBaseDN.isAncestorOf(baseDN))
+ {
+ searchContainers.add(rc);
+ }
+ }
+ }
+
+ for (ReplicationCache exportContainer : searchContainers)
+ {
+ processContainer(exportContainer, null, null, searchOperation);
+ }
+ }
+
+ /**
+ * Export the changes for a given ReplicationCache.
+ */
+ private void searchContainer2(ReplicationCache rc,
+ SearchOperation searchOperation)
+ throws DirectoryException
+ {
+ // Walk through the servers
+ for (Short serverId : rc.getServers())
+ {
+ ReplicationIterator ri = rc.getChangelogIterator(serverId,
+ null);
+
+ if (ri == null)
+ break;
+
+ // Walk through the changes
+ while (ri.getChange() != null)
+ {
+ UpdateMessage msg = ri.getChange();
+ processChange(msg, null, null, searchOperation);
+ if (!ri.next())
+ break;
+ }
+ }
+ }
+
+ /**
+ * Retrieves the replication server associated to this backend.
+ *
+ * @return The server retrieved
+ * @throws DirectoryException When it occurs.
+ */
+ protected static ReplicationServer retrievesReplicationServer()
+ throws DirectoryException
+ {
+ ReplicationServer replicationServer = null;
+
+ DirectoryServer.getSynchronizationProviders();
+ for (SynchronizationProvider provider :
+ DirectoryServer.getSynchronizationProviders())
+ {
+ if (provider instanceof MultimasterReplication)
+ {
+ MultimasterReplication mmp = (MultimasterReplication)provider;
+ ReplicationServerListener list = mmp.getReplicationServerListener();
+ if (list != null)
+ {
+ replicationServer = list.getReplicationServer();
+ break;
+ }
+ }
+ }
+ return replicationServer;
+ }
+
+ /**
+ * Writer class to read/write from/to a bytearray.
+ */
+ private static final class Writer
+ {
+ // The underlying output stream.
+ private final ByteArrayOutputStream stream;
+
+ // The underlying LDIF config.
+ private final LDIFExportConfig config;
+
+ // The LDIF writer.
+ private final LDIFWriter writer;
+
+ /**
+ * Create a new string writer.
+ */
+ public Writer() {
+ this.stream = new ByteArrayOutputStream();
+ this.config = new LDIFExportConfig(stream);
+ try {
+ this.writer = new LDIFWriter(config);
+ } catch (IOException e) {
+ // Should not happen.
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Get the LDIF writer.
+ *
+ * @return Returns the LDIF writer.
+ */
+ public LDIFWriter getLDIFWriter() {
+ return writer;
+ }
+
+ /**
+ * Close the writer and get a string reader for the LDIF content.
+ *
+ * @return Returns the string contents of the writer.
+ * @throws Exception
+ * If an error occurred closing the writer.
+ */
+ public BufferedReader getLDIFBufferedReader() throws Exception {
+ writer.close();
+ String ldif = stream.toString("UTF-8");
+ StringReader reader = new StringReader(ldif);
+ return new BufferedReader(reader);
+ }
+
+ /**
+ * Close the writer and get an LDIF reader for the LDIF content.
+ *
+ * @return Returns an LDIF Reader.
+ * @throws Exception
+ * If an error occurred closing the writer.
+ */
+ public LDIFReader getLDIFReader() throws Exception {
+ writer.close();
+ ByteArrayInputStream istream = new
+ ByteArrayInputStream(stream.toByteArray());
+ String ldif = stream.toString("UTF-8");
+ ldif = ldif.replace("\n-\n", "\n");
+ istream = new ByteArrayInputStream(ldif.getBytes());
+ LDIFImportConfig config = new LDIFImportConfig(istream);
+ return new LDIFReader(config);
+ }
+ }
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/ReplicationServerTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/ReplicationServerTest.java
index dcb3911..dc38816 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/ReplicationServerTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/ReplicationServerTest.java
@@ -26,6 +26,7 @@
*/
package org.opends.server.replication.server;
+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;
import static org.opends.server.replication.protocol.OperationContext.SYNCHROCONTEXT;
@@ -33,19 +34,26 @@
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.UUID;
+import org.opends.messages.Category;
+import org.opends.messages.Message;
+import org.opends.messages.Severity;
import org.opends.server.TestCaseUtils;
import org.opends.server.backends.task.TaskState;
+import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyDNOperationBasis;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
@@ -72,13 +80,18 @@
import org.opends.server.replication.protocol.WindowProbe;
import org.opends.server.types.Attribute;
import org.opends.server.types.DN;
+import org.opends.server.types.DereferencePolicy;
import org.opends.server.types.DirectoryConfig;
import org.opends.server.types.Entry;
+import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.Modification;
import org.opends.server.types.ModificationType;
import org.opends.server.types.RDN;
import org.opends.server.types.ResultCode;
+import org.opends.server.types.SearchFilter;
+import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchScope;
+import org.opends.server.util.LDIFWriter;
import org.opends.server.util.TimeThread;
import org.opends.server.workflowelement.localbackend.LocalBackendModifyDNOperation;
import org.testng.annotations.AfterClass;
@@ -132,7 +145,7 @@
private void debugInfo(String s)
{
- // logError(Message.raw(Category.SYNC, Severity.NOTICE, s));
+ // logError(Message.raw(Category.SYNC, Severity.NOTICE, "** TEST **" + s));
if (debugEnabled())
{
TRACER.debugInfo("** TEST **" + s);
@@ -905,7 +918,7 @@
public void shutdown() throws Exception
{
if (replicationServer != null) {
- replicationServer.shutdown();
+ replicationServer.remove();
replicationServer = null;
}
}
@@ -1058,6 +1071,11 @@
addTask(exportTask, ResultCode.SUCCESS, null);
waitTaskState(exportTask, TaskState.COMPLETED_SUCCESSFULLY, null);
+ if (server1 != null)
+ server1.stop();
+ if (server2 != null)
+ server2.stop();
+
debugInfo("Ending export");
}
@@ -1177,8 +1195,16 @@
// - Modify
Attribute attr1 = new Attribute("description", "new value");
Modification mod1 = new Modification(ModificationType.REPLACE, attr1);
+ Attribute attr2 = new Attribute("modifiersName", "cn=Directory Manager,cn=Root DNs,cn=config");
+ Modification mod2 = new Modification(ModificationType.REPLACE, attr2);
+ Attribute attr3 = new Attribute("modifyTimestamp", "20070917172420Z");
+ Modification mod3 = new Modification(ModificationType.REPLACE, attr3);
List<Modification> mods = new ArrayList<Modification>();
+
mods.add(mod1);
+ mods.add(mod2);
+ mods.add(mod3);
+
cn = new ChangeNumber(time, ts++, serverId);
DN dn = DN.decode("o=test,"+suffix);
ModifyMsg modMsg = new ModifyMsg(cn, dn,
@@ -1202,4 +1228,158 @@
catch(Exception e) {};
return l;
}
- }
+
+ /**
+ * Testing searches on the backend of the replication server.
+ * @throws Exception
+ */
+ @Test(enabled=true)
+ public void searchBackend() throws Exception
+ {
+ debugInfo("Starting searchBackend");
+
+ LDIFWriter ldifWriter = null;
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ LDIFExportConfig exportConfig = new LDIFExportConfig(stream);
+ try
+ {
+ ldifWriter = new LDIFWriter(exportConfig);
+ }
+ catch (Exception e){}
+
+ debugInfo("Create broker");
+ ReplicationBroker server1 = null;
+ try {
+ server1 = openReplicationSession(
+ DN.decode("dc=example,dc=com"), (short) 1, 100, replicationServerPort,
+ 1000, true);
+ }
+ catch(Exception e) {}
+
+ debugInfo("Publish changes");
+ List<UpdateMessage> msgs = createChanges("dc=example,dc=com", (short)1);
+ for(UpdateMessage msg : msgs )
+ {
+ server1.publish(msg);
+ }
+ Thread.sleep(200);
+
+ // Sets manually the association backend-replication server since
+ // no config object exist for our replication server.
+ ReplicationBackend b =
+ (ReplicationBackend)DirectoryServer.getBackend("replicationChanges");
+ b.setServer(replicationServer);
+
+ // General search
+ InternalSearchOperation op = connection.processSearch(
+ new ASN1OctetString("dc=oops"),
+ SearchScope.WHOLE_SUBTREE,
+ LDAPFilter.decode("(changetype=*)"));
+ assertEquals(op.getResultCode(), ResultCode.NO_SUCH_OBJECT);
+
+ // General search
+ op = connection.processSearch(
+ new ASN1OctetString("dc=replicationChanges"),
+ SearchScope.WHOLE_SUBTREE,
+ LDAPFilter.decode("(changetype=*)"));
+ assertEquals(op.getResultCode(), ResultCode.SUCCESS);
+ assertEquals(op.getSearchEntries().size(), 5);
+
+ debugInfo("Search result");
+ LinkedList<SearchResultEntry> entries = op.getSearchEntries();
+ if (entries != null)
+ {
+ for (SearchResultEntry entry : entries)
+ {
+ debugInfo(entry.toLDIFString());
+ ldifWriter.writeEntry(entry);
+ }
+ }
+ debugInfo("\n" + stream.toString());
+
+ debugInfo("Query / filter based on changetype");
+ op = connection.processSearch(
+ new ASN1OctetString("dc=replicationChanges"),
+ SearchScope.WHOLE_SUBTREE,
+ LDAPFilter.decode("(changetype=add)"));
+ assertEquals(op.getResultCode(), ResultCode.SUCCESS);
+ assertTrue(op.getSearchEntries().size() == 2);
+
+ op = connection.processSearch(
+ new ASN1OctetString("dc=replicationChanges"),
+ SearchScope.WHOLE_SUBTREE,
+ LDAPFilter.decode("(changetype=modify)"));
+ assertEquals(op.getResultCode(), ResultCode.SUCCESS);
+ assertTrue(op.getSearchEntries().size() == 1);
+
+ op = connection.processSearch(
+ new ASN1OctetString("dc=replicationChanges"),
+ SearchScope.WHOLE_SUBTREE,
+ LDAPFilter.decode("(changetype=moddn)"));
+ assertEquals(op.getResultCode(), ResultCode.SUCCESS);
+ assertTrue(op.getSearchEntries().size() == 1);
+
+ op = connection.processSearch(
+ new ASN1OctetString("dc=replicationChanges"),
+ SearchScope.WHOLE_SUBTREE,
+ LDAPFilter.decode("(changetype=delete)"));
+ assertEquals(op.getResultCode(), ResultCode.SUCCESS);
+ assertTrue(op.getSearchEntries().size() == 1);
+
+ debugInfo("Query / filter based on objectclass");
+ op = connection.processSearch(
+ new ASN1OctetString("dc=replicationChanges"),
+ SearchScope.WHOLE_SUBTREE,
+ LDAPFilter.decode("(objectclass=person)"));
+ assertEquals(op.getResultCode(), ResultCode.SUCCESS);
+ assertEquals(op.getSearchEntries().size(), 1);
+
+ debugInfo("Query / searchBase");
+ op = connection.processSearch(
+ new ASN1OctetString("uid=new person,ou=People,dc=example,dc=com,dc=replicationChanges"),
+ SearchScope.WHOLE_SUBTREE,
+ LDAPFilter.decode("(changetype=*)"));
+ assertEquals(op.getResultCode(), ResultCode.SUCCESS);
+ assertEquals(op.getSearchEntries().size(), 2);
+
+ debugInfo("Query / 1 attrib");
+
+ LinkedHashSet<String> attrs = new LinkedHashSet<String>(1);
+ attrs.add("newrdn");
+ SearchFilter ALLMATCH;
+ ALLMATCH = SearchFilter.createFilterFromString("(changetype=moddn)");
+ op =
+ connection.processSearch(DN.decode("dc=replicationChanges"),
+ SearchScope.WHOLE_SUBTREE,
+ DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, ALLMATCH,
+ attrs);
+ assertEquals(op.getResultCode(), ResultCode.SUCCESS);
+ assertEquals(op.getSearchEntries().size(), 1);
+ entries = op.getSearchEntries();
+ if (entries != null)
+ {
+ for (SearchResultEntry entry : entries)
+ {
+ debugInfo(entry.toLDIFString());
+ ldifWriter.writeEntry(entry);
+ }
+ }
+
+ debugInfo("Query / All attribs");
+ LinkedHashSet<String> attrs2 = new LinkedHashSet<String>(1);
+ attrs.add("*");
+ ALLMATCH = SearchFilter.createFilterFromString("(changetype=*)");
+ op =
+ connection.processSearch(DN.decode("dc=replicationChanges"),
+ SearchScope.WHOLE_SUBTREE,
+ DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, ALLMATCH,
+ attrs2);
+ assertEquals(op.getResultCode(), ResultCode.SUCCESS);
+ assertEquals(op.getSearchEntries().size(), 5);
+
+ if (server1 != null)
+ server1.stop();
+
+ debugInfo("Successfully ending searchBackend");
+ }
+}
--
Gitblit v1.10.0