From 2374566dcdd4c1df39c3a0b437db29a61d228a6f Mon Sep 17 00:00:00 2001 From: "waqas.ikram" Date: Wed, 4 Mar 2020 15:09:52 +0000 Subject: Add HTTPS support between SOL003 Adapter and ETSI Catalog Manager Change-Id: I66c9cae7b583fa929c5ebe98731dd10616c07047 Issue-ID: SO-2752 Signed-off-by: waqas.ikram --- .../EtsiCatalogServiceProviderConfiguration.java | 132 +++++++++++++++++++-- .../EtsiCatalogServiceProviderImpl.java | 9 +- .../vnfm/VnfmHttpServiceProviderConfiguration.java | 49 ++++++++ .../AbstractNotificationServiceProvider.java | 13 +- .../BasicAuthNotificationServiceProvider.java | 6 +- .../OAuthNotificationServiceProvider.java | 13 +- 6 files changed, 192 insertions(+), 30 deletions(-) create mode 100644 adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmHttpServiceProviderConfiguration.java (limited to 'adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap') diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java index 6840dd388b..860dfbbe9c 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java @@ -20,16 +20,41 @@ package org.onap.so.adapters.vnfmadapter.extclients.etsicatalog; -import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.concurrent.TimeUnit; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; +import org.onap.logging.filter.spring.SpringClientPayloadFilter; import org.onap.so.adapters.vnfmadapter.extclients.AbstractServiceProviderConfiguration; import org.onap.so.configuration.rest.BasicHttpHeadersProvider; -import org.onap.so.configuration.rest.HttpHeadersProvider; +import org.onap.so.configuration.rest.HttpClientConnectionConfiguration; +import org.onap.so.logging.jaxrs.filter.SOSpringClientFilter; import org.onap.so.rest.service.HttpRestServiceProvider; import org.onap.so.rest.service.HttpRestServiceProviderImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; /** @@ -41,16 +66,105 @@ import org.springframework.web.client.RestTemplate; @Configuration public class EtsiCatalogServiceProviderConfiguration extends AbstractServiceProviderConfiguration { - @Bean(name = "etsiCatalogServiceProvider") - public HttpRestServiceProvider httpRestServiceProvider( - @Qualifier(CONFIGURABLE_REST_TEMPLATE) @Autowired final RestTemplate restTemplate) { - return getHttpRestServiceProvider(restTemplate, new BasicHttpHeadersProvider()); + public static final String ETSI_CATALOG_REST_TEMPLATE_BEAN = "etsiCatalogRestTemplate"; + + public static final String ETSI_CATALOG_SERVICE_PROVIDER_BEAN = "etsiCatalogServiceProvider"; + + private final static Logger LOGGER = LoggerFactory.getLogger(EtsiCatalogServiceProviderConfiguration.class); + + private final HttpClientConnectionConfiguration clientConnectionConfiguration; + + @Value("${etsi-catalog-manager.http.client.ssl.trust-store:#{null}}") + private Resource trustStore; + @Value("${etsi-catalog-manager.http.client.ssl.trust-store-password:#{null}}") + private String trustStorePassword; + + @Autowired + public EtsiCatalogServiceProviderConfiguration( + final HttpClientConnectionConfiguration clientConnectionConfiguration) { + this.clientConnectionConfiguration = clientConnectionConfiguration; + } + + @Bean + @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) + public RestTemplate etsiCatalogRestTemplate() { + final RestTemplate restTemplate = new RestTemplate(); + restTemplate.getInterceptors().add(new SOSpringClientFilter()); + restTemplate.getInterceptors().add((new SpringClientPayloadFilter())); + return restTemplate; } - private HttpRestServiceProvider getHttpRestServiceProvider(final RestTemplate restTemplate, - final HttpHeadersProvider httpHeadersProvider) { + @Bean + @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN) + public HttpRestServiceProvider etsiCatalogHttpRestServiceProvider( + @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) final RestTemplate restTemplate) { setGsonMessageConverter(restTemplate); - return new HttpRestServiceProviderImpl(restTemplate, httpHeadersProvider); + + final HttpClientBuilder httpClientBuilder = getHttpClientBuilder(); + if (trustStore != null) { + try { + LOGGER.debug("Setting up HttpComponentsClientHttpRequestFactory with SSL Context"); + LOGGER.debug("Setting client trust-store: {}", trustStore.getURL()); + LOGGER.debug("Creating SSLConnectionSocketFactory with AllowAllHostsVerifier ... "); + final SSLContext sslContext = new SSLContextBuilder() + .loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()).build(); + final SSLConnectionSocketFactory sslConnectionSocketFactory = + new SSLConnectionSocketFactory(sslContext, AllowAllHostsVerifier.INSTANCE); + httpClientBuilder.setSSLSocketFactory(sslConnectionSocketFactory); + final Registry socketFactoryRegistry = RegistryBuilder + .create().register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https", sslConnectionSocketFactory).build(); + + httpClientBuilder.setConnectionManager(getConnectionManager(socketFactoryRegistry)); + } catch (final KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException + | IOException exception) { + LOGGER.error("Error reading truststore, TLS connection will fail.", exception); + } + + } else { + LOGGER.debug("Setting connection manager without SSL ConnectionSocketFactory ..."); + httpClientBuilder.setConnectionManager(getConnectionManager()); + } + + final HttpComponentsClientHttpRequestFactory factory = + new HttpComponentsClientHttpRequestFactory(httpClientBuilder.build()); + restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory)); + + return new HttpRestServiceProviderImpl(restTemplate, new BasicHttpHeadersProvider().getHttpHeaders()); + } + + private PoolingHttpClientConnectionManager getConnectionManager( + final Registry socketFactoryRegistry) { + return new PoolingHttpClientConnectionManager(socketFactoryRegistry, null, null, null, + clientConnectionConfiguration.getTimeToLiveInMins(), TimeUnit.MINUTES); + } + + private PoolingHttpClientConnectionManager getConnectionManager() { + return new PoolingHttpClientConnectionManager(clientConnectionConfiguration.getTimeToLiveInMins(), + TimeUnit.MINUTES); + } + + private HttpClientBuilder getHttpClientBuilder() { + return HttpClientBuilder.create().setMaxConnPerRoute(clientConnectionConfiguration.getMaxConnectionsPerRoute()) + .setMaxConnTotal(clientConnectionConfiguration.getMaxConnections()) + .setDefaultRequestConfig(getRequestConfig()); + } + + private RequestConfig getRequestConfig() { + return RequestConfig.custom().setSocketTimeout(clientConnectionConfiguration.getSocketTimeOutInMiliSeconds()) + .setConnectTimeout(clientConnectionConfiguration.getConnectionTimeOutInMilliSeconds()).build(); + } + + private static final class AllowAllHostsVerifier implements HostnameVerifier { + + private static final AllowAllHostsVerifier INSTANCE = new AllowAllHostsVerifier(); + + @Override + public boolean verify(final String hostname, final SSLSession session) { + LOGGER.debug("Skipping hostname verification ..."); + return true; + } + } } diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/etsicatalog/EtsiCatalogServiceProviderImpl.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/etsicatalog/EtsiCatalogServiceProviderImpl.java index 30d084629c..cae413ce10 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/etsicatalog/EtsiCatalogServiceProviderImpl.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/etsicatalog/EtsiCatalogServiceProviderImpl.java @@ -20,6 +20,7 @@ package org.onap.so.adapters.vnfmadapter.extclients.etsicatalog; +import static org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_SERVICE_PROVIDER_BEAN; import java.util.Optional; import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.NsdmSubscription; import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.PkgmSubscription; @@ -53,14 +54,14 @@ import org.springframework.stereotype.Service; public class EtsiCatalogServiceProviderImpl implements EtsiCatalogServiceProvider { private static final Logger logger = LoggerFactory.getLogger(EtsiCatalogServiceProviderImpl.class); - @Qualifier("etsiCatalogServiceProvider") private final HttpRestServiceProvider httpServiceProvider; private final EtsiCatalogUrlProvider etsiCatalogUrlProvider; private final ConversionService conversionService; @Autowired public EtsiCatalogServiceProviderImpl(final EtsiCatalogUrlProvider etsiCatalogUrlProvider, - final HttpRestServiceProvider httpServiceProvider, final ConversionService conversionService) { + @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider, + final ConversionService conversionService) { this.etsiCatalogUrlProvider = etsiCatalogUrlProvider; this.httpServiceProvider = httpServiceProvider; this.conversionService = conversionService; @@ -118,8 +119,10 @@ public class EtsiCatalogServiceProviderImpl implements EtsiCatalogServiceProvide if (inlineResponse2001 != null) { responses[index] = inlineResponse2001; } + } else { + logger.error("Unable to find Converter for response class: {}", + vnfPackages[index].getClass()); } - logger.error("Unable to find Converter for response class: {}", vnfPackages[index].getClass()); } return Optional.of(responses); } diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmHttpServiceProviderConfiguration.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmHttpServiceProviderConfiguration.java new file mode 100644 index 0000000000..9ed17e4379 --- /dev/null +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmHttpServiceProviderConfiguration.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.vnfmadapter.extclients.vnfm; + +import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE; +import org.onap.so.adapters.vnfmadapter.extclients.AbstractServiceProviderConfiguration; +import org.onap.so.configuration.rest.BasicHttpHeadersProvider; +import org.onap.so.rest.service.HttpRestServiceProvider; +import org.onap.so.rest.service.HttpRestServiceProviderImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Configuration +public class VnfmHttpServiceProviderConfiguration extends AbstractServiceProviderConfiguration { + public static final String VNFM_ADAPTER_HTTP_SERVICE_PROVIDER_BEAN = "vnfmAdapterHttpServiceProvider"; + + @Bean + @Qualifier(VNFM_ADAPTER_HTTP_SERVICE_PROVIDER_BEAN) + public HttpRestServiceProvider vnfmAdapterHttpRestServiceProvider( + @Autowired @Qualifier(CONFIGURABLE_REST_TEMPLATE) RestTemplate restTemplate) { + setGsonMessageConverter(restTemplate); + return new HttpRestServiceProviderImpl(restTemplate, new BasicHttpHeadersProvider().getHttpHeaders()); + } + +} diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/packagemanagement/subscriptionmanagement/AbstractNotificationServiceProvider.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/packagemanagement/subscriptionmanagement/AbstractNotificationServiceProvider.java index 86ca59cffe..d6b7ae7201 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/packagemanagement/subscriptionmanagement/AbstractNotificationServiceProvider.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/packagemanagement/subscriptionmanagement/AbstractNotificationServiceProvider.java @@ -19,16 +19,13 @@ */ package org.onap.so.adapters.vnfmadapter.packagemanagement.subscriptionmanagement; -import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE; +import static org.onap.so.adapters.vnfmadapter.extclients.vnfm.VnfmHttpServiceProviderConfiguration.VNFM_ADAPTER_HTTP_SERVICE_PROVIDER_BEAN; import java.nio.charset.StandardCharsets; import org.apache.commons.codec.binary.Base64; import org.onap.so.configuration.rest.BasicHttpHeadersProvider; -import org.onap.so.configuration.rest.HttpHeadersProvider; import org.onap.so.rest.service.HttpRestServiceProvider; -import org.onap.so.rest.service.HttpRestServiceProviderImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.web.client.RestTemplate; /** * A base class that can be extended by classes for providing notification services. Provides common methods that will @@ -40,12 +37,10 @@ import org.springframework.web.client.RestTemplate; public abstract class AbstractNotificationServiceProvider { @Autowired - @Qualifier(CONFIGURABLE_REST_TEMPLATE) - private RestTemplate restTemplate; + @Qualifier(VNFM_ADAPTER_HTTP_SERVICE_PROVIDER_BEAN) + private HttpRestServiceProvider httpRestServiceProvider; - protected HttpRestServiceProvider getHttpRestServiceProvider(final HttpHeadersProvider httpHeadersProvider) { - final HttpRestServiceProvider httpRestServiceProvider = - new HttpRestServiceProviderImpl(restTemplate, httpHeadersProvider); + protected HttpRestServiceProvider getHttpRestServiceProvider() { return httpRestServiceProvider; } diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/packagemanagement/subscriptionmanagement/BasicAuthNotificationServiceProvider.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/packagemanagement/subscriptionmanagement/BasicAuthNotificationServiceProvider.java index 6f9d94e9de..cf0cdb085a 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/packagemanagement/subscriptionmanagement/BasicAuthNotificationServiceProvider.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/packagemanagement/subscriptionmanagement/BasicAuthNotificationServiceProvider.java @@ -47,10 +47,10 @@ public class BasicAuthNotificationServiceProvider extends AbstractNotificationSe final HttpHeadersProvider httpHeadersProvider = getBasicHttpHeadersProviderWithBasicAuth(subscriptionsAuthentication.getParamsBasic().getUserName(), subscriptionsAuthentication.getParamsBasic().getPassword()); - final HttpRestServiceProvider httpRestServiceProvider = getHttpRestServiceProvider(httpHeadersProvider); + final HttpRestServiceProvider httpRestServiceProvider = getHttpRestServiceProvider(); - final ResponseEntity responseEntity = - httpRestServiceProvider.postHttpRequest(notification, callbackUri, Void.class); + final ResponseEntity responseEntity = httpRestServiceProvider.postHttpRequest(notification, callbackUri, + httpHeadersProvider.getHttpHeaders(), Void.class); if (responseEntity.getStatusCode().is2xxSuccessful()) { logger.info("Notification sent successfully."); return true; diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/packagemanagement/subscriptionmanagement/OAuthNotificationServiceProvider.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/packagemanagement/subscriptionmanagement/OAuthNotificationServiceProvider.java index 496fb083cf..c065203cd8 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/packagemanagement/subscriptionmanagement/OAuthNotificationServiceProvider.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/packagemanagement/subscriptionmanagement/OAuthNotificationServiceProvider.java @@ -48,13 +48,14 @@ public class OAuthNotificationServiceProvider extends AbstractNotificationServic final String token = getAccessToken(subscriptionsAuthentication); if (token == null) { + logger.error("Failed to get access token"); return false; } final HttpHeadersProvider httpHeadersProvider = getHttpHeadersProvider(token); - final HttpRestServiceProvider httpRestServiceProvider = getHttpRestServiceProvider(httpHeadersProvider); - final ResponseEntity responseEntity = - httpRestServiceProvider.postHttpRequest(notification, callbackUri, Void.class); + final HttpRestServiceProvider httpRestServiceProvider = getHttpRestServiceProvider(); + final ResponseEntity responseEntity = httpRestServiceProvider.postHttpRequest(notification, callbackUri, + httpHeadersProvider.getHttpHeaders(), Void.class); if (responseEntity.getStatusCode().is2xxSuccessful()) { logger.info("Notification sent successfully."); return true; @@ -83,9 +84,9 @@ public class OAuthNotificationServiceProvider extends AbstractNotificationServic subscriptionsAuthentication.getParamsOauth2ClientCredentials().getClientId(), subscriptionsAuthentication.getParamsOauth2ClientCredentials().getClientPassword()); - final HttpRestServiceProvider httpRestServiceProvider = getHttpRestServiceProvider(httpHeadersProvider); - final ResponseEntity responseEntity = - httpRestServiceProvider.postHttpRequest(null, tokenEndpoint, OAuthTokenResponse.class); + final HttpRestServiceProvider httpRestServiceProvider = getHttpRestServiceProvider(); + final ResponseEntity responseEntity = httpRestServiceProvider.postHttpRequest(null, + tokenEndpoint, httpHeadersProvider.getHttpHeaders(), OAuthTokenResponse.class); if (responseEntity.getStatusCode().is2xxSuccessful()) { if (responseEntity.getBody() != null) { logger.info("Returning Access Token."); -- cgit 1.2.3-korg