Refactor SOL003 Adapter to organize its modules

based on functions

Change-Id: I10b2376a552272ac3b405b2dae718adcb7e1e489
Issue-ID: SO-2771
Signed-off-by: waqas.ikram <waqas.ikram@est.tech>
diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/pom.xml b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/pom.xml
new file mode 100644
index 0000000..9c88f6a
--- /dev/null
+++ b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/pom.xml
@@ -0,0 +1,24 @@
+<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.so.adapters</groupId>
+    <artifactId>etsi-sol003-adapter</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>etsi-sol003-adapter-common</artifactId>
+  <name>ETSI SOL003 Adapter Common</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.springframework.security.oauth</groupId>
+      <artifactId>spring-security-oauth2</artifactId>
+      <version>${spring-security-oauth2-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.onap.so</groupId>
+      <artifactId>common</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/common/CommonConstants.java b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/common/CommonConstants.java
new file mode 100644
index 0000000..963bd51
--- /dev/null
+++ b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/common/CommonConstants.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.common;
+
+/**
+ * VNFM Adapter Common constants
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ * @author Gareth Roper (gareth.roper@est.tech)
+ */
+public class CommonConstants {
+
+    public static final String SERVICE_NAME = "vnfm-adapter";
+    public static final String SERVICE_VERSION = "v1";
+    public static final String BASE_URL = "/so/" + SERVICE_NAME + "/" + SERVICE_VERSION;
+
+    public static final String PACKAGE_MANAGEMENT_BASE_URL = BASE_URL + "/vnfpkgm/v1";
+
+    public static final String ETSI_CATALOG_MANAGER_BASE_ENDPOINT = "/etsicatalogmanager";
+    public static final String ETSI_SUBSCRIPTION_NOTIFICATION_ENDPOINT = "/notification";
+    public static final String ETSI_SUBSCRIPTION_NOTIFICATION_CONTROLLER_BASE_URL =
+            BASE_URL + ETSI_CATALOG_MANAGER_BASE_ENDPOINT;
+    public static final String ETSI_SUBSCRIPTION_NOTIFICATION_BASE_URL =
+            ETSI_SUBSCRIPTION_NOTIFICATION_CONTROLLER_BASE_URL + ETSI_SUBSCRIPTION_NOTIFICATION_ENDPOINT;
+
+    public static final String OPERATION_NOTIFICATION_ENDPOINT = "/lcn/VnfLcmOperationOccurrenceNotification";
+
+    private CommonConstants() {}
+}
diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/common/VnfmAdapterUrlProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/common/VnfmAdapterUrlProvider.java
new file mode 100644
index 0000000..99611ad
--- /dev/null
+++ b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/common/VnfmAdapterUrlProvider.java
@@ -0,0 +1,105 @@
+/*-
+ * ============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.common;
+
+import static org.onap.so.adapters.vnfmadapter.common.CommonConstants.BASE_URL;
+import static org.onap.so.adapters.vnfmadapter.common.CommonConstants.ETSI_SUBSCRIPTION_NOTIFICATION_BASE_URL;
+import static org.onap.so.adapters.vnfmadapter.common.CommonConstants.OPERATION_NOTIFICATION_ENDPOINT;
+import static org.onap.so.adapters.vnfmadapter.common.CommonConstants.PACKAGE_MANAGEMENT_BASE_URL;
+import static org.slf4j.LoggerFactory.getLogger;
+import java.net.URI;
+import java.security.GeneralSecurityException;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.onap.so.utils.CryptoUtils;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+
+/**
+ * Provides VNFM Adapter endpoint URLs
+ * 
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Configuration
+public class VnfmAdapterUrlProvider {
+
+    private static final Logger logger = getLogger(VnfmAdapterUrlProvider.class);
+    private static final String COLON = ":";
+    private static final int LIMIT = 2;
+
+    private final String vnfmAdapterEndpoint;
+    private final String msoKeyString;
+    private final String vnfmAdapterAuth;
+
+    @Autowired
+    public VnfmAdapterUrlProvider(@Value("${vnfmadapter.endpoint}") final String vnfmAdapterEndpoint,
+            @Value("${mso.key}") final String msoKeyString,
+            @Value("${vnfmadapter.auth:BF29BA36F0CFE1C05507781F6B97EFBCA7EFAC9F595954D465FC43F646883EF585C20A58CBB02528A6FAAC}") final String vnfmAdapterAuth) {
+        this.vnfmAdapterEndpoint = vnfmAdapterEndpoint;
+        this.msoKeyString = msoKeyString;
+        this.vnfmAdapterAuth = vnfmAdapterAuth;
+    }
+
+    public String getEtsiSubscriptionNotificationBaseUrl() {
+        return vnfmAdapterEndpoint + ETSI_SUBSCRIPTION_NOTIFICATION_BASE_URL;
+    }
+
+    public URI getSubscriptionUri(final String subscriptionId) {
+        return URI.create(getSubscriptionUriString(subscriptionId));
+    }
+
+    public ImmutablePair<String, String> getDecryptAuth() throws GeneralSecurityException {
+        final String decryptedAuth = CryptoUtils.decrypt(vnfmAdapterAuth, msoKeyString);
+        final String[] auth = decryptedAuth.split(COLON, LIMIT);
+        if (auth.length > 1) {
+            return ImmutablePair.of(auth[0], auth[1]);
+        }
+        logger.error("Unexpected auth value: {}", vnfmAdapterAuth);
+        return ImmutablePair.nullPair();
+    }
+
+    public String getSubscriptionUriString(final String subscriptionId) {
+        return vnfmAdapterEndpoint + PACKAGE_MANAGEMENT_BASE_URL + "/subscriptions/" + subscriptionId;
+    }
+
+    public String getVnfLcmOperationOccurrenceNotificationUrl() {
+        return vnfmAdapterEndpoint + BASE_URL + OPERATION_NOTIFICATION_ENDPOINT;
+    }
+
+    public String getVnfPackageUrl(final String vnfPkgId) {
+        return vnfmAdapterEndpoint + PACKAGE_MANAGEMENT_BASE_URL + "/vnf_packages/" + vnfPkgId;
+    }
+
+    public String getVnfPackageVnfdUrl(final String vnfPkgId) {
+        return getVnfPackageUrl(vnfPkgId) + "/vnfd";
+    }
+
+    public String getVnfPackageContentUrl(final String vnfPkgId) {
+        return getVnfPackageUrl(vnfPkgId) + "/package_content";
+    }
+
+    public String getOauthTokenUrl() {
+        return vnfmAdapterEndpoint + "/oauth/token";
+    }
+
+}
diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/common/configuration/MessageConverterConfiguration.java b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/common/configuration/MessageConverterConfiguration.java
new file mode 100644
index 0000000..6f3e0da
--- /dev/null
+++ b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/common/configuration/MessageConverterConfiguration.java
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.common.configuration;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import org.onap.so.adapters.vnfmadapter.oauth.OAuth2AccessTokenAdapter;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.GsonHttpMessageConverter;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * Configures message converter
+ */
+@Configuration
+public class MessageConverterConfiguration {
+
+    @Bean
+    public HttpMessageConverters customConverters() {
+        final Collection<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
+        final Gson gson = new GsonBuilder()
+                .registerTypeHierarchyAdapter(OAuth2AccessToken.class, new OAuth2AccessTokenAdapter()).create();
+        final GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter(gson);
+        messageConverters.add(gsonHttpMessageConverter);
+        return new HttpMessageConverters(true, messageConverters);
+    }
+}
diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/AuthorizationServerConfig.java b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/AuthorizationServerConfig.java
new file mode 100644
index 0000000..83534ff
--- /dev/null
+++ b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/AuthorizationServerConfig.java
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.oauth;
+
+import org.onap.so.utils.CryptoUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
+
+@Configuration
+@EnableAuthorizationServer
+/**
+ * Configures the authorization server for oauth token based authentication.
+ */
+public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
+
+    private static final int ONE_DAY = 60 * 60 * 24;
+
+    @Value("${vnfmadapter.auth:E39823AAB2739CC654C4E92B52C05BC34149342D0A46451B00CA508C8EDC62242CE4E9DA9445D3C01A3F13}")
+    private String vnfmAdapterAuth;
+
+    @Value("${mso.key}")
+    private String msoEncryptionKey;
+
+    @Override
+    public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
+        final String[] decrypedAuth = CryptoUtils.decrypt(vnfmAdapterAuth, msoEncryptionKey).split(":");
+        final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
+        clients.inMemory().withClient(decrypedAuth[0]).secret(passwordEncoder.encode(decrypedAuth[1]))
+                .authorizedGrantTypes("client_credentials").scopes("write").accessTokenValiditySeconds(ONE_DAY)
+                .refreshTokenValiditySeconds(ONE_DAY);
+    }
+
+}
diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/OAuth2AccessTokenAdapter.java b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/OAuth2AccessTokenAdapter.java
new file mode 100644
index 0000000..2f51406
--- /dev/null
+++ b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/OAuth2AccessTokenAdapter.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.oauth;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import java.lang.reflect.Type;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+
+public class OAuth2AccessTokenAdapter implements JsonSerializer<OAuth2AccessToken> {
+
+    @Override
+    public JsonElement serialize(final OAuth2AccessToken src, final Type typeOfSrc,
+            final JsonSerializationContext context) {
+        final JsonObject obj = new JsonObject();
+        obj.addProperty(OAuth2AccessToken.ACCESS_TOKEN, src.getValue());
+        obj.addProperty(OAuth2AccessToken.TOKEN_TYPE, src.getTokenType());
+        if (src.getRefreshToken() != null) {
+            obj.addProperty(OAuth2AccessToken.REFRESH_TOKEN, src.getRefreshToken().getValue());
+        }
+        obj.addProperty(OAuth2AccessToken.EXPIRES_IN, src.getExpiresIn());
+        final JsonArray scopeObj = new JsonArray();
+        for (final String scope : src.getScope()) {
+            scopeObj.add(scope);
+        }
+        obj.add(OAuth2AccessToken.SCOPE, scopeObj);
+
+        return obj;
+    }
+}
diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/OAuth2ResourceServer.java b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/OAuth2ResourceServer.java
new file mode 100644
index 0000000..9c871db
--- /dev/null
+++ b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-common/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/OAuth2ResourceServer.java
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.oauth;
+
+import javax.servlet.http.HttpServletRequest;
+import org.onap.so.adapters.vnfmadapter.common.CommonConstants;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+import org.springframework.security.web.util.matcher.RequestMatcher;
+
+@Configuration
+@EnableResourceServer
+/**
+ * Enforces oauth token based authentication when a token is provided in the request.
+ */
+public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {
+
+    @Override
+    public void configure(final HttpSecurity http) throws Exception {
+        http.requestMatcher(new OAuth2ResourceServerRequestMatcher()).authorizeRequests()
+                .antMatchers(CommonConstants.BASE_URL + "/grants/**", CommonConstants.BASE_URL + "/lcn/**")
+                .authenticated();
+    }
+
+    private static class OAuth2ResourceServerRequestMatcher implements RequestMatcher {
+        @Override
+        public boolean matches(HttpServletRequest request) {
+            String auth = request.getHeader("Authorization");
+            String uri = request.getRequestURI();
+            return (auth != null && auth.startsWith("Bearer") && (uri.contains("/grants") || uri.contains("/lcn/")));
+        }
+    }
+}