[java-identity-provider] branch master updated: IDP-1170 - REST DataConnector
Scott Cantor
cantor.2 at osu.edu
Fri Aug 18 14:28:37 EDT 2017
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=104d00813333aeaf79e5a1be2c549dfa9aa3eebb
The following commit(s) were added to refs/heads/master by this push:
new 104d008 IDP-1170 - REST DataConnector
104d008 is described below
commit 104d00813333aeaf79e5a1be2c549dfa9aa3eebb
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Fri Aug 18 14:28:34 2017 -0400
IDP-1170 - REST DataConnector
https://issues.shibboleth.net/jira/browse/IDP-1170
Some reorg of search builder base class and a POST-capable
subclass with a template-based request body.
---
.../dc/http/impl/AbstractHTTPSearchBuilder.java | 87 ++++-
.../dc/http/impl/TemplatedBodyBuilder.java | 403 +++++++++++++++++++++
.../dc/http/impl/HTTPDataConnectorTest.java | 98 +++++
3 files changed, 582 insertions(+), 6 deletions(-)
diff --git a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/AbstractHTTPSearchBuilder.java b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/AbstractHTTPSearchBuilder.java
index 1f9b951..c91d517 100644
--- a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/AbstractHTTPSearchBuilder.java
+++ b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/AbstractHTTPSearchBuilder.java
@@ -18,6 +18,8 @@
package net.shibboleth.idp.attribute.resolver.dc.http.impl;
import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -32,15 +34,21 @@ import org.apache.http.client.protocol.HttpClientContext;
import org.opensaml.security.httpclient.HttpClientSecurityParameters;
import org.opensaml.security.httpclient.HttpClientSecuritySupport;
+import com.google.common.collect.ImmutableMap;
+
import net.shibboleth.idp.attribute.IdPAttribute;
import net.shibboleth.idp.attribute.IdPAttributeValue;
import net.shibboleth.idp.attribute.resolver.ResolutionException;
import net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext;
import net.shibboleth.idp.attribute.resolver.dc.impl.ExecutableSearchBuilder;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotLive;
+import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
/**
* Basis of request builder. Derived classes just have to provide the per request URI but may override
@@ -56,9 +64,48 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
public abstract class AbstractHTTPSearchBuilder extends AbstractInitializableComponent implements
ExecutableSearchBuilder<HTTPSearch> {
+ /** Map of headers to set. */
+ @Nonnull @NonnullElements private Map<String,String> headerMap;
+
/** HTTP client security parameters. */
@Nullable private HttpClientSecurityParameters httpClientSecurityParameters;
+ /** Constructor. */
+ public AbstractHTTPSearchBuilder() {
+ headerMap = Collections.emptyMap();
+ }
+
+ /**
+ * Get map of headers that will be set on request.
+ *
+ * @return map of headers
+ */
+ @Nonnull @NonnullElements @NotLive @Unmodifiable public Map<String,String> getHeaders() {
+ return ImmutableMap.copyOf(headerMap);
+ }
+
+ /**
+ * Set map of headers that will be set on request.
+ *
+ * <p>These will be *set*, so replacing any existing headers and not allowing multiple.</p>
+ *
+ * @param headers map of headers
+ */
+ public void setHeaders(@Nonnull @NonnullElements final Map<String,String> headers) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ Constraint.isNotNull(headers, "Map of headers cannot be null");
+ headerMap = new HashMap<>(headers.size());
+
+ for (final Map.Entry<String,String> entry : headers.entrySet()) {
+ final String key = StringSupport.trimOrNull(entry.getKey());
+ final String value = StringSupport.trimOrNull(entry.getValue());
+ if (key != null && value != null) {
+ headerMap.put(key, value);
+ }
+ }
+ }
/**
* Get the optional client security parameters.
@@ -94,14 +141,19 @@ public abstract class AbstractHTTPSearchBuilder extends AbstractInitializableCom
@Nonnull final Map<String, List<IdPAttributeValue<?>>> dependencyAttributes) throws ResolutionException {
final HttpUriRequest request = getHttpRequest(resolutionContext, dependencyAttributes);
+
+ for (final Map.Entry<String,String> entry : headerMap.entrySet()) {
+ request.setHeader(entry.getKey(), entry.getValue());
+ }
// Checkstyle: AnonInnerLength OFF
return new HTTPSearch() {
/** {@inheritDoc} */
- @Nonnull public String getResultCacheKey() {
- Constraint.isTrue(request instanceof HttpGet, "Only GET requests are cacheable");
- return ((HttpGet) request).getURI().toString();
+ @Nullable public String getResultCacheKey() {
+ // Delegate to the outer class to allow override.
+ return AbstractHTTPSearchBuilder.this.getResultCacheKey(request, resolutionContext,
+ dependencyAttributes);
}
/** {@inheritDoc} */
@@ -129,14 +181,18 @@ public abstract class AbstractHTTPSearchBuilder extends AbstractInitializableCom
/**
* Method to return the URL to access via GET.
*
+ * <p>Subclasses may override this method to support simple GET requests.</p>
+ *
* @param resolutionContext the context of the resolution
* @param dependencyAttributes made available to the request
*
* @return the URL to GET
* @throws ResolutionException if an error occurs
*/
- @Nonnull @NotEmpty protected abstract String getURL(@Nonnull final AttributeResolutionContext resolutionContext,
- @Nonnull final Map<String,List<IdPAttributeValue<?>>> dependencyAttributes) throws ResolutionException;
+ @Nonnull @NotEmpty protected String getURL(@Nonnull final AttributeResolutionContext resolutionContext,
+ @Nonnull final Map<String,List<IdPAttributeValue<?>>> dependencyAttributes) throws ResolutionException {
+ throw new UnsupportedOperationException("getURL method not overridden by subclass");
+ }
/**
* Default implementation just supports GET and builds a request around a URL.
@@ -157,5 +213,24 @@ public abstract class AbstractHTTPSearchBuilder extends AbstractInitializableCom
throw new ResolutionException(e);
}
}
-
+
+ /**
+ * Default implementation just allows caching of GET requests and returns the URI itself.
+ *
+ * @param request the HTTP request about to be executed
+ * @param resolutionContext the attribute resolution context
+ * @param dependencyAttributes dependencies
+ *
+ * @return the cache key
+ */
+ @Nullable protected String getResultCacheKey(@Nonnull final HttpUriRequest request,
+ @Nonnull final AttributeResolutionContext resolutionContext,
+ @Nonnull final Map<String, List<IdPAttributeValue<?>>> dependencyAttributes) {
+ if (request instanceof HttpGet) {
+ return ((HttpGet) request).getURI().toString();
+ } else {
+ return null;
+ }
+ }
+
}
\ No newline at end of file
diff --git a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/TemplatedBodyBuilder.java b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/TemplatedBodyBuilder.java
new file mode 100644
index 0000000..6d634be
--- /dev/null
+++ b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/TemplatedBodyBuilder.java
@@ -0,0 +1,403 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.attribute.resolver.dc.http.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.idp.attribute.IdPAttributeValue;
+import net.shibboleth.idp.attribute.resolver.ResolutionException;
+import net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.velocity.Template;
+
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.exception.VelocityException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.escape.Escaper;
+import com.google.common.net.UrlEscapers;
+import com.google.common.xml.XmlEscapers;
+
+/**
+ * An {@link net.shibboleth.idp.attribute.resolver.dc.impl.ExecutableSearchBuilder} that generates a
+ * request by evaluating {@link Template}s against the currently resolved attributes within an
+ * {@link AttributeResolutionContext} to produce a URL and body, via GET or POST, and a configurable
+ * cache key.
+ */
+public class TemplatedBodyBuilder extends AbstractHTTPSearchBuilder {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(TemplatedBodyBuilder.class);
+
+ /** URL template to be evaluated. */
+ @NonnullAfterInit private Template urlTemplate;
+
+ /** Body template to be evaluated. */
+ @NonnullAfterInit private Template bodyTemplate;
+
+ /** Cache key template to be evaluated. */
+ @NonnullAfterInit private Template cacheKeyTemplate;
+
+ /** Text of URL template to be evaluated. */
+ @NonnullAfterInit private String urlTemplateText;
+
+ /** Text of body template to be evaluated. */
+ @NonnullAfterInit private String bodyTemplateText;
+
+ /** Text of cache key template to be evaluated. */
+ @NonnullAfterInit private String cacheKeyTemplateText;
+
+ /** VelocityEngine. */
+ @NonnullAfterInit private VelocityEngine engine;
+
+ /** HTTP method. */
+ @Nonnull @NotEmpty private String method;
+
+ /** MIME type. */
+ @Nonnull @NotEmpty private String mimeType;
+
+ /** Character set. */
+ @Nullable private String charset;
+
+ /** Content type. */
+ @NonnullAfterInit private ContentType contentType;
+
+ /** Escaper for form parameters. */
+ @Nonnull private final Escaper paramEscaper;
+
+ /** Escaper for fragments. */
+ @Nonnull private final Escaper fragmentEscaper;
+
+ /** Escaper for path segments. */
+ @Nonnull private final Escaper pathEscaper;
+
+ /** Escaper for XML Attributes. */
+ @Nonnull private final Escaper xmlAttributeEscaper;
+
+ /** Escaper for XML content. */
+ @Nonnull private final Escaper xmlContentEscaper;
+
+ /** Constructor. */
+ public TemplatedBodyBuilder() {
+ method = "POST";
+ mimeType ="text/plain";
+
+ paramEscaper = UrlEscapers.urlFormParameterEscaper();
+ fragmentEscaper = UrlEscapers.urlFragmentEscaper();
+ pathEscaper = UrlEscapers.urlPathSegmentEscaper();
+ xmlAttributeEscaper = XmlEscapers.xmlAttributeEscaper();
+ xmlContentEscaper = XmlEscapers.xmlContentEscaper();
+ }
+
+ /**
+ * Get the URL template to be evaluated.
+ *
+ * @return template
+ */
+ @NonnullAfterInit public Template getURLTemplate() {
+ return urlTemplate;
+ }
+
+ /**
+ * Get the body template to be evaluated.
+ *
+ * @return template
+ */
+ @NonnullAfterInit public Template getBodyTemplate() {
+ return bodyTemplate;
+ }
+
+ /**
+ * Get the cache key template to be evaluated.
+ *
+ * @return template
+ */
+ @Nullable public Template getCacheKeyTemplate() {
+ return cacheKeyTemplate;
+ }
+
+ /**
+ * Get the URL template text to be evaluated.
+ *
+ * @return template text
+ */
+ @NonnullAfterInit public String getURLTemplateText() {
+ return urlTemplateText;
+ }
+
+ /**
+ * Set the URL template to be evaluated.
+ *
+ * @param text template to be evaluated
+ */
+ public void setURLTemplateText(@Nullable final String text) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ urlTemplateText = StringSupport.trimOrNull(text);
+ }
+
+ /**
+ * Get the body template text to be evaluated.
+ *
+ * @return template text
+ */
+ @NonnullAfterInit public String getBodyTemplateText() {
+ return bodyTemplateText;
+ }
+
+ /**
+ * Set the body template to be evaluated.
+ *
+ * @param text template to be evaluated
+ */
+ public void setBodyTemplateText(@Nullable final String text) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ bodyTemplateText = StringSupport.trimOrNull(text);
+ }
+
+ /**
+ * Get the cache key template text to be evaluated.
+ *
+ * @return template text
+ */
+ @Nullable public String getCacheKeyTemplateText() {
+ return cacheKeyTemplateText;
+ }
+
+ /**
+ * Set the cache key template to be evaluated.
+ *
+ * @param text template to be evaluated
+ */
+ public void setCacheKeyTemplateText(@Nullable final String text) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ cacheKeyTemplateText = StringSupport.trimOrNull(text);
+ }
+
+ /**
+ * Get the {@link VelocityEngine} to be used.
+ *
+ * @return template engine
+ */
+ @NonnullAfterInit public VelocityEngine getVelocityEngine() {
+ return engine;
+ }
+
+ /**
+ * Set the {@link VelocityEngine} to be used.
+ *
+ * @param velocityEngine engine to be used
+ */
+ public void setVelocityEngine(@Nonnull final VelocityEngine velocityEngine) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ engine = Constraint.isNotNull(velocityEngine, "Velocity engine cannot be null");
+ }
+
+ /**
+ * Set the HTTP method.
+ *
+ * <p>Defaults to "POST".</p>
+ *
+ * @param m method
+ */
+ public void setMethod(@Nonnull @NotEmpty final String m) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ method = Constraint.isNotNull(StringSupport.trimOrNull(m), "HTTP method cannot be null or empty");
+ Constraint.isTrue(HttpPost.METHOD_NAME.equals(method) || HttpPut.METHOD_NAME.equals(method),
+ "HTTP method must be POST or PUT");
+ }
+
+ /**
+ * Set the MIME type.
+ *
+ * <p>Defaults to "text/plain".</p>
+ *
+ * @param type MIME type
+ */
+ public void setMIMEType(@Nonnull @NotEmpty final String type) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ mimeType = Constraint.isNotNull(StringSupport.trimOrNull(type), "MIME type cannot be null or empty");
+ }
+
+ /**
+ * Set the character set.
+ *
+ * @param c character set
+ */
+ public void setCharacterSet(@Nullable final String c) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ charset = StringSupport.trimOrNull(c);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (null == engine) {
+ throw new ComponentInitializationException("Velocity engine cannot be null");
+ }
+
+ if (null == urlTemplateText) {
+ throw new ComponentInitializationException("URL template text cannot be null");
+ } else if (null == bodyTemplateText) {
+ throw new ComponentInitializationException("Body template text cannot be null");
+ }
+
+ urlTemplate = Template.fromTemplate(engine, urlTemplateText);
+ bodyTemplate = Template.fromTemplate(engine, bodyTemplateText);
+
+ if (null != cacheKeyTemplateText) {
+ cacheKeyTemplate = Template.fromTemplate(engine, cacheKeyTemplateText);
+ }
+
+ contentType = ContentType.create(mimeType, charset);
+ }
+
+ /**
+ * Invokes {@link Template#merge(org.apache.velocity.context.Context)} on the supplied template and context.
+ *
+ * @param template template to merge
+ * @param context to merge
+ *
+ * @return result of the merge operation
+ */
+ @Nonnull @NotEmpty protected String merge(@Nonnull final Template template,
+ @Nonnull final VelocityContext context) {
+ return template.merge(context);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nonnull protected HttpUriRequest getHttpRequest(@Nonnull final AttributeResolutionContext resolutionContext,
+ @Nonnull final Map<String, List<IdPAttributeValue<?>>> dependencyAttributes) throws ResolutionException {
+
+ final VelocityContext context = new VelocityContext();
+ log.trace("Creating request using attribute resolution context {}", resolutionContext);
+ context.put("resolutionContext", resolutionContext);
+
+ context.put("httpClientSecurityParameters", getHttpClientSecurityParameters());
+ context.put("paramEscaper", paramEscaper);
+ context.put("fragmentEscaper", fragmentEscaper);
+ context.put("pathEscaper", pathEscaper);
+ context.put("xmlAttributeEscaper", xmlAttributeEscaper);
+ context.put("xmlContentEscaper", xmlContentEscaper);
+
+ // inject dependencies
+ if (dependencyAttributes != null && !dependencyAttributes.isEmpty()) {
+ for (final Map.Entry<String, List<IdPAttributeValue<?>>> entry : dependencyAttributes.entrySet()) {
+ final List<Object> values = new ArrayList<>(entry.getValue().size());
+ for (final IdPAttributeValue<?> value : entry.getValue()) {
+ values.add(value.getValue());
+ }
+ log.trace("Adding dependency {} to context with {} value(s)", entry.getKey(), values.size());
+ context.put(entry.getKey(), values);
+ }
+ }
+
+ final String url;
+ final String body;
+ final HttpEntityEnclosingRequestBase request;
+
+ try {
+ url = merge(urlTemplate, context);
+ body = merge(bodyTemplate, context);
+ } catch (final VelocityException e) {
+ log.error("Error running template engine", e);
+ throw new ResolutionException("Error running template engine", e);
+ }
+
+ try {
+ if (HttpPost.METHOD_NAME.equals(method)) {
+ request = new HttpPost(url);
+ } else if (HttpPut.METHOD_NAME.equals(method)) {
+ request = new HttpPut(url);
+ } else {
+ throw new ResolutionException("Unsupported HTTP method");
+ }
+
+ request.setEntity(new StringEntity(body, contentType));
+ } catch (final IllegalArgumentException e) {
+ throw new ResolutionException(e);
+ }
+
+ return request;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nonnull @NotEmpty protected String getResultCacheKey(@Nonnull final HttpUriRequest request,
+ @Nonnull final AttributeResolutionContext resolutionContext,
+ @Nonnull final Map<String, List<IdPAttributeValue<?>>> dependencyAttributes) {
+
+ if (cacheKeyTemplate == null) {
+ return null;
+ }
+
+ final VelocityContext context = new VelocityContext();
+ log.trace("Creating cache key using attribute resolution context {}", resolutionContext);
+ context.put("resolutionContext", resolutionContext);
+
+ context.put("httpClientSecurityParameters", getHttpClientSecurityParameters());
+
+ // inject dependencies
+ if (dependencyAttributes != null && !dependencyAttributes.isEmpty()) {
+ for (final Map.Entry<String, List<IdPAttributeValue<?>>> entry : dependencyAttributes.entrySet()) {
+ final List<Object> values = new ArrayList<>(entry.getValue().size());
+ for (final IdPAttributeValue<?> value : entry.getValue()) {
+ values.add(value.getValue());
+ }
+ log.trace("Adding dependency {} to context with {} value(s)", entry.getKey(), values.size());
+ context.put(entry.getKey(), values);
+ }
+ }
+
+ return merge(cacheKeyTemplate, context);
+ }
+
+}
\ No newline at end of file
diff --git a/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/HTTPDataConnectorTest.java b/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/HTTPDataConnectorTest.java
index 6a8ffe4..04976f4 100644
--- a/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/HTTPDataConnectorTest.java
+++ b/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/HTTPDataConnectorTest.java
@@ -244,4 +244,102 @@ public class HTTPDataConnectorTest {
Assert.assertEquals(cache.iterator().next(), optional);
}
+ @Test(enabled=false) public void testPOST() throws ComponentInitializationException, ResolutionException, ScriptException, IOException {
+ final TemplatedBodyBuilder builder = new TemplatedBodyBuilder();
+ builder.setURLTemplateText("https://shibboleth.net/cgi-bin/_frobnitz.cgi");
+ builder.setBodyTemplateText("[{\"name\" : \"foo\",\"values\" : [ \"foo1\" ]},{\"name\" : \"bar\",\"values\" : [ \"bar1\", \"bar2\" ]}]");
+ builder.setMIMEType("application/json");
+ builder.setVelocityEngine(VelocityEngine.newVelocityEngine());
+ builder.initialize();
+ connector.setExecutableSearchBuilder(builder);
+
+ final ScriptedResponseMappingStrategy mapping =
+ ScriptedResponseMappingStrategy.resourceScript(
+ ResourceHelper.of(new ClassPathResource((isV8() ? SCRIPT_PATH_V8 : SCRIPT_PATH) + "test.js")));
+ mapping.setLogPrefix(TEST_CONNECTOR_NAME + ":");
+ mapping.setAcceptStatuses(Collections.singleton(HttpStatus.SC_OK));
+ mapping.setAcceptTypes(Collections.singleton("application/json"));
+ connector.setMappingStrategy(mapping);
+ connector.initialize();
+
+ final AttributeResolutionContext context =
+ TestSources.createResolutionContext(TestSources.PRINCIPAL_ID, TestSources.IDP_ENTITY_ID,
+ TestSources.SP_ENTITY_ID);
+
+ final Map<String,IdPAttribute> attrs = connector.resolve(context);
+
+ Assert.assertEquals(attrs.size(), 2);
+
+ Assert.assertEquals(attrs.get("foo").getValues().size(), 1);
+ Assert.assertEquals(attrs.get("foo").getValues().get(0).getValue(), "foo1");
+
+ Assert.assertEquals(attrs.get("bar").getValues().size(), 2);
+ Assert.assertEquals(attrs.get("bar").getValues().get(0).getValue(), "bar1");
+ Assert.assertEquals(attrs.get("bar").getValues().get(1).getValue(), "bar2");
+ }
+
+ @Test(enabled=false) public void testCacheable() throws ComponentInitializationException, ResolutionException, ScriptException, IOException {
+ final TemplatedBodyBuilder builder = new TemplatedBodyBuilder();
+ builder.setURLTemplateText("https://shibboleth.net/cgi-bin/_frobnitz.cgi");
+ builder.setBodyTemplateText("[{\"name\" : \"foo\",\"values\" : [ \"foo1\" ]},{\"name\" : \"bar\",\"values\" : [ \"bar1\", \"bar2\" ]}]");
+ builder.setCacheKeyTemplateText("foo");
+ builder.setMIMEType("application/json");
+ builder.setVelocityEngine(VelocityEngine.newVelocityEngine());
+ builder.initialize();
+ connector.setExecutableSearchBuilder(builder);
+
+ final ScriptedResponseMappingStrategy mapping =
+ ScriptedResponseMappingStrategy.resourceScript(
+ ResourceHelper.of(new ClassPathResource((isV8() ? SCRIPT_PATH_V8 : SCRIPT_PATH) + "test.js")));
+ mapping.setLogPrefix(TEST_CONNECTOR_NAME + ":");
+ mapping.setAcceptStatuses(Collections.singleton(HttpStatus.SC_OK));
+ mapping.setAcceptTypes(Collections.singleton("application/json"));
+ connector.setMappingStrategy(mapping);
+
+ final TestCache cache = new TestCache();
+ connector.setResultsCache(cache);
+
+ connector.initialize();
+
+ final AttributeResolutionContext context =
+ TestSources.createResolutionContext(TestSources.PRINCIPAL_ID, TestSources.IDP_ENTITY_ID,
+ TestSources.SP_ENTITY_ID);
+
+ Assert.assertTrue(cache.size() == 0);
+ final Map<String,IdPAttribute> optional = connector.resolve(context);
+ Assert.assertTrue(cache.size() == 1);
+ Assert.assertEquals(cache.iterator().next(), optional);
+ }
+
+ @Test(enabled=false) public void testUncacheable() throws ComponentInitializationException, ResolutionException, ScriptException, IOException {
+ final TemplatedBodyBuilder builder = new TemplatedBodyBuilder();
+ builder.setURLTemplateText("https://shibboleth.net/cgi-bin/_frobnitz.cgi");
+ builder.setBodyTemplateText("[{\"name\" : \"foo\",\"values\" : [ \"foo1\" ]},{\"name\" : \"bar\",\"values\" : [ \"bar1\", \"bar2\" ]}]");
+ builder.setMIMEType("application/json");
+ builder.setVelocityEngine(VelocityEngine.newVelocityEngine());
+ builder.initialize();
+ connector.setExecutableSearchBuilder(builder);
+
+ final ScriptedResponseMappingStrategy mapping =
+ ScriptedResponseMappingStrategy.resourceScript(
+ ResourceHelper.of(new ClassPathResource((isV8() ? SCRIPT_PATH_V8 : SCRIPT_PATH) + "test.js")));
+ mapping.setLogPrefix(TEST_CONNECTOR_NAME + ":");
+ mapping.setAcceptStatuses(Collections.singleton(HttpStatus.SC_OK));
+ mapping.setAcceptTypes(Collections.singleton("application/json"));
+ connector.setMappingStrategy(mapping);
+
+ final TestCache cache = new TestCache();
+ connector.setResultsCache(cache);
+
+ connector.initialize();
+
+ final AttributeResolutionContext context =
+ TestSources.createResolutionContext(TestSources.PRINCIPAL_ID, TestSources.IDP_ENTITY_ID,
+ TestSources.SP_ENTITY_ID);
+
+ Assert.assertTrue(cache.size() == 0);
+ connector.resolve(context);
+ Assert.assertTrue(cache.size() == 0);
+ }
+
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list