From 9cb4730adfb2ad5fcf171c48a4d0aee46777902e Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 23 May 2012 10:06:17 +0000
Subject: [PATCH] * simplify example code and add groups container * allow AttributeMappers to throw ResourceExceptions instead of LDAP ErrorResultExceptions * rename IdentityAttributeMapper -> SimpleAttributeMapper.
---
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapperCompletionHandler.java | 29 +++++
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java | 25 ++--
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPResource.java | 22 ++--
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java | 41 ++++----
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java | 30 +++---
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Example.java | 129 ++++++-------------------
6 files changed, 118 insertions(+), 158 deletions(-)
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java
index 9387131..47acac8 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java
@@ -16,7 +16,6 @@
package org.forgerock.opendj.rest2ldap;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -25,7 +24,6 @@
import org.forgerock.json.fluent.JsonValue;
import org.forgerock.opendj.ldap.Attribute;
import org.forgerock.opendj.ldap.Entry;
-import org.forgerock.opendj.ldap.ResultHandler;
import org.forgerock.resource.provider.Context;
/**
@@ -34,30 +32,33 @@
public interface AttributeMapper {
/**
- * Returns an unmodifiable collection containing the names of the LDAP
- * attributes required by this attribute mapper. The returned collection
- * should only contain the names of attributes found in the LDAP entry
- * directly associated with the resource.
- *
- * @return An unmodifiable collection containing the names of the LDAP
- * attributes required by this attribute mapper.
- */
- Collection<String> getAllLDAPAttributes();
-
- /**
- * Adds the names of the LDAP attributes required by this attribute mapper
- * which are associated with the provided resource attribute.
+ * Adds the names of the all the LDAP attributes required by this attribute
+ * mapper to the provided set.
* <p>
* Implementations should only add the names of attributes found in the LDAP
* entry directly associated with the resource.
*
- * @param resourceAttribute
- * The name of the resource attribute requested by the client.
* @param ldapAttributes
* The set into which the required LDAP attribute names should be
* put.
*/
- void getLDAPAttributesFor(JsonPointer resourceAttribute, Set<String> ldapAttributes);
+ void getLDAPAttributes(Set<String> ldapAttributes);
+
+ /**
+ * Adds the names of the LDAP attributes required by this attribute mapper
+ * which are associated with the provided resource attribute to the provided
+ * set.
+ * <p>
+ * Implementations should only add the names of attributes found in the LDAP
+ * entry directly associated with the resource.
+ *
+ * @param ldapAttributes
+ * The set into which the required LDAP attribute names should be
+ * put.
+ * @param resourceAttribute
+ * The name of the resource attribute requested by the client.
+ */
+ void getLDAPAttributes(Set<String> ldapAttributes, JsonPointer resourceAttribute);
/**
* Transforms attributes contained in the provided LDAP entry to JSON
@@ -72,7 +73,7 @@
* @param e
* @param h
*/
- void toJson(Context c, Entry e, ResultHandler<Map<String, Object>> h);
+ void toJson(Context c, Entry e, AttributeMapperCompletionHandler<Map<String, Object>> h);
/**
* Transforms JSON content in the provided JSON value to LDAP attributes,
@@ -86,7 +87,7 @@
* @param v
* @param h
*/
- void toLDAP(Context c, JsonValue v, ResultHandler<List<Attribute>> h);
+ void toLDAP(Context c, JsonValue v, AttributeMapperCompletionHandler<List<Attribute>> h);
// TODO: methods for obtaining schema information (e.g. name, description,
// type information).
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapperCompletionHandler.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapperCompletionHandler.java
new file mode 100644
index 0000000..a6e92c9
--- /dev/null
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapperCompletionHandler.java
@@ -0,0 +1,29 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development and
+ * Distribution License (the License). You may not use this file except in compliance with the
+ * License.
+ *
+ * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+ * specific language governing permission and limitations under the License.
+ *
+ * When distributing Covered Software, include this CDDL Header Notice in each file and include
+ * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+ * Header, with the fields enclosed by brackets [] replaced by your own identifying
+ * information: "Portions Copyrighted [year] [name of copyright owner]".
+ *
+ * Copyright 2012 ForgeRock AS. All rights reserved.
+ */
+
+package org.forgerock.opendj.rest2ldap;
+
+import org.forgerock.resource.exception.ResourceException;
+
+/**
+ *
+ */
+public interface AttributeMapperCompletionHandler<T> {
+
+ void onSuccess(T result);
+
+ void onFailure(ResourceException e);
+}
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java
index 1bcfee1..3bb818d 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java
@@ -29,8 +29,7 @@
import org.forgerock.json.fluent.JsonValue;
import org.forgerock.opendj.ldap.Attribute;
import org.forgerock.opendj.ldap.Entry;
-import org.forgerock.opendj.ldap.ErrorResultException;
-import org.forgerock.opendj.ldap.ResultHandler;
+import org.forgerock.resource.exception.ResourceException;
import org.forgerock.resource.provider.Context;
/**
@@ -50,7 +49,7 @@
this.attributeMappers = new ArrayList<AttributeMapper>(attributeMappers);
Set<String> tmp = new LinkedHashSet<String>(attributeMappers.size());
for (final AttributeMapper mapper : attributeMappers) {
- tmp.addAll(mapper.getAllLDAPAttributes());
+ mapper.getLDAPAttributes(tmp);
}
allLDAPAttributes = Collections.unmodifiableSet(tmp);
}
@@ -58,37 +57,38 @@
/**
* {@inheritDoc}
*/
- public Set<String> getAllLDAPAttributes() {
- return allLDAPAttributes;
+ public void getLDAPAttributes(Set<String> ldapAttributes) {
+ ldapAttributes.addAll(allLDAPAttributes);
}
/**
* {@inheritDoc}
*/
- public void getLDAPAttributesFor(JsonPointer resourceAttribute, Set<String> ldapAttributes) {
+ public void getLDAPAttributes(Set<String> ldapAttributes, JsonPointer resourceAttribute) {
for (AttributeMapper attribute : attributeMappers) {
- attribute.getLDAPAttributesFor(resourceAttribute, ldapAttributes);
+ attribute.getLDAPAttributes(ldapAttributes, resourceAttribute);
}
}
/**
* {@inheritDoc}
*/
- public void toJson(Context c, Entry e, final ResultHandler<Map<String, Object>> h) {
- ResultHandler<Map<String, Object>> resultAccumulater =
- new ResultHandler<Map<String, Object>>() {
+ public void toJson(Context c, Entry e,
+ final AttributeMapperCompletionHandler<Map<String, Object>> h) {
+ AttributeMapperCompletionHandler<Map<String, Object>> resultAccumulater =
+ new AttributeMapperCompletionHandler<Map<String, Object>>() {
private final AtomicInteger latch = new AtomicInteger(attributeMappers.size());
private final List<Map<String, Object>> results =
new ArrayList<Map<String, Object>>(latch.get());
- public void handleErrorResult(ErrorResultException error) {
+ public void onFailure(ResourceException e) {
// Ensure that handler is only invoked once.
if (latch.getAndSet(0) > 0) {
- h.handleErrorResult(error);
+ h.onFailure(e);
}
}
- public void handleResult(Map<String, Object> result) {
+ public void onSuccess(Map<String, Object> result) {
synchronized (this) {
results.add(result);
}
@@ -106,7 +106,7 @@
mergeJsonValues(results, mergeResult);
break;
}
- h.handleResult(mergeResult);
+ h.onSuccess(mergeResult);
}
}
};
@@ -119,7 +119,7 @@
/**
* {@inheritDoc}
*/
- public void toLDAP(Context c, JsonValue v, ResultHandler<List<Attribute>> h) {
+ public void toLDAP(Context c, JsonValue v, AttributeMapperCompletionHandler<List<Attribute>> h) {
// TODO Auto-generated method stub
}
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Example.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Example.java
index eeaefd9..2994682 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Example.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Example.java
@@ -16,10 +16,6 @@
package org.forgerock.opendj.rest2ldap;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.forgerock.json.fluent.JsonValue;
import org.forgerock.json.resource.restlet.JsonResourceRestlet;
import org.forgerock.opendj.ldap.ConnectionFactory;
import org.forgerock.opendj.ldap.Connections;
@@ -30,7 +26,6 @@
import org.forgerock.resource.framework.impl.ResourceInvoker;
import org.restlet.Application;
import org.restlet.Component;
-import org.restlet.Request;
import org.restlet.Restlet;
import org.restlet.data.Protocol;
import org.restlet.routing.Router;
@@ -41,115 +36,53 @@
*/
public class Example {
- private static final String PATH_PROPERTY = "rest2ldap.restlet.path";
-
private Application application = new Application();
private final Router router = new Router();
- private HashMap<JsonResourceProvider, Restlet> restlets =
- new HashMap<JsonResourceProvider, Restlet>();
- protected synchronized void bindRestlet(Restlet restlet, Map<String, Object> properties) {
- Object path = properties.get(PATH_PROPERTY);
- if (path != null && path instanceof String) { // service is specified as
- // internally routable
- attach((String) path, restlet);
- }
- }
-
- protected synchronized void unbindRestlet(Restlet restlet, Map<String, Object> properties) {
- Object path = properties.get(PATH_PROPERTY);
- if (path != null && path instanceof String) { // service is specified as
- // internally routable
- detach(restlet);
- }
- }
-
- /**
- * Attaches a target Restlet to the Restlet router based on a given URI
- * prefix.
- *
- * @param path
- * the path to attach it to.
- * @param restlet
- * the restlet to route to if path matches.
- * @throws IllegalArgumentException
- * if path does not begin with a '/' character.
- */
- public void attach(String path, Restlet restlet) {
+ private void bindJsonResource(JsonResourceProvider resource, String path) {
+ Restlet restlet = new JsonResourceRestlet(resource);
restlet.setContext(application.getContext());
router.attach(path, restlet, Template.MODE_EQUALS);
router.attach(path + (path.equals("/") ? "" : "/"), restlet, Template.MODE_STARTS_WITH);
}
- /**
- * Remove a restlet from restlet router
- *
- * @param restlet
- * the restlet to remove
- */
- public void detach(Restlet restlet) {
- router.detach(restlet); // all routes to restlet are removed
- }
-
- protected synchronized void bindJsonResource(JsonResourceProvider resource,
- Map<String, Object> properties) {
- Restlet restlet = new CustomRestlet(resource);
- restlets.put(resource, restlet);
- bindRestlet(restlet, properties);
- }
-
- protected synchronized void unbindJsonResource(JsonResourceProvider resource,
- Map<String, Object> properties) {
- Restlet restlet = restlets.get(resource);
- if (restlet != null) {
- unbindRestlet(restlet, properties);
- restlets.remove(resource);
- }
- }
-
- private class CustomRestlet extends JsonResourceRestlet {
- public CustomRestlet(JsonResourceProvider resource) {
- super(resource);
- }
-
- @Override
- public JsonValue newContext(Request request) {
- JsonValue result = super.newContext(request);
- JsonValue security = result.get("security");
- security.put("openidm-roles", request.getAttributes().get("openidm.roles"));
- return result;
- }
- }
-
public void start() throws Exception {
- Component component = new Component();
-
- // Add http listener
- component.getServers().add(Protocol.HTTP, 8080);
- application.getTunnelService().setQueryTunnel(false); // query string
- // purism
- application.setInboundRoot(router);
-
- // Attach the json resource at the root path
- Map<String, Object> props = new HashMap<String, Object>();
- props.put(PATH_PROPERTY, "");
-
- AttributeMapper mapper = new IdentityAttributeMapper().excludeAttribute("entryUUID", "etag");
+ // All LDAP resources will use this connection factory.
ConnectionFactory factory =
Connections.newAuthenticatedConnectionFactory(new LDAPConnectionFactory(
"localhost", 1389), Requests.newSimpleBindRequest("cn=directory manager",
"password".toCharArray()));
- EntryContainer container =
+
+ // Create two entry containers whose members reference each other.
+ EntryContainer userContainer =
new EntryContainer(DN.valueOf("ou=people,dc=example,dc=com"), factory);
- LDAPResource resource = new LDAPResource(container, mapper);
- ResourceInvoker invoker = new ResourceInvoker();
- invoker.resource = resource;
- bindJsonResource(invoker, props);
+ EntryContainer groupContainer =
+ new EntryContainer(DN.valueOf("ou=groups,dc=example,dc=com"), factory);
- // Attach the sample application.
- component.getDefaultHost().attach("/example", application);
+ // Create user resource.
+ AttributeMapper userMapper =
+ new SimpleAttributeMapper().includeAttribute("uid", "cn", "sn", "mail",
+ "isMemberOf", "modifyTimestamp");
+ LDAPResource userResource = new LDAPResource(userContainer, userMapper);
+ ResourceInvoker userResourceInvoker = new ResourceInvoker();
+ userResourceInvoker.resource = userResource; // FIXME: Yuk!
+ bindJsonResource(userResourceInvoker, "/users");
- // Start the component.
+ // Create group resource.
+ AttributeMapper groupMapper =
+ new SimpleAttributeMapper().includeAttribute("cn", "ou", "description",
+ "uniquemember");
+ LDAPResource groupResource = new LDAPResource(groupContainer, groupMapper);
+ ResourceInvoker groupResourceInvoker = new ResourceInvoker();
+ groupResourceInvoker.resource = groupResource; // FIXME: Yuk!
+ bindJsonResource(groupResourceInvoker, "/groups");
+
+ // Configure and start the application.
+ application.getTunnelService().setQueryTunnel(false);
+ application.setInboundRoot(router);
+ Component component = new Component();
+ component.getServers().add(Protocol.HTTP, 8080);
+ component.getDefaultHost().attach("", application);
component.start();
}
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPResource.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPResource.java
index 58fdbc8..a0fe6f0 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPResource.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPResource.java
@@ -160,14 +160,13 @@
public void handleResult(final SearchResultEntry entry) {
final String revision = entryContainer.getEtagFromEntry(entry);
- final ResultHandler<Map<String, Object>> mapHandler =
- new ResultHandler<Map<String, Object>>() {
- public void handleErrorResult(
- final ErrorResultException error) {
- out.setFailure(adaptErrorResult(error));
+ final AttributeMapperCompletionHandler<Map<String, Object>> mapHandler =
+ new AttributeMapperCompletionHandler<Map<String, Object>>() {
+ public void onFailure(final ResourceException e) {
+ out.setFailure(e);
}
- public void handleResult(final Map<String, Object> result) {
+ public void onSuccess(final Map<String, Object> result) {
out.setResult(id, revision, new JsonValue(result));
}
};
@@ -227,18 +226,19 @@
* attributes.
*/
private Collection<String> getRequestedLDAPAttributes(final Set<JsonPointer> requestedAttributes) {
+ final Set<String> requestedLDAPAttributes;
if (requestedAttributes.isEmpty()) {
// Full read.
- return attributeMapper.getAllLDAPAttributes();
+ requestedLDAPAttributes = new LinkedHashSet<String>();
+ attributeMapper.getLDAPAttributes(requestedLDAPAttributes);
} else {
// Partial read.
- final Set<String> requestedLDAPAttributes =
- new LinkedHashSet<String>(requestedAttributes.size());
+ requestedLDAPAttributes = new LinkedHashSet<String>(requestedAttributes.size());
for (final JsonPointer requestedAttribute : requestedAttributes) {
- attributeMapper.getLDAPAttributesFor(requestedAttribute, requestedLDAPAttributes);
+ attributeMapper.getLDAPAttributes(requestedLDAPAttributes, requestedAttribute);
}
- return requestedLDAPAttributes;
}
+ return requestedLDAPAttributes;
}
}
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/IdentityAttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
similarity index 79%
rename from opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/IdentityAttributeMapper.java
rename to opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
index 3d2fca7..43bdf36 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/IdentityAttributeMapper.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
@@ -19,8 +19,6 @@
import static org.forgerock.opendj.rest2ldap.Utils.getAttributeName;
import static org.forgerock.opendj.rest2ldap.Utils.toLowerCase;
-import java.util.Collection;
-import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -30,46 +28,45 @@
import org.forgerock.json.fluent.JsonValue;
import org.forgerock.opendj.ldap.Attribute;
import org.forgerock.opendj.ldap.Entry;
-import org.forgerock.opendj.ldap.ResultHandler;
import org.forgerock.resource.provider.Context;
/**
*
*/
-public final class IdentityAttributeMapper implements AttributeMapper {
+public final class SimpleAttributeMapper implements AttributeMapper {
// All user attributes by default.
private final Map<String, String> includedAttributes = new LinkedHashMap<String, String>();
private final Map<String, String> excludedAttributes = new LinkedHashMap<String, String>();
- public IdentityAttributeMapper() {
+ public SimpleAttributeMapper() {
// No implementation required.
}
- public IdentityAttributeMapper includeAttribute(String... attributes) {
+ public SimpleAttributeMapper includeAttribute(String... attributes) {
for (String attribute : attributes) {
includedAttributes.put(toLowerCase(attribute), attribute);
}
return this;
}
- public IdentityAttributeMapper excludeAttribute(String... attributes) {
+ public SimpleAttributeMapper excludeAttribute(String... attributes) {
for (String attribute : attributes) {
excludedAttributes.put(toLowerCase(attribute), attribute);
}
return this;
}
- public Collection<String> getAllLDAPAttributes() {
+ public void getLDAPAttributes(Set<String> ldapAttributes) {
if (!includedAttributes.isEmpty()) {
- return includedAttributes.values();
+ ldapAttributes.addAll(includedAttributes.values());
} else {
// All user attributes.
- return Collections.singleton("*");
+ ldapAttributes.add("*");
}
}
- public void getLDAPAttributesFor(JsonPointer resourceAttribute, Set<String> ldapAttributes) {
+ public void getLDAPAttributes(Set<String> ldapAttributes, JsonPointer resourceAttribute) {
String name = resourceAttribute.leaf();
if (name != null) {
if (isIncludedAttribute(name)) {
@@ -80,7 +77,7 @@
}
}
- public void toJson(Context c, Entry e, ResultHandler<Map<String, Object>> h) {
+ public void toJson(Context c, Entry e, AttributeMapperCompletionHandler<Map<String, Object>> h) {
Map<String, Object> result = new LinkedHashMap<String, Object>(e.getAttributeCount());
for (Attribute a : e.getAllAttributes()) {
String name = getAttributeName(a);
@@ -88,7 +85,7 @@
result.put(name, Utils.attributeToJson(a));
}
}
- h.handleResult(result);
+ h.onSuccess(result);
}
private boolean isIncludedAttribute(String name) {
@@ -107,7 +104,7 @@
return false;
}
- public void toLDAP(Context c, JsonValue v, ResultHandler<List<Attribute>> h) {
+ public void toLDAP(Context c, JsonValue v, AttributeMapperCompletionHandler<List<Attribute>> h) {
// TODO:
}
}
--
Gitblit v1.10.0