From 14597a5c86e9cdf175d2fb81419e6ad66a45bbe6 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Fri, 06 Oct 2006 18:55:44 +0000
Subject: [PATCH] Add a number of test cases for add operations.
---
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestChangeNotificationListener.java | 180 ++++
opendj-sdk/opends/tests/unit-tests-testng/resource/config-changes.ldif | 10
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/UpdatePreOpPlugin.java | 277 ++++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java | 1889 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 2,356 insertions(+), 0 deletions(-)
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/resource/config-changes.ldif b/opendj-sdk/opends/tests/unit-tests-testng/resource/config-changes.ldif
index dcb8836..9721e9c 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/resource/config-changes.ldif
+++ b/opendj-sdk/opends/tests/unit-tests-testng/resource/config-changes.ldif
@@ -263,6 +263,16 @@
ds-cfg-plugin-type: preOperationModifyDN
ds-cfg-plugin-type: preOperationSearch
+dn: cn=Update PreOperation Plugin,cn=Plugins,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-plugin
+cn: Delay PreOperation Plugin
+ds-cfg-plugin-class: org.opends.server.plugins.UpdatePreOpPlugin
+ds-cfg-plugin-enabled: true
+ds-cfg-plugin-type: preOperationAdd
+ds-cfg-plugin-type: preOperationModify
+
dn: cn=LDAPS Connection Handler,cn=Connection Handlers,cn=config
changetype: add
objectClass: top
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
new file mode 100644
index 0000000..415d0ab
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
@@ -0,0 +1,1889 @@
+/*
+ * 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
+ *
+ *
+ * Portions Copyright 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.core;
+
+
+
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.api.Backend;
+import org.opends.server.plugins.UpdatePreOpPlugin;
+import org.opends.server.protocols.asn1.ASN1OctetString;
+import org.opends.server.protocols.asn1.ASN1Reader;
+import org.opends.server.protocols.asn1.ASN1Sequence;
+import org.opends.server.protocols.asn1.ASN1Writer;
+import org.opends.server.protocols.internal.InternalClientConnection;
+import org.opends.server.protocols.ldap.AddRequestProtocolOp;
+import org.opends.server.protocols.ldap.AddResponseProtocolOp;
+import org.opends.server.protocols.ldap.BindRequestProtocolOp;
+import org.opends.server.protocols.ldap.BindResponseProtocolOp;
+import org.opends.server.protocols.ldap.LDAPAttribute;
+import org.opends.server.protocols.ldap.LDAPMessage;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.AttributeValue;
+import org.opends.server.types.ByteString;
+import org.opends.server.types.Control;
+import org.opends.server.types.DN;
+import org.opends.server.types.Entry;
+import org.opends.server.types.ObjectClass;
+import org.opends.server.types.ResultCode;
+import org.opends.server.types.WritabilityMode;
+
+import static org.testng.Assert.*;
+
+import static org.opends.server.util.ServerConstants.*;
+
+
+
+/**
+ * A set of test cases for add operations
+ */
+public class AddOperationTestCase
+ extends OperationTestCase
+{
+ /**
+ * Retrieves a set of add operations that may be used for testing.
+ *
+ * @return A set of add operations that may be used for testing.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @DataProvider(name = "addOperations")
+ public Object[][] getAddOperations()
+ throws Exception
+ {
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ ArrayList<Control> noControls = new ArrayList<Control>();
+
+ ArrayList<LDAPAttribute> ldapAttrList = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ ldapAttrList.add(new LDAPAttribute("objectclass", values));
+
+ values.clear();
+ values.add(new ASN1OctetString("People"));
+ ldapAttrList.add(new LDAPAttribute("ou", values));
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People");
+
+ Operation[] opArray = new Operation[]
+ {
+ new AddOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
+ null, new ASN1OctetString("ou=People,o=test"),
+ ldapAttrList),
+ new AddOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
+ noControls, new ASN1OctetString("ou=People,o=test"),
+ ldapAttrList),
+ new AddOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
+ null, entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes()),
+ new AddOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
+ noControls, entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes()),
+ };
+
+ Object[][] objArray = new Object[opArray.length][1];
+ for (int i=0; i < opArray.length; i++)
+ {
+ objArray[i][0] = opArray[i];
+ }
+
+ return objArray;
+ }
+
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public Operation[] createTestOperations()
+ throws Exception
+ {
+ Object[][] objs = getAddOperations();
+ Operation[] ops = new Operation[objs.length];
+ for (int i=0; i < objs.length; i++)
+ {
+ ops[i] = (Operation) objs[i][0];
+ }
+
+ return ops;
+ }
+
+
+
+ /**
+ * Tests the <CODE>getRawEntryDN</CODE> and <CODE>setRawEntryDN</CODE>
+ * methods.
+ *
+ * @param addOperation The add operation to be tested.
+ */
+ @Test(dataProvider = "addOperations")
+ public void testGetAndSetRawEntryDN(AddOperation addOperation)
+ {
+ ByteString originalDN = addOperation.getRawEntryDN();
+ assertNotNull(originalDN);
+
+ addOperation.setRawEntryDN(new ASN1OctetString("uid=test,o=test"));
+ assertNotNull(addOperation.getRawEntryDN());
+ assertEquals(addOperation.getRawEntryDN(),
+ new ASN1OctetString("uid=test,o=test"));
+
+ addOperation.setRawEntryDN(originalDN);
+ assertNotNull(addOperation.getRawEntryDN());
+ assertEquals(addOperation.getRawEntryDN(), originalDN);
+ }
+
+
+
+ /**
+ * Tests the <CODE>getEntryDN</CODE> method for the case in which we expect
+ * the DN to be initially null.
+ */
+ @Test()
+ public void testGetEntryDNInitiallyNull()
+ {
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ ArrayList<LDAPAttribute> ldapAttrList = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ ldapAttrList.add(new LDAPAttribute("objectclass", values));
+
+ values.clear();
+ values.add(new ASN1OctetString("People"));
+ ldapAttrList.add(new LDAPAttribute("ou", values));
+
+ AddOperation addOperation =
+ new AddOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
+ null, new ASN1OctetString("ou=People,o=test"),
+ ldapAttrList);
+ assertNull(addOperation.getEntryDN());
+ }
+
+
+
+ /**
+ * Tests the <CODE>getEntryDN</CODE> method for the case in which we expect
+ * the DN to be initially non-null.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testGetEntryDNInitiallyNonNull()
+ throws Exception
+ {
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People");
+
+ AddOperation addOperation =
+ new AddOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
+ null, entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertNotNull(addOperation.getEntryDN());
+ }
+
+
+
+ /**
+ * Tests the <CODE>getEntryDN</CODE> method for the case in which we expect
+ * the DN to be initially non-null but then becomes null after the raw DN is
+ * changed.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testGetEntryDNNonNullChangedToNull()
+ throws Exception
+ {
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People");
+
+ AddOperation addOperation =
+ new AddOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
+ null, entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertNotNull(addOperation.getEntryDN());
+
+ addOperation.setRawEntryDN(new ASN1OctetString("ou=Users,o=test"));
+ assertNull(addOperation.getEntryDN());
+ }
+
+
+
+ /**
+ * Tests the <CODE>getRawAttributes</CODE>, <CODE>addRawAttribute</CODE>, and
+ * <CODE>setRawAttributes</CODE> methods.
+ *
+ * @param addOperation The add operation to be tested.
+ */
+ @Test(dataProvider = "addOperations")
+ public void testGetAndSetRawAttributes(AddOperation addOperation)
+ {
+ List<LDAPAttribute> rawAttrs = addOperation.getRawAttributes();
+ assertNotNull(rawAttrs);
+ assertFalse(rawAttrs.isEmpty());
+
+ ArrayList<LDAPAttribute> copiedAttrs =
+ new ArrayList<LDAPAttribute>(rawAttrs);
+ addOperation.setRawAttributes(copiedAttrs);
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("foo"));
+ addOperation.addRawAttribute(new LDAPAttribute("description", values));
+
+ boolean found = false;
+ for (LDAPAttribute a : addOperation.getRawAttributes())
+ {
+ if (a.getAttributeType().equalsIgnoreCase("description"))
+ {
+ found = true;
+ break;
+ }
+ }
+ assertTrue(found);
+
+ addOperation.setRawAttributes(rawAttrs);
+
+ found = false;
+ for (LDAPAttribute a : addOperation.getRawAttributes())
+ {
+ if (a.getAttributeType().equalsIgnoreCase("description"))
+ {
+ found = true;
+ break;
+ }
+ }
+ assertFalse(found);
+ }
+
+
+
+ /**
+ * Tests the <CODE>addObjectClass</CODE> method.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testAddObjectClass()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ UpdatePreOpPlugin.reset();
+
+ ObjectClass oc = DirectoryServer.getObjectClass("extensibleobject", true);
+ UpdatePreOpPlugin.addObjectClassToAdd(oc);
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+
+ Entry e = DirectoryServer.getEntry(DN.decode("ou=People,o=test"));
+ assertTrue(e.hasObjectClass(oc));
+
+ UpdatePreOpPlugin.reset();
+ }
+
+
+
+ /**
+ * Tests the <CODE>removeObjectClass</CODE> method.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testRemoveObjectClass()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "objectClass: extensibleObject",
+ "ou: People");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ UpdatePreOpPlugin.reset();
+
+ ObjectClass oc = DirectoryServer.getObjectClass("extensibleobject", true);
+ UpdatePreOpPlugin.addObjectClassToRemove(oc);
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+
+ Entry e = DirectoryServer.getEntry(DN.decode("ou=People,o=test"));
+ assertFalse(e.hasObjectClass(oc));
+
+ UpdatePreOpPlugin.reset();
+ }
+
+
+
+ /**
+ * Tests the <CODE>setAttribute</CODE> method for an attribute that already
+ * exists.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testSetAttributeOverwrite()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People",
+ "description: foo");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ UpdatePreOpPlugin.reset();
+
+ Attribute a = new Attribute("description", "bar");
+ UpdatePreOpPlugin.addAttributeToSet(a);
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+
+ Entry e = DirectoryServer.getEntry(DN.decode("ou=People,o=test"));
+ List<Attribute> attrList = e.getAttribute(a.getAttributeType());
+ assertNotNull(attrList);
+ assertFalse(attrList.isEmpty());
+
+ boolean foundFoo = false;
+ boolean foundBar = false;
+ for (Attribute attr : attrList)
+ {
+ if (attr.hasValue(new AttributeValue(a.getAttributeType(),
+ new ASN1OctetString("foo"))))
+ {
+ foundFoo = true;
+ }
+
+ if (attr.hasValue(new AttributeValue(a.getAttributeType(),
+ new ASN1OctetString("bar"))))
+ {
+ foundBar = true;
+ }
+ }
+
+ assertFalse(foundFoo);
+ assertTrue(foundBar);
+
+ UpdatePreOpPlugin.reset();
+ }
+
+
+
+ /**
+ * Tests the <CODE>setAttribute</CODE> method for an attribute that doesn't
+ * exist.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testSetAttributeAdd()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ UpdatePreOpPlugin.reset();
+
+ Attribute a = new Attribute("description", "foo");
+ UpdatePreOpPlugin.addAttributeToSet(a);
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+
+ Entry e = DirectoryServer.getEntry(DN.decode("ou=People,o=test"));
+ List<Attribute> attrList = e.getAttribute(a.getAttributeType());
+ assertNotNull(attrList);
+ assertFalse(attrList.isEmpty());
+
+ UpdatePreOpPlugin.reset();
+ }
+
+
+
+ /**
+ * Tests the <CODE>removeAttribute</CODE> method.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testSetAttributeRemove()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People",
+ "description: foo");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ UpdatePreOpPlugin.reset();
+
+ AttributeType attrType = DirectoryServer.getAttributeType("description",
+ true);
+ UpdatePreOpPlugin.addAttributeToRemove(attrType);
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+
+ Entry e = DirectoryServer.getEntry(DN.decode("ou=People,o=test"));
+ List<Attribute> attrList = e.getAttribute(attrType);
+ assertNull(attrList);
+
+ UpdatePreOpPlugin.reset();
+ }
+
+
+
+ /**
+ * Invokes methods to retrieve members of an add operation after it has
+ * completed.
+ *
+ * @param addOperation The add operation to examine. It should have
+ * completed successfully.
+ */
+ private void retrieveCompletedOperationElements(AddOperation addOperation)
+ {
+ assertNotNull(addOperation.getEntryToAdd());
+ assertTrue(addOperation.getProcessingStartTime() > 0);
+ assertTrue(addOperation.getProcessingStopTime() >=
+ addOperation.getProcessingStartTime());
+ assertTrue(addOperation.getProcessingTime() >= 0);
+ assertNotNull(addOperation.getResponseLogElements());
+
+ long changeNumber = addOperation.getChangeNumber();
+ addOperation.setChangeNumber(changeNumber);
+ }
+
+
+
+ /**
+ * Tests an internal add operation that should be successful using raw
+ * arguments.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddSuccessRaw()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(new ASN1OctetString("ou=People,o=test"), attrs);
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+ }
+
+
+
+ /**
+ * Tests an internal add operation that should be successful using processed
+ * arguments.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddSuccessProcessed()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+ }
+
+
+
+ /**
+ * Tests an internal add operation that fails because it contains a malformed
+ * DN.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureMalformedDN()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(new ASN1OctetString("invalid"), attrs);
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests an internal add operation that fails because it contains the DN of
+ * an entry that already exists.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureAlreadyExists()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organization"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("test"));
+ attrs.add(new LDAPAttribute("o", values));
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(new ASN1OctetString("o=test"), attrs);
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests an internal add operation that fails because it is a suffix that
+ * doesn't exist.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureNoSuchSuffix()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organization"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("undefined"));
+ attrs.add(new LDAPAttribute("o", values));
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(new ASN1OctetString("o=undefined"), attrs);
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests an internal add operation that fails because it is below a suffix
+ * that doesn't exist.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureNoSuchSuffixParent()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(new ASN1OctetString("ou=People,o=undefined"), attrs);
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests an internal add operation that fails because its parent doesn't
+ * exist.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureNoSuchParent()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(new ASN1OctetString("ou=People,o=missing,o=test"),
+ attrs);
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests an external add operation that fails because it contains an attribute
+ * that is marked no-user-modification.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testExternalAddFailureNoUserModification()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Socket s = new Socket("127.0.0.1", (int) TestCaseUtils.getServerLdapPort());
+ ASN1Reader r = new ASN1Reader(s);
+ ASN1Writer w = new ASN1Writer(s);
+ r.setIOTimeout(3000);
+
+ BindRequestProtocolOp bindRequest =
+ new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+ 3, new ASN1OctetString("password"));
+ LDAPMessage message = new LDAPMessage(1, bindRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ BindResponseProtocolOp bindResponse =
+ message.getBindResponseProtocolOp();
+ assertEquals(bindResponse.getResultCode(), 0);
+
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("cn=Directory Manager"));
+ attrs.add(new LDAPAttribute("creatorsName", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("20060101000000Z"));
+ attrs.add(new LDAPAttribute("createTimestamp", values));
+
+ AddRequestProtocolOp addRequest =
+ new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"),
+ attrs);
+ message = new LDAPMessage(2, addRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ AddResponseProtocolOp addResponse =
+ message.getAddResponseProtocolOp();
+ assertFalse(addResponse.getResultCode() == 0);
+
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+ }
+
+
+
+ /**
+ * Tests an internal add operation that fails because it has an undefined
+ * objectclass.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureUndefinedObjectClass()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("undefined"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(new ASN1OctetString("ou=People,o=test"),
+ attrs);
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests a successful internal add operation that contains a user-modifiable
+ * operational attribute.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddSuccessfulWithOperationalAttribute()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: uid=test.user,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: test.user",
+ "givenName: Test",
+ "sn: User",
+ "cn: Test User",
+ "userPassword: password",
+ "pwdPolicySubentry: cn=Clear UserPassword Policy," +
+ "cn=Password Policies,cn=config");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+ }
+
+
+
+ /**
+ * Tests a successful internal add operation that contains an attribute with
+ * multiple values where the values are spread throughout the entry.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddSuccessfulDisjointAttribute()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("foo"));
+ attrs.add(new LDAPAttribute("description", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("bar"));
+ attrs.add(new LDAPAttribute("description", values));
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(new ASN1OctetString("ou=People,o=test"),
+ attrs);
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests a successful internal add operation that contains raw attributes with
+ * options.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddSuccessfulWithRawAttributeOptions()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("foo"));
+ attrs.add(new LDAPAttribute("description", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("foo"));
+ attrs.add(new LDAPAttribute("description;lang-en-us", values));
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(new ASN1OctetString("ou=People,o=test"),
+ attrs);
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests a successful internal add operation that contains raw attributes with
+ * options and an attribute that doesn't have any values without options.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddSuccessfulWithRawAttributeOptionsOnlyOptions()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("foo"));
+ attrs.add(new LDAPAttribute("description;lang-en-us", values));
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(new ASN1OctetString("ou=People,o=test"),
+ attrs);
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests a successful internal add operation that contains attributes with
+ * options.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddSuccessfulWithAttributeOptions()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: uid=test.user,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: test.user",
+ "uid;lang-en-us: test.user",
+ "givenName: Test",
+ "givenName;lang-en-us: Test",
+ "sn: User",
+ "sn;lang-en-us: User",
+ "cn: Test User",
+ "cn;lang-en-us: Test User",
+ "userPassword: password");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+ }
+
+
+
+ /**
+ * Tests an internal add operation that fails because it attempts to add the
+ * root DSE.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureRootDSE()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("ds-root-dse"));
+ values.add(new ASN1OctetString("extensibleObject"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("Root DSE"));
+ attrs.add(new LDAPAttribute("cn", values));
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(new ASN1OctetString(), attrs);
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests a successful internal add operation that is missing RDN attributes.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddSuccessfulWithMissingRDNAttributes()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+
+ Entry e = DirectoryServer.getEntry(DN.decode("ou=People,o=test"));
+ List<Attribute> attrList = e.getAttribute("ou");
+ assertNotNull(attrList);
+ }
+
+
+
+ /**
+ * Tests a failed internal add operation that is missing RDN attributes.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureWithMissingRDNAttributes()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ DirectoryServer.setAddMissingRDNAttributes(false);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+
+ DirectoryServer.setAddMissingRDNAttributes(true);
+ }
+
+
+
+ /**
+ * Tests a successful internal add operation that is missing an objectclass
+ * in the hierarchical chain.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddSuccessfulWithMissingParentObjectClass()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: uid=test.user,o=test",
+ "objectClass: inetOrgPerson",
+ "uid: test.user",
+ "givenName: Test",
+ "sn: User",
+ "cn: Test User",
+ "userPassword: password");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+
+ Entry e = DirectoryServer.getEntry(DN.decode("uid=test.user,o=test"));
+ List<Attribute> attrList =
+ e.getAttribute(DirectoryServer.getObjectClassAttributeType());
+ assertNotNull(attrList);
+
+ boolean found = false;
+ for (Attribute a : attrList)
+ {
+ for (AttributeValue v : a.getValues())
+ {
+ if (v.getStringValue().equalsIgnoreCase("top"))
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ assertTrue(found);
+ }
+
+
+
+ /**
+ * Tests a failed internal add operation that doesn't have any objectclasses.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureNoObjectClasses()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "ou: People");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests a failed internal add operation that only has an abstract
+ * objectclass.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureOnlyAbstractObjectClass()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "ou: People");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests a failed internal add operation that doesn't have any structural
+ * objectclass (only abstract and auxiliary).
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureNoStructuralObjectClass()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: extensibleObject",
+ "ou: People");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests a failed internal add operation that has multiple structural
+ * objectclasses.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureMultipleStructuralObjectClasses()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "objectClass: person",
+ "ou: People",
+ "cn: Test User",
+ "sn: User");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests a failed internal add operation that is missing a required attribute.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureMissingRequiredAttribute()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: uid=test.user,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: test.user",
+ "givenName: Test",
+ "sn: User",
+ "userPassword: password"); // Missing cn
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests a failed internal add operation that is missing a required attribute
+ * but has the extensibleObject objectClass (which shouldn't change anything).
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureMissingRequiredAttributeExtensibleObject()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: uid=test.user,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "objectClass: extensibleObject",
+ "uid: test.user",
+ "givenName: Test",
+ "sn: User",
+ "userPassword: password"); // Missing cn
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests a failed internal add operation that contains an attribute not
+ * allowed by any objectclass.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureDisallowedAttribute()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: uid=test.user,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: test.user",
+ "givenName: Test",
+ "sn: User",
+ "cn: Test User",
+ "userPassword: password",
+ "dc: Not allowed by inetOrgPerson");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+
+
+
+ /**
+ * Tests a successful internal add operation that contains an attribute not
+ * allowed by any standard objectclass in the entry but is allowed by
+ * extensibleObject.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddSuccessfulDisallowedAttributeExtensibleObject()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: uid=test.user,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "objectClass: extensibleObject",
+ "uid: test.user",
+ "givenName: Test",
+ "sn: User",
+ "cn: Test User",
+ "userPassword: password",
+ "dc: Not allowed by inetOrgPerson but allowed by extensibleObject");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+ }
+
+
+
+ /**
+ * Tests a failed internal add operation with the server in complete read-only
+ * mode.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureServerCompletelyReadOnly()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: uid=test.user,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: test.user",
+ "givenName: Test",
+ "sn: User",
+ "cn: Test User",
+ "userPassword: password");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ DirectoryServer.setWritabilityMode(WritabilityMode.DISABLED);
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+
+ DirectoryServer.setWritabilityMode(WritabilityMode.ENABLED);
+ }
+
+
+
+ /**
+ * Tests a successful internal add operation with the server in read-only mode
+ * for external operations but allowed for internal operations.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddSuccessServerExternallyReadOnly()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: uid=test.user,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: test.user",
+ "givenName: Test",
+ "sn: User",
+ "cn: Test User",
+ "userPassword: password");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ DirectoryServer.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+
+ DirectoryServer.setWritabilityMode(WritabilityMode.ENABLED);
+ }
+
+
+
+ /**
+ * Tests a failed external add operation with the server in read-only mode
+ * for external operations but allowed for internal operations.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testExternalAddFailureServerExternallyReadOnly()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Socket s = new Socket("127.0.0.1", (int) TestCaseUtils.getServerLdapPort());
+ ASN1Reader r = new ASN1Reader(s);
+ ASN1Writer w = new ASN1Writer(s);
+ r.setIOTimeout(3000);
+
+ BindRequestProtocolOp bindRequest =
+ new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+ 3, new ASN1OctetString("password"));
+ LDAPMessage message = new LDAPMessage(1, bindRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ BindResponseProtocolOp bindResponse =
+ message.getBindResponseProtocolOp();
+ assertEquals(bindResponse.getResultCode(), 0);
+
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ DirectoryServer.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
+
+ AddRequestProtocolOp addRequest =
+ new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"),
+ attrs);
+ message = new LDAPMessage(2, addRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ AddResponseProtocolOp addResponse =
+ message.getAddResponseProtocolOp();
+ assertFalse(addResponse.getResultCode() == 0);
+
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+
+ DirectoryServer.setWritabilityMode(WritabilityMode.ENABLED);
+ }
+
+
+
+ /**
+ * Tests a failed internal add operation with the backend in complete
+ * read-only mode.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddFailureBackendCompletelyReadOnly()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: uid=test.user,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: test.user",
+ "givenName: Test",
+ "sn: User",
+ "cn: Test User",
+ "userPassword: password");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ Backend b = DirectoryServer.getBackend(DN.decode("o=test"));
+ b.setWritabilityMode(WritabilityMode.DISABLED);
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+
+ b.setWritabilityMode(WritabilityMode.ENABLED);
+ }
+
+
+
+ /**
+ * Tests a successful internal add operation with the backend in read-only
+ * mode for external operations but allowed for internal operations.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testIntenalAddSuccessBackendExternallyReadOnly()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: uid=test.user,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: test.user",
+ "givenName: Test",
+ "sn: User",
+ "cn: Test User",
+ "userPassword: password");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ Backend b = DirectoryServer.getBackend(DN.decode("o=test"));
+ b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+
+ b.setWritabilityMode(WritabilityMode.ENABLED);
+ }
+
+
+
+ /**
+ * Tests a failed external add operation with the backend in read-only mode
+ * for external operations but allowed for internal operations.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testExternalAddFailureBackendExternallyReadOnly()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Socket s = new Socket("127.0.0.1", (int) TestCaseUtils.getServerLdapPort());
+ ASN1Reader r = new ASN1Reader(s);
+ ASN1Writer w = new ASN1Writer(s);
+ r.setIOTimeout(3000);
+
+ BindRequestProtocolOp bindRequest =
+ new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+ 3, new ASN1OctetString("password"));
+ LDAPMessage message = new LDAPMessage(1, bindRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ BindResponseProtocolOp bindResponse =
+ message.getBindResponseProtocolOp();
+ assertEquals(bindResponse.getResultCode(), 0);
+
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ Backend b = DirectoryServer.getBackend(DN.decode("o=test"));
+ b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
+
+ AddRequestProtocolOp addRequest =
+ new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"),
+ attrs);
+ message = new LDAPMessage(2, addRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ AddResponseProtocolOp addResponse =
+ message.getAddResponseProtocolOp();
+ assertFalse(addResponse.getResultCode() == 0);
+
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+
+ b.setWritabilityMode(WritabilityMode.ENABLED);
+ }
+
+
+
+ /**
+ * Tests to ensure that any registered add notification listeners are invoked
+ * for a successful add operation.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testSuccessWithNotificationListener()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ TestChangeNotificationListener changeListener =
+ new TestChangeNotificationListener();
+ DirectoryServer.registerChangeNotificationListener(changeListener);
+ assertEquals(changeListener.getAddCount(), 0);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(addOperation);
+
+ assertEquals(changeListener.getAddCount(), 1);
+ DirectoryServer.deregisterChangeNotificationListener(changeListener);
+ }
+
+
+
+ /**
+ * Tests to ensure that any registered add notification listeners are not
+ * invoked for a failed add operation.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testFailureWithNotificationListener()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ TestChangeNotificationListener changeListener =
+ new TestChangeNotificationListener();
+ DirectoryServer.registerChangeNotificationListener(changeListener);
+ assertEquals(changeListener.getAddCount(), 0);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,ou=nonexistent,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+
+ assertEquals(changeListener.getAddCount(), 0);
+ DirectoryServer.deregisterChangeNotificationListener(changeListener);
+ }
+}
+
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestChangeNotificationListener.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestChangeNotificationListener.java
new file mode 100644
index 0000000..f5557fa
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestChangeNotificationListener.java
@@ -0,0 +1,180 @@
+/*
+ * 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
+ *
+ *
+ * Portions Copyright 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.core;
+
+
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.opends.server.api.ChangeNotificationListener;
+import org.opends.server.types.Entry;
+
+
+
+/**
+ * This class provides a simple change notification listener that simply counts
+ * the number of times that it is invoked during processing.
+ */
+public class TestChangeNotificationListener
+ implements ChangeNotificationListener
+{
+ // The number of times that the listener has been invoked for add operations.
+ private AtomicInteger addCount;
+
+ // The number of times that the listener has been invoked for delete
+ // operations.
+ private AtomicInteger deleteCount;
+
+ // The number of times that the listener has been invoked for modify
+ // operations.
+ private AtomicInteger modifyCount;
+
+ // The number of times that the listener has been invoked for modify DN
+ // operations.
+ private AtomicInteger modifyDNCount;
+
+
+
+ /**
+ * Creates a new instance of this change notification listener.
+ */
+ public TestChangeNotificationListener()
+ {
+ addCount = new AtomicInteger(0);
+ deleteCount = new AtomicInteger(0);
+ modifyCount = new AtomicInteger(0);
+ modifyDNCount = new AtomicInteger(0);
+ }
+
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void handleAddOperation(AddOperation addOperation,
+ Entry entry)
+ {
+ addCount.incrementAndGet();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void handleDeleteOperation(DeleteOperation deleteOperation,
+ Entry entry)
+ {
+ deleteCount.incrementAndGet();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void handleModifyOperation(ModifyOperation modifyOperation,
+ Entry oldEntry, Entry newEntry)
+ {
+ modifyCount.incrementAndGet();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void handleModifyDNOperation(
+ ModifyDNOperation modifyDNOperation,
+ Entry oldEntry, Entry newEntry)
+ {
+ modifyDNCount.incrementAndGet();
+ }
+
+
+
+ /**
+ * Resets all of the counts to zero.
+ */
+ public void reset()
+ {
+ addCount.set(0);
+ deleteCount.set(0);
+ modifyCount.set(0);
+ modifyDNCount.set(0);
+ }
+
+
+
+ /**
+ * Retrieves the current invocation count for add operations.
+ *
+ * @return The current invocation count for add operations.
+ */
+ public int getAddCount()
+ {
+ return addCount.get();
+ }
+
+
+
+ /**
+ * Retrieves the current invocation count for delete operations.
+ *
+ * @return The current invocation count for delete operations.
+ */
+ public int getDeleteCount()
+ {
+ return deleteCount.get();
+ }
+
+
+
+ /**
+ * Retrieves the current invocation count for modify operations.
+ *
+ * @return The current invocation count for modify operations.
+ */
+ public int getModifyCount()
+ {
+ return modifyCount.get();
+ }
+
+
+
+ /**
+ * Retrieves the current invocation count for modify DN operations.
+ *
+ * @return The current invocation count for modify DN operations.
+ */
+ public int getModifyDNCount()
+ {
+ return modifyDNCount.get();
+ }
+}
+
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/UpdatePreOpPlugin.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/UpdatePreOpPlugin.java
new file mode 100644
index 0000000..777b5bd
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/UpdatePreOpPlugin.java
@@ -0,0 +1,277 @@
+/*
+ * 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
+ *
+ *
+ * Portions Copyright 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.plugins;
+
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.opends.server.api.plugin.DirectoryServerPlugin;
+import org.opends.server.api.plugin.PluginType;
+import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.config.ConfigEntry;
+import org.opends.server.config.ConfigException;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.Modification;
+import org.opends.server.types.ObjectClass;
+import org.opends.server.types.operation.PreOperationAddOperation;
+import org.opends.server.types.operation.PreOperationModifyOperation;
+
+
+
+/**
+ * This class defines a pre-operation plugin that can be used in add and modify
+ * operations to make changes to the target operation during pre-op plugin
+ * processing. For add operations, it can add objectclasses, remove
+ * objectclasses, replace attributes, or remove attributes. For modify
+ * operations, it can add modifications.
+ */
+public class UpdatePreOpPlugin
+ extends DirectoryServerPlugin
+{
+ /**
+ * The singleton instance of this test password validator.
+ */
+ private static UpdatePreOpPlugin instance = null;
+
+
+
+ // The set of attributes to set in the next add operation.
+ private ArrayList<Attribute> setAttributes;
+
+ // The set of attribute types for attributes to remove from the next add
+ // operation.
+ private ArrayList<AttributeType> removeAttributes;
+
+ // The set of objectclasses to add to the next add operation.
+ private ArrayList<ObjectClass> addObjectClasses;
+
+ // The set of objectclasses to remove from the next add operation.
+ private ArrayList<ObjectClass> removeObjectClasses;
+
+ // The set of modifications to add to the next modify operation.
+ private ArrayList<Modification> modifications;
+
+
+
+ /**
+ * Creates a new instance of this Directory Server plugin. Every
+ * plugin must implement a default constructor (it is the only one
+ * that will be used to create plugins defined in the
+ * configuration), and every plugin constructor must call
+ * <CODE>super()</CODE> as its first element.
+ */
+ public UpdatePreOpPlugin()
+ {
+ super();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void initializePlugin(Set<PluginType> pluginTypes,
+ ConfigEntry configEntry)
+ throws ConfigException
+ {
+ // This plugin may only be used as a pre-operation plugin.
+ for (PluginType t : pluginTypes)
+ {
+ switch (t)
+ {
+ case PRE_OPERATION_ADD:
+ case PRE_OPERATION_MODIFY:
+ // This is fine.
+ break;
+ default:
+ throw new ConfigException(-1, "Invalid plugin type " + t +
+ " for update pre-op plugin.");
+ }
+ }
+
+ if (instance == null)
+ {
+ instance = this;
+ }
+ else
+ {
+ throw new ConfigException(-1, "Only one update preop plugin may be used");
+ }
+
+ setAttributes = new ArrayList<Attribute>();
+ removeAttributes = new ArrayList<AttributeType>();
+ addObjectClasses = new ArrayList<ObjectClass>();
+ removeObjectClasses = new ArrayList<ObjectClass>();
+ modifications = new ArrayList<Modification>();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public PreOperationPluginResult
+ doPreOperation(PreOperationAddOperation addOperation)
+ {
+ for (AttributeType t : removeAttributes)
+ {
+ addOperation.removeAttribute(t);
+ }
+
+ for (Attribute a : setAttributes)
+ {
+ ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
+ attrList.add(a);
+ addOperation.setAttribute(a.getAttributeType(), attrList);
+ }
+
+ for (ObjectClass oc : removeObjectClasses)
+ {
+ addOperation.removeObjectClass(oc);
+ }
+
+ for (ObjectClass oc : addObjectClasses)
+ {
+ addOperation.addObjectClass(oc, oc.getPrimaryName());
+ }
+
+ return new PreOperationPluginResult();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public PreOperationPluginResult
+ doPreOperation(PreOperationModifyOperation modifyOperation)
+ {
+ for (Modification m : modifications)
+ {
+ try
+ {
+ modifyOperation.addModification(m);
+ }
+ catch (DirectoryException de)
+ {
+ modifyOperation.setResponseData(de);
+ return new PreOperationPluginResult(false, false, true);
+ }
+ }
+
+ return new PreOperationPluginResult();
+ }
+
+
+
+ /**
+ * Clears all of the updates currently in place.
+ */
+ public static void reset()
+ {
+ instance.setAttributes.clear();
+ instance.removeAttributes.clear();
+ instance.addObjectClasses.clear();
+ instance.removeObjectClasses.clear();
+ instance.modifications.clear();
+ }
+
+
+
+ /**
+ * Adds the provided attribute to the set of attributes that will be set in
+ * the next add operation.
+ *
+ * @param attribute The attribute to be set in the next add operation.
+ */
+ public static void addAttributeToSet(Attribute attribute)
+ {
+ instance.setAttributes.add(attribute);
+ }
+
+
+
+ /**
+ * Adds the provided attribute type to the set of attributes that will be
+ * removed from the next add operation.
+ *
+ * @param attributeType The attribute type to be removed in the next add
+ * operation.
+ */
+ public static void addAttributeToRemove(AttributeType attributeType)
+ {
+ instance.removeAttributes.add(attributeType);
+ }
+
+
+
+ /**
+ * Adds the provided objectclass to the set of objectclasses that will be
+ * added to the next add operation.
+ *
+ * @param objectClass The objectclass to be added.
+ */
+ public static void addObjectClassToAdd(ObjectClass objectClass)
+ {
+ instance.addObjectClasses.add(objectClass);
+ }
+
+
+
+ /**
+ * Adds the provided objectclass to the set of objectclasses that will be
+ * removed from the next add operation.
+ *
+ * @param objectClass The objectclass to be added.
+ */
+ public static void addObjectClassToRemove(ObjectClass objectClass)
+ {
+ instance.removeObjectClasses.add(objectClass);
+ }
+
+
+
+ /**
+ * Adds the provided modification so that it will be included in the next
+ * modify operation.
+ *
+ * @param modification The modification to be added.
+ */
+ public static void addModification(Modification modification)
+ {
+ instance.modifications.add(modification);
+ }
+}
+
--
Gitblit v1.10.0