opends/src/server/org/opends/server/core/AbandonOperation.java
@@ -417,6 +417,21 @@ * {@inheritDoc} */ @Override() boolean setCancelRequest(CancelRequest cancelRequest) { assert debugEnter(CLASS_NAME, "setCancelRequest", String.valueOf(cancelRequest)); // Abandon operations cannot be canceled. return false; } /** * {@inheritDoc} */ @Override() public final void toString(StringBuilder buffer) { assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder"); opends/src/server/org/opends/server/core/AddOperation.java
@@ -2466,6 +2466,21 @@ * {@inheritDoc} */ @Override() boolean setCancelRequest(CancelRequest cancelRequest) { assert debugEnter(CLASS_NAME, "setCancelRequest", String.valueOf(cancelRequest)); this.cancelRequest = cancelRequest; return true; } /** * {@inheritDoc} */ @Override() public final void toString(StringBuilder buffer) { assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder"); opends/src/server/org/opends/server/core/BindOperation.java
@@ -2299,6 +2299,21 @@ * {@inheritDoc} */ @Override() boolean setCancelRequest(CancelRequest cancelRequest) { assert debugEnter(CLASS_NAME, "setCancelRequest", String.valueOf(cancelRequest)); // Bind operations cannot be canceled. return false; } /** * {@inheritDoc} */ @Override() public final void toString(StringBuilder buffer) { assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder"); opends/src/server/org/opends/server/core/CompareOperation.java
@@ -1153,6 +1153,21 @@ * {@inheritDoc} */ @Override() boolean setCancelRequest(CancelRequest cancelRequest) { assert debugEnter(CLASS_NAME, "setCancelRequest", String.valueOf(cancelRequest)); this.cancelRequest = cancelRequest; return true; } /** * {@inheritDoc} */ @Override() public final void toString(StringBuilder buffer) { assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder"); opends/src/server/org/opends/server/core/DeleteOperation.java
@@ -1318,6 +1318,21 @@ * {@inheritDoc} */ @Override() boolean setCancelRequest(CancelRequest cancelRequest) { assert debugEnter(CLASS_NAME, "setCancelRequest", String.valueOf(cancelRequest)); this.cancelRequest = cancelRequest; return true; } /** * {@inheritDoc} */ @Override() public final void toString(StringBuilder buffer) { assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder"); opends/src/server/org/opends/server/core/ExtendedOperation.java
@@ -771,6 +771,21 @@ * {@inheritDoc} */ @Override() boolean setCancelRequest(CancelRequest cancelRequest) { assert debugEnter(CLASS_NAME, "setCancelRequest", String.valueOf(cancelRequest)); this.cancelRequest = cancelRequest; return true; } /** * {@inheritDoc} */ @Override() public final void toString(StringBuilder buffer) { assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder"); opends/src/server/org/opends/server/core/ModifyDNOperation.java
@@ -2116,6 +2116,21 @@ * {@inheritDoc} */ @Override() boolean setCancelRequest(CancelRequest cancelRequest) { assert debugEnter(CLASS_NAME, "setCancelRequest", String.valueOf(cancelRequest)); this.cancelRequest = cancelRequest; return true; } /** * {@inheritDoc} */ @Override() public final void toString(StringBuilder buffer) { assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder"); opends/src/server/org/opends/server/core/ModifyOperation.java
@@ -2808,6 +2808,21 @@ * {@inheritDoc} */ @Override() boolean setCancelRequest(CancelRequest cancelRequest) { assert debugEnter(CLASS_NAME, "setCancelRequest", String.valueOf(cancelRequest)); this.cancelRequest = cancelRequest; return true; } /** * {@inheritDoc} */ @Override() public final void toString(StringBuilder buffer) { assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder"); opends/src/server/org/opends/server/core/Operation.java
@@ -928,6 +928,22 @@ /** * Sets the cancel request for this operation, if applicable. This should * only be used for testing purposes (e.g., for ensuring a cancel request is * submitted before processing begins on an operation, or to allow for * cancelling an internal operation). * * @param cancelRequest The cancel request to set for this operation. * * @return <CODE>true</CODE> if the cancel request was set, or * <CODE>false</CODE> if it was not for some reason (e.g., the * specified operation cannot be cancelled). */ abstract boolean setCancelRequest(CancelRequest cancelRequest); /** * Retrieves the cancel request that has been issued for this operation, if * there is one. This method should not be called by post-operation or * post-response plugins. opends/src/server/org/opends/server/core/SearchOperation.java
@@ -2179,6 +2179,21 @@ * {@inheritDoc} */ @Override() boolean setCancelRequest(CancelRequest cancelRequest) { assert debugEnter(CLASS_NAME, "setCancelRequest", String.valueOf(cancelRequest)); this.cancelRequest = cancelRequest; return true; } /** * {@inheritDoc} */ @Override() public final void toString(StringBuilder buffer) { assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder"); opends/src/server/org/opends/server/core/UnbindOperation.java
@@ -306,6 +306,21 @@ * {@inheritDoc} */ @Override() boolean setCancelRequest(CancelRequest cancelRequest) { assert debugEnter(CLASS_NAME, "setCancelRequest", String.valueOf(cancelRequest)); // Unbind operations cannot be canceled. return false; } /** * {@inheritDoc} */ @Override() public final void toString(StringBuilder buffer) { assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder"); opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
@@ -31,13 +31,16 @@ import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.Lock; 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.DisconnectClientPlugin; import org.opends.server.plugins.UpdatePreOpPlugin; import org.opends.server.protocols.asn1.ASN1Element; import org.opends.server.protocols.asn1.ASN1OctetString; import org.opends.server.protocols.asn1.ASN1Reader; import org.opends.server.protocols.asn1.ASN1Sequence; @@ -53,15 +56,18 @@ import org.opends.server.types.AttributeType; import org.opends.server.types.AttributeValue; import org.opends.server.types.ByteString; import org.opends.server.types.CancelRequest; import org.opends.server.types.Control; import org.opends.server.types.DN; import org.opends.server.types.Entry; import org.opends.server.types.LockManager; 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.protocols.ldap.LDAPConstants.*; import static org.opends.server.util.ServerConstants.*; @@ -1885,5 +1891,357 @@ assertEquals(changeListener.getAddCount(), 0); DirectoryServer.deregisterChangeNotificationListener(changeListener); } /** * Tests an add operation that gets canceled before startup. * * @throws Exception If an unexpected probem occurs. */ @Test() public void testCancelBeforeStartup() 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 = new AddOperation(conn, conn.nextOperationID(), conn.nextMessageID(), null, entry.getDN(), entry.getObjectClasses(), entry.getUserAttributes(), entry.getOperationalAttributes()); CancelRequest cancelRequest = new CancelRequest(false, "testCancelBeforeStartup"); addOperation.setCancelRequest(cancelRequest); addOperation.run(); assertEquals(addOperation.getResultCode(), ResultCode.CANCELED); } /** * Tests an add operation in which the server cannot obtain a lock on the * target entry because there is already a read lock held on it. * * @throws Exception If an unexpected problem occurs. */ @Test(groups = { "slow" }) public void testCannotLockEntry() throws Exception { TestCaseUtils.initializeTestBackend(true); Lock entryLock = LockManager.lockRead(DN.decode("ou=People,o=test")); try { 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()); assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS); } finally { LockManager.unlock(DN.decode("ou=People,o=test"), entryLock); } } /** * Tests an add operation that should be disconnected in a pre-parse plugin. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testDisconnectInPreParseAdd() 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(5000); 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)); AddRequestProtocolOp addRequest = new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"), attrs); message = new LDAPMessage(2, addRequest, DisconnectClientPlugin.createDisconnectLDAPControlList("PreParse")); w.writeElement(message.encode()); ASN1Element element = r.readElement(); if (element != null) { // If we got an element back, then it must be a notice of disconnect // unsolicited notification. message = LDAPMessage.decode(element.decodeAsSequence()); assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE); } try { s.close(); } catch (Exception e) {} } /** * Tests an add operation that should be disconnected in a pre-operation * plugin. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testDisconnectInPreOperationAdd() 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(5000); 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)); AddRequestProtocolOp addRequest = new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"), attrs); message = new LDAPMessage(2, addRequest, DisconnectClientPlugin.createDisconnectLDAPControlList( "PreOperation")); w.writeElement(message.encode()); ASN1Element element = r.readElement(); if (element != null) { // If we got an element back, then it must be a notice of disconnect // unsolicited notification. message = LDAPMessage.decode(element.decodeAsSequence()); assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE); } try { s.close(); } catch (Exception e) {} } /** * Tests an add operation that should be disconnected in a post-operation * plugin. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testDisconnectInPostOperationAdd() 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(5000); 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)); AddRequestProtocolOp addRequest = new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"), attrs); message = new LDAPMessage(2, addRequest, DisconnectClientPlugin.createDisconnectLDAPControlList( "PostOperation")); w.writeElement(message.encode()); ASN1Element element = r.readElement(); if (element != null) { // If we got an element back, then it must be a notice of disconnect // unsolicited notification. message = LDAPMessage.decode(element.decodeAsSequence()); assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE); } try { s.close(); } catch (Exception e) {} } /** * Tests an add operation that should be disconnected in a post-response * plugin. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testDisconnectInPostResponseAdd() 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(5000); 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)); AddRequestProtocolOp addRequest = new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"), attrs); message = new LDAPMessage(2, addRequest, DisconnectClientPlugin.createDisconnectLDAPControlList( "PostResponse")); w.writeElement(message.encode()); responseLoop: while (true) { ASN1Element element = r.readElement(); if (element == null) { // The connection has been closed. break responseLoop; } message = LDAPMessage.decode(element.decodeAsSequence()); switch (message.getProtocolOpType()) { case OP_TYPE_ADD_RESPONSE: // This was expected. The disconnect didn't happen until after the // response was sent. break; case OP_TYPE_EXTENDED_RESPONSE: // The server is notifying us that it will be closing the connection. break responseLoop; default: // This is a problem. It's an unexpected response. try { s.close(); } catch (Exception e) {} throw new Exception("Unexpected response message " + message + " encountered in " + "testDisconnectInPostResponseAdd"); } } try { s.close(); } catch (Exception e) {} } } opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java
@@ -30,6 +30,7 @@ import java.net.Socket; import java.util.ArrayList; import java.util.concurrent.locks.Lock; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -50,9 +51,11 @@ import org.opends.server.protocols.ldap.LDAPMessage; import org.opends.server.tools.LDAPDelete; import org.opends.server.types.ByteString; import org.opends.server.types.CancelRequest; import org.opends.server.types.Control; import org.opends.server.types.DN; import org.opends.server.types.Entry; import org.opends.server.types.LockManager; import org.opends.server.types.ResultCode; import org.opends.server.types.WritabilityMode; @@ -767,6 +770,64 @@ /** * Tests a delete operation that gets canceled before startup. * * @throws Exception If an unexpected probem occurs. */ @Test() public void testCancelBeforeStartup() throws Exception { TestCaseUtils.initializeTestBackend(true); InternalClientConnection conn = InternalClientConnection.getRootConnection(); DeleteOperation deleteOperation = new DeleteOperation(conn, conn.nextOperationID(), conn.nextMessageID(), null, new ASN1OctetString("o=test")); CancelRequest cancelRequest = new CancelRequest(false, "testCancelBeforeStartup"); deleteOperation.setCancelRequest(cancelRequest); deleteOperation.run(); assertEquals(deleteOperation.getResultCode(), ResultCode.CANCELED); } /** * Tests a delete operation in which the server cannot obtain a lock on the * target entry because there is already a read lock held on it. * * @throws Exception If an unexpected problem occurs. */ @Test(groups = { "slow" }) public void testCannotLockEntry() throws Exception { TestCaseUtils.initializeTestBackend(true); Lock entryLock = LockManager.lockRead(DN.decode("o=test")); try { InternalClientConnection conn = InternalClientConnection.getRootConnection(); DeleteOperation deleteOperation = conn.processDelete(new ASN1OctetString("o=test")); assertFalse(deleteOperation.getResultCode() == ResultCode.SUCCESS); } finally { LockManager.unlock(DN.decode("o=test"), entryLock); } } /** * Tests a delete operation that should be disconnected in a pre-parse plugin. * * @throws Exception If an unexpected problem occurs. @@ -997,5 +1058,66 @@ s.close(); } catch (Exception e) {} } /** * Tests to ensure that any registered notification listeners are invoked for * a successful delete 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); InternalClientConnection conn = InternalClientConnection.getRootConnection(); DeleteOperation deleteOperation = conn.processDelete(new ASN1OctetString("o=test")); assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); retrieveCompletedOperationElements(deleteOperation); assertEquals(changeListener.getDeleteCount(), 1); DirectoryServer.deregisterChangeNotificationListener(changeListener); } /** * Tests to ensure that any registered notification listeners are not invoked * for a failed delete 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); InternalClientConnection conn = InternalClientConnection.getRootConnection(); DeleteOperation deleteOperation = conn.processDelete(new ASN1OctetString("cn=nonexistent,o=test")); assertFalse(deleteOperation.getResultCode() == ResultCode.SUCCESS); assertEquals(changeListener.getDeleteCount(), 0); DirectoryServer.deregisterChangeNotificationListener(changeListener); } } opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
@@ -31,13 +31,16 @@ import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.Lock; 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.DisconnectClientPlugin; import org.opends.server.plugins.UpdatePreOpPlugin; import org.opends.server.protocols.asn1.ASN1Element; import org.opends.server.protocols.asn1.ASN1OctetString; import org.opends.server.protocols.asn1.ASN1Reader; import org.opends.server.protocols.asn1.ASN1Sequence; @@ -54,9 +57,11 @@ import org.opends.server.types.AttributeType; import org.opends.server.types.AttributeValue; import org.opends.server.types.ByteString; import org.opends.server.types.CancelRequest; import org.opends.server.types.Control; import org.opends.server.types.DN; import org.opends.server.types.Entry; import org.opends.server.types.LockManager; import org.opends.server.types.Modification; import org.opends.server.types.ModificationType; import org.opends.server.types.ObjectClass; @@ -65,6 +70,7 @@ import static org.testng.Assert.*; import static org.opends.server.protocols.ldap.LDAPConstants.*; import static org.opends.server.util.ServerConstants.*; @@ -3643,5 +3649,339 @@ assertEquals(changeListener.getModifyCount(), 0); DirectoryServer.deregisterChangeNotificationListener(changeListener); } /** * Tests a modify operation that gets canceled before startup. * * @throws Exception If an unexpected probem occurs. */ @Test() public void testCancelBeforeStartup() throws Exception { TestCaseUtils.initializeTestBackend(true); InternalClientConnection conn = InternalClientConnection.getRootConnection(); ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>(); values.add(new ASN1OctetString("foo")); LDAPAttribute attr = new LDAPAttribute("description", values); ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>(); mods.add(new LDAPModification(ModificationType.REPLACE, attr)); ModifyOperation modifyOperation = new ModifyOperation(conn, conn.nextOperationID(), conn.nextMessageID(), null, new ASN1OctetString("o=test"), mods); CancelRequest cancelRequest = new CancelRequest(false, "testCancelBeforeStartup"); modifyOperation.setCancelRequest(cancelRequest); modifyOperation.run(); assertEquals(modifyOperation.getResultCode(), ResultCode.CANCELED); } /** * Tests a modify operation in which the server cannot obtain a lock on the * target entry because there is already a read lock held on it. * * @throws Exception If an unexpected problem occurs. */ @Test(groups = { "slow" }) public void testCannotLockEntry() throws Exception { TestCaseUtils.initializeTestBackend(true); Lock entryLock = LockManager.lockRead(DN.decode("o=test")); try { InternalClientConnection conn = InternalClientConnection.getRootConnection(); ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>(); values.add(new ASN1OctetString("foo")); LDAPAttribute attr = new LDAPAttribute("description", values); ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>(); mods.add(new LDAPModification(ModificationType.REPLACE, attr)); ModifyOperation modifyOperation = conn.processModify(new ASN1OctetString("o=test"), mods); assertFalse(modifyOperation.getResultCode() == ResultCode.SUCCESS); } finally { LockManager.unlock(DN.decode("o=test"), entryLock); } } /** * Tests a modify operation that should be disconnected in a pre-parse plugin. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testDisconnectInPreParseModify() 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(5000); 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<ASN1OctetString> values = new ArrayList<ASN1OctetString>(); values.add(new ASN1OctetString("foo")); LDAPAttribute attr = new LDAPAttribute("description", values); ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>(); mods.add(new LDAPModification(ModificationType.REPLACE, attr)); ModifyRequestProtocolOp modifyRequest = new ModifyRequestProtocolOp(new ASN1OctetString("o=test"), mods); message = new LDAPMessage(2, modifyRequest, DisconnectClientPlugin.createDisconnectLDAPControlList("PreParse")); w.writeElement(message.encode()); ASN1Element element = r.readElement(); if (element != null) { // If we got an element back, then it must be a notice of disconnect // unsolicited notification. message = LDAPMessage.decode(element.decodeAsSequence()); assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE); } try { s.close(); } catch (Exception e) {} } /** * Tests a modify operation that should be disconnected in a pre-operation * plugin. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testDisconnectInPreOperationModify() 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(5000); 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<ASN1OctetString> values = new ArrayList<ASN1OctetString>(); values.add(new ASN1OctetString("foo")); LDAPAttribute attr = new LDAPAttribute("description", values); ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>(); mods.add(new LDAPModification(ModificationType.REPLACE, attr)); ModifyRequestProtocolOp modifyRequest = new ModifyRequestProtocolOp(new ASN1OctetString("o=test"), mods); message = new LDAPMessage(2, modifyRequest, DisconnectClientPlugin.createDisconnectLDAPControlList( "PreOperation")); w.writeElement(message.encode()); ASN1Element element = r.readElement(); if (element != null) { // If we got an element back, then it must be a notice of disconnect // unsolicited notification. message = LDAPMessage.decode(element.decodeAsSequence()); assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE); } try { s.close(); } catch (Exception e) {} } /** * Tests a modify operation that should be disconnected in a post-operation * plugin. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testDisconnectInPostOperationModify() 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(5000); 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<ASN1OctetString> values = new ArrayList<ASN1OctetString>(); values.add(new ASN1OctetString("foo")); LDAPAttribute attr = new LDAPAttribute("description", values); ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>(); mods.add(new LDAPModification(ModificationType.REPLACE, attr)); ModifyRequestProtocolOp modifyRequest = new ModifyRequestProtocolOp(new ASN1OctetString("o=test"), mods); message = new LDAPMessage(2, modifyRequest, DisconnectClientPlugin.createDisconnectLDAPControlList( "PostOperation")); w.writeElement(message.encode()); ASN1Element element = r.readElement(); if (element != null) { // If we got an element back, then it must be a notice of disconnect // unsolicited notification. message = LDAPMessage.decode(element.decodeAsSequence()); assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE); } try { s.close(); } catch (Exception e) {} } /** * Tests a modify operation that should be disconnected in a post-response * plugin. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testDisconnectInPostResponseModify() 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(5000); 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<ASN1OctetString> values = new ArrayList<ASN1OctetString>(); values.add(new ASN1OctetString("foo")); LDAPAttribute attr = new LDAPAttribute("description", values); ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>(); mods.add(new LDAPModification(ModificationType.REPLACE, attr)); ModifyRequestProtocolOp modifyRequest = new ModifyRequestProtocolOp(new ASN1OctetString("o=test"), mods); message = new LDAPMessage(2, modifyRequest, DisconnectClientPlugin.createDisconnectLDAPControlList( "PostResponse")); w.writeElement(message.encode()); responseLoop: while (true) { ASN1Element element = r.readElement(); if (element == null) { // The connection has been closed. break responseLoop; } message = LDAPMessage.decode(element.decodeAsSequence()); switch (message.getProtocolOpType()) { case OP_TYPE_MODIFY_RESPONSE: // This was expected. The disconnect didn't happen until after the // response was sent. break; case OP_TYPE_EXTENDED_RESPONSE: // The server is notifying us that it will be closing the connection. break responseLoop; default: // This is a problem. It's an unexpected response. try { s.close(); } catch (Exception e) {} throw new Exception("Unexpected response message " + message + " encountered in " + "testDisconnectInPostResponseModify"); } } try { s.close(); } catch (Exception e) {} } }