2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2020 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
13 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
23 package org.onap.policy.common.endpoints.http.client.internal;
25 import com.fasterxml.jackson.annotation.JsonIgnore;
26 import java.security.KeyManagementException;
27 import java.security.NoSuchAlgorithmException;
28 import java.security.SecureRandom;
30 import java.util.Map.Entry;
31 import java.util.concurrent.Future;
32 import javax.net.ssl.SSLContext;
33 import javax.ws.rs.client.Client;
34 import javax.ws.rs.client.ClientBuilder;
35 import javax.ws.rs.client.Entity;
36 import javax.ws.rs.client.Invocation.Builder;
37 import javax.ws.rs.client.InvocationCallback;
38 import javax.ws.rs.core.Response;
39 import org.apache.commons.lang3.StringUtils;
40 import org.glassfish.jersey.client.ClientProperties;
41 import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
42 import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams;
43 import org.onap.policy.common.endpoints.http.client.HttpClient;
44 import org.onap.policy.common.gson.annotation.GsonJsonIgnore;
45 import org.onap.policy.common.utils.network.NetworkUtil;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
50 * Http Client implementation using a Jersey Client.
52 public class JerseyClient implements HttpClient {
57 private static Logger logger = LoggerFactory.getLogger(JerseyClient.class);
59 protected static final String JERSEY_DEFAULT_SERIALIZATION_PROVIDER =
60 "org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider";
62 protected final String name;
63 protected final boolean https;
64 protected final boolean selfSignedCerts;
65 protected final String hostname;
66 protected final int port;
67 protected final String basePath;
68 protected final String userName;
69 protected final String password;
71 protected final Client client;
72 protected final String baseUrl;
74 protected boolean alive = true;
79 * <p>name the name https is it https or not selfSignedCerts are there self signed certs
80 * hostname the hostname port port being used basePath base context userName user
83 * @param busTopicParams Input parameters object
84 * @throws KeyManagementException key exception
85 * @throws NoSuchAlgorithmException no algorithm exception
86 * @throws ClassNotFoundException if the serialization provider cannot be found
88 public JerseyClient(BusTopicParams busTopicParams)
89 throws KeyManagementException, NoSuchAlgorithmException, ClassNotFoundException {
91 if (busTopicParams.isClientNameInvalid()) {
92 throw new IllegalArgumentException("Name must be provided");
95 if (busTopicParams.isHostnameInvalid()) {
96 throw new IllegalArgumentException("Hostname must be provided");
99 if (busTopicParams.isPortInvalid()) {
100 throw new IllegalArgumentException("Invalid Port provided: " + busTopicParams.getPort());
103 this.name = busTopicParams.getClientName();
104 this.https = busTopicParams.isUseHttps();
105 this.hostname = busTopicParams.getHostname();
106 this.port = busTopicParams.getPort();
107 this.basePath = busTopicParams.getBasePath();
108 this.userName = busTopicParams.getUserName();
109 this.password = busTopicParams.getPassword();
110 this.selfSignedCerts = busTopicParams.isAllowSelfSignedCerts();
111 this.client = detmClient();
113 if (!StringUtils.isBlank(this.userName) && !StringUtils.isBlank(this.password)) {
114 HttpAuthenticationFeature authFeature = HttpAuthenticationFeature.basic(userName, password);
115 this.client.register(authFeature);
118 this.client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true");
120 registerSerProviders(busTopicParams.getSerializationProvider());
122 this.baseUrl = (this.https ? "https://" : "http://") + this.hostname + ":" + this.port + "/"
123 + (this.basePath == null ? "" : this.basePath);
126 private Client detmClient() throws NoSuchAlgorithmException, KeyManagementException {
128 ClientBuilder clientBuilder;
129 SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
130 if (this.selfSignedCerts) {
131 sslContext.init(null, NetworkUtil.getAlwaysTrustingManager(), new SecureRandom());
133 ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier((host, session) -> true);
135 sslContext.init(null, null, null);
136 clientBuilder = ClientBuilder.newBuilder().sslContext(sslContext);
138 return clientBuilder.build();
141 return ClientBuilder.newClient();
146 * Registers the serialization provider(s) with the client.
148 * @param serializationProvider comma-separated list of serialization providers
149 * @throws ClassNotFoundException if the serialization provider cannot be found
151 private void registerSerProviders(String serializationProvider) throws ClassNotFoundException {
152 String providers = (StringUtils.isBlank(serializationProvider)
153 ? JERSEY_DEFAULT_SERIALIZATION_PROVIDER : serializationProvider);
154 for (String prov : providers.split(",")) {
155 this.client.register(Class.forName(prov));
160 public Response get(String path) {
161 if (!StringUtils.isBlank(path)) {
162 return this.client.target(this.baseUrl).path(path).request().get();
164 return this.client.target(this.baseUrl).request().get();
169 public Response get() {
170 return this.client.target(this.baseUrl).request().get();
174 public Future<Response> get(InvocationCallback<Response> callback, String path) {
175 if (!StringUtils.isBlank(path)) {
176 return this.client.target(this.baseUrl).path(path).request().async().get(callback);
178 return this.client.target(this.baseUrl).request().async().get(callback);
183 public Future<Response> get(InvocationCallback<Response> callback) {
184 return this.client.target(this.baseUrl).request().async().get(callback);
188 public Response put(String path, Entity<?> entity, Map<String, Object> headers) {
189 return getBuilder(path, headers).put(entity);
193 public Future<Response> put(InvocationCallback<Response> callback, String path, Entity<?> entity,
194 Map<String, Object> headers) {
195 return getBuilder(path, headers).async().put(entity, callback);
199 public Response post(String path, Entity<?> entity, Map<String, Object> headers) {
200 return getBuilder(path, headers).post(entity);
204 public Future<Response> post(InvocationCallback<Response> callback, String path, Entity<?> entity,
205 Map<String, Object> headers) {
206 return getBuilder(path, headers).async().post(entity, callback);
210 public Response delete(String path, Map<String, Object> headers) {
211 return getBuilder(path, headers).delete();
215 public Future<Response> delete(InvocationCallback<Response> callback, String path, Map<String, Object> headers) {
216 return getBuilder(path, headers).async().delete(callback);
220 public boolean start() {
225 public boolean stop() {
230 public void shutdown() {
231 synchronized (this) {
237 } catch (Exception e) {
238 logger.warn("{}: cannot close because of {}", this, e.getMessage(), e);
243 public synchronized boolean isAlive() {
248 public String getName() {
253 public boolean isHttps() {
258 public boolean isSelfSignedCerts() {
259 return selfSignedCerts;
263 public String getHostname() {
268 public int getPort() {
273 public String getBasePath() {
278 public String getUserName() {
285 public String getPassword() {
290 public String getBaseUrl() {
295 public String toString() {
296 StringBuilder builder = new StringBuilder();
297 builder.append("JerseyClient [name=");
298 builder.append(name);
299 builder.append(", https=");
300 builder.append(https);
301 builder.append(", selfSignedCerts=");
302 builder.append(selfSignedCerts);
303 builder.append(", hostname=");
304 builder.append(hostname);
305 builder.append(", port=");
306 builder.append(port);
307 builder.append(", basePath=");
308 builder.append(basePath);
309 builder.append(", userName=");
310 builder.append(userName);
311 builder.append(", password=");
312 builder.append(password);
313 builder.append(", client=");
314 builder.append(client);
315 builder.append(", baseUrl=");
316 builder.append(baseUrl);
317 builder.append(", alive=");
318 builder.append(alive);
320 return builder.toString();
323 private Builder getBuilder(String path, Map<String, Object> headers) {
324 Builder builder = this.client.target(this.baseUrl).path(path).request();
325 for (Entry<String, Object> header : headers.entrySet()) {
326 builder.header(header.getKey(), header.getValue());