From 9020a676bbe359cb158e96761ef6f1a3c32c80e5 Mon Sep 17 00:00:00 2001
From: Yannick Lecaillez <yannick.lecaillez@forgerock.com>
Date: Tue, 10 May 2016 16:42:27 +0000
Subject: [PATCH] REST2LDAP Refactoring
---
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java | 223 ++++++++++++++++++++++++++-----------------------------
1 files changed, 104 insertions(+), 119 deletions(-)
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java
index cf0fd1c..140a94c 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java
@@ -11,7 +11,7 @@
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions Copyright [year] [name of copyright owner]".
*
- * Copyright 2012-2015 ForgeRock AS.
+ * Copyright 2012-2016 ForgeRock AS.
*/
package org.forgerock.opendj.rest2ldap;
@@ -51,6 +51,7 @@
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.forgerock.opendj.ldap.responses.SearchResultReference;
+import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.util.AsyncFunction;
import org.forgerock.util.Function;
import org.forgerock.util.promise.ExceptionHandler;
@@ -70,14 +71,16 @@
private static final int SEARCH_MAX_CANDIDATES = 1000;
private final DN baseDN;
+ private final Schema schema;
private Filter filter;
private final AttributeMapper mapper;
private final AttributeDescription primaryKey;
private SearchScope scope = SearchScope.WHOLE_SUBTREE;
- ReferenceAttributeMapper(final AttributeDescription ldapAttributeName, final DN baseDN,
+ ReferenceAttributeMapper(final Schema schema, final AttributeDescription ldapAttributeName, final DN baseDN,
final AttributeDescription primaryKey, final AttributeMapper mapper) {
super(ldapAttributeName);
+ this.schema = schema;
this.baseDN = baseDN;
this.primaryKey = primaryKey;
this.mapper = mapper;
@@ -130,10 +133,9 @@
}
@Override
- Promise<Filter, ResourceException> getLDAPFilter(final RequestState requestState, final JsonPointer path,
+ Promise<Filter, ResourceException> getLDAPFilter(final Connection connection, final JsonPointer path,
final JsonPointer subPath, final FilterType type, final String operator, final Object valueAssertion) {
-
- return mapper.getLDAPFilter(requestState, path, subPath, type, operator, valueAssertion)
+ return mapper.getLDAPFilter(connection, path, subPath, type, operator, valueAssertion)
.thenAsync(new AsyncFunction<Filter, Filter, ResourceException>() {
@Override
public Promise<Filter, ResourceException> apply(final Filter result) {
@@ -141,56 +143,47 @@
final SearchRequest request = createSearchRequest(result);
final List<Filter> subFilters = new LinkedList<>();
- return requestState.getConnection().thenAsync(
- new AsyncFunction<Connection, Filter, ResourceException>() {
- @Override
- public Promise<Filter, ResourceException> apply(final Connection connection)
- throws ResourceException {
- return connection.searchAsync(request, new SearchResultHandler() {
- @Override
- public boolean handleEntry(final SearchResultEntry entry) {
- if (subFilters.size() < SEARCH_MAX_CANDIDATES) {
- subFilters.add(Filter.equality(
- ldapAttributeName.toString(), entry.getName()));
- return true;
- } else {
- // No point in continuing - maximum candidates reached.
- return false;
- }
- }
-
- @Override
- public boolean handleReference(final SearchResultReference reference) {
- // Ignore references.
- return true;
- }
- }).then(new Function<Result, Filter, ResourceException>() {
- @Override
- public Filter apply(Result result) throws ResourceException {
- if (subFilters.size() >= SEARCH_MAX_CANDIDATES) {
- throw asResourceException(
- newLdapException(ResultCode.ADMIN_LIMIT_EXCEEDED));
- } else if (subFilters.size() == 1) {
- return subFilters.get(0);
- } else {
- return Filter.or(subFilters);
- }
- }
- }, new Function<LdapException, Filter, ResourceException>() {
- @Override
- public Filter apply(LdapException exception) throws ResourceException {
- throw asResourceException(exception);
- }
- });
- }
- });
+ return connection.searchAsync(request, new SearchResultHandler() {
+ @Override
+ public boolean handleEntry(final SearchResultEntry entry) {
+ if (subFilters.size() < SEARCH_MAX_CANDIDATES) {
+ subFilters.add(Filter.equality(ldapAttributeName.toString(), entry.getName()));
+ return true;
+ } else {
+ // No point in continuing - maximum candidates reached.
+ return false;
+ }
+ }
+ @Override
+ public boolean handleReference(final SearchResultReference reference) {
+ // Ignore references.
+ return true;
+ }
+ }).then(new Function<Result, Filter, ResourceException>() {
+ @Override
+ public Filter apply(Result result) throws ResourceException {
+ if (subFilters.size() >= SEARCH_MAX_CANDIDATES) {
+ throw asResourceException(
+ newLdapException(ResultCode.ADMIN_LIMIT_EXCEEDED));
+ } else if (subFilters.size() == 1) {
+ return subFilters.get(0);
+ } else {
+ return Filter.or(subFilters);
+ }
+ }
+ }, new Function<LdapException, Filter, ResourceException>() {
+ @Override
+ public Filter apply(LdapException exception) throws ResourceException {
+ throw asResourceException(exception);
+ }
+ });
}
});
}
@Override
- Promise<Attribute, ResourceException> getNewLDAPAttributes(
- final RequestState requestState, final JsonPointer path, final List<Object> newValues) {
+ Promise<Attribute, ResourceException> getNewLDAPAttributes(final Connection connection, final JsonPointer path,
+ final List<Object> newValues) {
/*
* For each value use the subordinate mapper to obtain the LDAP primary
* key, the perform a search for each one to find the corresponding entries.
@@ -201,7 +194,7 @@
final PromiseImpl<Attribute, ResourceException> promise = PromiseImpl.create();
for (final Object value : newValues) {
- mapper.create(requestState, path, new JsonValue(value)).thenOnResult(new ResultHandler<List<Attribute>>() {
+ mapper.create(connection, path, new JsonValue(value)).thenOnResult(new ResultHandler<List<Attribute>>() {
@Override
public void handleResult(List<Attribute> result) {
Attribute primaryKeyAttribute = null;
@@ -228,43 +221,38 @@
final ByteString primaryKeyValue = primaryKeyAttribute.firstValue();
final Filter filter = Filter.equality(primaryKey.toString(), primaryKeyValue);
final SearchRequest search = createSearchRequest(filter);
- requestState.getConnection().thenOnResult(new ResultHandler<Connection>() {
- @Override
- public void handleResult(Connection connection) {
- connection.searchSingleEntryAsync(search)
- .thenOnResult(new ResultHandler<SearchResultEntry>() {
- @Override
- public void handleResult(final SearchResultEntry result) {
- synchronized (newLDAPAttribute) {
- newLDAPAttribute.add(result.getName());
- }
- completeIfNecessary();
- }
- }).thenOnException(new ExceptionHandler<LdapException>() {
- @Override
- public void handleException(final LdapException error) {
- ResourceException re;
- try {
- throw error;
- } catch (final EntryNotFoundException e) {
- re = new BadRequestException(i18n(
- "The request cannot be processed because the resource "
- + "'%s' referenced in field '%s' does not exist",
- primaryKeyValue.toString(), path));
- } catch (final MultipleEntriesFoundException e) {
- re = new BadRequestException(i18n(
- "The request cannot be processed because the resource "
- + "'%s' referenced in field '%s' is ambiguous",
- primaryKeyValue.toString(), path));
- } catch (final LdapException e) {
- re = asResourceException(e);
- }
- exception.compareAndSet(null, re);
- completeIfNecessary();
- }
- });
- }
- });
+ connection.searchSingleEntryAsync(search)
+ .thenOnResult(new ResultHandler<SearchResultEntry>() {
+ @Override
+ public void handleResult(final SearchResultEntry result) {
+ synchronized (newLDAPAttribute) {
+ newLDAPAttribute.add(result.getName());
+ }
+ completeIfNecessary();
+ }
+ }).thenOnException(new ExceptionHandler<LdapException>() {
+ @Override
+ public void handleException(final LdapException error) {
+ ResourceException re;
+ try {
+ throw error;
+ } catch (final EntryNotFoundException e) {
+ re = new BadRequestException(i18n(
+ "The request cannot be processed because the resource "
+ + "'%s' referenced in field '%s' does not exist",
+ primaryKeyValue.toString(), path));
+ } catch (final MultipleEntriesFoundException e) {
+ re = new BadRequestException(i18n(
+ "The request cannot be processed because the resource "
+ + "'%s' referenced in field '%s' is ambiguous",
+ primaryKeyValue.toString(), path));
+ } catch (final LdapException e) {
+ re = asResourceException(e);
+ }
+ exception.compareAndSet(null, re);
+ completeIfNecessary();
+ }
+ });
}
private void completeIfNecessary() {
@@ -287,25 +275,25 @@
}
@Override
- Promise<JsonValue, ResourceException> read(final RequestState c, final JsonPointer path, final Entry e) {
+ Promise<JsonValue, ResourceException> read(final Connection connection, final JsonPointer path, final Entry e) {
final Attribute attribute = e.getAttribute(ldapAttributeName);
if (attribute == null || attribute.isEmpty()) {
return Promises.newResultPromise(null);
} else if (attributeIsSingleValued()) {
try {
- final DN dn = attribute.parse().usingSchema(c.getConfig().schema()).asDN();
- return readEntry(c, path, dn);
+ final DN dn = attribute.parse().usingSchema(schema).asDN();
+ return readEntry(connection, path, dn);
} catch (final Exception ex) {
// The LDAP attribute could not be decoded.
return Promises.newExceptionPromise(asResourceException(ex));
}
} else {
try {
- final Set<DN> dns = attribute.parse().usingSchema(c.getConfig().schema()).asSetOfDN();
+ final Set<DN> dns = attribute.parse().usingSchema(schema).asSetOfDN();
final List<Promise<JsonValue, ResourceException>> promises = new ArrayList<>(dns.size());
for (final DN dn : dns) {
- promises.add(readEntry(c, path, dn));
+ promises.add(readEntry(connection, path, dn));
}
return Promises.when(promises)
@@ -340,33 +328,30 @@
}
private Promise<JsonValue, ResourceException> readEntry(
- final RequestState requestState, final JsonPointer path, final DN dn) {
+ final Connection connection, final JsonPointer path, final DN dn) {
final Set<String> requestedLDAPAttributes = new LinkedHashSet<>();
- mapper.getLDAPAttributes(requestState, path, new JsonPointer(), requestedLDAPAttributes);
- return requestState.getConnection().thenAsync(new AsyncFunction<Connection, JsonValue, ResourceException>() {
- @Override
- public Promise<JsonValue, ResourceException> apply(Connection connection) throws ResourceException {
- final Filter searchFilter = filter != null ? filter : Filter.alwaysTrue();
- final String[] attributes = requestedLDAPAttributes.toArray(new String[requestedLDAPAttributes.size()]);
- final SearchRequest request = newSearchRequest(dn, SearchScope.BASE_OBJECT, searchFilter, attributes);
+ mapper.getLDAPAttributes(connection, path, new JsonPointer(), requestedLDAPAttributes);
- return connection.searchSingleEntryAsync(request)
- .thenAsync(new AsyncFunction<SearchResultEntry, JsonValue, ResourceException>() {
- @Override
- public Promise<JsonValue, ResourceException> apply(final SearchResultEntry result) {
- return mapper.read(requestState, path, result);
- }
- }, new AsyncFunction<LdapException, JsonValue, ResourceException>() {
- @Override
- public Promise<JsonValue, ResourceException> apply(final LdapException error) {
- if (error instanceof EntryNotFoundException) {
- // Ignore missing entry since it cannot be mapped.
- return Promises.newResultPromise(null);
- }
- return Promises.newExceptionPromise(asResourceException(error));
- }
- });
- }
- });
+ final Filter searchFilter = filter != null ? filter : Filter.alwaysTrue();
+ final String[] attributes = requestedLDAPAttributes.toArray(new String[requestedLDAPAttributes.size()]);
+ final SearchRequest request = newSearchRequest(dn, SearchScope.BASE_OBJECT, searchFilter, attributes);
+
+ return connection
+ .searchSingleEntryAsync(request)
+ .thenAsync(new AsyncFunction<SearchResultEntry, JsonValue, ResourceException>() {
+ @Override
+ public Promise<JsonValue, ResourceException> apply(final SearchResultEntry result) {
+ return mapper.read(connection, path, result);
+ }
+ }, new AsyncFunction<LdapException, JsonValue, ResourceException>() {
+ @Override
+ public Promise<JsonValue, ResourceException> apply(final LdapException error) {
+ if (error instanceof EntryNotFoundException) {
+ // Ignore missing entry since it cannot be mapped.
+ return Promises.newResultPromise(null);
+ }
+ return Promises.newExceptionPromise(asResourceException(error));
+ }
+ });
}
}
--
Gitblit v1.10.0