From eec7ba4411d0535c8229d08f0cdad60d04da7ca6 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 25 Aug 2016 14:28:39 +0000
Subject: [PATCH] OPENDJ-3160 Pass Context through to PropertyMapper methods

---
 opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/PropertyMapper.java             |   27 ++----
 opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimplePropertyMapper.java       |    8 +-
 opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JsonConstantPropertyMapper.java |   12 +-
 opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectPropertyMapper.java       |   30 +++---
 opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ResourceTypePropertyMapper.java |   12 +-
 opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SubResourceImpl.java            |   70 ++++++++---------
 opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferencePropertyMapper.java    |   27 +++---
 opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java                      |    6 +
 opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLdapPropertyMapper.java |   20 ++--
 9 files changed, 105 insertions(+), 107 deletions(-)

diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLdapPropertyMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLdapPropertyMapper.java
index 23f37fd..0feff58 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLdapPropertyMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLdapPropertyMapper.java
@@ -39,11 +39,11 @@
 import org.forgerock.json.resource.ResourceException;
 import org.forgerock.opendj.ldap.Attribute;
 import org.forgerock.opendj.ldap.AttributeDescription;
-import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.Entry;
 import org.forgerock.opendj.ldap.LinkedAttribute;
 import org.forgerock.opendj.ldap.Modification;
 import org.forgerock.opendj.ldap.ModificationType;
+import org.forgerock.services.context.Context;
 import org.forgerock.util.Function;
 import org.forgerock.util.promise.Promise;
 import org.forgerock.util.promise.Promises;
@@ -102,10 +102,10 @@
     }
 
     @Override
-    Promise<List<Attribute>, ResourceException> create(final Connection connection,
+    Promise<List<Attribute>, ResourceException> create(final Context context,
                                                        final Resource resource, final JsonPointer path,
                                                        final JsonValue v) {
-        return getNewLdapAttributes(connection, resource, path, v).then(
+        return getNewLdapAttributes(context, resource, path, v).then(
             new Function<Attribute, List<Attribute>, ResourceException>() {
                 @Override
                 public List<Attribute> apply(Attribute newLDAPAttribute) throws ResourceException {
@@ -130,13 +130,13 @@
         ldapAttributes.add(ldapAttributeName.toString());
     }
 
-    abstract Promise<Attribute, ResourceException> getNewLdapAttributes(Connection connection, Resource resource,
+    abstract Promise<Attribute, ResourceException> getNewLdapAttributes(Context context, Resource resource,
                                                                         JsonPointer path, List<Object> newValues);
 
     abstract T getThis();
 
     @Override
-    Promise<List<Modification>, ResourceException> patch(final Connection connection, final Resource resource,
+    Promise<List<Modification>, ResourceException> patch(final Context context, final Resource resource,
                                                          final JsonPointer path, final PatchOperation operation) {
         try {
             final JsonPointer field = operation.getField();
@@ -233,7 +233,7 @@
                         singletonList(new Modification(modType, emptyAttribute(ldapAttributeName))));
                 }
             } else {
-                return getNewLdapAttributes(connection, resource, path, newValues)
+                return getNewLdapAttributes(context, resource, path, newValues)
                         .then(new Function<Attribute, List<Modification>, ResourceException>() {
                             @Override
                             public List<Modification> apply(final Attribute value) {
@@ -249,9 +249,9 @@
     }
 
     @Override
-    Promise<List<Modification>, ResourceException> update(final Connection connection, final Resource resource,
+    Promise<List<Modification>, ResourceException> update(final Context context, final Resource resource,
                                                           final JsonPointer path, final Entry e, final JsonValue v) {
-        return getNewLdapAttributes(connection, resource, path, v).then(
+        return getNewLdapAttributes(context, resource, path, v).then(
             new Function<Attribute, List<Modification>, ResourceException>() {
                 @Override
                 public List<Modification> apply(final Attribute newLDAPAttribute) throws ResourceException {
@@ -333,7 +333,7 @@
         }
     }
 
-    private Promise<Attribute, ResourceException> getNewLdapAttributes(final Connection connection,
+    private Promise<Attribute, ResourceException> getNewLdapAttributes(final Context context,
                                                                        final Resource resource, final JsonPointer path,
                                                                        final JsonValue v) {
         try {
@@ -344,7 +344,7 @@
                 // Skip sub-class implementation if there are no values.
                 return newResultPromise(emptyAttribute(ldapAttributeName));
             } else {
-                return getNewLdapAttributes(connection, resource, path, newValues);
+                return getNewLdapAttributes(context, resource, path, newValues);
             }
         } catch (final Exception e) {
             return asResourceException(e).asPromise();
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JsonConstantPropertyMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JsonConstantPropertyMapper.java
index f171ad8..01525ff 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JsonConstantPropertyMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JsonConstantPropertyMapper.java
@@ -33,10 +33,10 @@
 import org.forgerock.json.resource.PatchOperation;
 import org.forgerock.json.resource.ResourceException;
 import org.forgerock.opendj.ldap.Attribute;
-import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.Entry;
 import org.forgerock.opendj.ldap.Filter;
 import org.forgerock.opendj.ldap.Modification;
+import org.forgerock.services.context.Context;
 import org.forgerock.util.promise.Promise;
 
 /**
@@ -55,7 +55,7 @@
     }
 
     @Override
-    Promise<List<Attribute>, ResourceException> create(final Connection connection,
+    Promise<List<Attribute>, ResourceException> create(final Context context,
                                                        final Resource resource, final JsonPointer path,
                                                        final JsonValue v) {
         if (!isNullOrEmpty(v) && !v.getObject().equals(value.getObject())) {
@@ -71,7 +71,7 @@
     }
 
     @Override
-    Promise<Filter, ResourceException> getLdapFilter(final Connection connection, final Resource resource,
+    Promise<Filter, ResourceException> getLdapFilter(final Context context, final Resource resource,
                                                      final JsonPointer path, final JsonPointer subPath,
                                                      final FilterType type, final String operator,
                                                      final Object valueAssertion) {
@@ -111,19 +111,19 @@
     }
 
     @Override
-    Promise<List<Modification>, ResourceException> patch(final Connection connection, final Resource resource,
+    Promise<List<Modification>, ResourceException> patch(final Context context, final Resource resource,
                                                          final JsonPointer path, final PatchOperation operation) {
         return newBadRequestException(ERR_PATCH_READ_ONLY_FIELD.get(path)).asPromise();
     }
 
     @Override
-    Promise<JsonValue, ResourceException> read(final Connection connection, final Resource resource,
+    Promise<JsonValue, ResourceException> read(final Context context, final Resource resource,
                                                final JsonPointer path, final Entry e) {
         return newResultPromise(value.copy());
     }
 
     @Override
-    Promise<List<Modification>, ResourceException> update(final Connection connection, final Resource resource,
+    Promise<List<Modification>, ResourceException> update(final Context context, final Resource resource,
                                                           final JsonPointer path, final Entry e, final JsonValue v) {
         if (!isNullOrEmpty(v) && !v.getObject().equals(value.getObject())) {
             return newBadRequestException(ERR_MODIFY_READ_ONLY_FIELD.get("update", path)).asPromise();
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectPropertyMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectPropertyMapper.java
index 4aa4ab1..615c7a6 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectPropertyMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectPropertyMapper.java
@@ -40,10 +40,10 @@
 import org.forgerock.json.resource.PatchOperation;
 import org.forgerock.json.resource.ResourceException;
 import org.forgerock.opendj.ldap.Attribute;
-import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.Entry;
 import org.forgerock.opendj.ldap.Filter;
 import org.forgerock.opendj.ldap.Modification;
+import org.forgerock.services.context.Context;
 import org.forgerock.util.Function;
 import org.forgerock.util.Pair;
 import org.forgerock.util.promise.Promise;
@@ -136,7 +136,7 @@
     }
 
     @Override
-    Promise<List<Attribute>, ResourceException> create(final Connection connection,
+    Promise<List<Attribute>, ResourceException> create(final Context context,
                                                        final Resource resource, final JsonPointer path,
                                                        final JsonValue v) {
         try {
@@ -151,14 +151,14 @@
                 for (final Map.Entry<String, Object> me : v.asMap().entrySet()) {
                     final Mapping mapping = getMapping(me.getKey());
                     final JsonValue subValue = new JsonValue(me.getValue());
-                    promises.add(mapping.mapper.create(connection, resource, path.child(me.getKey()),
+                    promises.add(mapping.mapper.create(context, resource, path.child(me.getKey()),
                                                        subValue));
                 }
             }
 
             // Invoke mappings for which there were no values provided.
             for (final Mapping mapping : missingMappings.values()) {
-                promises.add(mapping.mapper.create(connection, resource, path.child(mapping.name), null));
+                promises.add(mapping.mapper.create(context, resource, path.child(mapping.name), null));
             }
 
             return Promises.when(promises)
@@ -189,13 +189,13 @@
     }
 
     @Override
-    Promise<Filter, ResourceException> getLdapFilter(final Connection connection, final Resource resource,
+    Promise<Filter, ResourceException> getLdapFilter(final Context context, final Resource resource,
                                                      final JsonPointer path, final JsonPointer subPath,
                                                      final FilterType type, final String operator,
                                                      final Object valueAssertion) {
         final Mapping mapping = getMappingOrNull(subPath);
         if (mapping != null) {
-            return mapping.mapper.getLdapFilter(connection,
+            return mapping.mapper.getLdapFilter(context,
                                                 resource,
                                                 path.child(subPath.get(0)),
                                                 subPath.relativePointer(),
@@ -213,7 +213,7 @@
     }
 
     @Override
-    Promise<List<Modification>, ResourceException> patch(final Connection connection, final Resource resource,
+    Promise<List<Modification>, ResourceException> patch(final Context context, final Resource resource,
                                                          final JsonPointer path, final PatchOperation operation) {
         try {
             final JsonPointer field = operation.getField();
@@ -237,7 +237,7 @@
                         final JsonValue subValue = new JsonValue(me.getValue());
                         final PatchOperation subOperation =
                                 operation(operation.getOperation(), field /* empty */, subValue);
-                        promises.add(mapping.mapper.patch(connection, resource, path.child(me.getKey()), subOperation));
+                        promises.add(mapping.mapper.patch(context, resource, path.child(me.getKey()), subOperation));
                     }
                 }
 
@@ -256,7 +256,7 @@
                 }
                 final PatchOperation subOperation =
                         operation(operation.getOperation(), field.relativePointer(), v);
-                return mapping.mapper.patch(connection, resource, path.child(fieldName), subOperation);
+                return mapping.mapper.patch(context, resource, path.child(fieldName), subOperation);
             }
         } catch (final Exception e) {
             return asResourceException(e).asPromise();
@@ -264,7 +264,7 @@
     }
 
     @Override
-    Promise<JsonValue, ResourceException> read(final Connection connection, final Resource resource,
+    Promise<JsonValue, ResourceException> read(final Context context, final Resource resource,
                                                final JsonPointer path, final Entry e) {
         /*
          * Use an accumulator which will aggregate the results from the
@@ -275,7 +275,7 @@
                 new ArrayList<>(mappings.size());
 
         for (final Mapping mapping : mappings.values()) {
-            promises.add(mapping.mapper.read(connection, resource, path.child(mapping.name), e)
+            promises.add(mapping.mapper.read(context, resource, path.child(mapping.name), e)
                                        .then(toProperty(mapping.name)));
         }
 
@@ -296,7 +296,7 @@
                 }
                 // This attribute needs to be mapped.
                 final SimplePropertyMapper mapper = simple(attribute.getAttributeDescription());
-                promises.add(mapper.read(connection, resource, path.child(attributeName), e)
+                promises.add(mapper.read(context, resource, path.child(attributeName), e)
                                    .then(toProperty(attributeName)));
             }
         }
@@ -332,7 +332,7 @@
     }
 
     @Override
-    Promise<List<Modification>, ResourceException> update(final Connection connection, final Resource resource,
+    Promise<List<Modification>, ResourceException> update(final Context context, final Resource resource,
                                                           final JsonPointer path, final Entry e, final JsonValue v) {
         try {
             // First check that the JSON value is an object and that the fields it contains are known by this mapper.
@@ -346,13 +346,13 @@
                 for (final Map.Entry<String, Object> me : v.asMap().entrySet()) {
                     final Mapping mapping = getMapping(me.getKey());
                     final JsonValue subValue = new JsonValue(me.getValue());
-                    promises.add(mapping.mapper.update(connection, resource, path.child(me.getKey()), e, subValue));
+                    promises.add(mapping.mapper.update(context, resource, path.child(me.getKey()), e, subValue));
                 }
             }
 
             // Invoke mappings for which there were no values provided.
             for (final Mapping mapping : missingMappings.values()) {
-                promises.add(mapping.mapper.update(connection, resource, path.child(mapping.name), e, null));
+                promises.add(mapping.mapper.update(context, resource, path.child(mapping.name), e, null));
             }
 
             return Promises.when(promises)
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/PropertyMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/PropertyMapper.java
index 3755d3f..d428e09 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/PropertyMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/PropertyMapper.java
@@ -23,10 +23,10 @@
 import org.forgerock.json.resource.PatchOperation;
 import org.forgerock.json.resource.ResourceException;
 import org.forgerock.opendj.ldap.Attribute;
-import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.Entry;
 import org.forgerock.opendj.ldap.Filter;
 import org.forgerock.opendj.ldap.Modification;
+import org.forgerock.services.context.Context;
 import org.forgerock.util.promise.Promise;
 
 /** An property mapper is responsible for converting JSON values to and from LDAP attributes. */
@@ -51,8 +51,7 @@
      * action in this case, perhaps by substituting default LDAP values, or by
      * returning a failed promise with an appropriate {@link ResourceException}.
      *
-     * @param connection
-     *            The LDAP connection to use to perform the operation.
+     * @param context The request context.
      * @param resource The exact type of resource being created.
      * @param path
      *            The pointer from the root of the JSON resource to this
@@ -64,7 +63,7 @@
      *            in the resource.
      * @return A {@link Promise} containing the result of the operation.
      */
-    abstract Promise<List<Attribute>, ResourceException> create(Connection connection, Resource resource,
+    abstract Promise<List<Attribute>, ResourceException> create(Context context, Resource resource,
                                                                 JsonPointer path, JsonValue v);
 
     /**
@@ -96,8 +95,7 @@
      * promise must be returned with an appropriate {@link ResourceException}
      * indicating the problem which occurred.
      *
-     * @param connection
-     *            The LDAP connection to use to perform the operation.
+     * @param context The request context.
      * @param resource The type of resource being queried.
      * @param path
      *            The pointer from the root of the JSON resource to this
@@ -118,7 +116,7 @@
      *            {@link FilterType#PRESENT}.
      * @return A {@link Promise} containing the result of the operation.
      */
-    abstract Promise<Filter, ResourceException> getLdapFilter(Connection connection, Resource resource,
+    abstract Promise<Filter, ResourceException> getLdapFilter(Context context, Resource resource,
                                                               JsonPointer path, JsonPointer subPath, FilterType type,
                                                               String operator, Object valueAssertion);
 
@@ -127,8 +125,7 @@
      * a promise once the transformation has completed. This method is invoked
      * when a REST resource is modified using a patch request.
      *
-     * @param connection
-     *            The LDAP connection to use to perform the operation.
+     * @param context The request context.
      * @param resource The exact type of resource being patched.
      * @param path
      *            The pointer from the root of the JSON resource to this
@@ -141,7 +138,7 @@
      *            with this mapper have been targeted.
      * @return A {@link Promise} containing the result of the operation.
      */
-    abstract Promise<List<Modification>, ResourceException> patch(Connection connection, Resource resource,
+    abstract Promise<List<Modification>, ResourceException> patch(Context context, Resource resource,
                                                                   JsonPointer path, PatchOperation operation);
 
     /**
@@ -159,8 +156,7 @@
      * they contain unexpected content, then a failed promise must be returned
      * with an appropriate exception indicating the problem which occurred.
      *
-     * @param connection
-     *            The LDAP connection to use to perform the operation.
+     * @param context The request context.
      * @param resource The exact type of resource being read.
      * @param path
      *            The pointer from the root of the JSON resource to this
@@ -170,7 +166,7 @@
      *            The LDAP entry to be converted to JSON.
      * @return A {@link Promise} containing the result of the operation.
      */
-    abstract Promise<JsonValue, ResourceException> read(Connection connection, Resource resource,
+    abstract Promise<JsonValue, ResourceException> read(Context context, Resource resource,
                                                         JsonPointer path, Entry e);
 
     /**
@@ -184,8 +180,7 @@
      * action in this case, perhaps by substituting default LDAP values, or by
      * returning a failed promise with an appropriate {@link ResourceException}.
      *
-     * @param connection
-     *            The LDAP connection to use to perform the operation.
+     * @param context The request context.
      * @param resource The exact type of resource being updated.
      * @param v
      *            The JSON value to be converted to LDAP attributes, which may
@@ -193,7 +188,7 @@
      *            in the resource.
      * @return A {@link Promise} containing the result of the operation.
      */
-    abstract Promise<List<Modification>, ResourceException> update(Connection connection, Resource resource,
+    abstract Promise<List<Modification>, ResourceException> update(Context context, Resource resource,
                                                                    JsonPointer path, Entry e, JsonValue v);
 
     // TODO: methods for obtaining schema information (e.g. name, description, type information).
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferencePropertyMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferencePropertyMapper.java
index e01c530..f20052b 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferencePropertyMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferencePropertyMapper.java
@@ -20,6 +20,7 @@
 import static org.forgerock.opendj.ldap.LdapException.newLdapException;
 import static org.forgerock.opendj.ldap.requests.Requests.newSearchRequest;
 import static org.forgerock.opendj.rest2ldap.Rest2Ldap.asResourceException;
+import static org.forgerock.opendj.rest2ldap.Utils.connectionFrom;
 import static org.forgerock.util.Reject.checkNotNull;
 import static org.forgerock.opendj.rest2ldap.Utils.newBadRequestException;
 import static org.forgerock.util.promise.Promises.newResultPromise;
@@ -38,7 +39,6 @@
 import org.forgerock.opendj.ldap.Attribute;
 import org.forgerock.opendj.ldap.AttributeDescription;
 import org.forgerock.opendj.ldap.ByteString;
-import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.DN;
 import org.forgerock.opendj.ldap.Entry;
 import org.forgerock.opendj.ldap.EntryNotFoundException;
@@ -53,6 +53,7 @@
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
 import org.forgerock.opendj.ldap.responses.SearchResultReference;
 import org.forgerock.opendj.ldap.schema.Schema;
+import org.forgerock.services.context.Context;
 import org.forgerock.util.AsyncFunction;
 import org.forgerock.util.Function;
 import org.forgerock.util.promise.ExceptionHandler;
@@ -134,11 +135,11 @@
     }
 
     @Override
-    Promise<Filter, ResourceException> getLdapFilter(final Connection connection, final Resource resource,
+    Promise<Filter, ResourceException> getLdapFilter(final Context context, final Resource resource,
                                                      final JsonPointer path, final JsonPointer subPath,
                                                      final FilterType type, final String operator,
                                                      final Object valueAssertion) {
-        return mapper.getLdapFilter(connection, resource, path, subPath, type, operator, valueAssertion)
+        return mapper.getLdapFilter(context, resource, path, subPath, type, operator, valueAssertion)
                 .thenAsync(new AsyncFunction<Filter, Filter, ResourceException>() {
                     @Override
                     public Promise<Filter, ResourceException> apply(final Filter result) {
@@ -146,7 +147,7 @@
                         final SearchRequest request = createSearchRequest(result);
                         final List<Filter> subFilters = new LinkedList<>();
 
-                        return connection.searchAsync(request, new SearchResultHandler() {
+                        return connectionFrom(context).searchAsync(request, new SearchResultHandler() {
                             @Override
                             public boolean handleEntry(final SearchResultEntry entry) {
                                 if (subFilters.size() < SEARCH_MAX_CANDIDATES) {
@@ -184,7 +185,7 @@
     }
 
     @Override
-    Promise<Attribute, ResourceException> getNewLdapAttributes(final Connection connection, final Resource resource,
+    Promise<Attribute, ResourceException> getNewLdapAttributes(final Context context, final Resource resource,
                                                                final JsonPointer path, final List<Object> newValues) {
         /*
          * For each value use the subordinate mapper to obtain the LDAP primary
@@ -196,7 +197,7 @@
         final PromiseImpl<Attribute, ResourceException> promise = PromiseImpl.create();
 
         for (final Object value : newValues) {
-            mapper.create(connection, resource, path, new JsonValue(value))
+            mapper.create(context, resource, path, new JsonValue(value))
                   .thenOnResult(new ResultHandler<List<Attribute>>() {
                       @Override
                       public void handleResult(List<Attribute> result) {
@@ -224,7 +225,7 @@
                           final ByteString primaryKeyValue = primaryKeyAttribute.firstValue();
                           final Filter filter = Filter.equality(primaryKey.toString(), primaryKeyValue);
                           final SearchRequest search = createSearchRequest(filter);
-                          connection.searchSingleEntryAsync(search)
+                          connectionFrom(context).searchSingleEntryAsync(search)
                                     .thenOnResult(new ResultHandler<SearchResultEntry>() {
                                         @Override
                                         public void handleResult(final SearchResultEntry result) {
@@ -276,7 +277,7 @@
 
     @SuppressWarnings("fallthrough")
     @Override
-    Promise<JsonValue, ResourceException> read(final Connection connection, final Resource resource,
+    Promise<JsonValue, ResourceException> read(final Context context, final Resource resource,
                                                final JsonPointer path, final Entry e) {
         final Set<DN> dns = e.parseAttribute(ldapAttributeName).usingSchema(schema).asSetOfDN();
         switch (dns.size()) {
@@ -285,7 +286,7 @@
         case 1:
             if (attributeIsSingleValued()) {
                 try {
-                    return readEntry(connection, resource, path, dns.iterator().next());
+                    return readEntry(context, resource, path, dns.iterator().next());
                 } catch (final Exception ex) {
                     // The LDAP attribute could not be decoded.
                     return Promises.newExceptionPromise(asResourceException(ex));
@@ -296,7 +297,7 @@
             try {
                 final List<Promise<JsonValue, ResourceException>> promises = new ArrayList<>(dns.size());
                 for (final DN dn : dns) {
-                    promises.add(readEntry(connection, resource, path, dn));
+                    promises.add(readEntry(context, resource, path, dn));
                 }
                 return Promises.when(promises)
                                .then(new Function<List<JsonValue>, JsonValue, ResourceException>() {
@@ -330,7 +331,7 @@
     }
 
     private Promise<JsonValue, ResourceException> readEntry(
-            final Connection connection, final Resource resource, final JsonPointer path, final DN dn) {
+            final Context context, final Resource resource, final JsonPointer path, final DN dn) {
         final Set<String> requestedLDAPAttributes = new LinkedHashSet<>();
         mapper.getLdapAttributes(path, new JsonPointer(), requestedLDAPAttributes);
 
@@ -338,12 +339,12 @@
         final String[] attributes = requestedLDAPAttributes.toArray(new String[requestedLDAPAttributes.size()]);
         final SearchRequest request = newSearchRequest(dn, SearchScope.BASE_OBJECT, searchFilter, attributes);
 
-        return connection
+        return connectionFrom(context)
                 .searchSingleEntryAsync(request)
                 .thenAsync(new AsyncFunction<SearchResultEntry, JsonValue, ResourceException>() {
                     @Override
                     public Promise<JsonValue, ResourceException> apply(final SearchResultEntry result) {
-                        return mapper.read(connection, resource, path, result);
+                        return mapper.read(context, resource, path, result);
                     }
                 }, new AsyncFunction<LdapException, JsonValue, ResourceException>() {
                     @Override
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ResourceTypePropertyMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ResourceTypePropertyMapper.java
index 845f821..4f79fd8 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ResourceTypePropertyMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ResourceTypePropertyMapper.java
@@ -37,10 +37,10 @@
 import org.forgerock.json.resource.ResourceException;
 import org.forgerock.opendj.ldap.Attribute;
 import org.forgerock.opendj.ldap.ByteString;
-import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.Entry;
 import org.forgerock.opendj.ldap.Filter;
 import org.forgerock.opendj.ldap.Modification;
+import org.forgerock.services.context.Context;
 import org.forgerock.util.promise.Promise;
 
 /**
@@ -57,7 +57,7 @@
     }
 
     @Override
-    Promise<List<Attribute>, ResourceException> create(final Connection connection,
+    Promise<List<Attribute>, ResourceException> create(final Context context,
                                                        final Resource resource, final JsonPointer path,
                                                        final JsonValue v) {
         return newResultPromise(singletonList(resource.getObjectClassAttribute()));
@@ -69,7 +69,7 @@
     }
 
     @Override
-    Promise<Filter, ResourceException> getLdapFilter(final Connection connection, final Resource resource,
+    Promise<Filter, ResourceException> getLdapFilter(final Context context, final Resource resource,
                                                      final JsonPointer path, final JsonPointer subPath,
                                                      final FilterType type, final String operator,
                                                      final Object valueAssertion) {
@@ -100,19 +100,19 @@
     }
 
     @Override
-    Promise<List<Modification>, ResourceException> patch(final Connection connection, final Resource resource,
+    Promise<List<Modification>, ResourceException> patch(final Context context, final Resource resource,
                                                          final JsonPointer path, final PatchOperation operation) {
         return newBadRequestException(ERR_PATCH_READ_ONLY_FIELD.get(path)).asPromise();
     }
 
     @Override
-    Promise<JsonValue, ResourceException> read(final Connection connection, final Resource resource,
+    Promise<JsonValue, ResourceException> read(final Context context, final Resource resource,
                                                final JsonPointer path, final Entry e) {
         return newResultPromise(new JsonValue(resource.getResourceId()));
     }
 
     @Override
-    Promise<List<Modification>, ResourceException> update(final Connection connection, final Resource resource,
+    Promise<List<Modification>, ResourceException> update(final Context context, final Resource resource,
                                                           final JsonPointer path, final Entry e, final JsonValue v) {
         if (!isNullOrEmpty(v) && !v.getObject().equals(resource.getResourceId())) {
             return newBadRequestException(ERR_MODIFY_READ_ONLY_FIELD.get("update", path)).asPromise();
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimplePropertyMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimplePropertyMapper.java
index 3abe8cd..2d82561 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimplePropertyMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimplePropertyMapper.java
@@ -28,9 +28,9 @@
 import org.forgerock.opendj.ldap.Attribute;
 import org.forgerock.opendj.ldap.AttributeDescription;
 import org.forgerock.opendj.ldap.ByteString;
-import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.Entry;
 import org.forgerock.opendj.ldap.Filter;
+import org.forgerock.services.context.Context;
 import org.forgerock.util.Function;
 import org.forgerock.util.promise.NeverThrowsException;
 import org.forgerock.util.promise.Promise;
@@ -133,7 +133,7 @@
     }
 
     @Override
-    Promise<Filter, ResourceException> getLdapFilter(final Connection connection, final Resource resource,
+    Promise<Filter, ResourceException> getLdapFilter(final Context context, final Resource resource,
                                                      final JsonPointer path, final JsonPointer subPath,
                                                      final FilterType type, final String operator,
                                                      final Object valueAssertion) {
@@ -153,7 +153,7 @@
     }
 
     @Override
-    Promise<Attribute, ResourceException> getNewLdapAttributes(final Connection connection, final Resource resource,
+    Promise<Attribute, ResourceException> getNewLdapAttributes(final Context context, final Resource resource,
                                                                final JsonPointer path, final List<Object> newValues) {
         try {
             return newResultPromise(jsonToAttribute(newValues, ldapAttributeName, encoder()));
@@ -169,7 +169,7 @@
 
     @SuppressWarnings("fallthrough")
     @Override
-    Promise<JsonValue, ResourceException> read(final Connection connection, final Resource resource,
+    Promise<JsonValue, ResourceException> read(final Context context, final Resource resource,
                                                final JsonPointer path, final Entry e) {
         try {
             final Set<Object> s = e.parseAttribute(ldapAttributeName).asSetOf(decoder(), defaultJsonValues);
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SubResourceImpl.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SubResourceImpl.java
index e48282d..5e6f81c 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SubResourceImpl.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SubResourceImpl.java
@@ -34,6 +34,7 @@
 import static org.forgerock.opendj.ldap.SearchScope.SINGLE_LEVEL;
 import static org.forgerock.opendj.ldap.requests.Requests.*;
 import static org.forgerock.opendj.rest2ldap.ReadOnUpdatePolicy.CONTROLS;
+import static org.forgerock.opendj.rest2ldap.Utils.connectionFrom;
 import static org.forgerock.opendj.rest2ldap.Utils.newBadRequestException;
 import static org.forgerock.opendj.rest2ldap.Utils.newNotSupportedException;
 import static org.forgerock.opendj.rest2ldap.Utils.toFilter;
@@ -262,7 +263,7 @@
         // Now build the LDAP representation and add it.
         final Connection connection = connectionFrom(context);
         return subType.getPropertyMapper()
-                      .create(connection, subType, ROOT, request.getContent())
+                      .create(context, subType, ROOT, request.getContent())
                       .thenAsync(new AsyncFunction<List<Attribute>, ResourceResponse, ResourceException>() {
                           @Override
                           public Promise<ResourceResponse, ResourceException> apply(final List<Attribute> attributes) {
@@ -285,7 +286,7 @@
                               }
                               return connection.addAsync(addRequest)
                                                .thenCatchAsync(lazilyAddGlueEntry(connection, addRequest))
-                                               .thenAsync(encodeUpdateResourceResponse(connection, subType),
+                                               .thenAsync(encodeUpdateResourceResponse(context, subType),
                                                           adaptLdapException(ResourceResponse.class));
                           }
                       });
@@ -322,10 +323,6 @@
         };
     }
 
-    private Connection connectionFrom(final Context context) {
-        return context.asContext(AuthenticatedConnectionContext.class).getConnection();
-    }
-
     Promise<ResourceResponse, ResourceException> delete(
             final Context context, final String resourceId, final DeleteRequest request) {
         final Connection connection = connectionFrom(context);
@@ -349,7 +346,7 @@
                         return connection.applyChangeAsync(deleteRequest)
                                          .thenCatchAsync(deleteSubtreeWithoutUsingSubtreeDeleteControl(connection,
                                                                                                        deleteRequest))
-                                         .thenAsync(encodeUpdateResourceResponse(connection, dnAndType.getType()),
+                                         .thenAsync(encodeUpdateResourceResponse(context, dnAndType.getType()),
                                                     adaptLdapException(ResourceResponse.class));
                     }
                 });
@@ -436,7 +433,7 @@
                         final Resource subType = dnAndType.getType();
                         final PropertyMapper propertyMapper = subType.getPropertyMapper();
                         for (final PatchOperation operation : request.getPatchOperations()) {
-                            promises.add(propertyMapper.patch(connection, subType, ROOT, operation));
+                            promises.add(propertyMapper.patch(context, subType, ROOT, operation));
                         }
                         return when(promises);
                     }
@@ -460,7 +457,7 @@
                         if (modifyRequest.getModifications().isEmpty()) {
                             // This patch is a no-op so just read the entry and check its version.
                             return connection.readEntryAsync(dnAndType.getDn(), attributes)
-                                             .thenAsync(encodeEmptyPatchResourceResponse(connection, subType, request),
+                                             .thenAsync(encodeEmptyPatchResourceResponse(context, subType, request),
                                                         adaptLdapException(ResourceResponse.class));
                         } else {
                             // Add controls and perform the modify request.
@@ -472,7 +469,7 @@
                             }
                             addAssertionControl(modifyRequest, request.getRevision());
                             return connection.applyChangeAsync(modifyRequest)
-                                             .thenAsync(encodeUpdateResourceResponse(connection, subType),
+                                             .thenAsync(encodeUpdateResourceResponse(context, subType),
                                                         adaptLdapException(ResourceResponse.class));
                         }
                     }
@@ -480,13 +477,13 @@
     }
 
     private AsyncFunction<Entry, ResourceResponse, ResourceException> encodeEmptyPatchResourceResponse(
-            final Connection connection, final Resource resource, final PatchRequest request) {
+            final Context context, final Resource resource, final PatchRequest request) {
         return new AsyncFunction<Entry, ResourceResponse, ResourceException>() {
             @Override
             public Promise<ResourceResponse, ResourceException> apply(Entry entry) throws ResourceException {
                 try {
                     ensureMvccVersionMatches(entry, request.getRevision());
-                    return encodeResourceResponse(connection, resource, entry);
+                    return encodeResourceResponse(context, resource, entry);
                 } catch (final Exception e) {
                     return asResourceException(e).asPromise();
                 }
@@ -496,14 +493,13 @@
 
     Promise<QueryResponse, ResourceException> query(
             final Context context, final QueryRequest request, final QueryResourceHandler resourceHandler) {
-        final Connection connection = connectionFrom(context);
-        return getLdapFilter(connection, request.getQueryFilter())
-                .thenAsync(runQuery(request, resourceHandler, connection));
+        return getLdapFilter(context, request.getQueryFilter())
+                .thenAsync(runQuery(context, request, resourceHandler));
     }
 
     // FIXME: supporting assertions against sub-type properties.
     private Promise<Filter, ResourceException> getLdapFilter(
-            final Connection connection, final QueryFilter<JsonPointer> queryFilter) {
+            final Context context, final QueryFilter<JsonPointer> queryFilter) {
         if (queryFilter == null) {
             return new BadRequestException(ERR_QUERY_BY_ID_OR_EXPRESSION_NOT_SUPPORTED.get().toString()).asPromise();
         }
@@ -553,14 +549,14 @@
                     public Promise<Filter, ResourceException> visitContainsFilter(
                             final Void unused, final JsonPointer field, final Object valueAssertion) {
                         return propertyMapper.getLdapFilter(
-                                connection, resource, ROOT, field, CONTAINS, null, valueAssertion);
+                                context, resource, ROOT, field, CONTAINS, null, valueAssertion);
                     }
 
                     @Override
                     public Promise<Filter, ResourceException> visitEqualsFilter(
                             final Void unused, final JsonPointer field, final Object valueAssertion) {
                         return propertyMapper.getLdapFilter(
-                                connection, resource, ROOT, field, EQUAL_TO, null, valueAssertion);
+                                context, resource, ROOT, field, EQUAL_TO, null, valueAssertion);
                     }
 
                     @Override
@@ -569,35 +565,35 @@
                                                                                        final String operator,
                                                                                        final Object valueAssertion) {
                         return propertyMapper.getLdapFilter(
-                                connection, resource, ROOT, field, EXTENDED, operator, valueAssertion);
+                                context, resource, ROOT, field, EXTENDED, operator, valueAssertion);
                     }
 
                     @Override
                     public Promise<Filter, ResourceException> visitGreaterThanFilter(
                             final Void unused, final JsonPointer field, final Object valueAssertion) {
                         return propertyMapper.getLdapFilter(
-                                connection, resource, ROOT, field, GREATER_THAN, null, valueAssertion);
+                                context, resource, ROOT, field, GREATER_THAN, null, valueAssertion);
                     }
 
                     @Override
                     public Promise<Filter, ResourceException> visitGreaterThanOrEqualToFilter(
                             final Void unused, final JsonPointer field, final Object valueAssertion) {
                         return propertyMapper.getLdapFilter(
-                                connection, resource, ROOT, field, GREATER_THAN_OR_EQUAL_TO, null, valueAssertion);
+                                context, resource, ROOT, field, GREATER_THAN_OR_EQUAL_TO, null, valueAssertion);
                     }
 
                     @Override
                     public Promise<Filter, ResourceException> visitLessThanFilter(
                             final Void unused, final JsonPointer field, final Object valueAssertion) {
                         return propertyMapper.getLdapFilter(
-                                connection, resource, ROOT, field, LESS_THAN, null, valueAssertion);
+                                context, resource, ROOT, field, LESS_THAN, null, valueAssertion);
                     }
 
                     @Override
                     public Promise<Filter, ResourceException> visitLessThanOrEqualToFilter(
                             final Void unused, final JsonPointer field, final Object valueAssertion) {
                         return propertyMapper.getLdapFilter(
-                                connection, resource, ROOT, field, LESS_THAN_OR_EQUAL_TO, null, valueAssertion);
+                                context, resource, ROOT, field, LESS_THAN_OR_EQUAL_TO, null, valueAssertion);
                     }
 
                     @Override
@@ -653,14 +649,14 @@
                     @Override
                     public Promise<Filter, ResourceException> visitPresentFilter(
                             final Void unused, final JsonPointer field) {
-                        return propertyMapper.getLdapFilter(connection, resource, ROOT, field, PRESENT, null, null);
+                        return propertyMapper.getLdapFilter(context, resource, ROOT, field, PRESENT, null, null);
                     }
 
                     @Override
                     public Promise<Filter, ResourceException> visitStartsWithFilter(
                             final Void unused, final JsonPointer field, final Object valueAssertion) {
                         return propertyMapper.getLdapFilter(
-                                connection, resource, ROOT, field, STARTS_WITH, null, valueAssertion);
+                                context, resource, ROOT, field, STARTS_WITH, null, valueAssertion);
                     }
                 };
         // Note that the returned LDAP filter may be null if it could not be mapped by any property mappers.
@@ -668,7 +664,7 @@
     }
 
     private AsyncFunction<Filter, QueryResponse, ResourceException> runQuery(
-            final QueryRequest request, final QueryResourceHandler resourceHandler, final Connection connection) {
+            final Context context, final QueryRequest request, final QueryResourceHandler resourceHandler) {
         return new AsyncFunction<Filter, QueryResponse, ResourceException>() {
             // The following fields are guarded by sequenceLock. In addition, the sequenceLock ensures that
             // we send one JSON resource at a time back to the client.
@@ -714,7 +710,7 @@
                     pageResultStartIndex = 0;
                 }
 
-                connection.searchAsync(searchRequest, new SearchResultHandler() {
+                connectionFrom(context).searchAsync(searchRequest, new SearchResultHandler() {
                     @Override
                     public boolean handleEntry(final SearchResultEntry entry) {
                         // Search result entries will be returned before the search result/error so the only reason
@@ -746,7 +742,7 @@
                         final String revision = getRevisionFromEntry(entry);
                         final Resource subType = resource.resolveSubTypeFromObjectClasses(entry);
                         final PropertyMapper propertyMapper = subType.getPropertyMapper();
-                        propertyMapper.read(connection, subType, ROOT, entry)
+                        propertyMapper.read(context, subType, ROOT, entry)
                                       .thenOnResult(new ResultHandler<JsonValue>() {
                                           @Override
                                           public void handleResult(final JsonValue result) {
@@ -849,7 +845,7 @@
                              @Override
                              public Promise<ResourceResponse, ResourceException> apply(SearchResultEntry entry) {
                                  final Resource subType = resource.resolveSubTypeFromObjectClasses(entry);
-                                 return encodeResourceResponse(connection, subType, entry);
+                                 return encodeResourceResponse(context, subType, entry);
                              }
                          });
     }
@@ -875,7 +871,7 @@
                         final Resource subType = resource.resolveSubTypeFromObjectClasses(entry);
                         subTypeHolder.set(subType);
                         final PropertyMapper propertyMapper = subType.getPropertyMapper();
-                        return propertyMapper.update(connection, subType , ROOT, entry, request.getContent());
+                        return propertyMapper.update(context, subType , ROOT, entry, request.getContent());
                     }
                 }).thenAsync(new AsyncFunction<List<Modification>, ResourceResponse, ResourceException>() {
                     @Override
@@ -884,7 +880,7 @@
                         final Resource subType = subTypeHolder.get();
                         if (modifications.isEmpty()) {
                             // No changes to be performed so just return the entry that we read.
-                            return encodeResourceResponse(connection, subType, entryHolder.get());
+                            return encodeResourceResponse(context, subType, entryHolder.get());
                         }
                         // Perform the modify operation.
                         final ModifyRequest modifyRequest = newModifyRequest(entryHolder.get().getName());
@@ -898,16 +894,16 @@
                         addAssertionControl(modifyRequest, request.getRevision());
                         modifyRequest.getModifications().addAll(modifications);
                         return connection.applyChangeAsync(modifyRequest)
-                                         .thenAsync(encodeUpdateResourceResponse(connection, subType),
+                                         .thenAsync(encodeUpdateResourceResponse(context, subType),
                                                     adaptLdapException(ResourceResponse.class));
                     }
                 });
     }
 
     private Promise<ResourceResponse, ResourceException> encodeResourceResponse(
-            final Connection connection, final Resource resource, final Entry entry) {
+            final Context context, final Resource resource, final Entry entry) {
         final PropertyMapper propertyMapper = resource.getPropertyMapper();
-        return propertyMapper.read(connection, resource, ROOT, entry)
+        return propertyMapper.read(context, resource, ROOT, entry)
                              .then(new Function<JsonValue, ResourceResponse, ResourceException>() {
                                  @Override
                                  public ResourceResponse apply(final JsonValue value) {
@@ -1020,7 +1016,7 @@
     }
 
     private AsyncFunction<Result, ResourceResponse, ResourceException> encodeUpdateResourceResponse(
-            final Connection connection, final Resource resource) {
+            final Context context, final Resource resource) {
         return new AsyncFunction<Result, ResourceResponse, ResourceException>() {
             @Override
             public Promise<ResourceResponse, ResourceException> apply(Result result) {
@@ -1029,12 +1025,12 @@
                     final PostReadResponseControl postReadControl =
                             result.getControl(PostReadResponseControl.DECODER, decodeOptions);
                     if (postReadControl != null) {
-                        return encodeResourceResponse(connection, resource, postReadControl.getEntry());
+                        return encodeResourceResponse(context, resource, postReadControl.getEntry());
                     }
                     final PreReadResponseControl preReadControl =
                             result.getControl(PreReadResponseControl.DECODER, decodeOptions);
                     if (preReadControl != null) {
-                        return encodeResourceResponse(connection, resource, preReadControl.getEntry());
+                        return encodeResourceResponse(context, resource, preReadControl.getEntry());
                     }
                 } catch (final DecodeException e) {
                     logger.error(ERR_DECODING_CONTROL.get(e.getLocalizedMessage()), e);
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
index 5ace36c..042b591 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
@@ -40,10 +40,12 @@
 import org.forgerock.opendj.ldap.Attribute;
 import org.forgerock.opendj.ldap.AttributeDescription;
 import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.Filter;
 import org.forgerock.opendj.ldap.GeneralizedTime;
 import org.forgerock.opendj.ldap.LinkedAttribute;
 import org.forgerock.opendj.ldap.schema.Syntax;
+import org.forgerock.services.context.Context;
 import org.forgerock.util.Function;
 import org.forgerock.util.promise.NeverThrowsException;
 
@@ -185,6 +187,10 @@
         return new BadRequestException(message.toString(), cause);
     }
 
+    static Connection connectionFrom(final Context context) {
+        return context.asContext(AuthenticatedConnectionContext.class).getConnection();
+    }
+
     /** Prevent instantiation. */
     private Utils() {
         // No implementation required.

--
Gitblit v1.10.0