trust-store-used: false
trust-store-password: policy_agent
trust-store: /opt/app/policy-agent/etc/cert/truststore.jks
+ http.proxy-host:
+ http.proxy-port: 0
import java.lang.invoke.MethodHandles;
import java.util.concurrent.atomic.AtomicInteger;
+import org.onap.ccsdk.oran.a1policymanagementservice.configuration.WebClientConfig.HttpProxyConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;
+import reactor.netty.tcp.ProxyProvider.Proxy;
import reactor.netty.tcp.TcpClient;
/**
private final String baseUrl;
private static final AtomicInteger sequenceNumber = new AtomicInteger();
private final SslContext sslContext;
+ private final HttpProxyConfig httpProxyConfig;
- /**
- * Note that only http (not https) will work when this constructor is used.
- *
- * @param baseUrl
- */
- public AsyncRestClient(String baseUrl) {
- this(baseUrl, null);
- }
-
- public AsyncRestClient(String baseUrl, SslContext sslContext) {
+ public AsyncRestClient(String baseUrl, @Nullable SslContext sslContext, @Nullable HttpProxyConfig httpProxyConfig) {
this.baseUrl = baseUrl;
this.sslContext = sslContext;
+ this.httpProxyConfig = httpProxyConfig;
}
public Mono<ResponseEntity<String>> postForEntity(String uri, @Nullable String body) {
}
}
- private TcpClient createTcpClientSecure(SslContext sslContext) {
- return TcpClient.create(ConnectionProvider.newConnection()) //
- .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) //
- .secure(c -> c.sslContext(sslContext)) //
- .doOnConnected(connection -> {
- connection.addHandlerLast(new ReadTimeoutHandler(30));
- connection.addHandlerLast(new WriteTimeoutHandler(30));
- });
+ private boolean isHttpProxyConfigured() {
+ return httpProxyConfig != null && httpProxyConfig.httpProxyPort() > 0
+ && !httpProxyConfig.httpProxyHost().isEmpty();
}
- private TcpClient createTcpClientInsecure() {
- return TcpClient.create(ConnectionProvider.newConnection()) //
+ private TcpClient createTcpClient() {
+ TcpClient client = TcpClient.create(ConnectionProvider.newConnection()) //
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) //
.doOnConnected(connection -> {
connection.addHandlerLast(new ReadTimeoutHandler(30));
connection.addHandlerLast(new WriteTimeoutHandler(30));
});
+ if (this.sslContext != null) {
+ client = client.secure(c -> c.sslContext(sslContext));
+ }
+ if (isHttpProxyConfigured()) {
+ client = client.proxy(proxy -> {
+ proxy.type(Proxy.HTTP).host(httpProxyConfig.httpProxyHost()).port(httpProxyConfig.httpProxyPort());
+ });
+ }
+ return client;
}
private WebClient createWebClient(String baseUrl, TcpClient tcpClient) {
HttpClient httpClient = HttpClient.from(tcpClient);
+
ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() //
.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)) //
private Mono<WebClient> getWebClient() {
if (this.webClient == null) {
try {
- if (this.sslContext != null) {
- TcpClient tcpClient = createTcpClientSecure(sslContext);
- this.webClient = createWebClient(this.baseUrl, tcpClient);
- } else {
- TcpClient tcpClient = createTcpClientInsecure();
- this.webClient = createWebClient(this.baseUrl, tcpClient);
- }
+ TcpClient tcpClient = createTcpClient();
+ this.webClient = createWebClient(this.baseUrl, tcpClient);
} catch (Exception e) {
logger.error("Could not create WebClient {}", e.getMessage());
return Mono.error(e);
import javax.net.ssl.KeyManagerFactory;
import org.onap.ccsdk.oran.a1policymanagementservice.configuration.WebClientConfig;
+import org.onap.ccsdk.oran.a1policymanagementservice.configuration.WebClientConfig.HttpProxyConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
/**
* Factory for a generic reactive REST client.
*/
+@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally
public class AsyncRestClientFactory {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private final SslContextFactory sslContextFactory;
+ private final HttpProxyConfig httpProxyConfig;
public AsyncRestClientFactory(WebClientConfig clientConfig) {
if (clientConfig != null) {
this.sslContextFactory = new CachingSslContextFactory(clientConfig);
+ this.httpProxyConfig = clientConfig.httpProxyConfig();
} else {
+ logger.warn("HTTPS will not work");
this.sslContextFactory = null;
+ this.httpProxyConfig = null;
}
}
+ public AsyncRestClient createRestClientNoHttpProxy(String baseUrl) {
+ return createRestClient(baseUrl, false);
+ }
+
public AsyncRestClient createRestClient(String baseUrl) {
+ return createRestClient(baseUrl, true);
+ }
+
+ private AsyncRestClient createRestClient(String baseUrl, boolean useHttpProxy) {
if (this.sslContextFactory != null) {
try {
- return new AsyncRestClient(baseUrl, this.sslContextFactory.createSslContext());
+ return new AsyncRestClient(baseUrl, this.sslContextFactory.createSslContext(),
+ useHttpProxy ? httpProxyConfig : null);
} catch (Exception e) {
String exceptionString = e.toString();
logger.error("Could not init SSL context, reason: {}", exceptionString);
}
}
- return new AsyncRestClient(baseUrl);
+ return new AsyncRestClient(baseUrl, null, httpProxyConfig);
}
private class SslContextFactory {
* Constructor that creates the REST client to use.
*
* @param protocolType the southbound protocol of the controller. Supported
- * protocols are CCSDK_A1_ADAPTER_STD_V1_1, CCSDK_A1_ADAPTER_OSC_V1 and
+ * protocols are CCSDK_A1_ADAPTER_STD_V1_1,
+ * CCSDK_A1_ADAPTER_OSC_V1 and
* CCSDK_A1_ADAPTER_STD_V2_0_0 with
* @param ricConfig the configuration of the Near-RT RIC to communicate
* with
public CcsdkA1AdapterClient(A1ProtocolType protocolType, RicConfig ricConfig, ControllerConfig controllerConfig,
AsyncRestClientFactory restClientFactory) {
this(protocolType, ricConfig, controllerConfig,
- restClientFactory.createRestClient(controllerConfig.baseUrl() + "/restconf/operations"));
+ restClientFactory.createRestClientNoHttpProxy(controllerConfig.baseUrl() + "/restconf/operations"));
}
/**
* Constructor where the REST client to use is provided.
*
* @param protocolType the southbound protocol of the controller. Supported
- * protocols are CCSDK_A1_ADAPTER_STD_V1_1, CCSDK_A1_ADAPTER_OSC_V1 and
+ * protocols are CCSDK_A1_ADAPTER_STD_V1_1,
+ * CCSDK_A1_ADAPTER_OSC_V1 and
* CCSDK_A1_ADAPTER_STD_V2_0_0 with
* @param ricConfig the configuration of the Near-RT RIC to communicate
* with
*
* @throws IllegalArgumentException when the protocolType is illegal.
*/
- public CcsdkA1AdapterClient(A1ProtocolType protocolType, RicConfig ricConfig, ControllerConfig controllerConfig,
+ CcsdkA1AdapterClient(A1ProtocolType protocolType, RicConfig ricConfig, ControllerConfig controllerConfig,
AsyncRestClient restClient) {
if (A1ProtocolType.CCSDK_A1_ADAPTER_STD_V1_1.equals(protocolType) //
|| A1ProtocolType.CCSDK_A1_ADAPTER_OSC_V1.equals(protocolType) //
import lombok.Getter;
+import org.onap.ccsdk.oran.a1policymanagementservice.configuration.WebClientConfig.HttpProxyConfig;
import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Value("${app.webclient.trust-store}")
private String sslTrustStore = "";
+ @Value("${app.webclient.http.proxy-host}")
+ private String httpProxyHost = "";
+
+ @Value("${app.webclient.http.proxy-port}")
+ private int httpProxyPort = 0;
+
private Map<String, RicConfig> ricConfigs = new HashMap<>();
@Getter
}
public WebClientConfig getWebClientConfig() {
+ HttpProxyConfig httpProxyConfig = ImmutableHttpProxyConfig.builder() //
+ .httpProxyHost(this.httpProxyHost) //
+ .httpProxyPort(this.httpProxyPort) //
+ .build();
+
return ImmutableWebClientConfig.builder() //
.keyStoreType(this.sslKeyStoreType) //
.keyStorePassword(this.sslKeyStorePassword) //
.isTrustStoreUsed(this.sslTrustStoreUsed) //
.trustStore(this.sslTrustStore) //
.trustStorePassword(this.sslTrustStorePassword) //
+ .httpProxyConfig(httpProxyConfig) //
.build();
}
public String trustStore();
+ @Value.Immutable
+ public interface HttpProxyConfig {
+ public String httpProxyHost();
+
+ public int httpProxyPort();
+ }
+
+ public HttpProxyConfig httpProxyConfig();
+
}
private final AsyncRestClient restClient;
public ServiceCallbacks(AsyncRestClientFactory restClientFactory) {
- this.restClient = restClientFactory.createRestClient("");
+ this.restClient = restClientFactory.createRestClientNoHttpProxy("");
}
public void notifyServicesRicSynchronized(Ric ric, Services services) {
private static Gson gson = new GsonBuilder() //
.create(); //
- @GetMapping(path = "/v2/policy-types/{policytype_id:.+}", produces = MediaType.APPLICATION_JSON_VALUE)
+ @GetMapping(path = Consts.V2_API_ROOT + "/policy-types/{policytype_id:.+}",
+ produces = MediaType.APPLICATION_JSON_VALUE)
@ApiOperation(value = "Returns a policy type definition")
@ApiResponses(value = { //
@ApiResponse(code = 200, message = "Policy type", response = PolicyTypeInfo.class), //
protected Mono<String> getFromMessageRouter(String topicUrl) {
logger.trace("getFromMessageRouter {}", topicUrl);
- AsyncRestClient c = restClientFactory.createRestClient("");
+ AsyncRestClient c = restClientFactory.createRestClientNoHttpProxy("");
return c.get(topicUrl);
}
private DmaapMessageHandler getDmaapMessageHandler() {
if (this.dmaapMessageHandler == null) {
String pmsBaseUrl = "http://localhost:" + this.localServerHttpPort;
- AsyncRestClient pmsClient = restClientFactory.createRestClient(pmsBaseUrl);
+ AsyncRestClient pmsClient = restClientFactory.createRestClientNoHttpProxy(pmsBaseUrl);
AsyncRestClient producer =
- restClientFactory.createRestClient(this.applicationConfig.getDmaapProducerTopicUrl());
+ restClientFactory.createRestClientNoHttpProxy(this.applicationConfig.getDmaapProducerTopicUrl());
this.dmaapMessageHandler = new DmaapMessageHandler(producer, pmsClient);
}
return this.dmaapMessageHandler;
InternalLoggerFactory.setDefaultFactory(JdkLoggerFactory.INSTANCE);
Loggers.useJdkLoggers();
mockWebServer = new MockWebServer();
- clientUnderTest = new AsyncRestClient(mockWebServer.url(BASE_URL).toString());
+ clientUnderTest = new AsyncRestClient(mockWebServer.url(BASE_URL).toString(), null, null);
}
@AfterAll
@Test
void createClientWithWrongProtocol_thenErrorIsThrown() {
assertThrows(IllegalArgumentException.class, () -> {
- new CcsdkA1AdapterClient(A1ProtocolType.STD_V1_1, null, null, new AsyncRestClient("", null));
+ new CcsdkA1AdapterClient(A1ProtocolType.STD_V1_1, null, null, new AsyncRestClient("", null, null));
});
}
.isTrustStoreUsed(useTrustValidation) //
.trustStore(config.trustStore()) //
.trustStorePassword(config.trustStorePassword()) //
+ .httpProxyConfig(config.httpProxyConfig()) //
.build();
AsyncRestClientFactory f = new AsyncRestClientFactory(config);
- return f.createRestClient(baseUrl());
+ return f.createRestClientNoHttpProxy(baseUrl());
}
private AsyncRestClient restClient() {
.isTrustStoreUsed(useTrustValidation) //
.trustStore(config.trustStore()) //
.trustStorePassword(config.trustStorePassword()) //
+ .httpProxyConfig(config.httpProxyConfig()) //
.build();
AsyncRestClientFactory f = new AsyncRestClientFactory(config);
- return f.createRestClient(baseUrl);
+ return f.createRestClientNoHttpProxy(baseUrl);
}