mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Matthew Swift
05.41.2013 df38eb2ff437f173ad2adf208da699393e2bee8c
opendj3/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/BasicRequestsTest.java
@@ -42,6 +42,8 @@
import static org.forgerock.opendj.rest2ldap.TestUtils.ctx;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import org.forgerock.json.fluent.JsonValue;
import org.forgerock.json.resource.BadRequestException;
@@ -49,10 +51,27 @@
import org.forgerock.json.resource.NotFoundException;
import org.forgerock.json.resource.NotSupportedException;
import org.forgerock.json.resource.PreconditionFailedException;
import org.forgerock.json.resource.RequestHandler;
import org.forgerock.json.resource.Resource;
import org.forgerock.opendj.ldap.ConnectionFactory;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.MemoryBackend;
import org.forgerock.opendj.ldap.RequestContext;
import org.forgerock.opendj.ldap.RequestHandler;
import org.forgerock.opendj.ldap.ResultHandler;
import org.forgerock.opendj.ldap.SearchResultHandler;
import org.forgerock.opendj.ldap.requests.AddRequest;
import org.forgerock.opendj.ldap.requests.BindRequest;
import org.forgerock.opendj.ldap.requests.CompareRequest;
import org.forgerock.opendj.ldap.requests.DeleteRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequest;
import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
import org.forgerock.opendj.ldap.requests.ModifyRequest;
import org.forgerock.opendj.ldap.requests.Request;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.responses.BindResult;
import org.forgerock.opendj.ldap.responses.CompareResult;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldif.LDIFEntryReader;
import org.forgerock.opendj.rest2ldap.Rest2LDAP.Builder;
import org.forgerock.testng.ForgeRockTestCase;
@@ -70,8 +89,7 @@
    @Test
    public void testDelete() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final Resource resource = connection.delete(ctx(), newDeleteRequest("/test1"));
        checkResourcesAreEqual(resource, getTestUser1(12345));
        try {
@@ -84,8 +102,7 @@
    @Test
    public void testDeleteMVCCMatch() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final Resource resource =
                connection.delete(ctx(), newDeleteRequest("/test1").setRevision("12345"));
        checkResourcesAreEqual(resource, getTestUser1(12345));
@@ -99,22 +116,19 @@
    @Test(expectedExceptions = PreconditionFailedException.class)
    public void testDeleteMVCCNoMatch() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.delete(ctx(), newDeleteRequest("/test1").setRevision("12346"));
    }
    @Test(expectedExceptions = NotFoundException.class)
    public void testDeleteNotFound() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.delete(ctx(), newDeleteRequest("/missing"));
    }
    @Test
    public void testPatch() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final Resource resource1 =
                connection.patch(ctx(), newPatchRequest("/test1", add("/name/displayName",
                        "changed")));
@@ -124,9 +138,26 @@
    }
    @Test
    public void testPatchEmpty() throws Exception {
        final List<Request> requests = new LinkedList<Request>();
        final Connection connection = newConnection(requests);
        final Resource resource1 = connection.patch(ctx(), newPatchRequest("/test1"));
        checkResourcesAreEqual(resource1, getTestUser1(12345));
        /*
         * Check that no modify operation was sent (only a single search should
         * be sent in order to get the current resource).
         */
        assertThat(requests).hasSize(1);
        assertThat(requests.get(0)).isInstanceOf(SearchRequest.class);
        final Resource resource2 = connection.read(ctx(), newReadRequest("/test1"));
        checkResourcesAreEqual(resource2, getTestUser1(12345));
    }
    @Test
    public void testPatchAddOptionalAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final JsonValue newContent = getTestUser1(12345);
        newContent.put("description", asList("one", "two"));
        final Resource resource1 =
@@ -139,8 +170,7 @@
    @Test
    public void testPatchAddOptionalAttributeIndexAppend() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final JsonValue newContent = getTestUser1(12345);
        newContent.put("description", asList("one", "two"));
        final Resource resource1 =
@@ -153,15 +183,13 @@
    @Test(expectedExceptions = BadRequestException.class)
    public void testPatchConstantAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", add("/schemas", asList("junk"))));
    }
    @Test
    public void testPatchDeleteOptionalAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(),
                newPatchRequest("/test1", add("/description", asList("one", "two"))));
        final Resource resource1 =
@@ -173,8 +201,7 @@
    @Test
    public void testPatchIncrement() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final JsonValue newContent = getTestUser1(12345);
        newContent.put("singleNumber", 100);
        newContent.put("multiNumber", asList(200, 300));
@@ -190,15 +217,13 @@
    @Test(expectedExceptions = BadRequestException.class)
    public void testPatchMissingRequiredAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", remove("/name/surname")));
    }
    @Test
    public void testPatchModifyOptionalAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(),
                newPatchRequest("/test1", add("/description", asList("one", "two"))));
        final Resource resource1 =
@@ -213,30 +238,26 @@
    @Test(expectedExceptions = NotSupportedException.class)
    public void testPatchMultiValuedAttributeIndexAppend() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", add("/description/0", "junk")));
    }
    @Test(expectedExceptions = BadRequestException.class)
    public void testPatchMultiValuedAttributeIndexAppendWithList() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", add("/description/-",
                asList("one", "two"))));
    }
    @Test(expectedExceptions = BadRequestException.class)
    public void testPatchMultiValuedAttributeWithSingleValue() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", add("/description", "one")));
    }
    @Test
    public void testPatchMVCCMatch() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final Resource resource1 =
                connection.patch(ctx(), newPatchRequest("/test1",
                        add("/name/displayName", "changed")).setRevision("12345"));
@@ -247,31 +268,27 @@
    @Test(expectedExceptions = PreconditionFailedException.class)
    public void testPatchMVCCNoMatch() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", add("/name/displayName", "changed"))
                .setRevision("12346"));
    }
    @Test(expectedExceptions = NotFoundException.class)
    public void testPatchNotFound() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/missing", add("/name/displayName", "changed")));
    }
    @Test(expectedExceptions = BadRequestException.class)
    public void testPatchReadOnlyAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        // Etag is read-only.
        connection.patch(ctx(), newPatchRequest("/test1", add("_rev", "99999")));
    }
    @Test
    public void testPatchReplacePartialObject() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final JsonValue expected =
                json(object(field("schemas", asList("urn:scim:schemas:core:1.0")), field("_id",
                        "test1"), field("_rev", "12345"), field("name", object(field("displayName",
@@ -286,8 +303,7 @@
    @Test
    public void testPatchReplaceWholeObject() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final JsonValue newContent =
                json(object(field("name", object(field("displayName", "Humpty"), field("surname",
                        "Dumpty")))));
@@ -304,83 +320,70 @@
    @Test(expectedExceptions = BadRequestException.class)
    public void testPatchSingleValuedAttributeIndexAppend() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", add("/name/surname/-", "junk")));
    }
    @Test(expectedExceptions = NotSupportedException.class)
    public void testPatchSingleValuedAttributeIndexNumber() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", add("/name/surname/0", "junk")));
    }
    @Test(expectedExceptions = BadRequestException.class)
    public void testPatchSingleValuedAttributeWithMultipleValues() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", add("/name/surname", asList("black",
                "white"))));
    }
    @Test(expectedExceptions = BadRequestException.class)
    public void testPatchUnknownAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", add("/dummy", "junk")));
    }
    @Test(expectedExceptions = NotSupportedException.class)
    public void testPatchUnknownOperation() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", operation("dummy", "/description",
                asList("one", "two"))));
    }
    @Test(expectedExceptions = BadRequestException.class)
    public void testPatchUnknownSubAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", add("/description/dummy", "junk")));
    }
    @Test(expectedExceptions = BadRequestException.class)
    public void testPatchUnknownSubSubAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.patch(ctx(), newPatchRequest("/test1", add("/description/dummy/dummy", "junk")));
    }
    @Test
    public void testRead() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Resource resource =
                newInternalConnection(handler).read(ctx(), newReadRequest("/test1"));
        final Resource resource = newConnection().read(ctx(), newReadRequest("/test1"));
        checkResourcesAreEqual(resource, getTestUser1(12345));
    }
    @Test(expectedExceptions = NotFoundException.class)
    public void testReadNotFound() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        newInternalConnection(handler).read(ctx(), newReadRequest("/missing"));
        newConnection().read(ctx(), newReadRequest("/missing"));
    }
    @Test
    public void testReadSelectAllFields() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Resource resource =
                newInternalConnection(handler).read(ctx(), newReadRequest("/test1").addField("/"));
                newConnection().read(ctx(), newReadRequest("/test1").addField("/"));
        checkResourcesAreEqual(resource, getTestUser1(12345));
    }
    @Test
    public void testReadSelectPartial() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Resource resource =
                newInternalConnection(handler).read(ctx(),
                        newReadRequest("/test1").addField("/name/surname"));
                newConnection().read(ctx(), newReadRequest("/test1").addField("/name/surname"));
        assertThat(resource.getId()).isEqualTo("test1");
        assertThat(resource.getRevision()).isEqualTo("12345");
        assertThat(resource.getContent().get("_id").asString()).isNull();
@@ -392,10 +395,8 @@
    // Disabled - see CREST-86 (Should JSON resource fields be case insensitive?)
    @Test(enabled = false)
    public void testReadSelectPartialInsensitive() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Resource resource =
                newInternalConnection(handler).read(ctx(),
                        newReadRequest("/test1").addField("/name/SURNAME"));
                newConnection().read(ctx(), newReadRequest("/test1").addField("/name/SURNAME"));
        assertThat(resource.getId()).isEqualTo("test1");
        assertThat(resource.getRevision()).isEqualTo("12345");
        assertThat(resource.getContent().get("_id").asString()).isNull();
@@ -406,8 +407,7 @@
    @Test
    public void testUpdate() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final Resource resource1 =
                connection.update(ctx(), newUpdateRequest("/test1", getTestUser1Updated(12345)));
        checkResourcesAreEqual(resource1, getTestUser1Updated(12345));
@@ -416,9 +416,27 @@
    }
    @Test
    public void testUpdateNoChange() throws Exception {
        final List<Request> requests = new LinkedList<Request>();
        final Connection connection = newConnection(requests);
        final Resource resource1 =
                connection.update(ctx(), newUpdateRequest("/test1", getTestUser1(12345)));
        /*
         * Check that no modify operation was sent (only a single search should
         * be sent in order to get the current resource).
         */
        assertThat(requests).hasSize(1);
        assertThat(requests.get(0)).isInstanceOf(SearchRequest.class);
        checkResourcesAreEqual(resource1, getTestUser1(12345));
        final Resource resource2 = connection.read(ctx(), newReadRequest("/test1"));
        checkResourcesAreEqual(resource2, getTestUser1(12345));
    }
    @Test
    public void testUpdateAddOptionalAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final JsonValue newContent = getTestUser1Updated(12345);
        newContent.put("description", asList("one", "two"));
        final Resource resource1 = connection.update(ctx(), newUpdateRequest("/test1", newContent));
@@ -429,8 +447,7 @@
    @Test(expectedExceptions = BadRequestException.class)
    public void testUpdateConstantAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final JsonValue newContent = getTestUser1Updated(12345);
        newContent.put("schemas", asList("junk"));
        connection.update(ctx(), newUpdateRequest("/test1", newContent));
@@ -438,8 +455,7 @@
    @Test
    public void testUpdateDeleteOptionalAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final JsonValue newContent = getTestUser1Updated(12345);
        newContent.put("description", asList("one", "two"));
        connection.update(ctx(), newUpdateRequest("/test1", newContent));
@@ -452,8 +468,7 @@
    @Test(expectedExceptions = BadRequestException.class)
    public void testUpdateMissingRequiredAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final JsonValue newContent = getTestUser1Updated(12345);
        newContent.get("name").remove("surname");
        connection.update(ctx(), newUpdateRequest("/test1", newContent));
@@ -461,8 +476,7 @@
    @Test
    public void testUpdateModifyOptionalAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final JsonValue newContent = getTestUser1Updated(12345);
        newContent.put("description", asList("one", "two"));
        connection.update(ctx(), newUpdateRequest("/test1", newContent));
@@ -475,8 +489,7 @@
    @Test
    public void testUpdateMVCCMatch() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final Resource resource1 =
                connection.update(ctx(), newUpdateRequest("/test1", getTestUser1Updated(12345))
                        .setRevision("12345"));
@@ -487,31 +500,27 @@
    @Test(expectedExceptions = PreconditionFailedException.class)
    public void testUpdateMVCCNoMatch() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.update(ctx(), newUpdateRequest("/test1", getTestUser1Updated(12345))
                .setRevision("12346"));
    }
    @Test(expectedExceptions = NotFoundException.class)
    public void testUpdateNotFound() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        connection.update(ctx(), newUpdateRequest("/missing", getTestUser1Updated(12345)));
    }
    @Test(expectedExceptions = BadRequestException.class)
    public void testUpdateReadOnlyAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        // Etag is read-only.
        connection.update(ctx(), newUpdateRequest("/test1", getTestUser1Updated(99999)));
    }
    @Test(expectedExceptions = BadRequestException.class)
    public void testUpdateSingleValuedAttributeWithMultipleValues() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final JsonValue newContent = getTestUser1Updated(12345);
        newContent.put("surname", asList("black", "white"));
        connection.update(ctx(), newUpdateRequest("/test1", newContent));
@@ -519,17 +528,24 @@
    @Test(expectedExceptions = BadRequestException.class)
    public void testUpdateUnknownAttribute() throws Exception {
        final RequestHandler handler = newCollection(builder().build());
        final Connection connection = newInternalConnection(handler);
        final Connection connection = newConnection();
        final JsonValue newContent = getTestUser1Updated(12345);
        newContent.add("dummy", "junk");
        connection.update(ctx(), newUpdateRequest("/test1", newContent));
    }
    private Builder builder() throws IOException {
        return Rest2LDAP.builder().ldapConnectionFactory(getConnectionFactory()).baseDN("dc=test")
                .useEtagAttribute().useClientDNNaming("uid").readOnUpdatePolicy(
                        ReadOnUpdatePolicy.CONTROLS).authorizationPolicy(AuthorizationPolicy.NONE)
    private Connection newConnection() throws IOException {
        return newConnection(new LinkedList<Request>());
    }
    private Connection newConnection(final List<Request> requests) throws IOException {
        return newInternalConnection(newCollection(builder(requests).build()));
    }
    private Builder builder(final List<Request> requests) throws IOException {
        return Rest2LDAP.builder().ldapConnectionFactory(getConnectionFactory(requests)).baseDN(
                "dc=test").useEtagAttribute().useClientDNNaming("uid").readOnUpdatePolicy(
                ReadOnUpdatePolicy.CONTROLS).authorizationPolicy(AuthorizationPolicy.NONE)
                .additionalLDAPAttribute("objectClass", "top", "person")
                .mapper(object()
                        .attribute("schemas", constant(asList("urn:scim:schemas:core:1.0")))
@@ -560,7 +576,7 @@
                expectedResource.getContent().getObject());
    }
    private ConnectionFactory getConnectionFactory() throws IOException {
    private ConnectionFactory getConnectionFactory(final List<Request> requests) throws IOException {
        // @formatter:off
        final MemoryBackend backend =
                new MemoryBackend(new LDIFEntryReader(
@@ -589,7 +605,86 @@
                ));
        // @formatter:on
        return newInternalConnectionFactory(backend);
        return newInternalConnectionFactory(recordRequests(backend, requests));
    }
    private RequestHandler<RequestContext> recordRequests(
            final RequestHandler<RequestContext> handler, final List<Request> requests) {
        return new RequestHandler<RequestContext>() {
            @Override
            public void handleAdd(RequestContext requestContext, AddRequest request,
                    IntermediateResponseHandler intermediateResponseHandler,
                    ResultHandler<Result> resultHandler) {
                requests.add(request);
                handler.handleAdd(requestContext, request, intermediateResponseHandler,
                        resultHandler);
            }
            @Override
            public void handleBind(RequestContext requestContext, int version, BindRequest request,
                    IntermediateResponseHandler intermediateResponseHandler,
                    ResultHandler<BindResult> resultHandler) {
                requests.add(request);
                handler.handleBind(requestContext, version, request, intermediateResponseHandler,
                        resultHandler);
            }
            @Override
            public void handleCompare(RequestContext requestContext, CompareRequest request,
                    IntermediateResponseHandler intermediateResponseHandler,
                    ResultHandler<CompareResult> resultHandler) {
                requests.add(request);
                handler.handleCompare(requestContext, request, intermediateResponseHandler,
                        resultHandler);
            }
            @Override
            public void handleDelete(RequestContext requestContext, DeleteRequest request,
                    IntermediateResponseHandler intermediateResponseHandler,
                    ResultHandler<Result> resultHandler) {
                requests.add(request);
                handler.handleDelete(requestContext, request, intermediateResponseHandler,
                        resultHandler);
            }
            @Override
            public <R extends ExtendedResult> void handleExtendedRequest(
                    RequestContext requestContext, ExtendedRequest<R> request,
                    IntermediateResponseHandler intermediateResponseHandler,
                    ResultHandler<R> resultHandler) {
                requests.add(request);
                handler.handleExtendedRequest(requestContext, request, intermediateResponseHandler,
                        resultHandler);
            }
            @Override
            public void handleModify(RequestContext requestContext, ModifyRequest request,
                    IntermediateResponseHandler intermediateResponseHandler,
                    ResultHandler<Result> resultHandler) {
                requests.add(request);
                handler.handleModify(requestContext, request, intermediateResponseHandler,
                        resultHandler);
            }
            @Override
            public void handleModifyDN(RequestContext requestContext, ModifyDNRequest request,
                    IntermediateResponseHandler intermediateResponseHandler,
                    ResultHandler<Result> resultHandler) {
                requests.add(request);
                handler.handleModifyDN(requestContext, request, intermediateResponseHandler,
                        resultHandler);
            }
            @Override
            public void handleSearch(RequestContext requestContext, SearchRequest request,
                    IntermediateResponseHandler intermediateResponseHandler,
                    SearchResultHandler resultHandler) {
                requests.add(request);
                handler.handleSearch(requestContext, request, intermediateResponseHandler,
                        resultHandler);
            }
        };
    }
    private JsonValue getTestUser1(final int rev) {