001/*
002 * (C) Copyright 2017 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Antoine Taillefer <ataillefer@nuxeo.com>
018 */
019package org.nuxeo.jaxrs.test;
020
021import org.apache.http.client.HttpClient;
022import org.apache.http.client.config.RequestConfig;
023import org.apache.http.impl.client.BasicCookieStore;
024import org.apache.http.impl.client.HttpClientBuilder;
025
026import com.sun.jersey.api.client.Client;
027import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
028import com.sun.jersey.client.apache4.ApacheHttpClient4Handler;
029
030/**
031 * Helper for using the Jersey 1 {@link Client}.
032 *
033 * @since 9.3
034 */
035public final class JerseyClientHelper {
036
037    public static final int DEFAULT_CONNECTION_TIMEOUT = 60 * 1000; // 60 seconds
038
039    /**
040     * Default instance of a Jersey 1 {@link Client} relying on the Apache HTTP client,
041     * {@link #DEFAULT_CONNECTION_TIMEOUT} for the connection timeout parameters and no authentication.
042     */
043    public static final Client DEFAULT_CLIENT = clientBuilder().build();
044
045    private JerseyClientHelper() {
046        // Helper class
047    }
048
049    /**
050     * Allows to build a custom instance of a Jersey 1 {@link Client} relying on the Apache HTTP client.
051     * <p>
052     * For instance, you can set the connection timeout and credentials for basic authentication by calling:
053     *
054     * <pre>
055     * {@code
056     *     Client client = JerseyClientHelper.clientBuilder()
057     *                                       .setConnectTimeout(5000)
058     *                                       .setCredentials("joe", "password")
059     *                                       .build();
060     * }
061     * </pre>
062     */
063    public static ApacheHttpClientBuilder clientBuilder() {
064        return new ApacheHttpClientBuilder();
065    }
066
067    public static class ApacheHttpClientBuilder {
068
069        protected int socketTimeout;
070
071        protected int connectTimeout;
072
073        protected int connectionRequestTimeout;
074
075        protected boolean redirectsEnabled;
076
077        protected String username;
078
079        protected String password;
080
081        protected ApacheHttpClientBuilder() {
082            this.socketTimeout = DEFAULT_CONNECTION_TIMEOUT;
083            this.connectTimeout = DEFAULT_CONNECTION_TIMEOUT;
084            this.connectionRequestTimeout = DEFAULT_CONNECTION_TIMEOUT;
085            this.redirectsEnabled = true;
086        }
087
088        public ApacheHttpClientBuilder setSocketTimeout(final int socketTimeout) {
089            this.socketTimeout = socketTimeout;
090            return this;
091        }
092
093        public ApacheHttpClientBuilder setConnectTimeout(final int connectTimeout) {
094            this.connectTimeout = connectTimeout;
095            return this;
096        }
097
098        public ApacheHttpClientBuilder setConnectionRequestTimeout(final int connectionRequestTimeout) {
099            this.connectionRequestTimeout = connectionRequestTimeout;
100            return this;
101        }
102
103        public ApacheHttpClientBuilder setRedirectsEnabled(final boolean redirectsEnabled) {
104            this.redirectsEnabled = redirectsEnabled;
105            return this;
106        }
107
108        public ApacheHttpClientBuilder setCredentials(final String username, final String password) {
109            this.username = username;
110            this.password = password;
111            return this;
112        }
113
114        @SuppressWarnings("resource") // Client builder
115        public Client build() {
116            RequestConfig requestConfig = RequestConfig.custom()
117                                                       .setSocketTimeout(socketTimeout)
118                                                       .setConnectTimeout(connectTimeout)
119                                                       .setConnectionRequestTimeout(connectionRequestTimeout)
120                                                       .setRedirectsEnabled(redirectsEnabled)
121                                                       .build();
122            HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
123            Client client = new Client(new ApacheHttpClient4Handler(httpClient, new BasicCookieStore(), true));
124            if (username != null && password != null) {
125                client.addFilter(new HTTPBasicAuthFilter(username, password));
126            }
127            return client;
128        }
129
130    }
131
132}