Adding common classes for workflows 80/132980/1
authorwaqas.ikram <waqas.ikram@est.tech>
Mon, 23 Jan 2023 11:58:29 +0000 (11:58 +0000)
committerwaqas.ikram <waqas.ikram@est.tech>
Mon, 23 Jan 2023 11:58:40 +0000 (11:58 +0000)
Change-Id: Id86256ee21ee8c78da82ae3141f7936191593597
Issue-ID: SO-4068
Signed-off-by: waqas.ikram <waqas.ikram@est.tech>
44 files changed:
pom.xml
so-cnfm/so-cnfm-lcm/pom.xml
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/pom.xml [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaCustomConfiguration.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaDatabaseConfiguration.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaVariableNameConstants.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/Constants.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/GsonProvider.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/AsRequestProcessingException.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/BasicAuthConfigException.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/FileNotFoundInCsarException.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/PropertyNotFoundException.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/SdcPackageRequestFailureException.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/kubernetes/KubernetesResource.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/DeploymentItem.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcClientConfigurationProvider.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPackageParser.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPropertiesConstants.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcHttpRestServiceProviderConfiguration.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcPackageProvider.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcPackageProviderImpl.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/JobExecutorService.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/WorkflowExecutorService.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/WorkflowQueryService.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/OffsetDateTimeTypeAdapter.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/PropertiesToYamlConverter.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/META-INF/services/org.onap.so.client.RestProperties [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPackageParserTest.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapterTest.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/OffsetDateTimeTypeAdapterTest.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/PropertiesToYamlConverterTest.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/application.yaml [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/request.json [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/resource-Generatedasdpackage-csar.csar [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/beans/AsLifecycleParam.java
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/beans/utils/Utils.java
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/config/CnfmDatabaseConfiguration.java
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/test/java/org/onap/so/cnfm/lcm/database/beans/utils/UtilsTest.java
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/test/java/org/onap/so/cnfm/lcm/database/service/DatabaseServiceProviderTest.java

diff --git a/pom.xml b/pom.xml
index ffb9e8f..5f0dcce 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -22,6 +22,9 @@
         <version-swagger-codegen-v3>3.0.33</version-swagger-codegen-v3>
         <so-core-version>1.9.0-SNAPSHOT</so-core-version>
         <equalsverifier-version>3.4.1</equalsverifier-version>
+        <snakeyaml-version>0.11</snakeyaml-version>
+        <kubernetes-client-version>16.0.0</kubernetes-client-version>
+        <kotlin-stdlib-version>1.3.70</kotlin-stdlib-version>
     </properties>
 
     <build>
index 4d6df9e..ad758d1 100644 (file)
@@ -14,5 +14,6 @@
     <modules>
         <module>so-cnfm-lcm-api</module>
         <module>so-cnfm-lcm-database-service</module>
+        <module>so-cnfm-lcm-bpmn-flows</module>
     </modules>
 </project>
\ No newline at end of file
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/pom.xml b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/pom.xml
new file mode 100644 (file)
index 0000000..3982680
--- /dev/null
@@ -0,0 +1,145 @@
+<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.so.adapters.so-cnf-adapter.so-cnfm.lcm</groupId>
+        <artifactId>so-cnfm-lcm</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>so-cnfm-lcm-bpmn-flows</artifactId>
+    <name>SO CNFM LCM BPMN Flows</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <systemPropertyVariables>
+                        <so.log.level>DEBUG</so.log.level>
+                    </systemPropertyVariables>
+                    <rerunFailingTestsCount>2</rerunFailingTestsCount>
+                    <parallel>suites</parallel>
+                    <useUnlimitedThreads>false</useUnlimitedThreads>
+                    <threadCount>1</threadCount>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.so.adapters.so-cnf-adapter.so-cnfm.lcm</groupId>
+            <artifactId>so-cnfm-lcm-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.so.adapters.so-cnf-adapter.so-cnfm.lcm</groupId>
+            <artifactId>so-cnfm-lcm-database-service</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.so</groupId>
+            <artifactId>aai-client</artifactId>
+            <version>${so-core-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.aai.schema-service</groupId>
+            <artifactId>aai-schema</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.camunda.bpm.springboot</groupId>
+            <artifactId>camunda-bpm-spring-boot-starter-rest</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.camunda.bpmn</groupId>
+                    <artifactId>camunda-engine-rest-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.yaml</groupId>
+            <artifactId>snakeyaml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.shazam</groupId>
+            <artifactId>shazamcrest</artifactId>
+            <version>${snakeyaml-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.commons</groupId>
+                    <artifactId>commons-lang3</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.vaadin.external.google</groupId>
+                    <artifactId>android-json</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>nl.jqno.equalsverifier</groupId>
+            <artifactId>equalsverifier</artifactId>
+            <version>${equalsverifier-version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-contract-wiremock</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.so</groupId>
+            <artifactId>common</artifactId>
+            <version>${so-core-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>log4j</groupId>
+                    <artifactId>log4j</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.tomcat</groupId>
+                    <artifactId>tomcat-catalina</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>io.kubernetes</groupId>
+            <artifactId>client-java</artifactId>
+            <version>${kubernetes-client-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.jetbrains.kotlin</groupId>
+                    <artifactId>kotlin-stdlib-common</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-stdlib</artifactId>
+            <version>${kotlin-stdlib-version}</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaCustomConfiguration.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaCustomConfiguration.java
new file mode 100644 (file)
index 0000000..765d25b
--- /dev/null
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows;
+
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.AS_WORKFLOW_ENGINE;
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.TENANT_ID;
+import static org.slf4j.LoggerFactory.getLogger;
+import org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration;
+import org.camunda.bpm.spring.boot.starter.configuration.Ordering;
+import org.camunda.bpm.spring.boot.starter.configuration.impl.AbstractCamundaConfiguration;
+import org.slf4j.Logger;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+@Order(Ordering.DEFAULT_ORDER + 1)
+public class CamundaCustomConfiguration extends AbstractCamundaConfiguration {
+    private static final Logger logger = getLogger(CamundaCustomConfiguration.class);
+
+    @Override
+    public void preInit(final SpringProcessEngineConfiguration processEngineConfiguration) {
+        logger.info("Setting DeploymentTenantId to {} and DeploymentName to {}", TENANT_ID, AS_WORKFLOW_ENGINE);
+        processEngineConfiguration.setDeploymentTenantId(TENANT_ID);
+        processEngineConfiguration.setDeploymentName(AS_WORKFLOW_ENGINE);
+        super.preInit(processEngineConfiguration);
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaDatabaseConfiguration.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaDatabaseConfiguration.java
new file mode 100644 (file)
index 0000000..cc8bb01
--- /dev/null
@@ -0,0 +1,89 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows;
+
+
+import static org.slf4j.LoggerFactory.getLogger;
+import javax.sql.DataSource;
+import org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration;
+import org.camunda.bpm.spring.boot.starter.util.SpringBootProcessEnginePlugin;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.jmx.export.MBeanExporter;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Configuration
+@EnableTransactionManagement
+public class CamundaDatabaseConfiguration {
+
+    private static final String CAMUNDA_TRANSACTION_MANAGER_BEAN_NAME = "camundaTransactionManager";
+
+    private static final String CAMUNDA_DATA_SOURCE_BEAN_NAME = "camundaBpmDataSource";
+
+    private static final Logger logger = getLogger(CamundaDatabaseConfiguration.class);
+
+    @Bean
+    @ConfigurationProperties(prefix = "spring.datasource.hikari.camunda")
+    public HikariConfig camundaDbConfig() {
+        logger.debug("Creating Camunda HikariConfig bean ... ");
+        return new HikariConfig();
+    }
+
+    @Bean(name = CAMUNDA_DATA_SOURCE_BEAN_NAME)
+    public DataSource camundaDataSource(@Autowired(required = false) final MBeanExporter mBeanExporter) {
+        if (mBeanExporter != null) {
+            mBeanExporter.addExcludedBean(CAMUNDA_DATA_SOURCE_BEAN_NAME);
+        }
+        logger.debug("Creating Camunda HikariDataSource bean ... ");
+        final HikariConfig hikariConfig = this.camundaDbConfig();
+        return new HikariDataSource(hikariConfig);
+    }
+
+    @Bean(name = CAMUNDA_TRANSACTION_MANAGER_BEAN_NAME)
+    public PlatformTransactionManager camundaTransactionManager(
+            @Qualifier(CAMUNDA_DATA_SOURCE_BEAN_NAME) final DataSource dataSource) {
+        return new DataSourceTransactionManager(dataSource);
+    }
+
+    @Bean
+    public SpringBootProcessEnginePlugin transactionManagerProcessEnginePlugin(
+            @Qualifier(CAMUNDA_TRANSACTION_MANAGER_BEAN_NAME) final PlatformTransactionManager camundaTransactionManager) {
+        return new SpringBootProcessEnginePlugin() {
+            @Override
+            public void preInit(final SpringProcessEngineConfiguration processEngineConfiguration) {
+                logger.info("Setting Camunda TransactionManager ...");
+                processEngineConfiguration.setTransactionManager(camundaTransactionManager);
+
+            }
+        };
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaVariableNameConstants.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaVariableNameConstants.java
new file mode 100644 (file)
index 0000000..47c5795
--- /dev/null
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class CamundaVariableNameConstants {
+
+    public static final String AS_DEPLOYMENT_ITEM_INST_ID_PARAM_NAME = "asDeploymentItemInstId";
+    public static final String KUBE_KINDS_RESULT_PARAM_NAME = "kubeKindsResult";
+    public static final String KUBE_CONFIG_FILE_PATH_PARAM_NAME = "kubeConfigFilePath";
+    public static final String KUBE_KINDS_PARAM_NAME = "kubeKinds";
+    public static final String KIND_PARAM_NAME = "kind";
+    public static final String RELEASE_NAME_PARAM_NAME = "releaseName";
+    public static final String JOB_ID_PARAM_NAME = "jobId";
+    public static final String JOB_BUSINESS_KEY_PARAM_NAME = "jobBusinessKey";
+    public static final String CREATE_AS_REQUEST_PARAM_NAME = "createAsRequest";
+
+    public static final String AS_PACKAGE_MODEL_PARAM_NAME = "AsPackageModel";
+    public static final String AS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME = "AsWorkflowProcessingException";
+    public static final String CREATE_AS_RESPONSE_PARAM_NAME = "createAsResponse";
+
+    public static final String INSTANTIATE_AS_REQUEST_PARAM_NAME = "instantiateAsRequest";
+    public static final String AS_INSTANCE_ID_PARAM_NAME = "AsInstanceId";
+    public static final String OCC_ID_PARAM_NAME = "occId";
+
+    public static final String DEPLOYMENT_ITEM_INSTANTIATE_REQUESTS = "deploymentItemInstantiateRequests";
+    public static final String DEPLOYMENT_ITEM_TERMINATE_REQUESTS = "deploymentItemTerminateRequests";
+
+    public static final String TERMINATE_AS_REQUEST_PARAM_NAME = "terminateAsRequest";
+
+    private CamundaVariableNameConstants() {}
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/Constants.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/Constants.java
new file mode 100644 (file)
index 0000000..45c36be
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class Constants {
+
+    public static final String TENANT_ID = "as-workflow-engine-tenant";
+    public static final String AS_WORKFLOW_ENGINE = "AS-WORKFLOW-ENGINE";
+    public static final String CREATE_AS_WORKFLOW_NAME = "CreateAs";
+    public static final String INSTANTIATE_AS_WORKFLOW_NAME = "InstantiateAs";
+    public static final String TERMINATE_AS_WORKFLOW_NAME = "TerminateAs";
+    public static final String DELETE_AS_WORKFLOW_NAME = "DeleteAs";
+
+    public static final String KIND_STATEFUL_SET = "StatefulSet";
+    public static final String KIND_DAEMON_SET = "DaemonSet";
+    public static final String KIND_REPLICA_SET = "ReplicaSet";
+    public static final String KIND_DEPLOYMENT = "Deployment";
+    public static final String KIND_SERVICE = "Service";
+    public static final String KIND_POD = "Pod";
+    public static final String KIND_JOB = "Job";
+
+    private Constants() {}
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/GsonProvider.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/GsonProvider.java
new file mode 100644 (file)
index 0000000..486c528
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows;
+
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import org.onap.so.cnfm.lcm.bpmn.flows.utils.LocalDateTimeTypeAdapter;
+import org.onap.so.cnfm.lcm.bpmn.flows.utils.OffsetDateTimeTypeAdapter;
+import org.springframework.stereotype.Component;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+public class GsonProvider {
+
+    private final OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
+
+    public Gson getGson() {
+        return new GsonBuilder().registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter)
+                .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()).create();
+    }
+
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/AsRequestProcessingException.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/AsRequestProcessingException.java
new file mode 100644 (file)
index 0000000..991c3c3
--- /dev/null
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.exceptions;
+
+import org.onap.so.cnfm.lcm.model.ErrorDetails;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+/**
+ * 
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ */
+@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
+public class AsRequestProcessingException extends RuntimeException {
+
+    private static final long serialVersionUID = 66862444537194516L;
+    private final ErrorDetails errorDetails;
+
+    public AsRequestProcessingException(final String message) {
+        super(message);
+        errorDetails = null;
+    }
+
+    public AsRequestProcessingException(final String message, final ErrorDetails errorContents) {
+        super(message);
+        this.errorDetails = errorContents;
+    }
+
+    @Override
+    public synchronized Throwable fillInStackTrace() {
+        return this;
+    }
+
+    public ErrorDetails getErrorDetails() {
+        return errorDetails;
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/BasicAuthConfigException.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/BasicAuthConfigException.java
new file mode 100644 (file)
index 0000000..4b9bfb1
--- /dev/null
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.exceptions;
+
+/**
+ * 
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ */
+public class BasicAuthConfigException extends RuntimeException {
+
+    private static final long serialVersionUID = -6317913344782441364L;
+
+    public BasicAuthConfigException(final String message) {
+        super(message);
+    }
+
+    public BasicAuthConfigException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/FileNotFoundInCsarException.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/FileNotFoundInCsarException.java
new file mode 100644 (file)
index 0000000..4bad50c
--- /dev/null
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.exceptions;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class FileNotFoundInCsarException extends RuntimeException {
+
+    private static final long serialVersionUID = -3294117029811603499L;
+
+    public FileNotFoundInCsarException(final String message) {
+        super(message);
+    }
+
+    public FileNotFoundInCsarException(final String message, final Throwable cause) {
+        super(message);
+    }
+
+    @Override
+    public synchronized Throwable fillInStackTrace() {
+        return this;
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/PropertyNotFoundException.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/PropertyNotFoundException.java
new file mode 100644 (file)
index 0000000..908a04d
--- /dev/null
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.exceptions;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class PropertyNotFoundException extends RuntimeException {
+
+    private static final long serialVersionUID = 684205374040870233L;
+
+    public PropertyNotFoundException(final String message) {
+        super(message);
+    }
+
+    public PropertyNotFoundException(final String message, final Throwable cause) {
+        super(message);
+    }
+
+    @Override
+    public synchronized Throwable fillInStackTrace() {
+        return this;
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/SdcPackageRequestFailureException.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/SdcPackageRequestFailureException.java
new file mode 100644 (file)
index 0000000..d33c51f
--- /dev/null
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.exceptions;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
+public class SdcPackageRequestFailureException extends RuntimeException {
+
+    private static final long serialVersionUID = 5816306976965772635L;
+
+    public SdcPackageRequestFailureException(final String message) {
+        super(message);
+    }
+
+    public SdcPackageRequestFailureException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java
new file mode 100644 (file)
index 0000000..aceafe7
--- /dev/null
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.aai;
+
+import org.onap.aaiclient.client.aai.AAIResourcesClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AaiClientProvider {
+
+    @Bean
+    public AAIResourcesClient getAaiClient() {
+        return new AAIResourcesClient();
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java
new file mode 100644 (file)
index 0000000..b0986d8
--- /dev/null
@@ -0,0 +1,108 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.aai;
+
+import org.onap.aaiclient.client.aai.AAIProperties;
+import org.onap.aaiclient.client.aai.AAIVersion;
+import org.onap.so.client.CacheProperties;
+import org.onap.so.spring.SpringContextHelper;
+import org.springframework.context.ApplicationContext;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public class AaiPropertiesImpl implements AAIProperties {
+
+    private final String endpoint;
+    private final String encryptedBasicAuth;
+    private final String encryptionKey;
+    private final String aaiVersion;
+    private final Long readTimeout;
+    private final Long connectionTimeout;
+    private final boolean enableCaching;
+    private final Long cacheMaxAge;
+
+    public AaiPropertiesImpl() {
+        final ApplicationContext context = SpringContextHelper.getAppContext();
+        this.endpoint = context.getEnvironment().getProperty("aai.endpoint");
+        this.encryptedBasicAuth = context.getEnvironment().getProperty("aai.auth");
+        this.encryptionKey = context.getEnvironment().getProperty("mso.key");
+        this.aaiVersion = context.getEnvironment().getProperty("aai.version");
+        this.readTimeout = context.getEnvironment().getProperty("aai.readTimeout", Long.class, 60000L);
+        this.connectionTimeout = context.getEnvironment().getProperty("aai.connectionTimeout", Long.class, 60000L);
+        this.enableCaching = context.getEnvironment().getProperty("aai.caching.enabled", Boolean.class, false);
+        this.cacheMaxAge = context.getEnvironment().getProperty("aai.caching.maxAge", Long.class, 60000L);
+    }
+
+    @Override
+    public URL getEndpoint() throws MalformedURLException {
+        return new URL(endpoint);
+    }
+
+    @Override
+    public String getSystemName() {
+        return "MSO";
+    }
+
+    @Override
+    public AAIVersion getDefaultVersion() {
+        for (final AAIVersion version : AAIVersion.values()) {
+            if (version.toString().equalsIgnoreCase(this.aaiVersion)) {
+                return version;
+            }
+        }
+        return AAIVersion.LATEST;
+    }
+
+    @Override
+    public String getAuth() {
+        return encryptedBasicAuth;
+    }
+
+    @Override
+    public String getKey() {
+        return encryptionKey;
+    }
+
+    @Override
+    public Long getReadTimeout() {
+        return this.readTimeout;
+    }
+
+    @Override
+    public Long getConnectionTimeout() {
+        return this.connectionTimeout;
+    }
+
+    @Override
+    public boolean isCachingEnabled() {
+        return this.enableCaching;
+    }
+
+    @Override
+    public CacheProperties getCacheProperties() {
+        return new AAICacheProperties() {
+            @Override
+            public Long getMaxAge() {
+                return cacheMaxAge;
+            }
+        };
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java
new file mode 100644 (file)
index 0000000..fae677d
--- /dev/null
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.aai;
+
+import java.util.List;
+import java.util.Optional;
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.aai.domain.yang.K8SResource;
+import org.onap.aai.domain.yang.VfModule;
+import org.onap.so.beans.nsmf.OrchestrationStatusEnum;
+import org.onap.so.cnfm.lcm.bpmn.flows.extclients.kubernetes.KubernetesResource;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface AaiServiceProvider {
+
+    void createGenericVnfAndConnectServiceInstance(final String serviceInstanceId, final String vnfId,
+            final GenericVnf genericVnf);
+
+    void connectGenericVnfToTenant(final String vnfId, final String cloudOwner, final String cloudRegion,
+            final String tenantId);
+
+    Optional<GenericVnf> getGenericVnf(final String vnfId);
+
+    void deleteGenericVnf(final String vnfId);
+
+    void updateGenericVnf(final String vnfId, final GenericVnf vnf);
+
+    void createVfModule(final String vnfId, final String vfModuleId, final VfModule vfModule);
+
+    void createK8sResource(final String k8sResourceId, final String cloudOwner, final String cloudRegion,
+            final String tenantId, K8SResource k8sResource);
+
+    void connectK8sResourceToVfModule(final String k8sResourceId, final String cloudOwner, final String cloudRegion,
+            final String tenantId, final String vnfId, final String vfModuleId);
+
+    void connectK8sResourceToGenericVnf(final String k8sResourceId, final String cloudOwner, final String cloudRegion,
+            final String tenantId, final String vnfId);
+
+    List<KubernetesResource> getK8sResources(final String vnfId, final String vfModuleId);
+
+    void deleteK8SResource(final String k8sResourceId, final String cloudOwner, final String cloudRegion,
+            final String tenantId);
+
+    void deleteVfModule(final String vnfId, final String vfModuleId);
+
+    boolean updateGenericVnfStatus(final String vnfId, final OrchestrationStatusEnum status);
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java
new file mode 100644 (file)
index 0000000..4f5ec8d
--- /dev/null
@@ -0,0 +1,211 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.aai;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.aai.domain.yang.K8SResource;
+import org.onap.aai.domain.yang.VfModule;
+import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
+import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
+import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
+import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
+import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types;
+import org.onap.so.beans.nsmf.OrchestrationStatusEnum;
+import org.onap.so.cnfm.lcm.bpmn.flows.GsonProvider;
+import org.onap.so.cnfm.lcm.bpmn.flows.extclients.kubernetes.KubernetesResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.google.gson.Gson;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ */
+@Service
+public class AaiServiceProviderImpl implements AaiServiceProvider {
+    private static final Logger logger = LoggerFactory.getLogger(AaiServiceProviderImpl.class);
+    private final AaiClientProvider aaiClientProvider;
+    private final Gson gson;
+
+    @Autowired
+    public AaiServiceProviderImpl(final AaiClientProvider aaiClientProvider, final GsonProvider gsonProvider) {
+        this.aaiClientProvider = aaiClientProvider;
+        this.gson = gsonProvider.getGson();
+    }
+
+    @Override
+    public void createGenericVnfAndConnectServiceInstance(final String serviceInstanceId, final String vnfId,
+            final GenericVnf genericVnf) {
+        logger.info("Creating GenericVnf in AAI: {}", genericVnf);
+        final AAIResourceUri genericVnfURI =
+                AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId));
+        final AAIResourceUri serviceInstanceURI =
+                AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(serviceInstanceId));
+        aaiClientProvider.getAaiClient().createIfNotExists(genericVnfURI, Optional.of(genericVnf))
+                .connect(genericVnfURI, serviceInstanceURI);
+
+    }
+
+    @Override
+    public void connectGenericVnfToTenant(final String vnfId, final String cloudOwner, final String cloudRegion,
+            final String tenantId) {
+        logger.info("Connecting GenericVnf {} to {}/{}/{} in AAI", vnfId, cloudOwner, cloudRegion, tenantId);
+        final AAIResourceUri tenantURI = AAIUriFactory.createResourceUri(
+                AAIFluentTypeBuilder.cloudInfrastructure().cloudRegion(cloudOwner, cloudRegion).tenant(tenantId));
+        final AAIResourceUri genericVnfURI =
+                AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId));
+        aaiClientProvider.getAaiClient().connect(tenantURI, genericVnfURI);
+    }
+
+    @Override
+    public Optional<GenericVnf> getGenericVnf(final String vnfId) {
+        return aaiClientProvider.getAaiClient().get(GenericVnf.class,
+                AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId)));
+    }
+
+    @Override
+    public void deleteGenericVnf(final String vnfId) {
+        logger.info("Deleting GenericVnf with id: {} from AAI.", vnfId);
+        final AAIResourceUri aaiResourceUri =
+                AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId));
+        aaiClientProvider.getAaiClient().delete(aaiResourceUri);
+    }
+
+    @Override
+    public void updateGenericVnf(final String vnfId, final GenericVnf vnf) {
+        logger.info("Updating GenericVnf of id: {} in AAI.", vnfId);
+        final AAIResourceUri aaiResourceUri =
+                AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId));
+        aaiClientProvider.getAaiClient().update(aaiResourceUri, vnf);
+    }
+
+    @Override
+    public void createVfModule(final String vnfId, final String vfModuleId, final VfModule vfModule) {
+        logger.info("Creating VfModule in AAI: {}", vfModule);
+
+        final AAIResourceUri vfModuleURI =
+                AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId).vfModule(vfModuleId));
+        aaiClientProvider.getAaiClient().createIfNotExists(vfModuleURI, Optional.of(vfModule));
+
+    }
+
+    @Override
+    public void createK8sResource(final String k8sResourceId, final String cloudOwner, final String cloudRegion,
+            final String tenantId, final K8SResource k8sResource) {
+        logger.info("Creating K8SResource in AAI: {} using {}/{}/{}/{}", k8sResource, k8sResourceId, cloudOwner,
+                cloudRegion, tenantId);
+
+        final AAIResourceUri k8sResourceURI = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure()
+                .cloudRegion(cloudOwner, cloudRegion).tenant(tenantId).k8sResource(k8sResourceId));
+
+        final String payload = gson.toJson(k8sResource);
+        logger.debug("Creating K8sResource in A&AI: {}", payload);
+
+        aaiClientProvider.getAaiClient().createIfNotExists(k8sResourceURI, Optional.of(payload));
+
+    }
+
+    @Override
+    public void connectK8sResourceToVfModule(final String k8sResourceId, final String cloudOwner,
+            final String cloudRegion, final String tenantId, final String vnfId, final String vfModuleId) {
+        logger.info("Connecting K8sResource {}/{}/{}/{} to VF Moudle {}/{} in AAI", cloudOwner, cloudRegion, tenantId,
+                k8sResourceId, vnfId, vfModuleId);
+
+        final AAIResourceUri k8sResourceURI = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure()
+                .cloudRegion(cloudOwner, cloudRegion).tenant(tenantId).k8sResource(k8sResourceId));
+
+        final AAIResourceUri vfModuleURI =
+                AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId).vfModule(vfModuleId));
+        aaiClientProvider.getAaiClient().connect(k8sResourceURI, vfModuleURI);
+
+    }
+
+    @Override
+    public void connectK8sResourceToGenericVnf(final String k8sResourceId, final String cloudOwner,
+            final String cloudRegion, final String tenantId, final String vnfId) {
+        logger.info("Connecting K8sResource {}/{}/{}/{} to Generic Vnf {} in AAI", cloudOwner, cloudRegion, tenantId,
+                k8sResourceId, vnfId);
+        final AAIResourceUri k8sResourceURI = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure()
+                .cloudRegion(cloudOwner, cloudRegion).tenant(tenantId).k8sResource(k8sResourceId));
+        final AAIResourceUri genericVnfURI =
+                AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId));
+        aaiClientProvider.getAaiClient().connect(k8sResourceURI, genericVnfURI);
+
+    }
+
+    @Override
+    public List<KubernetesResource> getK8sResources(final String vnfId, final String vfModuleId) {
+        logger.info("Getting K8S resources related to VfModule: {} from AAI", vfModuleId);
+        final AAIResourceUri vfModuleURI =
+                AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId).vfModule(vfModuleId));
+        final AAIResultWrapper vfModuleInstance = aaiClientProvider.getAaiClient().get(vfModuleURI);
+        if (vfModuleInstance.hasRelationshipsTo(Types.K8S_RESOURCE)
+                && vfModuleInstance.getRelationships().isPresent()) {
+            logger.debug("VfModule has relations of type K8SResource");
+            return vfModuleInstance.getRelationships().get().getByType(Types.K8S_RESOURCE).stream()
+                    .map(relation -> relation.asBean(KubernetesResource.class)).filter(Optional::isPresent)
+                    .map(Optional::get).collect(Collectors.toList());
+        }
+        logger.info("No K8S resources found for VfModule :{}", vfModuleId);
+        return Collections.emptyList();
+    }
+
+    @Override
+    public void deleteK8SResource(final String k8sResourceId, final String cloudOwner, final String cloudRegion,
+            final String tenantId) {
+        logger.info("Deleting K8sResource {} from AAI", k8sResourceId);
+
+        final AAIResourceUri k8sResourceURI = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure()
+                .cloudRegion(cloudOwner, cloudRegion).tenant(tenantId).k8sResource(k8sResourceId));
+        aaiClientProvider.getAaiClient().deleteIfExists(k8sResourceURI);
+
+        logger.info("K8S resource removed from AAI using URI: {}", k8sResourceURI);
+    }
+
+    @Override
+    public void deleteVfModule(final String vnfId, final String vfModuleId) {
+        logger.info("Deleting VfModule {} from AAI", vfModuleId);
+
+        final AAIResourceUri vfModuleURI =
+                AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId).vfModule(vfModuleId));
+        aaiClientProvider.getAaiClient().deleteIfExists(vfModuleURI);
+        logger.info("VfModule deleted from AAI using URI: {}", vfModuleId);
+    }
+
+    @Override
+    public boolean updateGenericVnfStatus(final String vnfId, final OrchestrationStatusEnum status) {
+        logger.info("Updating GenericVnf status to deactivated for vnfID: {}", vnfId);
+        final Optional<GenericVnf> optionalVnf = getGenericVnf(vnfId);
+        if (optionalVnf.isPresent()) {
+            final GenericVnf vnf = optionalVnf.get();
+            vnf.setOrchestrationStatus(status.getValue());
+            updateGenericVnf(vnfId, vnf);
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/kubernetes/KubernetesResource.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/kubernetes/KubernetesResource.java
new file mode 100644 (file)
index 0000000..7ec50f0
--- /dev/null
@@ -0,0 +1,209 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.kubernetes;
+
+import static org.onap.so.cnfm.lcm.database.beans.utils.Utils.toIndentedString;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class KubernetesResource implements Serializable {
+
+    private static final long serialVersionUID = -4342437130757578686L;
+
+    private String id;
+    private String name;
+    private String group;
+    private String version;
+    private String kind;
+    private String namespace;
+    private String selflink;
+    private String resourceVersion;
+    private List<String> labels;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(final String id) {
+        this.id = id;
+    }
+
+    public KubernetesResource id(final String id) {
+        this.id = id;
+        return this;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    public KubernetesResource name(final String name) {
+        this.name = name;
+        return this;
+    }
+
+    public String getGroup() {
+        return group;
+    }
+
+    public void setGroup(final String group) {
+        this.group = group;
+    }
+
+    public KubernetesResource group(final String group) {
+        this.group = group;
+        return this;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(final String version) {
+        this.version = version;
+    }
+
+    public KubernetesResource version(final String version) {
+        this.version = version;
+        return this;
+    }
+
+    public String getKind() {
+        return kind;
+    }
+
+    public void setKind(final String kind) {
+        this.kind = kind;
+    }
+
+    public KubernetesResource kind(final String kind) {
+        this.kind = kind;
+        return this;
+    }
+
+    public String getNamespace() {
+        return namespace;
+    }
+
+    public void setNamespace(final String namespace) {
+        this.namespace = namespace;
+    }
+
+    public KubernetesResource namespace(final String namespace) {
+        this.namespace = namespace;
+        return this;
+    }
+
+    public String getSelflink() {
+        return selflink;
+    }
+
+    public void setSelflink(final String selflink) {
+        this.selflink = selflink;
+    }
+
+    public KubernetesResource selflink(final String selflink) {
+        this.selflink = selflink;
+        return this;
+    }
+
+    public String getResourceVersion() {
+        return resourceVersion;
+    }
+
+    public void setResourceVersion(final String resourceVersion) {
+        this.resourceVersion = resourceVersion;
+    }
+
+    public KubernetesResource resourceVersion(final String resourceVersion) {
+        this.resourceVersion = resourceVersion;
+        return this;
+    }
+
+    public List<String> getLabels() {
+        return labels;
+    }
+
+    public void setLabels(final List<String> labels) {
+        this.labels = labels;
+    }
+
+    public KubernetesResource labels(final List<String> labels) {
+        this.labels = labels;
+        return this;
+    }
+
+    public KubernetesResource label(final String label) {
+        if (this.labels == null) {
+            this.labels = new ArrayList<>();
+        }
+
+        this.labels.add(label);
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, name, group, version, kind, namespace, selflink, resourceVersion, labels);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj instanceof KubernetesResource) {
+            final KubernetesResource other = (KubernetesResource) obj;
+            return Objects.equals(id, other.id) && Objects.equals(name, other.name)
+                    && Objects.equals(group, other.group) && Objects.equals(version, other.version)
+                    && Objects.equals(kind, other.kind) && Objects.equals(namespace, other.namespace)
+                    && Objects.equals(selflink, other.selflink)
+                    && Objects.equals(resourceVersion, other.resourceVersion) && Objects.equals(labels, other.labels);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("class KubernetesResource {\n");
+        sb.append("    id: ").append(toIndentedString(id)).append("\n");
+        sb.append("    name: ").append(toIndentedString(name)).append("\n");
+        sb.append("    group: ").append(toIndentedString(group)).append("\n");
+        sb.append("    version: ").append(toIndentedString(version)).append("\n");
+        sb.append("    kind: ").append(toIndentedString(kind)).append("\n");
+        sb.append("    namespace: ").append(toIndentedString(namespace)).append("\n");
+        sb.append("    selflink: ").append(toIndentedString(selflink)).append("\n");
+        sb.append("    resourceVersion: ").append(toIndentedString(resourceVersion)).append("\n");
+        sb.append("    labels: ").append(toIndentedString(labels)).append("\n");
+
+        sb.append("}");
+        return sb.toString();
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/DeploymentItem.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/DeploymentItem.java
new file mode 100644 (file)
index 0000000..1062cb7
--- /dev/null
@@ -0,0 +1,143 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.sdc;
+
+import static org.onap.so.cnfm.lcm.database.beans.utils.Utils.toIndentedString;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class DeploymentItem implements Serializable {
+
+    private static final long serialVersionUID = -1974244669409099225L;
+    private String name;
+    private String file;
+    private String itemId;
+    private String deploymentOrder;
+
+    private List<String> lifecycleParameters;
+
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    public DeploymentItem name(final String name) {
+        this.name = name;
+        return this;
+    }
+
+
+    public String getFile() {
+        return file;
+    }
+
+    public void setFile(final String file) {
+        this.file = file;
+    }
+
+    public DeploymentItem file(final String file) {
+        this.file = file;
+        return this;
+    }
+
+
+    public String getItemId() {
+        return itemId;
+    }
+
+    public void setItemId(final String itemId) {
+        this.itemId = itemId;
+    }
+
+    public DeploymentItem itemId(final String itemId) {
+        this.itemId = itemId;
+        return this;
+    }
+
+    public String getDeploymentOrder() {
+        return deploymentOrder;
+    }
+
+    public void setDeploymentOrder(String deploymentOrder) {
+        this.deploymentOrder = deploymentOrder;
+    }
+
+    public DeploymentItem deploymentOrder(final String deploymentOrder) {
+        this.deploymentOrder = deploymentOrder;
+        return this;
+    }
+
+
+    public List<String> getLifecycleParameters() {
+        return lifecycleParameters;
+    }
+
+    public void setLifecycleParameters(final List<String> lifecycleParameters) {
+        this.lifecycleParameters = lifecycleParameters;
+    }
+
+    public DeploymentItem lifecycleParameters(final List<String> lifecycleParameters) {
+        this.lifecycleParameters = lifecycleParameters;
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(name, file, itemId, deploymentOrder, lifecycleParameters);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null || getClass() != obj.getClass())
+            return false;
+        if (obj instanceof DeploymentItem) {
+            final DeploymentItem other = (DeploymentItem) obj;
+            return Objects.equals(name, other.name) && Objects.equals(file, other.file)
+                    && Objects.equals(itemId, other.itemId) && Objects.equals(deploymentOrder, other.deploymentOrder)
+                    && Objects.equals(lifecycleParameters, other.lifecycleParameters);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("class DeploymentItem {\n");
+        sb.append("    name: ").append(toIndentedString(name)).append("\n");
+        sb.append("    file: ").append(toIndentedString(file)).append("\n");
+        sb.append("    itemId: ").append(toIndentedString(itemId)).append("\n");
+        sb.append("    deploymentOrder: ").append(toIndentedString(deploymentOrder)).append("\n");
+        sb.append("    lifecycleParameters: ").append(toIndentedString(lifecycleParameters)).append("\n");
+        sb.append("}");
+        return sb.toString();
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcClientConfigurationProvider.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcClientConfigurationProvider.java
new file mode 100644 (file)
index 0000000..4ae1d43
--- /dev/null
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.sdc;
+
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import org.apache.commons.codec.binary.Base64;
+import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.BasicAuthConfigException;
+import org.onap.so.utils.CryptoUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Configuration
+public class SdcClientConfigurationProvider {
+
+    private static final Logger logger = LoggerFactory.getLogger(SdcClientConfigurationProvider.class);
+
+    @Value("${sdc.username:mso}")
+    private String sdcUsername;
+
+    @Value("${sdc.password:76966BDD3C7414A03F7037264FF2E6C8EEC6C28F2B67F2840A1ED857C0260FEE731D73F47F828E5527125D29FD25D3E0DE39EE44C058906BF1657DE77BF897EECA93BDC07FA64F}")
+    private String sdcPassword;
+
+    @Value("${sdc.key:566B754875657232314F5548556D3665}")
+    private String sdcKey;
+
+    @Value("${sdc.endpoint:https://sdc-be.onap:8443}")
+    private String baseUrl;
+
+    private static String basicAuth = null;
+
+
+    public String getBasicAuth() {
+        if (basicAuth == null) {
+            synchronized (this) {
+                if (basicAuth == null) {
+                    try {
+                        final String auth = sdcUsername + ":" + CryptoUtils.decrypt(sdcPassword, sdcKey);
+                        final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
+                        basicAuth = "Basic " + new String(encodedAuth);
+                    } catch (final GeneralSecurityException exception) {
+                        logger.error("Unable to process basic auth information", exception);
+                        throw new BasicAuthConfigException("Unable to process basic auth information", exception);
+                    }
+                }
+            }
+        }
+        return basicAuth;
+    }
+
+    public String getSdcPackageUrl(final String packageId) {
+        return baseUrl + "/sdc/v1/catalog/resources/" + packageId + "/toscaModel";
+
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPackageParser.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPackageParser.java
new file mode 100644 (file)
index 0000000..0ade7bf
--- /dev/null
@@ -0,0 +1,201 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.sdc;
+
+import static com.google.common.base.Splitter.on;
+import static com.google.common.collect.Iterables.filter;
+import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.APPLICATION_NAME_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.APPLICATION_VERSION_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.DEPLOYMENT_ITEMS_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.DESCRIPTOR_ID_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.DESCRIPTOR_INVARIANT_ID_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.PROVIDER_PARAM_NAME;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import com.google.gson.JsonArray;
+import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.FileNotFoundInCsarException;
+import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.PropertyNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.yaml.snakeyaml.Yaml;
+import com.google.common.io.ByteStreams;
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class SdcCsarPackageParser {
+    private static final String TOCSA_METADATA_FILE_PATH = "TOSCA-Metadata/TOSCA.meta";
+    private static final String ENTRY_DEFINITIONS_ENTRY = "Entry-Definitions";
+
+    private static final Logger logger = LoggerFactory.getLogger(SdcCsarPackageParser.class);
+
+    public Map<String, Object> getAsdProperties(final byte[] onapPackage) {
+
+        try (final ByteArrayInputStream stream = new ByteArrayInputStream(onapPackage);
+                final ZipInputStream zipInputStream = new ZipInputStream(stream);) {
+            final String asdLocation = getAsdLocation(zipInputStream);
+            final String onapAsdContent = getFileInZip(zipInputStream, asdLocation).toString();
+            logger.debug("ASD CONTENTS: {}", onapAsdContent);
+            final JsonObject root = new Gson().toJsonTree(new Yaml().load(onapAsdContent)).getAsJsonObject();
+
+            final JsonObject topologyTemplates = child(root, "topology_template");
+            final JsonObject nodeTemplates = child(topologyTemplates, "node_templates");
+            for (final JsonObject child : children(nodeTemplates)) {
+                final String type = childElement(child, "type").getAsString();
+                if ("tosca.nodes.asd".equals(type)) {
+                    final JsonObject properties = child(child, "properties");
+                    logger.debug("properties: {}", properties.toString());
+                    final Map<String, Object> propertiesValues = new HashMap<>();
+                    propertiesValues.put(DESCRIPTOR_ID_PARAM_NAME,
+                            getStringValue(properties, DESCRIPTOR_ID_PARAM_NAME));
+                    propertiesValues.put(DESCRIPTOR_INVARIANT_ID_PARAM_NAME,
+                            getStringValue(properties, DESCRIPTOR_INVARIANT_ID_PARAM_NAME));
+                    propertiesValues.put(PROVIDER_PARAM_NAME, getStringValue(properties, PROVIDER_PARAM_NAME));
+                    propertiesValues.put(APPLICATION_NAME_PARAM_NAME,
+                            getStringValue(properties, APPLICATION_NAME_PARAM_NAME));
+                    propertiesValues.put(APPLICATION_VERSION_PARAM_NAME,
+                            getStringValue(properties, APPLICATION_VERSION_PARAM_NAME));
+                    propertiesValues.put(DEPLOYMENT_ITEMS_PARAM_NAME, getDeploymentItems(child));
+
+                    return propertiesValues;
+
+                }
+            }
+
+
+        } catch (final Exception exception) {
+            throw new IllegalArgumentException("Unable to parser CSAR package", exception);
+        }
+        return Collections.emptyMap();
+    }
+
+    private String getStringValue(final JsonObject properties, final String key) {
+        final JsonElement element = properties.get(key);
+        if (element != null && element.isJsonPrimitive()) {
+            return element.getAsString();
+        }
+        logger.warn("'{}' value is not Primitive or null val:{}", key, element != null ? element.toString() : null);
+        return null;
+    }
+
+    private List<DeploymentItem> getDeploymentItems(final JsonObject child) {
+        final List<DeploymentItem> items = new ArrayList<>();
+
+        final JsonObject artifacts = child(child, "artifacts");
+        artifacts.keySet().forEach(key -> {
+            final JsonObject element = artifacts.getAsJsonObject(key);
+            final JsonObject artifactsProperties = child(element, "properties");
+            final List<String> lcp = getLifecycleParameters(artifactsProperties);
+            items.add(new DeploymentItem().name(key).itemId(getStringValue(artifactsProperties, "itemId"))
+                    .file(getStringValue(element, "file"))
+                    .deploymentOrder(getStringValue(artifactsProperties, "deployment_order")).lifecycleParameters(lcp));
+        });
+        return items;
+    }
+
+    private List<String> getLifecycleParameters(final JsonObject artifactsProperties) {
+        final JsonArray lcParameters = childElement(artifactsProperties, "lifecycle_parameters").getAsJsonArray();
+        final List<String> lifecycleParameters = new ArrayList<>();
+        if(lcParameters != null) {
+            final Iterator<JsonElement> it = lcParameters.iterator();
+            while(it.hasNext()){
+                lifecycleParameters.add(it.next().getAsString());
+            }
+        }
+        return lifecycleParameters;
+    }
+
+    private String getAsdLocation(final ZipInputStream zipInputStream) throws IOException {
+
+        try (final ByteArrayOutputStream fileContent = getFileInZip(zipInputStream, TOCSA_METADATA_FILE_PATH);) {
+            final String toscaMetadata = new String(fileContent.toByteArray());
+            if (!toscaMetadata.isEmpty()) {
+                final String entry =
+                        filter(on("\n").split(toscaMetadata), line -> line.contains(ENTRY_DEFINITIONS_ENTRY)).iterator()
+                                .next();
+                return entry.replace(ENTRY_DEFINITIONS_ENTRY + ":", "").trim();
+            }
+            final String message = "Unable to find valid Tosca Path";
+            logger.error(message);
+            throw new FileNotFoundInCsarException(message);
+        }
+    }
+
+    public ByteArrayOutputStream getFileInZip(final ZipInputStream zipInputStream, final String path)
+            throws IOException {
+        ZipEntry zipEntry;
+        final Set<String> items = new HashSet<>();
+        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
+            items.add(zipEntry.getName());
+            if (zipEntry.getName().matches(path)) {
+                final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+                ByteStreams.copy(zipInputStream, byteArrayOutputStream);
+                return byteArrayOutputStream;
+            }
+        }
+        logger.error("Unable to find the {} in archive found: {}", path, items);
+        throw new NoSuchElementException("Unable to find the " + path + " in archive found: " + items);
+    }
+
+    private JsonObject child(final JsonObject parent, final String name) {
+        return childElement(parent, name).getAsJsonObject();
+    }
+
+    private JsonElement childElement(final JsonObject parent, final String name) {
+        final JsonElement child = parent.get(name);
+        if (child == null) {
+            final String message = "Missing child " + name;
+            logger.error(message);
+            throw new PropertyNotFoundException(message);
+        }
+        return child;
+    }
+
+    private Collection<JsonObject> children(final JsonObject parent) {
+        final ArrayList<JsonObject> childElements = new ArrayList<>();
+        parent.keySet().stream().forEach(childKey -> {
+            if (parent.get(childKey).isJsonObject()) {
+                childElements.add(parent.get(childKey).getAsJsonObject());
+            }
+        });
+        return childElements;
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPropertiesConstants.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPropertiesConstants.java
new file mode 100644 (file)
index 0000000..40a0d0d
--- /dev/null
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.sdc;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class SdcCsarPropertiesConstants {
+    public static final String DEPLOYMENT_ITEMS_PARAM_NAME = "deployment_items";
+    public static final String APPLICATION_VERSION_PARAM_NAME = "application_version";
+    public static final String APPLICATION_NAME_PARAM_NAME = "application_name";
+    public static final String PROVIDER_PARAM_NAME = "provider";
+    public static final String DESCRIPTOR_INVARIANT_ID_PARAM_NAME = "descriptor_invariant_id";
+    public static final String DESCRIPTOR_ID_PARAM_NAME = "descriptor_id";
+
+    private SdcCsarPropertiesConstants() {}
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcHttpRestServiceProviderConfiguration.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcHttpRestServiceProviderConfiguration.java
new file mode 100644 (file)
index 0000000..f727e07
--- /dev/null
@@ -0,0 +1,108 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.sdc;
+
+import java.util.Iterator;
+import javax.net.ssl.SSLContext;
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.HttpClients;
+import org.onap.logging.filter.spring.SpringClientPayloadFilter;
+import org.onap.so.cnfm.lcm.bpmn.flows.GsonProvider;
+import org.onap.so.configuration.rest.HttpComponentsClientConfiguration;
+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.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.BufferingClientHttpRequestFactory;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.GsonHttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Configuration
+public class SdcHttpRestServiceProviderConfiguration {
+
+    private static final Logger logger = LoggerFactory.getLogger(SdcHttpRestServiceProviderConfiguration.class);
+
+    public static final String SDC_REST_TEMPLATE_CLIENT_BEAN = "SdcRestTemplateClientBean";
+    public static final String SDC_HTTP_REST_SERVICE_PROVIDER_BEAN = "SdcHttpRestServiceProviderBean";
+
+    @Autowired
+    private GsonProvider gsonProvider;
+
+    @Bean
+    @Qualifier(SDC_REST_TEMPLATE_CLIENT_BEAN)
+    public RestTemplate sdcAdapterRestTemplate(
+            @Autowired final HttpComponentsClientConfiguration httpComponentsClientConfiguration) {
+
+        final HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =
+                httpComponentsClientConfiguration.httpComponentsClientHttpRequestFactory();
+
+        final RestTemplate restTemplate =
+                new RestTemplate(new BufferingClientHttpRequestFactory(clientHttpRequestFactory));
+        restTemplate.getInterceptors().add(new SOSpringClientFilter());
+        restTemplate.getInterceptors().add((new SpringClientPayloadFilter()));
+        return restTemplate;
+
+    }
+
+    @Bean
+    @Qualifier(SDC_HTTP_REST_SERVICE_PROVIDER_BEAN)
+    public HttpRestServiceProvider sdcHttpRestServiceProvider(
+            @Qualifier(SDC_REST_TEMPLATE_CLIENT_BEAN) @Autowired final RestTemplate restTemplate) {
+
+        try {
+            logger.info("Setting SSLConnectionSocketFactory with Default SSL ...");
+            final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(SSLContext.getDefault());
+            final HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
+            final HttpComponentsClientHttpRequestFactory factory =
+                    new HttpComponentsClientHttpRequestFactory(httpClient);
+            restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory));
+        } catch (final Exception exception) {
+            logger.error("Error reading truststore, TLS connection to SDC will fail.", exception);
+        }
+        setGsonMessageConverter(restTemplate);
+
+
+        return new HttpRestServiceProviderImpl(restTemplate);
+    }
+
+    private void setGsonMessageConverter(final RestTemplate restTemplate) {
+        final Iterator<HttpMessageConverter<?>> iterator = restTemplate.getMessageConverters().iterator();
+        while (iterator.hasNext()) {
+            if (iterator.next() instanceof MappingJackson2HttpMessageConverter) {
+                iterator.remove();
+            }
+        }
+        restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gsonProvider.getGson()));
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcPackageProvider.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcPackageProvider.java
new file mode 100644 (file)
index 0000000..f75d5f5
--- /dev/null
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.sdc;
+
+import java.util.Optional;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface SdcPackageProvider {
+    
+    Optional<byte[]> getSdcResourcePackage(final String packageId);
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcPackageProviderImpl.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcPackageProviderImpl.java
new file mode 100644 (file)
index 0000000..5e69661
--- /dev/null
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.sdc;
+
+import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcHttpRestServiceProviderConfiguration.SDC_HTTP_REST_SERVICE_PROVIDER_BEAN;
+import java.util.Optional;
+import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.SdcPackageRequestFailureException;
+import org.onap.so.rest.service.HttpRestServiceProvider;
+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.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class SdcPackageProviderImpl implements SdcPackageProvider {
+    private static final Logger logger = LoggerFactory.getLogger(SdcPackageProviderImpl.class);
+    private final SdcClientConfigurationProvider sdcClientConfigurationProvider;
+    private final HttpRestServiceProvider httpServiceProvider;
+    private static final String SERVICE_NAME = "SO-CNFM";
+
+    @Autowired
+    public SdcPackageProviderImpl(final SdcClientConfigurationProvider sdcClientConfigurationProvider,
+            @Qualifier(SDC_HTTP_REST_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider) {
+        this.sdcClientConfigurationProvider = sdcClientConfigurationProvider;
+        this.httpServiceProvider = httpServiceProvider;
+    }
+
+    @Override
+    public Optional<byte[]> getSdcResourcePackage(final String packageId) {
+        try {
+            final HttpHeaders headers = new HttpHeaders();
+            headers.add(HttpHeaders.AUTHORIZATION, sdcClientConfigurationProvider.getBasicAuth());
+            headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_OCTET_STREAM_VALUE);
+            headers.add("X-ECOMP-InstanceID", SERVICE_NAME);
+            headers.add("X-FromAppId", SERVICE_NAME);
+
+            logger.info("Will retrieve resource package with id: {} from SDC", packageId);
+            final String url = sdcClientConfigurationProvider.getSdcPackageUrl(packageId);
+
+            final ResponseEntity<byte[]> response = httpServiceProvider.getHttpResponse(url, headers, byte[].class);
+            if (response.getStatusCode().is2xxSuccessful()) {
+                if (response.hasBody()) {
+                    return Optional.of(response.getBody());
+                }
+                logger.error("Received response without body ...");
+            }
+            return Optional.empty();
+        } catch (final Exception restProcessingException) {
+            final String message = "Caught exception while getting resource package content for: " + packageId;
+            throw new SdcPackageRequestFailureException(message, restProcessingException);
+        }
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/JobExecutorService.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/JobExecutorService.java
new file mode 100644 (file)
index 0000000..c4bd210
--- /dev/null
@@ -0,0 +1,376 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.service;
+
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.AS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_AS_REQUEST_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.INSTANTIATE_AS_REQUEST_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.JOB_ID_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.OCC_ID_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.TERMINATE_AS_REQUEST_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.CREATE_AS_WORKFLOW_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.DELETE_AS_WORKFLOW_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.INSTANTIATE_AS_WORKFLOW_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.TERMINATE_AS_WORKFLOW_NAME;
+import static org.onap.so.cnfm.lcm.database.beans.JobStatusEnum.ERROR;
+import static org.onap.so.cnfm.lcm.database.beans.JobStatusEnum.FINISHED;
+import static org.onap.so.cnfm.lcm.database.beans.JobStatusEnum.FINISHED_WITH_ERROR;
+import static org.onap.so.cnfm.lcm.database.beans.JobStatusEnum.IN_PROGRESS;
+import static org.slf4j.LoggerFactory.getLogger;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.onap.so.cnfm.lcm.bpmn.flows.GsonProvider;
+import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.AsRequestProcessingException;
+import org.onap.so.cnfm.lcm.database.beans.AsInst;
+import org.onap.so.cnfm.lcm.database.beans.AsLcmOpOcc;
+import org.onap.so.cnfm.lcm.database.beans.AsLcmOpType;
+import org.onap.so.cnfm.lcm.database.beans.Job;
+import org.onap.so.cnfm.lcm.database.beans.JobAction;
+import org.onap.so.cnfm.lcm.database.beans.JobStatusEnum;
+import org.onap.so.cnfm.lcm.database.beans.OperationStateEnum;
+import org.onap.so.cnfm.lcm.database.beans.State;
+import org.onap.so.cnfm.lcm.database.service.DatabaseServiceProvider;
+import org.onap.so.cnfm.lcm.model.AsInstance;
+import org.onap.so.cnfm.lcm.model.CreateAsRequest;
+import org.onap.so.cnfm.lcm.model.ErrorDetails;
+import org.onap.so.cnfm.lcm.model.InstantiateAsRequest;
+import org.onap.so.cnfm.lcm.model.TerminateAsRequest;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import com.google.common.collect.ImmutableSet;
+import com.google.gson.Gson;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class JobExecutorService {
+
+    private static final Logger logger = getLogger(JobExecutorService.class);
+
+    private static final ImmutableSet<JobStatusEnum> JOB_FINISHED_STATES =
+            ImmutableSet.of(FINISHED, ERROR, FINISHED_WITH_ERROR);
+
+    private static final int SLEEP_TIME_IN_SECONDS = 5;
+
+    @Value("${so-cnfm-lcm.requesttimeout.timeoutInSeconds:300}")
+    private int timeOutInSeconds;
+
+    private final DatabaseServiceProvider databaseServiceProvider;
+    private final WorkflowExecutorService workflowExecutorService;
+    private final WorkflowQueryService workflowQueryService;
+    private final Gson gson;
+
+    @Autowired
+    public JobExecutorService(final DatabaseServiceProvider databaseServiceProvider,
+            final WorkflowExecutorService workflowExecutorService, final WorkflowQueryService workflowQueryService,
+            final GsonProvider gsonProvider) {
+        this.databaseServiceProvider = databaseServiceProvider;
+        this.workflowExecutorService = workflowExecutorService;
+        this.workflowQueryService = workflowQueryService;
+        this.gson = gsonProvider.getGson();
+    }
+
+    public AsInstance runCreateAsJob(final CreateAsRequest createAsRequest) {
+        logger.info("Starting 'Create AS' workflow job for request:\n{}", createAsRequest);
+        final Job newJob = new Job().startTime(LocalDateTime.now()).jobType("AS").jobAction(JobAction.CREATE)
+                .resourceId(createAsRequest.getAsdId()).resourceName(createAsRequest.getAsInstanceName())
+                .status(JobStatusEnum.STARTING);
+        databaseServiceProvider.addJob(newJob);
+
+        logger.info("New job created in database :\n{}", newJob);
+
+        workflowExecutorService.executeWorkflow(newJob.getJobId(), CREATE_AS_WORKFLOW_NAME,
+                getVariables(newJob.getJobId(), createAsRequest));
+
+        final ImmutablePair<String, JobStatusEnum> immutablePair =
+                waitForJobToFinish(newJob.getJobId(), JOB_FINISHED_STATES);
+
+        if (immutablePair.getRight() == null) {
+            final String message = "Failed to create AS for request: \n" + createAsRequest;
+            logger.error(message);
+            throw new AsRequestProcessingException(message);
+        }
+        final JobStatusEnum finalJobStatus = immutablePair.getRight();
+        final String processInstanceId = immutablePair.getLeft();
+
+        if (!FINISHED.equals(finalJobStatus)) {
+
+            final Optional<ErrorDetails> optional = workflowQueryService.getErrorDetails(processInstanceId);
+            if (optional.isPresent()) {
+                final ErrorDetails errorDetails = optional.get();
+                final String message =
+                        "Failed to create AS for request: \n" + createAsRequest + " due to \n" + errorDetails;
+                logger.error(message);
+                throw new AsRequestProcessingException(message, errorDetails);
+            }
+
+            final String message = "Received unexpected Job Status: " + finalJobStatus
+                    + " Failed to Create AS for request: \n" + createAsRequest;
+            logger.error(message);
+            throw new AsRequestProcessingException(message);
+        }
+
+        logger.debug("Will query for CreateAsResponse using processInstanceId:{}", processInstanceId);
+        final Optional<AsInstance> optional = workflowQueryService.getCreateNsResponse(processInstanceId);
+        if (optional.isEmpty()) {
+            final String message =
+                    "Unable to find CreateAsReponse in Camunda History for process instance: " + processInstanceId;
+            logger.error(message);
+            throw new AsRequestProcessingException(message);
+        }
+        return optional.get();
+    }
+
+    public String runInstantiateAsJob(final String asInstanceId, final InstantiateAsRequest instantiateAsRequest) {
+        final Job newJob = new Job().startTime(LocalDateTime.now()).jobType("AS").jobAction(JobAction.INSTANTIATE)
+                .resourceId(asInstanceId).status(JobStatusEnum.STARTING);
+        databaseServiceProvider.addJob(newJob);
+        logger.info("New job created in database :\n{}", newJob);
+
+        final LocalDateTime currentDateTime = LocalDateTime.now();
+        final AsLcmOpOcc newAsLcmOpOcc = new AsLcmOpOcc().id(asInstanceId).operation(AsLcmOpType.INSTANTIATE)
+                .operationState(OperationStateEnum.PROCESSING).stateEnteredTime(currentDateTime)
+                .startTime(currentDateTime).asInst(getAsInst(asInstanceId)).isAutoInvocation(false)
+                .isCancelPending(false).operationParams(gson.toJson(instantiateAsRequest));
+        databaseServiceProvider.addAsLcmOpOcc(newAsLcmOpOcc);
+        logger.info("New AsLcmOpOcc created in database :\n{}", newAsLcmOpOcc);
+
+        workflowExecutorService.executeWorkflow(newJob.getJobId(), INSTANTIATE_AS_WORKFLOW_NAME,
+                getVariables(asInstanceId, newJob.getJobId(), newAsLcmOpOcc.getId(), instantiateAsRequest));
+
+        final ImmutableSet<JobStatusEnum> jobFinishedStates =
+                ImmutableSet.of(FINISHED, ERROR, FINISHED_WITH_ERROR, IN_PROGRESS);
+        final ImmutablePair<String, JobStatusEnum> immutablePair =
+                waitForJobToFinish(newJob.getJobId(), jobFinishedStates);
+
+        if (immutablePair.getRight() == null) {
+            final String message = "Failed to Instantiate AS for request: \n" + instantiateAsRequest;
+            logger.error(message);
+            throw new AsRequestProcessingException(message);
+        }
+
+        final JobStatusEnum finalJobStatus = immutablePair.getRight();
+        if (IN_PROGRESS.equals(finalJobStatus) || FINISHED.equals(finalJobStatus)) {
+            logger.info("Instantiation Job status: {}", finalJobStatus);
+            return newAsLcmOpOcc.getId();
+        }
+
+        final String message = "Received unexpected Job Status: " + finalJobStatus
+                + " Failed to instantiate AS for request: \n" + instantiateAsRequest;
+        logger.error(message);
+        throw new AsRequestProcessingException(message);
+    }
+
+    public String runTerminateAsJob(final String asInstanceId, final TerminateAsRequest terminateAsRequest) {
+        doInitialTerminateChecks(asInstanceId, terminateAsRequest);
+
+        final Job newJob = new Job().startTime(LocalDateTime.now()).jobType("AS").jobAction(JobAction.TERMINATE)
+                .resourceId(asInstanceId).status(JobStatusEnum.STARTING);
+        databaseServiceProvider.addJob(newJob);
+        logger.info("New job created in database :\n{}", newJob);
+
+        final LocalDateTime currentDateTime = LocalDateTime.now();
+        final AsLcmOpOcc newAsLcmOpOcc = new AsLcmOpOcc().id(asInstanceId).operation(AsLcmOpType.TERMINATE)
+                .operationState(OperationStateEnum.PROCESSING).stateEnteredTime(currentDateTime)
+                .startTime(currentDateTime).asInst(getAsInst(asInstanceId)).isAutoInvocation(false)
+                .isCancelPending(false).operationParams(gson.toJson(terminateAsRequest));
+        databaseServiceProvider.addAsLcmOpOcc(newAsLcmOpOcc);
+        logger.info("New AsLcmOpOcc created in database :\n{}", newAsLcmOpOcc);
+
+        workflowExecutorService.executeWorkflow(newJob.getJobId(), TERMINATE_AS_WORKFLOW_NAME,
+                getVariables(asInstanceId, newJob.getJobId(), newAsLcmOpOcc.getId(), terminateAsRequest));
+
+        final ImmutableSet<JobStatusEnum> jobFinishedStates =
+                ImmutableSet.of(FINISHED, ERROR, FINISHED_WITH_ERROR, IN_PROGRESS);
+        final ImmutablePair<String, JobStatusEnum> immutablePair =
+                waitForJobToFinish(newJob.getJobId(), jobFinishedStates);
+
+        if (immutablePair.getRight() == null) {
+            final String message =
+                    "Failed to Terminate AS with id: " + asInstanceId + " for request: \n" + terminateAsRequest;
+            logger.error(message);
+            throw new AsRequestProcessingException(message);
+        }
+
+        final JobStatusEnum finalJobStatus = immutablePair.getRight();
+
+        if (IN_PROGRESS.equals(finalJobStatus) || FINISHED.equals(finalJobStatus)) {
+            logger.info("Termination Job status: {}", finalJobStatus);
+            return newAsLcmOpOcc.getId();
+        }
+
+        final String message = "Received unexpected Job Status: " + finalJobStatus + " Failed to Terminate AS with id: "
+                + asInstanceId + " for request: \n" + terminateAsRequest;
+        logger.error(message);
+        throw new AsRequestProcessingException(message);
+    }
+
+    public void runDeleteAsJob(final String asInstanceId) {
+        final Job newJob = new Job().startTime(LocalDateTime.now()).jobType("AS").jobAction(JobAction.DELETE)
+                .resourceId(asInstanceId).status(JobStatusEnum.STARTING);
+        databaseServiceProvider.addJob(newJob);
+        logger.info("New job created in database :\n{}", newJob);
+
+        workflowExecutorService.executeWorkflow(newJob.getJobId(), DELETE_AS_WORKFLOW_NAME,
+                getVariables(asInstanceId, newJob.getJobId()));
+
+        final ImmutablePair<String, JobStatusEnum> immutablePair =
+                waitForJobToFinish(newJob.getJobId(), JOB_FINISHED_STATES);
+
+        if (immutablePair.getRight() == null) {
+            final String message = "Failed to Delete AS with id: " + asInstanceId;
+            logger.error(message);
+            throw new AsRequestProcessingException(message);
+        }
+
+        final JobStatusEnum finalJobStatus = immutablePair.getRight();
+        final String processInstanceId = immutablePair.getLeft();
+
+        logger.info("Delete Job status: {}", finalJobStatus);
+
+        if (!FINISHED.equals(finalJobStatus)) {
+
+            final Optional<ErrorDetails> optional = workflowQueryService.getErrorDetails(processInstanceId);
+            if (optional.isPresent()) {
+                final ErrorDetails errorDetails = optional.get();
+                final String message = "Failed to Delete AS with id: " + asInstanceId + " due to \n" + errorDetails;
+                logger.error(message);
+                throw new AsRequestProcessingException(message, errorDetails);
+            }
+
+            final String message = "Received unexpected Job Status: " + finalJobStatus
+                    + " Failed to Delete AS with id: " + asInstanceId;
+            logger.error(message);
+            throw new AsRequestProcessingException(message);
+        }
+
+        logger.debug("Delete AS finished successfully ...");
+    }
+
+    private AsInst getAsInst(final String asInstId) {
+        logger.info("Getting AsInst with nsInstId: {}", asInstId);
+        final Optional<AsInst> optionalNfvoNsInst = databaseServiceProvider.getAsInst(asInstId);
+
+        if (optionalNfvoNsInst.isEmpty()) {
+            final String message = "No matching AS Instance for id: " + asInstId + " found in database.";
+            throw new AsRequestProcessingException(message);
+        }
+
+        return optionalNfvoNsInst.get();
+    }
+
+    private ImmutablePair<String, JobStatusEnum> waitForJobToFinish(final String jobId,
+            final ImmutableSet<JobStatusEnum> jobFinishedStates) {
+        try {
+            final long startTimeInMillis = System.currentTimeMillis();
+            final long timeOutTime = startTimeInMillis + TimeUnit.SECONDS.toMillis(timeOutInSeconds);
+
+            logger.info("Will wait till {} for {} job to finish", Instant.ofEpochMilli(timeOutTime).toString(), jobId);
+            JobStatusEnum currentJobStatus = null;
+            while (timeOutTime > System.currentTimeMillis()) {
+
+                final Optional<Job> optional = databaseServiceProvider.getRefreshedJob(jobId);
+
+                if (optional.isEmpty()) {
+                    logger.error("Unable to find Job using jobId: {}", jobId);
+                    return ImmutablePair.nullPair();
+                }
+
+                final Job job = optional.get();
+                currentJobStatus = job.getStatus();
+                logger.debug("Received job status response: \n {}", job);
+                if (jobFinishedStates.contains(currentJobStatus)) {
+                    logger.info("Job finished \n {}", currentJobStatus);
+                    return ImmutablePair.of(job.getProcessInstanceId(), currentJobStatus);
+                }
+
+                logger.info("Haven't received one of finish state {} yet, will try again in {} seconds",
+                        jobFinishedStates, SLEEP_TIME_IN_SECONDS);
+                TimeUnit.SECONDS.sleep(SLEEP_TIME_IN_SECONDS);
+
+            }
+            logger.warn("Timeout current job status: {}", currentJobStatus);
+            return ImmutablePair.nullPair();
+        } catch (final InterruptedException interruptedException) {
+            Thread.currentThread().interrupt();
+            logger.error("Sleep was interrupted", interruptedException);
+            return ImmutablePair.nullPair();
+        }
+    }
+
+    private void doInitialTerminateChecks(final String asInstanceId, final TerminateAsRequest terminateAsRequest) {
+        final AsInst asInst = getAsInst(asInstanceId);
+        if (isNotInstantiated(asInst)) {
+            final String message = "TerminateAsRequest received: " + terminateAsRequest + " for asInstanceId: "
+                    + asInstanceId + "\nUnable to terminate.  AS Instance is already in " + State.NOT_INSTANTIATED
+                    + " state." + "\nThis method can only be used with an AS instance in the " + State.INSTANTIATED
+                    + " state.";
+            logger.error(message);
+            throw new AsRequestProcessingException(message);
+        }
+    }
+
+    private boolean isNotInstantiated(final AsInst asInst) {
+        return State.NOT_INSTANTIATED.equals(asInst.getStatus());
+    }
+
+    private Map<String, Object> getVariables(final String jobId, final CreateAsRequest createAsRequest) {
+        final Map<String, Object> variables = new HashMap<>();
+        variables.put(JOB_ID_PARAM_NAME, jobId);
+        variables.put(CREATE_AS_REQUEST_PARAM_NAME, createAsRequest);
+        return variables;
+    }
+
+    private Map<String, Object> getVariables(final String asInstanceId, final String jobId, final String occId,
+            final InstantiateAsRequest instantiateAsRequest) {
+        final Map<String, Object> variables = new HashMap<>();
+        variables.put(AS_INSTANCE_ID_PARAM_NAME, asInstanceId);
+        variables.put(JOB_ID_PARAM_NAME, jobId);
+        variables.put(OCC_ID_PARAM_NAME, occId);
+        variables.put(INSTANTIATE_AS_REQUEST_PARAM_NAME, instantiateAsRequest);
+        return variables;
+    }
+
+    private Map<String, Object> getVariables(final String asInstanceId, final String jobId, final String occId,
+            final TerminateAsRequest terminateAsRequest) {
+        final Map<String, Object> variables = new HashMap<>();
+        variables.put(AS_INSTANCE_ID_PARAM_NAME, asInstanceId);
+        variables.put(JOB_ID_PARAM_NAME, jobId);
+        variables.put(OCC_ID_PARAM_NAME, occId);
+        variables.put(TERMINATE_AS_REQUEST_PARAM_NAME, terminateAsRequest);
+        return variables;
+    }
+
+    private Map<String, Object> getVariables(final String asInstanceId, final String jobId) {
+        final Map<String, Object> variables = new HashMap<>();
+        variables.put(AS_INSTANCE_ID_PARAM_NAME, asInstanceId);
+        variables.put(JOB_ID_PARAM_NAME, jobId);
+        return variables;
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/WorkflowExecutorService.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/WorkflowExecutorService.java
new file mode 100644 (file)
index 0000000..57a8a41
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.service;
+
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.TENANT_ID;
+import static org.slf4j.LoggerFactory.getLogger;
+import java.util.Map;
+import org.camunda.bpm.engine.RuntimeService;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class WorkflowExecutorService {
+
+    private static final Logger logger = getLogger(WorkflowExecutorService.class);
+
+    private final RuntimeService runtimeService;
+
+    @Autowired
+    public WorkflowExecutorService(final RuntimeService runtimeService) {
+        this.runtimeService = runtimeService;
+    }
+
+    @Async
+    public void executeWorkflow(final String jobId, final String processDefinitionKey,
+            final Map<String, Object> variables) {
+        logger.info("Executing {} workflow with business key: {}", processDefinitionKey, jobId);
+        final ProcessInstance processInstance = runtimeService.createProcessInstanceByKey(processDefinitionKey)
+                .businessKey(jobId).setVariables(variables).processDefinitionTenantId(TENANT_ID).execute();
+
+        logger.info("Workflow running with processInstanceId: {} and business key: {}",
+                processInstance.getProcessInstanceId(), processInstance.getBusinessKey());
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/WorkflowQueryService.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/WorkflowQueryService.java
new file mode 100644 (file)
index 0000000..b6dbd77
--- /dev/null
@@ -0,0 +1,111 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.service;
+
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.AS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_AS_RESPONSE_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.TENANT_ID;
+import static org.slf4j.LoggerFactory.getLogger;
+import java.util.Optional;
+import org.camunda.bpm.engine.HistoryService;
+import org.camunda.bpm.engine.ProcessEngineException;
+import org.camunda.bpm.engine.history.HistoricVariableInstance;
+import org.onap.so.cnfm.lcm.model.AsInstance;
+import org.onap.so.cnfm.lcm.model.ErrorDetails;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.google.common.base.Strings;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class WorkflowQueryService {
+
+    private static final Logger logger = getLogger(WorkflowQueryService.class);
+
+    private final HistoryService camundaHistoryService;
+
+    @Autowired
+    public WorkflowQueryService(final HistoryService camundaHistoryService) {
+        this.camundaHistoryService = camundaHistoryService;
+    }
+
+    public Optional<AsInstance> getCreateNsResponse(final String processInstanceId) {
+        try {
+
+            if (Strings.isNullOrEmpty(processInstanceId)) {
+                logger.error("Invalid processInstanceId: {}", processInstanceId);
+                return Optional.empty();
+            }
+
+            final HistoricVariableInstance historicVariableInstance =
+                    getVariable(processInstanceId, CREATE_AS_RESPONSE_PARAM_NAME);
+
+            if (historicVariableInstance != null) {
+                logger.info("Found HistoricVariableInstance : {}", historicVariableInstance);
+                final Object variableValue = historicVariableInstance.getValue();
+                if (variableValue instanceof AsInstance) {
+                    return Optional.ofNullable((AsInstance) variableValue);
+                }
+                logger.error("Unknown CreateAsResponse object type {} received value: {}",
+                        historicVariableInstance.getValue() != null ? variableValue.getClass() : null, variableValue);
+            }
+        } catch (final ProcessEngineException processEngineException) {
+            logger.error("Unable to find {} variable using processInstanceId: {}", CREATE_AS_RESPONSE_PARAM_NAME,
+                    processInstanceId, processEngineException);
+        }
+        logger.error("Unable to find {} variable using processInstanceId: {}", CREATE_AS_RESPONSE_PARAM_NAME,
+                processInstanceId);
+        return Optional.empty();
+
+    }
+
+    public Optional<ErrorDetails> getErrorDetails(final String processInstanceId) {
+        try {
+            final HistoricVariableInstance historicVariableInstance =
+                    getVariable(processInstanceId, AS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME);
+
+            logger.info("Found HistoricVariableInstance : {}", historicVariableInstance);
+            if (historicVariableInstance != null) {
+                final Object variableValue = historicVariableInstance.getValue();
+                if (variableValue instanceof ErrorDetails) {
+                    return Optional.ofNullable((ErrorDetails) variableValue);
+                }
+                logger.error("Unknown ErrorContents object type {} received value: {}",
+                        historicVariableInstance.getValue() != null ? variableValue.getClass() : null, variableValue);
+            }
+            logger.error("Unable to retrieve HistoricVariableInstance value was null");
+        } catch (final ProcessEngineException processEngineException) {
+            logger.error("Unable to find {} variable using processInstanceId: {}",
+                    AS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, processInstanceId, processEngineException);
+        }
+        return Optional.empty();
+    }
+
+
+    private HistoricVariableInstance getVariable(final String processInstanceId, final String name) {
+        return camundaHistoryService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId)
+                .variableName(name).tenantIdIn(TENANT_ID).singleResult();
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java
new file mode 100644 (file)
index 0000000..57a4dd6
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.utils;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class LocalDateTimeTypeAdapter extends TypeAdapter<LocalDateTime> {
+
+    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+    @Override
+    public void write(final JsonWriter out, final LocalDateTime localDateTime) throws IOException {
+        if (localDateTime == null) {
+            out.nullValue();
+        } else {
+            out.value(FORMATTER.format(localDateTime));
+        }
+    }
+
+    @Override
+    public LocalDateTime read(final JsonReader in) throws IOException {
+        if (JsonToken.NULL == in.peek()) {
+            in.nextNull();
+            return null;
+
+        }
+        final String dateTime = in.nextString();
+        return LocalDateTime.parse(dateTime, FORMATTER);
+
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/OffsetDateTimeTypeAdapter.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/OffsetDateTimeTypeAdapter.java
new file mode 100644 (file)
index 0000000..1f63cc1
--- /dev/null
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.utils;
+
+import java.io.IOException;
+import java.time.OffsetDateTime;
+import java.time.format.DateTimeFormatter;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class OffsetDateTimeTypeAdapter extends TypeAdapter<OffsetDateTime> {
+
+    private DateTimeFormatter formatter;
+
+    public OffsetDateTimeTypeAdapter() {
+        this(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+    }
+
+    public OffsetDateTimeTypeAdapter(final DateTimeFormatter formatter) {
+        this.formatter = formatter;
+    }
+
+    @Override
+    public void write(final JsonWriter out, final OffsetDateTime date) throws IOException {
+        if (date == null) {
+            out.nullValue();
+        } else {
+            out.value(formatter.format(date));
+        }
+    }
+
+    @Override
+    public OffsetDateTime read(final JsonReader in) throws IOException {
+        if (JsonToken.NULL == in.peek()) {
+            in.nextNull();
+            return null;
+
+        }
+        String date = in.nextString();
+        if (date.endsWith("+0000")) {
+            date = date.substring(0, date.length() - 5) + "Z";
+        }
+        return OffsetDateTime.parse(date, formatter);
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/PropertiesToYamlConverter.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/PropertiesToYamlConverter.java
new file mode 100644 (file)
index 0000000..4cc1f8a
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.utils;
+
+import java.util.Map;
+import java.util.TreeMap;
+import org.springframework.stereotype.Service;
+import org.yaml.snakeyaml.Yaml;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+
+@Service
+public class PropertiesToYamlConverter {
+    public String getValuesYamlFileContent(final Map<String, String> lifeCycleParams) {
+        final Map<String, Object> root = new TreeMap<>();
+        lifeCycleParams.entrySet().stream().forEach(entry -> processProperty(root, entry.getKey(), entry.getValue()));
+        final Yaml yaml = new Yaml();
+        return yaml.dumpAsMap(root);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void processProperty(final Map<String, Object> root, final String key, final String value) {
+        Map<String, Object> local = root;
+        final String[] keys = key.split("\\.");
+        final int lastIndex = keys.length - 1;
+        for (int index = 0; index < lastIndex; index++) {
+            final String currentKey = keys[index];
+            if (!local.containsKey(currentKey)) {
+                final Map<String, Object> subMap = new TreeMap<>();
+                local.put(currentKey, subMap);
+                local = subMap;
+                continue;
+            } else {
+                local = (Map<String, Object>) local.get(currentKey);
+            }
+        }
+        local.put(keys[lastIndex], value);
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/META-INF/services/org.onap.so.client.RestProperties b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/META-INF/services/org.onap.so.client.RestProperties
new file mode 100644 (file)
index 0000000..90c1ca7
--- /dev/null
@@ -0,0 +1 @@
+org.onap.so.cnfm.lcm.bpmn.flows.extclients.aai.AaiPropertiesImpl
\ No newline at end of file
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPackageParserTest.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPackageParserTest.java
new file mode 100644 (file)
index 0000000..7de9bdc
--- /dev/null
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.extclients.sdc;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.APPLICATION_NAME_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.DESCRIPTOR_ID_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.DESCRIPTOR_INVARIANT_ID_PARAM_NAME;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Map;
+import org.junit.Test;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class SdcCsarPackageParserTest {
+
+    private static final String RESOURCE_ASD_PACKAGE_CSAR_PATH =
+            "src/test/resources/resource-Generatedasdpackage-csar.csar";
+
+    @Test
+    public void testResourceAsdCsar() throws IOException {
+        final SdcCsarPackageParser objUnderTest = new SdcCsarPackageParser();
+
+        final byte[] content = getFileContent(Paths.get(getAbsolutePath(RESOURCE_ASD_PACKAGE_CSAR_PATH)));
+
+        final Map<String, Object> properties = objUnderTest.getAsdProperties(content);
+        assertEquals("123e4567-e89b-12d3-a456-426614174000", properties.get(DESCRIPTOR_ID_PARAM_NAME));
+        assertEquals("123e4yyy-e89b-12d3-a456-426614174abc", properties.get(DESCRIPTOR_INVARIANT_ID_PARAM_NAME));
+        assertEquals("SampleApp", properties.get(APPLICATION_NAME_PARAM_NAME));
+        assertEquals("2.3", properties.get(SdcCsarPropertiesConstants.APPLICATION_VERSION_PARAM_NAME));
+        assertEquals("MyCompany", properties.get(SdcCsarPropertiesConstants.PROVIDER_PARAM_NAME));
+
+        @SuppressWarnings("unchecked")
+        final List<DeploymentItem> items =
+                (List<DeploymentItem>) properties.get(SdcCsarPropertiesConstants.DEPLOYMENT_ITEMS_PARAM_NAME);
+        assertNotNull(items);
+        assertTrue(items.size() == 2);
+
+        DeploymentItem deploymentItem = items.get(0);
+        assertEquals("sampleapp-db", deploymentItem.getName());
+        assertEquals("1", deploymentItem.getItemId());
+        assertEquals("1", deploymentItem.getDeploymentOrder());
+        assertEquals("Artifacts/Deployment/HELM/sampleapp-db-operator-helm.tgz", deploymentItem.getFile());
+
+
+    }
+
+    private String getAbsolutePath(final String path) {
+        final File file = new File(path);
+        return file.getAbsolutePath();
+    }
+
+    private byte[] getFileContent(final Path path) throws IOException {
+        return Files.readAllBytes(path);
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapterTest.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapterTest.java
new file mode 100644 (file)
index 0000000..3015d87
--- /dev/null
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.utils;
+
+import static org.junit.Assert.assertEquals;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.time.LocalDateTime;
+import org.junit.Test;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class LocalDateTimeTypeAdapterTest {
+    private static final LocalDateTime LOCAL_DATETIME_VALUE = LocalDateTime.of(2023, 1, 1, 12, 0, 15);
+    private static final String STRING_VALUE = "\"2023-01-01 12:00:15\"";
+
+    @Test
+    public void testReadWithValidLocalDateTimeString() throws IOException {
+        final LocalDateTimeTypeAdapter objUnderTest = new LocalDateTimeTypeAdapter();
+
+        final Reader reader = new StringReader(STRING_VALUE);
+        final JsonReader jsonReader = new JsonReader(reader);
+
+        final LocalDateTime actual = objUnderTest.read(jsonReader);
+        assertEquals(LOCAL_DATETIME_VALUE, actual);
+
+    }
+
+    @Test
+    public void testWritedWithValidLocalDateTime() throws IOException {
+        final LocalDateTimeTypeAdapter objUnderTest = new LocalDateTimeTypeAdapter();
+
+        final StringWriter writer = new StringWriter();
+        final JsonWriter jsonWriter = new JsonWriter(writer);
+
+        objUnderTest.write(jsonWriter, LOCAL_DATETIME_VALUE);
+        assertEquals(STRING_VALUE, writer.toString());
+
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/OffsetDateTimeTypeAdapterTest.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/OffsetDateTimeTypeAdapterTest.java
new file mode 100644 (file)
index 0000000..0adbef0
--- /dev/null
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.utils;
+
+import static org.junit.Assert.assertEquals;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import org.junit.Test;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class OffsetDateTimeTypeAdapterTest {
+    private static final OffsetDateTime OFF_SET_DATETIME_VALUE =
+            OffsetDateTime.of(2023, 1, 1, 12, 00, 15, 0, ZoneOffset.UTC);
+    private static final String STRING_VALUE = "\"2023-01-01T12:00:15Z\"";
+
+    @Test
+    public void testReadWithValidOffsetDateTimeString() throws IOException {
+        final OffsetDateTimeTypeAdapter objUnderTest = new OffsetDateTimeTypeAdapter();
+
+        final Reader reader = new StringReader(STRING_VALUE);
+        final JsonReader jsonReader = new JsonReader(reader);
+
+        final OffsetDateTime actual = objUnderTest.read(jsonReader);
+        assertEquals(OFF_SET_DATETIME_VALUE, actual);
+
+    }
+
+    @Test
+    public void testWritedWithValidOffsetDateTime() throws IOException {
+        final OffsetDateTimeTypeAdapter objUnderTest = new OffsetDateTimeTypeAdapter();
+
+        final StringWriter writer = new StringWriter();
+        final JsonWriter jsonWriter = new JsonWriter(writer);
+
+        objUnderTest.write(jsonWriter, OFF_SET_DATETIME_VALUE);
+        assertEquals(STRING_VALUE, writer.toString());
+
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/PropertiesToYamlConverterTest.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/PropertiesToYamlConverterTest.java
new file mode 100644 (file)
index 0000000..2410d73
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.utils;
+
+import static org.junit.Assert.assertEquals;
+import java.util.Map;
+import org.junit.Test;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class PropertiesToYamlConverterTest {
+
+    @Test
+    public void testGetValuesYamlFileContent() {
+        final String expected = "primary:\n" + "  service:\n" + "    nodePorts:\n" + "      mysql: '1234'\n"
+                + "    ports:\n" + "      mysql: dummy\n";
+        final PropertiesToYamlConverter objUnderTest = new PropertiesToYamlConverter();
+        final Map<String, String> lifeCycleParams =
+                Map.of("primary.service.ports.mysql", "dummy", "primary.service.nodePorts.mysql", "1234");
+        final String actual = objUnderTest.getValuesYamlFileContent(lifeCycleParams);
+
+        assertEquals(expected, actual);
+
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/application.yaml b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/application.yaml
new file mode 100644 (file)
index 0000000..404bbdb
--- /dev/null
@@ -0,0 +1,52 @@
+# Copyright © 2022 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.
+spring:
+   main:
+      allow-bean-definition-overriding: true
+   datasource:
+      hikari:
+         camunda:
+            jdbcUrl: jdbc:h2:mem:example-simple;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
+            driver-class-name: org.h2.Driver
+            pool-name: cnfm-lcm-bpmn-pool
+            registerMbeans: true
+         cnfm:
+            jdbcUrl: jdbc:h2:mem:nfvo;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS cnfm;MODE=MYSQL;DATABASE_TO_LOWER=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE
+            driver-class-name: org.h2.Driver
+            pool-name: cnfm-lcm-bpmn-pool
+            registerMbeans: true
+   jpa:
+      generate-ddl: true
+      hibernate:
+         ddl-auto: create
+hibernate:
+   dialect: org.hibernate.dialect.H2Dialect
+   hbm2ddl:
+      auto: create
+aai:
+   version: v19
+   endpoint: http://localhost:${wiremock.server.port}
+sdc:
+   endpoint: http://localhost:${wiremock.server.port}
+logging:
+   level:
+      org.reflections.Reflections: ERROR
+cnfm:
+   kube-configs-dir: ${java.io.tmpdir}/kube-configs
+   csar:
+      dir: ${java.io.tmpdir}
+kubernetes:
+   client:
+      http-request:
+         timeoutSeconds: 1
\ No newline at end of file
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/request.json b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/request.json
new file mode 100644 (file)
index 0000000..042247f
--- /dev/null
@@ -0,0 +1,25 @@
+{
+    "deploymentItems": [
+        {
+            "deploymentItemsId": "1",
+            "lifecycleParameterKeyValues": {
+                ".Values.primary.service.ports.mysql": "dummy",
+                ".Values.primary.service.nodePorts.mysql": "dummy"
+            }
+        },
+        {
+            "deploymentItemsId": "2",
+            "lifecycleParameterKeyValues": {
+
+            }
+        }
+    ],
+    "asdExtCpdInputParams": {
+        "extCpdId": null,
+        "loadbalanceIP": null,
+        "externalIPs": [],
+        "nadNames": [],
+        "nadNamespace": null
+    },
+    "additionalParams": {}
+}
\ No newline at end of file
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/resource-Generatedasdpackage-csar.csar b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/resource-Generatedasdpackage-csar.csar
new file mode 100644 (file)
index 0000000..b3c629d
Binary files /dev/null and b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/resource-Generatedasdpackage-csar.csar differ
index 4d40087..5e1c638 100644 (file)
@@ -40,19 +40,20 @@ public class Utils {
             return second == null;
         }
 
-        if (first.isEmpty()) {
-            return second.isEmpty();
+        if (second == null) {
+            return false;
+        }
+
+        if (first.size() != second.size()) {
+            return false;
         }
-        if ((first != null && second != null) && (first.size() == second.size())) {
-            for (int index = 0; index < first.size(); index++) {
-                if (!Objects.equals(first.get(index), second.get(index))) {
-                    return false;
-                }
-            }
-            return true;
 
+        for (int index = 0; index < first.size(); index++) {
+            if (!Objects.equals(first.get(index), second.get(index))) {
+                return false;
+            }
         }
-        return false;
+        return true;
     }
 
 
index 62a90f8..043b846 100644 (file)
@@ -55,9 +55,6 @@ public class CnfmDatabaseConfiguration {
     private static final String PERSISTENCE_UNIT = "cnfm";
     private static final String CNFM_DATA_SOURCE_QUALIFIER = "cnfmDataSource";
 
-    @Autowired(required = false)
-    private MBeanExporter mBeanExporter;
-
     @Bean
     @ConfigurationProperties(prefix = "spring.datasource.hikari.cnfm")
     public HikariConfig cnfmDbConfig() {
@@ -68,7 +65,7 @@ public class CnfmDatabaseConfiguration {
     @Primary
     @FlywayDataSource
     @Bean(name = CNFM_DATA_SOURCE_QUALIFIER)
-    public DataSource dataSource() {
+    public DataSource dataSource(@Autowired(required = false) final MBeanExporter mBeanExporter) {
         if (mBeanExporter != null) {
             mBeanExporter.addExcludedBean(CNFM_DATA_SOURCE_QUALIFIER);
         }
index ab24f94..9d9714e 100644 (file)
@@ -50,6 +50,11 @@ public class UtilsTest {
     public void testNullListAndEmptyList_notEqual() {
         assertFalse(Utils.isEquals(null, Collections.emptyList()));
     }
+    
+    @Test
+    public void testEmptyListAndNullList_notEqual() {
+        assertFalse(Utils.isEquals(Collections.emptyList(), null));
+    }
 
     @Test
     public void testTwoNotEmptyListsContainSameObjects_equal() {
index d353ea6..4397fb5 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2022 Nordix Foundation.
+ *  Copyright (C) 2023 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.