3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay/*
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay *
c8408fe9c4eb7f97ffa5b6aafcd4157afd478bc8Jon Branch * Copyright 2014-2015 ForgeRock AS
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay *
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * The contents of this file are subject to the terms
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * of the Common Development and Distribution License
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * (the License). You may not use this file except in
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * compliance with the License.
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay *
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * You can obtain a copy of the License at
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * http://forgerock.org/license/CDDLv1.0.html
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * See the License for the specific language governing
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * permission and limitations under the License.
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay *
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * When distributing Covered Code, include this CDDL
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * Header Notice in each file and include the License file
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * at http://forgerock.org/license/CDDLv1.0.html
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * If applicable, add the following below the CDDL Header,
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * with the fields enclosed by brackets [] replaced by
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * your own identifying information:
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * "Portions Copyrighted [year] [name of copyright owner]"
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay */
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemaypackage org.forgerock.openicf.connectors.scriptedcrest
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.HttpHost
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.auth.AuthScope
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.auth.AuthenticationException
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.auth.InvalidCredentialsException
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.auth.UsernamePasswordCredentials
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.client.CredentialsProvider
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.client.config.RequestConfig
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.client.methods.HttpUriRequest
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.client.protocol.HttpClientContext
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.conn.routing.HttpRoute
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.impl.auth.BasicScheme
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.impl.client.BasicAuthCache
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.impl.client.BasicCookieStore
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.impl.client.BasicCredentialsProvider
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.impl.nio.client.HttpAsyncClientBuilder
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemayimport org.apache.http.nio.reactor.ConnectingIOReactor
c8408fe9c4eb7f97ffa5b6aafcd4157afd478bc8Jon Branchimport org.forgerock.json.JsonValue
c8408fe9c4eb7f97ffa5b6aafcd4157afd478bc8Jon Branchimport org.forgerock.services.context.Context
c8408fe9c4eb7f97ffa5b6aafcd4157afd478bc8Jon Branchimport org.forgerock.json.resource.QueryResponse
c8408fe9c4eb7f97ffa5b6aafcd4157afd478bc8Jon Branchimport org.forgerock.json.resource.ResourceResponse
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemayimport org.identityconnectors.common.security.GuardedString
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemayimport org.forgerock.openicf.connectors.scriptedcrest.ScriptedCRESTConfiguration.AuthMethod
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay/**
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay * A customizer script defines the custom closures to interact with the default implementation and customize it.
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay */
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemaycustomize {
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay init { HttpAsyncClientBuilder builder ->
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay //SEE: http://hc.apache.org/httpcomponents-asyncclient-4.0.x/httpasyncclient/examples/org/apache/http/examples/nio/client/AsyncClientConfiguration.java
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay def c = delegate as ScriptedCRESTConfiguration
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay def httpHost = new HttpHost(c.serviceAddress?.host, c.serviceAddress?.port, c.serviceAddress?.scheme);
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay PoolingNHttpClientConnectionManager cm = new PoolingNHttpClientConnectionManager(ioReactor);
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay // Increase max total connection to 200
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay cm.setMaxTotal(200);
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay // Increase default max connection per route to 20
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay cm.setDefaultMaxPerRoute(20);
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay // Increase max connections for httpHost to 50
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay cm.setMaxPerRoute(new HttpRoute(httpHost), 50);
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay builder.setConnectionManager(cm)
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay // configure timeout on the entire client
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay RequestConfig requestConfig = RequestConfig.custom().build();
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay builder.setDefaultRequestConfig(requestConfig)
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay //PROXY
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay if (c.proxyAddress != null) {
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay HttpHost proxy = new HttpHost(c.proxyAddress.host, c.proxyAddress.port, c.proxyAddress.scheme);
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay builder.setDefaultRequestConfig(config)
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay }
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay // Authentication
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay switch (AuthMethod.valueOf(c.defaultAuthMethod)) {
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay case AuthMethod.BASIC_PREEMPTIVE:
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay case AuthMethod.BASIC:
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay // It's part of the http client spec to request the resource anonymously
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay // first and respond to the 401 with the Authorization header.
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay c.password.access(
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay {
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay credentialsProvider.setCredentials(new AuthScope(httpHost.getHostName(), httpHost.getPort()),
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay new UsernamePasswordCredentials(c.username, new String(it)));
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay } as GuardedString.Accessor
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay );
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay builder.setDefaultCredentialsProvider(credentialsProvider);
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay break;
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay case AuthMethod.NONE:
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay break;
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay default:
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay throw new IllegalArgumentException();
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay }
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay c.propertyBag.put(HttpClientContext.COOKIE_STORE, new BasicCookieStore());
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay }
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay release {
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay propertyBag.clear()
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay }
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay beforeRequest { Context context, HttpClientContext clientContext, HttpUriRequest request ->
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay clientContext.setCookieStore(propertyBag.get(HttpClientContext.COOKIE_STORE))
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay def c = delegate as ScriptedCRESTConfiguration
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay if (AuthMethod.valueOf(c.defaultAuthMethod).equals(AuthMethod.BASIC_PREEMPTIVE)){
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay def authCache = new BasicAuthCache();
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay authCache.put(new HttpHost(c.serviceAddress?.host, c.serviceAddress?.port, c.serviceAddress?.scheme), new BasicScheme());
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay clientContext.setAuthCache(authCache)
85228c8f36d756625d95699bb40938ca5e6f2015Jason Lemay }
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay }
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay onFail { Context context, HttpClientContext clientContext, HttpUriRequest request, Exception ex ->
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay if (true) {
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay completed(new HashMap<String, Object>())
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay } else {
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay if (ex instanceof InvalidCredentialsException) {
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay failed(ex)
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay } else if (ex instanceof AuthenticationException) {
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay failed(ex)
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay } else {
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay failed(ex)
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay }
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay }
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay }
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay onComplete { Object result ->
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay if (result instanceof JsonValue) {
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
c8408fe9c4eb7f97ffa5b6aafcd4157afd478bc8Jon Branch } else if (result instanceof ResourceResponse) {
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
c8408fe9c4eb7f97ffa5b6aafcd4157afd478bc8Jon Branch } else if (result instanceof QueryResponse) {
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay }
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay completed(result)
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay }
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay
3b9de50fdf0980762d6930a49e1a0f20b61a6f6bJason Lemay}