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