View Javadoc

1   /*
2    * Copyright (C) 2017-2019 Centre National d'Etudes Spatiales (CNES).
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 3.0 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not, write to the Free Software
16   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17   * MA 02110-1301  USA
18   */
19  package org.restlet.ext.httpclient4;
20  
21  import fr.cnes.doi.settings.ProxySettings;
22  import fr.cnes.httpclient.HttpClient;
23  import fr.cnes.httpclient.HttpClientFactory;
24  import fr.cnes.httpclient.HttpClientFactory.Type;
25  import java.io.IOException;
26  import java.util.HashMap;
27  import java.util.Map;
28  import java.util.logging.Level;
29  import org.apache.logging.log4j.LogManager;
30  import org.apache.logging.log4j.Logger;
31  import org.restlet.Client;
32  import org.restlet.Request;
33  import org.restlet.data.Parameter;
34  import org.restlet.data.Protocol;
35  import org.restlet.engine.adapter.ClientCall;
36  import org.restlet.engine.util.ReferenceUtils;
37  import org.restlet.util.Series;
38  
39  /**
40   * HttpClient configuration.
41   *
42   * @author Jean-Christophe Malapert (jean-christophe.malapert@cnes.fr)
43   */
44  public class HttpDOIClientHelper extends org.restlet.engine.connector.HttpClientHelper {
45  
46      /**
47       * Logger.
48       */
49      private static final Logger LOG = LogManager.getLogger(HttpDOIClientHelper.class.getName());
50  
51      /**
52       * Http client.
53       */
54      private volatile HttpClient httpClient;
55  
56      /**
57       * Constructor.
58       *
59       * @param client client
60       */
61      public HttpDOIClientHelper(final Client client) {
62          super(client);
63          getProtocols().add(Protocol.HTTP);
64          getProtocols().add(Protocol.HTTPS);
65          this.httpClient = null;
66      }
67  
68      /**
69       * Returns the key store type.
70       *
71       * @return the key store type or null
72       */
73      public String getKeyStoreType() {
74          return getHelpedParameters().getFirstValue(HttpClient.KEYSTORE_TYPE, null);
75      }
76  
77      /**
78       * Returns the key store path.
79       *
80       * @return the key store path or null
81       */
82      public String getKeyStorePath() {
83          return getHelpedParameters().getFirstValue(HttpClient.KEYSTORE_PATH, null);
84      }
85  
86      /**
87       * Returns the key store password.
88       *
89       * @return the key store password or null
90       */
91      public String getKeyStorePwd() {
92          return getHelpedParameters().getFirstValue(HttpClient.KEYSTORE_PWD, null);
93      }
94  
95      /**
96       * Returns the trust store type.
97       *
98       * @return the key store type or null
99       */
100     public String getTrustStoreType() {
101         return getHelpedParameters().getFirstValue(HttpClient.TRUSTSTORE_TYPE, null);
102     }
103 
104     /**
105      * Returns the trust store path.
106      *
107      * @return the key store path or null
108      */
109     public String getTrustStorePath() {
110         return getHelpedParameters().getFirstValue(HttpClient.TRUSTSTORE_PATH, null);
111     }
112 
113     /**
114      * Returns the trust store password.
115      *
116      * @return the key store password or null
117      */
118     public String getTrustStorePwd() {
119         return getHelpedParameters().getFirstValue(HttpClient.TRUSTSTORE_PWD, null);
120     }
121 
122     /**
123      * Returns the maximum number of connections that will be created for any
124      * particular host.
125      *
126      * @return The maximum number of connections that will be created for any
127      * particular host.
128      */
129     public int getMaxConnectionsPerHost() {
130         return Integer.parseInt(getHelpedParameters().getFirstValue(
131                 HttpClient.CONNECTION_MAX_PER_ROUTE, "10"));
132     }
133 
134     /**
135      * Returns the maximum number of active connections.
136      *
137      * @return The maximum number of active connections.
138      */
139     public int getMaxTotalConnections() {
140         return Integer.parseInt(getHelpedParameters().getFirstValue(
141                 HttpClient.CONNECTION_MAX_TOTAL, "20"));
142     }
143 
144     /**
145      * Returns the time in ms beyond which idle connections are eligible for
146      * reaping. The default value is 60000 ms.
147      *
148      * @return The time in millis beyond which idle connections are eligible for
149      * reaping.
150      */
151     public long getIdleTimeout() {
152         return Long.parseLong(getHelpedParameters().getFirstValue(
153                 HttpClient.CONNECTION_TIME_TO_LIVE_MS, "60000"));
154     }
155 
156     /**
157      * Get Max retry.
158      *
159      * @return max retry
160      */
161     public int getRetry() {
162         return Integer.parseInt(getHelpedParameters().getFirstValue(HttpClient.MAX_RETRY, "3"));
163     }
164 
165     /**
166      * Delay between two retries.
167      *
168      * @return max retry the delay between two retries.
169      */
170     public long getRetryDelay() {
171         return Long.parseLong(getHelpedParameters().getFirstValue(HttpClient.RETRY_DELAY, "1000"));
172     }
173 
174     /**
175      * Get Max retry.
176      *
177      * @return max retry
178      */
179     public int getMaxRedirects() {
180         return Integer.
181                 parseInt(getHelpedParameters().getFirstValue(HttpClient.MAX_REDIRECTION, "5"));
182     }
183 
184     /**
185      * Returns true if the SSL is disabled otherwise false.
186      *
187      * @return true if the SSL is disabled otherwise false
188      */
189     public boolean isDisabledSSL() {
190         return Boolean.parseBoolean(getHelpedParameters().getFirstValue(HttpClient.IS_DISABLED_SSL,
191                 "false"));
192     }
193 
194     /**
195      * {@inheritDoc}
196      */
197     @Override
198     public ClientCall create(final Request request) {
199         ClientCall result = null;
200 
201         try {
202             result = new HttpMethodCall(this, request.getMethod().toString(),
203                     ReferenceUtils.update(request.getResourceRef(), request)
204                     .toString(), request.isEntityAvailable());
205         } catch (IOException ioe) {
206             getLogger().log(Level.WARNING,
207                     "Unable to create the HTTP client call", ioe);
208         }
209 
210         return result;
211     }
212 
213     /**
214      * Returns the wrapped Apache HTTP Client.
215      *
216      * @return The wrapped Apache HTTP Client.
217      */
218     public HttpClient getHttpClient() {
219         return this.httpClient;
220     }
221 
222     /**
223      * Configures the http client.
224      *
225      * @param parameters parameters
226      */
227     private void configure(final Series<Parameter> parameters) {
228         final Map<String, String> config = new HashMap<>();
229         config.put(HttpClient.CONNECTION_MAX_PER_ROUTE, String.valueOf(this.
230                 getMaxConnectionsPerHost()));
231         config.put(HttpClient.CONNECTION_MAX_TOTAL, String.valueOf(this.getMaxTotalConnections()));
232         config.put(HttpClient.CONNECTION_TIME_TO_LIVE_MS, String.valueOf(this.getIdleTimeout()));
233         config.put(HttpClient.MAX_RETRY, String.valueOf(this.getRetry()));
234         config.put(HttpClient.RETRY_DELAY, String.valueOf(this.getRetryDelay()));
235         config.put(HttpClient.MAX_REDIRECTION, String.valueOf(this.getMaxRedirects()));
236         config.computeIfAbsent(HttpClient.KEYSTORE_TYPE, v -> this.getKeyStoreType());
237         config.computeIfAbsent(HttpClient.KEYSTORE_PATH, v -> this.getKeyStorePath());
238         config.computeIfAbsent(HttpClient.KEYSTORE_PWD, v -> this.getKeyStorePwd());
239         config.computeIfAbsent(HttpClient.TRUSTSTORE_TYPE, v -> this.getTrustStoreType());
240         config.computeIfAbsent(HttpClient.TRUSTSTORE_PATH, v -> this.getTrustStorePath());
241         config.computeIfAbsent(HttpClient.TRUSTSTORE_PWD, v -> this.getTrustStorePwd());
242 
243         LOG.info("Http Config : {}", config);
244 
245         final Type type = HttpClientFactory.Type.valueOf(ProxySettings.getInstance().getProxyType());
246         ProxySettings.getInstance().configureProxy();
247         LOG.info("Httpclient type : {}", type);
248         this.httpClient = HttpClientFactory.create(type, this.isDisabledSSL(), config);
249     }
250 
251     /**
252      * {@inheritDoc}
253      */
254     @Override
255     public synchronized void start() throws Exception {
256         final Series<Parameter> parameters = getHelpedParameters();
257         configure(parameters);
258         LOG.info("Starting the internal HTTP client");
259     }
260 
261     /**
262      * {@inheritDoc}
263      */
264     @Override
265     public synchronized void stop() throws Exception {
266         if (this.httpClient != null) {
267             this.getHttpClient().close();
268             this.httpClient = null;
269             LOG.info("Stopping the internal HTTP client");
270         }
271     }
272 
273 }