aboutsummaryrefslogtreecommitdiffstats
path: root/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client
diff options
context:
space:
mode:
Diffstat (limited to 'policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client')
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClient.java82
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientConfigException.java4
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientFactoryInstance.java10
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/IndexedHttpClientFactory.java20
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/internal/JerseyClient.java181
5 files changed, 176 insertions, 121 deletions
diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClient.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClient.java
index 2fe46fb3..01deaa2d 100644
--- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClient.java
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClient.java
@@ -2,7 +2,8 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2023 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +21,17 @@
package org.onap.policy.common.endpoints.http.client;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.InvocationCallback;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Response;
import java.util.Map;
-
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Response;
-
+import java.util.concurrent.Future;
import org.onap.policy.common.capabilities.Startable;
/**
- * Http Client interface.
+ * Http Client interface. Supports both synchronous and asynchronous operations.
+ *
*/
public interface HttpClient extends Startable {
@@ -48,6 +51,26 @@ public interface HttpClient extends Startable {
Response get();
/**
+ * Asynchronous GET request.
+ *
+ * @param callback callback to be invoked, asynchronously, when the request completes
+ * @param path context uri path
+ * @param headers request headers
+ *
+ * @return future that can be used to cancel the request or await the response
+ */
+ Future<Response> get(InvocationCallback<Response> callback, String path, Map<String, Object> headers);
+
+ /**
+ * Asynchronous GET request.
+ *
+ * @param callback callback to be invoked, asynchronously, when the request completes
+ * @param headers request headers
+ * @return future that can be used to cancel the request or await the response
+ */
+ Future<Response> get(InvocationCallback<Response> callback, Map<String, Object> headers);
+
+ /**
* PUT request.
*
* @param path context uri path
@@ -59,6 +82,19 @@ public interface HttpClient extends Startable {
Response put(String path, Entity<?> entity, Map<String, Object> headers);
/**
+ * Asynchronous PUT request.
+ *
+ * @param callback callback to be invoked, asynchronously, when the request completes
+ * @param path context uri path
+ * @param entity body
+ * @param headers headers
+ *
+ * @return future that can be used to cancel the request or await the response
+ */
+ Future<Response> put(InvocationCallback<Response> callback, String path, Entity<?> entity,
+ Map<String, Object> headers);
+
+ /**
* POST request.
*
* @param path context uri path
@@ -70,6 +106,19 @@ public interface HttpClient extends Startable {
Response post(String path, Entity<?> entity, Map<String, Object> headers);
/**
+ * Asynchronous POST request.
+ *
+ * @param callback callback to be invoked, asynchronously, when the request completes
+ * @param path context uri path
+ * @param entity body
+ * @param headers headers
+ *
+ * @return future that can be used to cancel the request or await the response
+ */
+ Future<Response> post(InvocationCallback<Response> callback, String path, Entity<?> entity,
+ Map<String, Object> headers);
+
+ /**
* DELETE request.
*
* @param path context uri path
@@ -80,6 +129,17 @@ public interface HttpClient extends Startable {
Response delete(String path, Map<String, Object> headers);
/**
+ * Asynchronous DELETE request.
+ *
+ * @param callback callback to be invoked, asynchronously, when the request completes
+ * @param path context uri path
+ * @param headers headers
+ *
+ * @return future that can be used to cancel the request or await the response
+ */
+ Future<Response> delete(InvocationCallback<Response> callback, String path, Map<String, Object> headers);
+
+ /**
* Retrieve the body from the HTTP transaction.
*
* @param response response.
@@ -134,9 +194,9 @@ public interface HttpClient extends Startable {
String getBasePath();
/**
- * Get the user name.
+ * Get the username.
*
- * @return the user name
+ * @return the username
*/
String getUserName();
@@ -154,4 +214,10 @@ public interface HttpClient extends Startable {
*/
String getBaseUrl();
+ /**
+ * Gets a web target associated with the base URL.
+ *
+ * @return a webtarget
+ */
+ WebTarget getWebTarget();
}
diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientConfigException.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientConfigException.java
index 98ec576f..bb871fa0 100644
--- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientConfigException.java
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientConfigException.java
@@ -3,6 +3,7 @@
* ONAP
* ================================================================================
* Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2023 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,10 +21,13 @@
package org.onap.policy.common.endpoints.http.client;
+import java.io.Serial;
+
/**
* Exception generated by HttpClient builder.
*/
public class HttpClientConfigException extends Exception {
+ @Serial
private static final long serialVersionUID = 1L;
public HttpClientConfigException() {
diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientFactoryInstance.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientFactoryInstance.java
index c2921640..f64be30e 100644
--- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientFactoryInstance.java
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientFactoryInstance.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,8 +20,11 @@
package org.onap.policy.common.endpoints.http.client;
+import lombok.AccessLevel;
import lombok.Getter;
+import lombok.NoArgsConstructor;
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class HttpClientFactoryInstance {
/**
@@ -29,9 +32,4 @@ public class HttpClientFactoryInstance {
*/
@Getter
private static final HttpClientFactory clientFactory = new IndexedHttpClientFactory();
-
-
- private HttpClientFactoryInstance() {
- // do nothing
- }
}
diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/IndexedHttpClientFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/IndexedHttpClientFactory.java
index edf8ff6f..5f0b1d6e 100644
--- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/IndexedHttpClientFactory.java
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/IndexedHttpClientFactory.java
@@ -2,7 +2,8 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2019, 2021 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2023 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +21,7 @@
package org.onap.policy.common.endpoints.http.client;
+import com.google.re2j.Pattern;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
@@ -38,11 +40,12 @@ import org.slf4j.LoggerFactory;
* HTTP client factory implementation indexed by name.
*/
class IndexedHttpClientFactory implements HttpClientFactory {
+ private static final Pattern COMMA_SPACE_PAT = Pattern.compile("\\s*,\\s*");
/**
* Logger.
*/
- private static Logger logger = LoggerFactory.getLogger(IndexedHttpClientFactory.class);
+ private static final Logger logger = LoggerFactory.getLogger(IndexedHttpClientFactory.class);
protected HashMap<String, HttpClient> clients = new HashMap<>();
@@ -75,7 +78,7 @@ class IndexedHttpClientFactory implements HttpClientFactory {
return clientList;
}
- for (String clientName : clientNames.split("\\s*,\\s*")) {
+ for (String clientName : COMMA_SPACE_PAT.split(clientNames)) {
addClient(clientList, clientName, properties);
}
@@ -85,23 +88,22 @@ class IndexedHttpClientFactory implements HttpClientFactory {
private void addClient(ArrayList<HttpClient> clientList, String clientName, Properties properties) {
String clientPrefix = PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + clientName;
- PropertyUtils props = new PropertyUtils(properties, clientPrefix,
+ var props = new PropertyUtils(properties, clientPrefix,
(name, value, ex) ->
logger.warn("{}: {} {} is in invalid format for http client {} ", this, name, value, clientName));
- int port = props.getInteger(PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX, -1);
+ var port = props.getInteger(PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX, -1);
if (port < 0) {
logger.warn("No HTTP port for client in {}", clientName);
return;
}
- boolean https = props.getBoolean(PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX, false);
-
try {
HttpClient client = this.build(BusTopicParams.builder()
.clientName(clientName)
- .useHttps(https)
- .allowSelfSignedCerts(https)
+ .useHttps(props.getBoolean(PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX, false))
+ .allowSelfSignedCerts(
+ props.getBoolean(PolicyEndPointProperties.PROPERTY_ALLOW_SELF_SIGNED_CERTIFICATES_SUFFIX, false))
.hostname(props.getString(PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX, null))
.port(port)
.basePath(props.getString(PolicyEndPointProperties.PROPERTY_HTTP_URL_SUFFIX, null))
diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/internal/JerseyClient.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/internal/JerseyClient.java
index 8a717712..130b6c15 100644
--- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/internal/JerseyClient.java
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/internal/JerseyClient.java
@@ -2,9 +2,9 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved.
* Modifications Copyright (C) 2018 Samsung Electronics Co., Ltd.
- * Modifications Copyright (C) 2019 Nordix Foundation.
+ * Modifications Copyright (C) 2019, 2023 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,24 +22,29 @@
package org.onap.policy.common.endpoints.http.client.internal;
-import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.re2j.Pattern;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.Invocation.Builder;
+import jakarta.ws.rs.client.InvocationCallback;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Response;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
+import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.Future;
import javax.net.ssl.SSLContext;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.Invocation.Builder;
-import javax.ws.rs.core.Response;
+import lombok.Getter;
+import lombok.ToString;
import org.apache.commons.lang3.StringUtils;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams;
import org.onap.policy.common.endpoints.http.client.HttpClient;
-import org.onap.policy.common.gson.annotation.GsonJsonIgnore;
import org.onap.policy.common.utils.network.NetworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,15 +52,18 @@ import org.slf4j.LoggerFactory;
/**
* Http Client implementation using a Jersey Client.
*/
+@Getter
+@ToString
public class JerseyClient implements HttpClient {
+ private static final Pattern COMMA_PAT = Pattern.compile(",");
/**
* Logger.
*/
- private static Logger logger = LoggerFactory.getLogger(JerseyClient.class);
+ private static final Logger logger = LoggerFactory.getLogger(JerseyClient.class);
protected static final String JERSEY_DEFAULT_SERIALIZATION_PROVIDER =
- "org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider";
+ "org.onap.policy.common.gson.GsonMessageBodyHandler";
protected final String name;
protected final boolean https;
@@ -74,9 +82,14 @@ public class JerseyClient implements HttpClient {
/**
* Constructor.
*
- * <p>name the name https is it https or not selfSignedCerts are there self signed certs
- * hostname the hostname port port being used basePath base context userName user
- * password password
+ * <p>name - the name
+ * https - is it https or not
+ * selfSignedCerts - are there self-signed certs
+ * hostname - the hostname
+ * port - port being used
+ * basePath - base context
+ * userName - user credentials
+ * password - password credentials
*
* @param busTopicParams Input parameters object
* @throws KeyManagementException key exception
@@ -109,7 +122,7 @@ public class JerseyClient implements HttpClient {
this.client = detmClient();
if (!StringUtils.isBlank(this.userName) && !StringUtils.isBlank(this.password)) {
- HttpAuthenticationFeature authFeature = HttpAuthenticationFeature.basic(userName, password);
+ var authFeature = HttpAuthenticationFeature.basic(userName, password);
this.client.register(authFeature);
}
@@ -124,11 +137,17 @@ public class JerseyClient implements HttpClient {
private Client detmClient() throws NoSuchAlgorithmException, KeyManagementException {
if (this.https) {
ClientBuilder clientBuilder;
- SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
+ var sslContext = SSLContext.getInstance("TLSv1.2");
if (this.selfSignedCerts) {
sslContext.init(null, NetworkUtil.getAlwaysTrustingManager(), new SecureRandom());
+
+ // This falls under self-signed certs which is used for non-production testing environments where
+ // the hostname in the cert is unlikely to be crafted properly. We always return true for the
+ // hostname verifier. This causes a sonar vuln, but we ignore it as it could cause problems in some
+ // testing environments.
clientBuilder =
- ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier((host, session) -> true);
+ ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(
+ (host, session) -> true); //NOSONAR
} else {
sslContext.init(null, null, null);
clientBuilder = ClientBuilder.newBuilder().sslContext(sslContext);
@@ -149,23 +168,48 @@ public class JerseyClient implements HttpClient {
private void registerSerProviders(String serializationProvider) throws ClassNotFoundException {
String providers = (StringUtils.isBlank(serializationProvider)
? JERSEY_DEFAULT_SERIALIZATION_PROVIDER : serializationProvider);
- for (String prov : providers.split(",")) {
+ for (String prov : COMMA_PAT.split(providers)) {
this.client.register(Class.forName(prov));
}
}
@Override
+ public WebTarget getWebTarget() {
+ return this.client.target(this.baseUrl);
+ }
+
+ @Override
public Response get(String path) {
if (!StringUtils.isBlank(path)) {
- return this.client.target(this.baseUrl).path(path).request().get();
+ return getWebTarget().path(path).request().get();
} else {
- return this.client.target(this.baseUrl).request().get();
+ return getWebTarget().request().get();
}
}
@Override
public Response get() {
- return this.client.target(this.baseUrl).request().get();
+ return getWebTarget().request().get();
+ }
+
+ @Override
+ public Future<Response> get(InvocationCallback<Response> callback, String path, Map<String, Object> headers) {
+ Map<String, Object> headers2 = (headers != null ? headers : Collections.emptyMap());
+
+ if (!StringUtils.isBlank(path)) {
+ return getBuilder(path, headers2).async().get(callback);
+ } else {
+ return get(callback, headers2);
+ }
+ }
+
+ @Override
+ public Future<Response> get(InvocationCallback<Response> callback, Map<String, Object> headers) {
+ var builder = getWebTarget().request();
+ if (headers != null) {
+ headers.forEach(builder::header);
+ }
+ return builder.async().get(callback);
}
@Override
@@ -174,16 +218,33 @@ public class JerseyClient implements HttpClient {
}
@Override
+ public Future<Response> put(InvocationCallback<Response> callback, String path, Entity<?> entity,
+ Map<String, Object> headers) {
+ return getBuilder(path, headers).async().put(entity, callback);
+ }
+
+ @Override
public Response post(String path, Entity<?> entity, Map<String, Object> headers) {
return getBuilder(path, headers).post(entity);
}
@Override
+ public Future<Response> post(InvocationCallback<Response> callback, String path, Entity<?> entity,
+ Map<String, Object> headers) {
+ return getBuilder(path, headers).async().post(entity, callback);
+ }
+
+ @Override
public Response delete(String path, Map<String, Object> headers) {
return getBuilder(path, headers).delete();
}
@Override
+ public Future<Response> delete(InvocationCallback<Response> callback, String path, Map<String, Object> headers) {
+ return getBuilder(path, headers).async().delete(callback);
+ }
+
+ @Override
public boolean start() {
return alive;
}
@@ -211,84 +272,8 @@ public class JerseyClient implements HttpClient {
return this.alive;
}
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public boolean isHttps() {
- return https;
- }
-
- @Override
- public boolean isSelfSignedCerts() {
- return selfSignedCerts;
- }
-
- @Override
- public String getHostname() {
- return hostname;
- }
-
- @Override
- public int getPort() {
- return port;
- }
-
- @Override
- public String getBasePath() {
- return basePath;
- }
-
- @Override
- public String getUserName() {
- return userName;
- }
-
- @JsonIgnore
- @GsonJsonIgnore
- @Override
- public String getPassword() {
- return password;
- }
-
- @Override
- public String getBaseUrl() {
- return baseUrl;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("JerseyClient [name=");
- builder.append(name);
- builder.append(", https=");
- builder.append(https);
- builder.append(", selfSignedCerts=");
- builder.append(selfSignedCerts);
- builder.append(", hostname=");
- builder.append(hostname);
- builder.append(", port=");
- builder.append(port);
- builder.append(", basePath=");
- builder.append(basePath);
- builder.append(", userName=");
- builder.append(userName);
- builder.append(", password=");
- builder.append(password);
- builder.append(", client=");
- builder.append(client);
- builder.append(", baseUrl=");
- builder.append(baseUrl);
- builder.append(", alive=");
- builder.append(alive);
- builder.append("]");
- return builder.toString();
- }
-
private Builder getBuilder(String path, Map<String, Object> headers) {
- Builder builder = this.client.target(this.baseUrl).path(path).request();
+ var builder = getWebTarget().path(path).request();
for (Entry<String, Object> header : headers.entrySet()) {
builder.header(header.getKey(), header.getValue());
}