diff options
Diffstat (limited to 'aai-rest/src/main/java')
10 files changed, 586 insertions, 0 deletions
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; + } + +} |