From 2a98df5779f11957712ea3b7a7a10a07f51558ba Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 21 Feb 2013 22:55:52 +0000
Subject: [PATCH] OPENDJ-757: Add Rest2LDAP gateway Servlet
---
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java | 162 +++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 125 insertions(+), 37 deletions(-)
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
index cfb3b5d..6ce5469 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
@@ -18,7 +18,7 @@
import static org.forgerock.opendj.ldap.requests.Requests.newSearchRequest;
import static org.forgerock.opendj.ldap.schema.CoreSchema.getEntryUUIDAttributeType;
-import static org.forgerock.opendj.rest2ldap.ReadOnUpdatePolicy.USE_READ_ENTRY_CONTROLS;
+import static org.forgerock.opendj.rest2ldap.ReadOnUpdatePolicy.CONTROLS;
import static org.forgerock.opendj.rest2ldap.Utils.ensureNotNull;
import java.util.ArrayList;
@@ -29,6 +29,7 @@
import java.util.concurrent.TimeUnit;
import org.forgerock.json.fluent.JsonValue;
+import org.forgerock.json.fluent.JsonValueException;
import org.forgerock.json.resource.BadRequestException;
import org.forgerock.json.resource.CollectionResourceProvider;
import org.forgerock.json.resource.ResourceException;
@@ -66,8 +67,8 @@
private ConnectionFactory factory;
private MVCCStrategy mvccStrategy;
private NameStrategy nameStrategy;
- private ReadOnUpdatePolicy readOnUpdatePolicy = USE_READ_ENTRY_CONTROLS;
- private final ObjectAttributeMapper rootMapper = new ObjectAttributeMapper();
+ private ReadOnUpdatePolicy readOnUpdatePolicy = CONTROLS;
+ private AttributeMapper rootMapper;
private Schema schema = Schema.getDefaultSchema();
Builder() {
@@ -81,23 +82,7 @@
}
public Builder additionalLDAPAttribute(final String attribute, final Object... values) {
- additionalLDAPAttributes.add(new LinkedAttribute(attribute, values));
- return this;
- }
-
- /**
- * Creates a mapping for the named JSON attribute.
- *
- * @param name
- * The name of the JSON attribute to be mapped.
- * @param mapper
- * The attribute mapper responsible for mapping the JSON
- * attribute to LDAP attribute(s).
- * @return A reference to this builder.
- */
- public Builder attribute(final String name, final AttributeMapper mapper) {
- rootMapper.attribute(name, mapper);
- return this;
+ return additionalLDAPAttribute(new LinkedAttribute(ad(attribute), values));
}
public Builder baseDN(final DN dn) {
@@ -107,15 +92,13 @@
}
public Builder baseDN(final String dn) {
- ensureNotNull(dn);
- this.baseDN = DN.valueOf(dn);
- return this;
+ return baseDN(DN.valueOf(dn, schema));
}
public CollectionResourceProvider build() {
ensureNotNull(factory);
ensureNotNull(baseDN);
- if (rootMapper.isEmpty()) {
+ if (rootMapper == null) {
throw new IllegalStateException("No mappings provided");
}
return new LDAPCollectionResourceProvider(baseDN, rootMapper, factory, nameStrategy,
@@ -152,8 +135,8 @@
* "baseDN" : "ou=people,dc=example,dc=com",
*
* // The mechanism which should be used for read resources during updates, must be
- * // one of "disabled", "useReadEntryControls", or "useSearch".
- * "readOnUpdatePolicy" : "useReadEntryControls",
+ * // one of "disabled", "controls", or "search".
+ * "readOnUpdatePolicy" : "controls",
*
* // Additional LDAP attributes which should be included with entries during add (create) operations.
* "additionalLDAPAttributes" : [
@@ -188,18 +171,18 @@
* "etagAttribute" : "etag",
*
* // The JSON to LDAP attribute mappings.
- * "attributes" : [
+ * "attributes" : {
* "schemas" : { "constant" : [ "urn:scim:schemas:core:1.0" ] },
* "id" : { "simple" : { "ldapAttribute" : "uid", "isSingleValued" : true, "isRequired" : true, "writability" : "createOnly" } },
* "rev" : { "simple" : { "ldapAttribute" : "etag", "isSingleValued" : true, "writability" : "readOnly" } },
* "userName" : { "simple" : { "ldapAttribute" : "mail", "isSingleValued" : true, "writability" : "readOnly" } },
* "displayName" : { "simple" : { "ldapAttribute" : "cn", "isSingleValued" : true, "isRequired" : true } },
- * "name" : { "object" : [
+ * "name" : { "object" : {
* "givenName" : { "simple" : { "ldapAttribute" : "givenName", "isSingleValued" : true } },
* "familyName" : { "simple" : { "ldapAttribute" : "sn", "isSingleValued" : true, "isRequired" : true } },
- * ],
+ * },
* ...
- * ]
+ * }
* }
* </pre>
*
@@ -211,6 +194,43 @@
*/
public Builder configureMapping(final JsonValue configuration)
throws IllegalArgumentException {
+ baseDN(configuration.get("baseDN").required().asString());
+
+ final JsonValue readOnUpdatePolicy = configuration.get("readOnUpdatePolicy");
+ if (!readOnUpdatePolicy.isNull()) {
+ readOnUpdatePolicy(readOnUpdatePolicy.asEnum(ReadOnUpdatePolicy.class));
+ }
+
+ for (final JsonValue v : configuration.get("additionalLDAPAttributes")) {
+ final String type = v.get("type").required().asString();
+ final List<Object> values = v.get("values").required().asList();
+ additionalLDAPAttribute(new LinkedAttribute(type, values));
+ }
+
+ final JsonValue namingStrategy = configuration.get("namingStrategy");
+ if (!namingStrategy.isNull()) {
+ final String name = namingStrategy.get("strategy").required().asString();
+ if (name.equalsIgnoreCase("clientDNNaming")) {
+ useClientDNNaming(namingStrategy.get("dnAttribute").required().asString());
+ } else if (name.equalsIgnoreCase("clientNaming")) {
+ useClientNaming(namingStrategy.get("dnAttribute").required().asString(),
+ namingStrategy.get("idAttribute").required().asString());
+ } else if (name.equalsIgnoreCase("serverNaming")) {
+ useServerNaming(namingStrategy.get("dnAttribute").required().asString(),
+ namingStrategy.get("idAttribute").required().asString());
+ } else {
+ throw new IllegalArgumentException(
+ "Illegal naming strategy. Must be one of: clientDNNaming, clientNaming, or serverNaming");
+ }
+ }
+
+ final JsonValue etagAttribute = configuration.get("etagAttribute");
+ if (!etagAttribute.isNull()) {
+ useEtagAttribute(etagAttribute.asString());
+ }
+
+ mapper(configureObjectMapper(configuration.get("attributes").required()));
+
return this;
}
@@ -220,6 +240,11 @@
return this;
}
+ public Builder mapper(final AttributeMapper mapper) {
+ this.rootMapper = mapper;
+ return this;
+ }
+
/**
* Sets the policy which should be used in order to read an entry before
* it is deleted, or after it is added or modified.
@@ -254,7 +279,7 @@
}
public Builder useClientDNNaming(final String attribute) {
- return useClientDNNaming(Schema.getDefaultSchema().getAttributeType(attribute));
+ return useClientDNNaming(at(attribute));
}
public Builder useClientNaming(final AttributeType dnAttribute,
@@ -264,8 +289,7 @@
}
public Builder useClientNaming(final String dnAttribute, final String idAttribute) {
- return useClientNaming(Schema.getDefaultSchema().getAttributeType(dnAttribute),
- AttributeDescription.valueOf(idAttribute));
+ return useClientNaming(at(dnAttribute), ad(idAttribute));
}
public Builder useEtagAttribute() {
@@ -278,7 +302,7 @@
}
public Builder useEtagAttribute(final String attribute) {
- return useEtagAttribute(AttributeDescription.valueOf(attribute));
+ return useEtagAttribute(ad(attribute));
}
public Builder useServerEntryUUIDNaming(final AttributeType dnAttribute) {
@@ -287,7 +311,7 @@
}
public Builder useServerEntryUUIDNaming(final String dnAttribute) {
- return useServerEntryUUIDNaming(Schema.getDefaultSchema().getAttributeType(dnAttribute));
+ return useServerEntryUUIDNaming(at(dnAttribute));
}
public Builder useServerNaming(final AttributeType dnAttribute,
@@ -297,8 +321,72 @@
}
public Builder useServerNaming(final String dnAttribute, final String idAttribute) {
- return useServerNaming(Schema.getDefaultSchema().getAttributeType(dnAttribute),
- AttributeDescription.valueOf(idAttribute));
+ return useServerNaming(at(dnAttribute), ad(idAttribute));
+ }
+
+ private AttributeDescription ad(final String attribute) {
+ return AttributeDescription.valueOf(attribute, schema);
+ }
+
+ private AttributeType at(final String attribute) {
+ return schema.getAttributeType(attribute);
+ }
+
+ private AttributeMapper configureMapper(final JsonValue mapper) {
+ if (mapper.isDefined("constant")) {
+ return constant(mapper.get("constant").getObject());
+ } else if (mapper.isDefined("simple")) {
+ final JsonValue config = mapper.get("simple");
+ final SimpleAttributeMapper s =
+ simple(ad(config.get("ldapAttribute").required().asString()));
+ if (config.isDefined("defaultJSONValue")) {
+ s.defaultJSONValue(config.get("defaultJSONValue").getObject());
+ }
+ if (config.isDefined("defaultLDAPValue")) {
+ s.defaultLDAPValue(config.get("defaultLDAPValue").getObject());
+ }
+ if (config.get("isBinary").defaultTo(false).asBoolean()) {
+ s.isBinary();
+ }
+ if (config.get("isRequired").defaultTo(false).asBoolean()) {
+ s.isRequired();
+ }
+ if (config.get("isSingleValued").defaultTo(false).asBoolean()) {
+ s.isSingleValued();
+ }
+ if (config.isDefined("writability")) {
+ final String writability = config.get("writability").asString();
+ if (writability.equalsIgnoreCase("readOnly")) {
+ s.writability(WritabilityPolicy.READ_ONLY);
+ } else if (writability.equalsIgnoreCase("readOnlyDiscardWrites")) {
+ s.writability(WritabilityPolicy.READ_ONLY_DISCARD_WRITES);
+ } else if (writability.equalsIgnoreCase("createOnly")) {
+ s.writability(WritabilityPolicy.CREATE_ONLY);
+ } else if (writability.equalsIgnoreCase("createOnlyDiscardWrites")) {
+ s.writability(WritabilityPolicy.CREATE_ONLY_DISCARD_WRITES);
+ } else if (writability.equalsIgnoreCase("readWrite")) {
+ s.writability(WritabilityPolicy.READ_WRITE);
+ } else {
+ throw new JsonValueException(mapper,
+ "Illegal writability: must be one of readOnly, readOnlyDiscardWrites, "
+ + "createOnly, createOnlyDiscardWrites, or readWrite");
+ }
+ }
+ return s;
+ } else if (mapper.isDefined("object")) {
+ return configureObjectMapper(mapper.get("object"));
+ } else {
+ throw new JsonValueException(mapper,
+ "Illegal mapping: must contain constant, simple, or object");
+ }
+ }
+
+ private ObjectAttributeMapper configureObjectMapper(final JsonValue mapper) {
+ final ObjectAttributeMapper object = object();
+ for (final String attribute : mapper.keys()) {
+ object.attribute(attribute, configureMapper(mapper.get(attribute)));
+ }
+ return object;
}
}
--
Gitblit v1.10.0