summaryrefslogtreecommitdiffstats
path: root/aai-rest
diff options
context:
space:
mode:
Diffstat (limited to 'aai-rest')
-rw-r--r--aai-rest/LICENSE.TXT17
-rw-r--r--aai-rest/pom.xml129
-rw-r--r--aai-rest/src/main/java/org/onap/aai/restclient/JettyPasswordDecoder.java33
-rw-r--r--aai-rest/src/main/java/org/onap/aai/restclient/NoAuthRestClient.java53
-rw-r--r--aai-rest/src/main/java/org/onap/aai/restclient/OneWaySSLRestClient.java76
-rw-r--r--aai-rest/src/main/java/org/onap/aai/restclient/PasswordDecoder.java25
-rw-r--r--aai-rest/src/main/java/org/onap/aai/restclient/PropertyPasswordConfiguration.java78
-rw-r--r--aai-rest/src/main/java/org/onap/aai/restclient/RestClient.java99
-rw-r--r--aai-rest/src/main/java/org/onap/aai/restclient/RestClientFactory.java35
-rw-r--r--aai-rest/src/main/java/org/onap/aai/restclient/RestClientFactoryConfiguration.java37
-rw-r--r--aai-rest/src/main/java/org/onap/aai/restclient/RestClientResponseErrorHandler.java59
-rw-r--r--aai-rest/src/main/java/org/onap/aai/restclient/TwoWaySSLRestClient.java91
-rw-r--r--aai-rest/src/test/java/org/onap/aai/restclient/RestClientTest.java24
13 files changed, 756 insertions, 0 deletions
diff --git a/aai-rest/LICENSE.TXT b/aai-rest/LICENSE.TXT
new file mode 100644
index 00000000..34558621
--- /dev/null
+++ b/aai-rest/LICENSE.TXT
@@ -0,0 +1,17 @@
+============LICENSE_START=======================================================
+org.onap.aai
+================================================================================
+Copyright © 2017-2018 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.
+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.
+============LICENSE_END=========================================================
diff --git a/aai-rest/pom.xml b/aai-rest/pom.xml
new file mode 100644
index 00000000..9822061a
--- /dev/null
+++ b/aai-rest/pom.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ Copyright © 2017 Amdocs
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.aai.aai-common</groupId>
+ <artifactId>aai-common</artifactId>
+ <version>1.4.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>aai-rest</artifactId>
+ <name>aai-rest</name>
+ <version>1.4.1-SNAPSHOT</version>
+
+ <properties>
+ <onap.nexus.url>https://nexus.onap.org</onap.nexus.url>
+ <eelf.core.version>1.0.0</eelf.core.version>
+ <spring.boot.starter.web.version>1.5.15.RELEASE</spring.boot.starter.web.version>
+ <spring.boot.starter.parent.version>1.5.15.RELEASE</spring.boot.starter.parent.version>
+ <spring.security.version>1.0.3.RELEASE</spring.security.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-parent</artifactId>
+ <version>${spring.boot.starter.parent.version}</version>
+ <scope>import</scope>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.att.eelf</groupId>
+ <artifactId>eelf-core</artifactId>
+ <version>${eelf.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ <version>${spring.boot.starter.web.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-tomcat</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>log4j-over-slf4j</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-jetty</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-jersey</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ <version>2.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.5.1</version>
+ </dependency>
+ <!--
+ Explicitly stating the security spring framework and
+ exclude the bouncy castle since that is somehow overwriting
+ our p12 file decryption that's built into java security
+ This will cause the password is incorrect
+ This needs to be added back if org.bouncy castle dependency
+ sneaks backs in and causing issues with the two way ssl
+ -->
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-rsa</artifactId>
+ <version>${spring.security.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcpkix-jdk15on</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-test</artifactId>
+ <version>1.5.1.RELEASE</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/aai-rest/src/main/java/org/onap/aai/restclient/JettyPasswordDecoder.java b/aai-rest/src/main/java/org/onap/aai/restclient/JettyPasswordDecoder.java
new file mode 100644
index 00000000..552aef96
--- /dev/null
+++ b/aai-rest/src/main/java/org/onap/aai/restclient/JettyPasswordDecoder.java
@@ -0,0 +1,33 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.restclient;
+
+import org.eclipse.jetty.util.security.Password;
+
+public class JettyPasswordDecoder implements PasswordDecoder {
+
+ @Override
+ public String decode(String input) {
+ if (input.startsWith("OBF:")) {
+ return Password.deobfuscate(input);
+ }
+ return Password.deobfuscate("OBF:" + input);
+ }
+}
diff --git a/aai-rest/src/main/java/org/onap/aai/restclient/NoAuthRestClient.java b/aai-rest/src/main/java/org/onap/aai/restclient/NoAuthRestClient.java
new file mode 100644
index 00000000..7e3524d7
--- /dev/null
+++ b/aai-rest/src/main/java/org/onap/aai/restclient/NoAuthRestClient.java
@@ -0,0 +1,53 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.restclient;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.PostConstruct;
+
+public abstract class NoAuthRestClient extends RestClient{
+
+ private static EELFLogger logger = EELFManager.getInstance().getLogger(NoAuthRestClient.class);
+
+ protected RestTemplate restTemplate;
+
+ @PostConstruct
+ public void init () throws Exception {
+ HttpClient client = HttpClients.createDefault();
+ restTemplate = new RestTemplateBuilder()
+ .requestFactory(new HttpComponentsClientHttpRequestFactory(client))
+ .build();
+
+ restTemplate.setErrorHandler(new RestClientResponseErrorHandler(getLogger()));
+ }
+
+ @Override
+ public RestTemplate getRestTemplate() {
+ return restTemplate;
+ }
+
+}
diff --git a/aai-rest/src/main/java/org/onap/aai/restclient/OneWaySSLRestClient.java b/aai-rest/src/main/java/org/onap/aai/restclient/OneWaySSLRestClient.java
new file mode 100644
index 00000000..e502e5e5
--- /dev/null
+++ b/aai-rest/src/main/java/org/onap/aai/restclient/OneWaySSLRestClient.java
@@ -0,0 +1,76 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.restclient;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.util.ResourceUtils;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.PostConstruct;
+import javax.net.ssl.SSLContext;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.KeyStore;
+
+public abstract class OneWaySSLRestClient extends RestClient {
+
+ private RestTemplate restTemplate;
+
+ @PostConstruct
+ public void init() throws Exception {
+
+ char[] trustStorePassword = getTruststorePassword();
+
+ String trustStore = getTruststorePath();
+
+ SSLContext sslContext = SSLContextBuilder
+ .create()
+ .loadTrustMaterial(ResourceUtils.getFile(trustStore), trustStorePassword)
+ .build();
+
+ HttpClient client = HttpClients.custom()
+ .setSSLContext(sslContext)
+ .setSSLHostnameVerifier((s, sslSession) -> true)
+ .build();
+
+ restTemplate = new RestTemplateBuilder()
+ .requestFactory(new HttpComponentsClientHttpRequestFactory(client))
+ .build();
+
+ restTemplate.setErrorHandler(new RestClientResponseErrorHandler(getLogger()));
+
+ }
+
+
+ protected abstract String getTruststorePath();
+
+ protected abstract char[] getTruststorePassword();
+
+ @Override
+ public RestTemplate getRestTemplate() {
+ return restTemplate;
+ }
+
+}
diff --git a/aai-rest/src/main/java/org/onap/aai/restclient/PasswordDecoder.java b/aai-rest/src/main/java/org/onap/aai/restclient/PasswordDecoder.java
new file mode 100644
index 00000000..51c11181
--- /dev/null
+++ b/aai-rest/src/main/java/org/onap/aai/restclient/PasswordDecoder.java
@@ -0,0 +1,25 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.restclient;
+
+public interface PasswordDecoder {
+
+ String decode(String input);
+}
diff --git a/aai-rest/src/main/java/org/onap/aai/restclient/PropertyPasswordConfiguration.java b/aai-rest/src/main/java/org/onap/aai/restclient/PropertyPasswordConfiguration.java
new file mode 100644
index 00000000..97ae7bc6
--- /dev/null
+++ b/aai-rest/src/main/java/org/onap/aai/restclient/PropertyPasswordConfiguration.java
@@ -0,0 +1,78 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.restclient;
+
+import org.springframework.context.ApplicationContextInitializer;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.EnumerablePropertySource;
+import org.springframework.core.env.MapPropertySource;
+import org.springframework.core.env.PropertySource;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class PropertyPasswordConfiguration implements ApplicationContextInitializer<ConfigurableApplicationContext> {
+
+ private static final Pattern decodePasswordPattern = Pattern.compile("password\\((.*?)\\)");
+
+ private PasswordDecoder passwordDecoder = new JettyPasswordDecoder();
+
+ @Override
+ public void initialize(ConfigurableApplicationContext applicationContext) {
+ ConfigurableEnvironment environment = applicationContext.getEnvironment();
+ for (PropertySource<?> propertySource : environment.getPropertySources()) {
+ Map<String, Object> propertyOverrides = new LinkedHashMap<>();
+ decodePasswords(propertySource, propertyOverrides);
+ if (!propertyOverrides.isEmpty()) {
+ PropertySource<?> decodedProperties = new MapPropertySource("decoded " + propertySource.getName(), propertyOverrides);
+ environment.getPropertySources().addBefore(propertySource.getName(), decodedProperties);
+ }
+ }
+ }
+
+ private void decodePasswords(PropertySource<?> source, Map<String, Object> propertyOverrides) {
+ if (source instanceof EnumerablePropertySource) {
+ EnumerablePropertySource<?> enumerablePropertySource = (EnumerablePropertySource<?>) source;
+ for (String key : enumerablePropertySource.getPropertyNames()) {
+ Object rawValue = source.getProperty(key);
+ if (rawValue instanceof String) {
+ String decodedValue = decodePasswordsInString((String) rawValue);
+ propertyOverrides.put(key, decodedValue);
+ }
+ }
+ }
+ }
+
+ private String decodePasswordsInString(String input) {
+ if (input == null) return null;
+ StringBuffer output = new StringBuffer();
+ Matcher matcher = decodePasswordPattern.matcher(input);
+ while (matcher.find()) {
+ String replacement = passwordDecoder.decode(matcher.group(1));
+ matcher.appendReplacement(output, replacement);
+ }
+ matcher.appendTail(output);
+ return output.toString();
+ }
+
+}
diff --git a/aai-rest/src/main/java/org/onap/aai/restclient/RestClient.java b/aai-rest/src/main/java/org/onap/aai/restclient/RestClient.java
new file mode 100644
index 00000000..a17880f3
--- /dev/null
+++ b/aai-rest/src/main/java/org/onap/aai/restclient/RestClient.java
@@ -0,0 +1,99 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright © 2018 IBM.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.restclient;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.Map;
+
+public abstract class RestClient {
+
+ private static EELFLogger log = EELFManager.getInstance().getLogger(RestClient.class);
+ @Value("${spring.application.name}")
+ protected String appName;
+
+ public ResponseEntity execute(String uri, HttpMethod method, Map<String, String> headers, String body) throws RestClientException {
+
+ HttpEntity httpEntity;
+ log.debug("Headers: " + headers.toString());
+ if (body == null) {
+ httpEntity = new HttpEntity(getHeaders(headers));
+ } else {
+ httpEntity = new HttpEntity(body, getHeaders(headers));
+ }
+ String url = getBaseUrl() + uri;
+ return getRestTemplate().exchange(url, method, httpEntity, String.class);
+ }
+
+ public ResponseEntity executeResource(String uri, HttpMethod method, Map<String, String> headers, String body) throws RestClientException {
+
+ HttpEntity httpEntity;
+ log.debug("Headers: " + headers.toString());
+ if (body == null) {
+ httpEntity = new HttpEntity(getHeaders(headers));
+ } else {
+ httpEntity = new HttpEntity(body, getHeaders(headers));
+ }
+ String url = getBaseUrl() + uri;
+ return getRestTemplate().exchange(url, method, httpEntity, Resource.class);
+ }
+
+ public ResponseEntity execute(String uri, String method, Map<String, String> headers) throws RestClientException {
+ return execute(uri, HttpMethod.valueOf(method), headers, null);
+ }
+
+ public ResponseEntity getGetRequest(String content, String uri, Map<String, String> headersMap) {
+ return this.execute(
+ uri,
+ HttpMethod.GET,
+ headersMap,
+ content);
+
+ }
+
+ public ResponseEntity getGetResource(String content, String uri, Map<String, String> headersMap) {
+ return this.executeResource(
+ uri,
+ HttpMethod.GET,
+ headersMap,
+ content);
+
+ }
+
+ public abstract RestTemplate getRestTemplate();
+
+ public abstract String getBaseUrl();
+
+ protected abstract MultiValueMap<String, String> getHeaders(Map<String, String> headers);
+
+ protected abstract EELFLogger getLogger();
+
+}
diff --git a/aai-rest/src/main/java/org/onap/aai/restclient/RestClientFactory.java b/aai-rest/src/main/java/org/onap/aai/restclient/RestClientFactory.java
new file mode 100644
index 00000000..3a19f2de
--- /dev/null
+++ b/aai-rest/src/main/java/org/onap/aai/restclient/RestClientFactory.java
@@ -0,0 +1,35 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.restclient;
+
+/**
+ * Factory to get parser strategy based on rest client type.
+ */
+public interface RestClientFactory {
+
+ /**
+ *
+ * @param clientType
+ * type of client to return
+ * @return
+ */
+ RestClient getRestClient(String clientType);
+
+}
diff --git a/aai-rest/src/main/java/org/onap/aai/restclient/RestClientFactoryConfiguration.java b/aai-rest/src/main/java/org/onap/aai/restclient/RestClientFactoryConfiguration.java
new file mode 100644
index 00000000..08060238
--- /dev/null
+++ b/aai-rest/src/main/java/org/onap/aai/restclient/RestClientFactoryConfiguration.java
@@ -0,0 +1,37 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.restclient;
+
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.config.ServiceLocatorFactoryBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class RestClientFactoryConfiguration {
+
+ @Bean
+ public FactoryBean restClientFactoryBean() {
+ ServiceLocatorFactoryBean factoryBean = new ServiceLocatorFactoryBean();
+ factoryBean.setServiceLocatorInterface(RestClientFactory.class);
+ return factoryBean;
+ }
+}
diff --git a/aai-rest/src/main/java/org/onap/aai/restclient/RestClientResponseErrorHandler.java b/aai-rest/src/main/java/org/onap/aai/restclient/RestClientResponseErrorHandler.java
new file mode 100644
index 00000000..1d6486b0
--- /dev/null
+++ b/aai-rest/src/main/java/org/onap/aai/restclient/RestClientResponseErrorHandler.java
@@ -0,0 +1,59 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.restclient;
+
+import com.att.eelf.configuration.EELFLogger;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.web.client.ResponseErrorHandler;
+
+import java.io.IOException;
+
+public class RestClientResponseErrorHandler implements ResponseErrorHandler {
+
+ private EELFLogger logger;
+
+ public RestClientResponseErrorHandler(EELFLogger logger) {
+ this.logger = logger;
+ }
+
+ @Override
+ public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
+ if (!clientHttpResponse.getStatusCode().is2xxSuccessful()) {
+
+ logger.debug("Status code: " + clientHttpResponse.getStatusCode());
+
+ if (clientHttpResponse.getStatusCode() == HttpStatus.FORBIDDEN) {
+ logger.debug("Call returned a error 403 forbidden resposne ");
+ return true;
+ }
+
+ if (clientHttpResponse.getRawStatusCode() % 100 == 5) {
+ logger.debug("Call returned a error " + clientHttpResponse.getStatusText());
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
+ }
+}
diff --git a/aai-rest/src/main/java/org/onap/aai/restclient/TwoWaySSLRestClient.java b/aai-rest/src/main/java/org/onap/aai/restclient/TwoWaySSLRestClient.java
new file mode 100644
index 00000000..2fe9500f
--- /dev/null
+++ b/aai-rest/src/main/java/org/onap/aai/restclient/TwoWaySSLRestClient.java
@@ -0,0 +1,91 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.restclient;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.util.ResourceUtils;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.PostConstruct;
+import javax.net.ssl.SSLContext;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.KeyStore;
+
+public abstract class TwoWaySSLRestClient extends RestClient {
+
+ private RestTemplate restTemplate;
+
+ @PostConstruct
+ public void init() throws Exception {
+
+ char[] keyStorePassword = getKeystorePassword();
+ char[] trustStorePassword = getTruststorePassword();
+
+ String keyStore = getKeystorePath();
+ String trustStore = getTruststorePath();
+
+ SSLContext sslContext = SSLContextBuilder
+ .create()
+ .loadKeyMaterial(loadPfx(keyStore, keyStorePassword), keyStorePassword)
+ .loadTrustMaterial(ResourceUtils.getFile(trustStore), trustStorePassword)
+ .build();
+
+ HttpClient client = HttpClients.custom()
+ .setSSLContext(sslContext)
+ .setSSLHostnameVerifier((s, sslSession) -> true)
+ .build();
+
+ restTemplate = new RestTemplateBuilder()
+ .requestFactory(new HttpComponentsClientHttpRequestFactory(client))
+ .build();
+
+ restTemplate.setErrorHandler(new RestClientResponseErrorHandler(getLogger()));
+
+ }
+
+ private KeyStore loadPfx(String file, char[] password) throws Exception {
+ KeyStore keyStore = KeyStore.getInstance("PKCS12");
+ File key = ResourceUtils.getFile(file);
+ try (InputStream in = new FileInputStream(key)) {
+ keyStore.load(in, password);
+ }
+ return keyStore;
+ }
+
+ protected abstract String getKeystorePath();
+
+ protected abstract String getTruststorePath();
+
+ protected abstract char[] getTruststorePassword();
+
+ protected abstract char[] getKeystorePassword();
+
+ @Override
+ public RestTemplate getRestTemplate() {
+ return restTemplate;
+ }
+
+}
diff --git a/aai-rest/src/test/java/org/onap/aai/restclient/RestClientTest.java b/aai-rest/src/test/java/org/onap/aai/restclient/RestClientTest.java
new file mode 100644
index 00000000..4c3b0fcf
--- /dev/null
+++ b/aai-rest/src/test/java/org/onap/aai/restclient/RestClientTest.java
@@ -0,0 +1,24 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.restclient;
+
+public class RestClientTest {
+
+}