8a717712496400b2e8e13f5fce64d4379281d3ea
[policy/common.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2018 Samsung Electronics Co., Ltd.
7  * Modifications Copyright (C) 2019 Nordix Foundation.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.common.endpoints.http.client.internal;
24
25 import com.fasterxml.jackson.annotation.JsonIgnore;
26 import java.security.KeyManagementException;
27 import java.security.NoSuchAlgorithmException;
28 import java.security.SecureRandom;
29 import java.util.Map;
30 import java.util.Map.Entry;
31 import javax.net.ssl.SSLContext;
32 import javax.ws.rs.client.Client;
33 import javax.ws.rs.client.ClientBuilder;
34 import javax.ws.rs.client.Entity;
35 import javax.ws.rs.client.Invocation.Builder;
36 import javax.ws.rs.core.Response;
37 import org.apache.commons.lang3.StringUtils;
38 import org.glassfish.jersey.client.ClientProperties;
39 import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
40 import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams;
41 import org.onap.policy.common.endpoints.http.client.HttpClient;
42 import org.onap.policy.common.gson.annotation.GsonJsonIgnore;
43 import org.onap.policy.common.utils.network.NetworkUtil;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 /**
48  * Http Client implementation using a Jersey Client.
49  */
50 public class JerseyClient implements HttpClient {
51
52     /**
53      * Logger.
54      */
55     private static Logger logger = LoggerFactory.getLogger(JerseyClient.class);
56
57     protected static final String JERSEY_DEFAULT_SERIALIZATION_PROVIDER =
58                     "org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider";
59
60     protected final String name;
61     protected final boolean https;
62     protected final boolean selfSignedCerts;
63     protected final String hostname;
64     protected final int port;
65     protected final String basePath;
66     protected final String userName;
67     protected final String password;
68
69     protected final Client client;
70     protected final String baseUrl;
71
72     protected boolean alive = true;
73
74     /**
75      * Constructor.
76      *
77      * <p>name the name https is it https or not selfSignedCerts are there self signed certs
78      * hostname the hostname port port being used basePath base context userName user
79      * password password
80      *
81      * @param busTopicParams Input parameters object
82      * @throws KeyManagementException key exception
83      * @throws NoSuchAlgorithmException no algorithm exception
84      * @throws ClassNotFoundException if the serialization provider cannot be found
85      */
86     public JerseyClient(BusTopicParams busTopicParams)
87                     throws KeyManagementException, NoSuchAlgorithmException, ClassNotFoundException {
88
89         if (busTopicParams.isClientNameInvalid()) {
90             throw new IllegalArgumentException("Name must be provided");
91         }
92
93         if (busTopicParams.isHostnameInvalid()) {
94             throw new IllegalArgumentException("Hostname must be provided");
95         }
96
97         if (busTopicParams.isPortInvalid()) {
98             throw new IllegalArgumentException("Invalid Port provided: " + busTopicParams.getPort());
99         }
100
101         this.name = busTopicParams.getClientName();
102         this.https = busTopicParams.isUseHttps();
103         this.hostname = busTopicParams.getHostname();
104         this.port = busTopicParams.getPort();
105         this.basePath = busTopicParams.getBasePath();
106         this.userName = busTopicParams.getUserName();
107         this.password = busTopicParams.getPassword();
108         this.selfSignedCerts = busTopicParams.isAllowSelfSignedCerts();
109         this.client = detmClient();
110
111         if (!StringUtils.isBlank(this.userName) && !StringUtils.isBlank(this.password)) {
112             HttpAuthenticationFeature authFeature = HttpAuthenticationFeature.basic(userName, password);
113             this.client.register(authFeature);
114         }
115
116         this.client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true");
117
118         registerSerProviders(busTopicParams.getSerializationProvider());
119
120         this.baseUrl = (this.https ? "https://" : "http://") + this.hostname + ":" + this.port + "/"
121                         + (this.basePath == null ? "" : this.basePath);
122     }
123
124     private Client detmClient() throws NoSuchAlgorithmException, KeyManagementException {
125         if (this.https) {
126             ClientBuilder clientBuilder;
127             SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
128             if (this.selfSignedCerts) {
129                 sslContext.init(null, NetworkUtil.getAlwaysTrustingManager(), new SecureRandom());
130                 clientBuilder =
131                         ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier((host, session) -> true);
132             } else {
133                 sslContext.init(null, null, null);
134                 clientBuilder = ClientBuilder.newBuilder().sslContext(sslContext);
135             }
136             return clientBuilder.build();
137
138         } else {
139             return ClientBuilder.newClient();
140         }
141     }
142
143     /**
144      * Registers the serialization provider(s) with the client.
145      *
146      * @param serializationProvider comma-separated list of serialization providers
147      * @throws ClassNotFoundException if the serialization provider cannot be found
148      */
149     private void registerSerProviders(String serializationProvider) throws ClassNotFoundException {
150         String providers = (StringUtils.isBlank(serializationProvider)
151                         ? JERSEY_DEFAULT_SERIALIZATION_PROVIDER : serializationProvider);
152         for (String prov : providers.split(",")) {
153             this.client.register(Class.forName(prov));
154         }
155     }
156
157     @Override
158     public Response get(String path) {
159         if (!StringUtils.isBlank(path)) {
160             return this.client.target(this.baseUrl).path(path).request().get();
161         } else {
162             return this.client.target(this.baseUrl).request().get();
163         }
164     }
165
166     @Override
167     public Response get() {
168         return this.client.target(this.baseUrl).request().get();
169     }
170
171     @Override
172     public Response put(String path, Entity<?> entity, Map<String, Object> headers) {
173         return getBuilder(path, headers).put(entity);
174     }
175
176     @Override
177     public Response post(String path, Entity<?> entity, Map<String, Object> headers) {
178         return getBuilder(path, headers).post(entity);
179     }
180
181     @Override
182     public Response delete(String path, Map<String, Object> headers) {
183         return getBuilder(path, headers).delete();
184     }
185
186     @Override
187     public boolean start() {
188         return alive;
189     }
190
191     @Override
192     public boolean stop() {
193         return !alive;
194     }
195
196     @Override
197     public void shutdown() {
198         synchronized (this) {
199             alive = false;
200         }
201
202         try {
203             this.client.close();
204         } catch (Exception e) {
205             logger.warn("{}: cannot close because of {}", this, e.getMessage(), e);
206         }
207     }
208
209     @Override
210     public synchronized boolean isAlive() {
211         return this.alive;
212     }
213
214     @Override
215     public String getName() {
216         return name;
217     }
218
219     @Override
220     public boolean isHttps() {
221         return https;
222     }
223
224     @Override
225     public boolean isSelfSignedCerts() {
226         return selfSignedCerts;
227     }
228
229     @Override
230     public String getHostname() {
231         return hostname;
232     }
233
234     @Override
235     public int getPort() {
236         return port;
237     }
238
239     @Override
240     public String getBasePath() {
241         return basePath;
242     }
243
244     @Override
245     public String getUserName() {
246         return userName;
247     }
248
249     @JsonIgnore
250     @GsonJsonIgnore
251     @Override
252     public String getPassword() {
253         return password;
254     }
255
256     @Override
257     public String getBaseUrl() {
258         return baseUrl;
259     }
260
261     @Override
262     public String toString() {
263         StringBuilder builder = new StringBuilder();
264         builder.append("JerseyClient [name=");
265         builder.append(name);
266         builder.append(", https=");
267         builder.append(https);
268         builder.append(", selfSignedCerts=");
269         builder.append(selfSignedCerts);
270         builder.append(", hostname=");
271         builder.append(hostname);
272         builder.append(", port=");
273         builder.append(port);
274         builder.append(", basePath=");
275         builder.append(basePath);
276         builder.append(", userName=");
277         builder.append(userName);
278         builder.append(", password=");
279         builder.append(password);
280         builder.append(", client=");
281         builder.append(client);
282         builder.append(", baseUrl=");
283         builder.append(baseUrl);
284         builder.append(", alive=");
285         builder.append(alive);
286         builder.append("]");
287         return builder.toString();
288     }
289
290     private Builder getBuilder(String path, Map<String, Object> headers) {
291         Builder builder = this.client.target(this.baseUrl).path(path).request();
292         for (Entry<String, Object> header : headers.entrySet()) {
293             builder.header(header.getKey(), header.getValue());
294         }
295         return builder;
296     }
297
298
299 }