summaryrefslogtreecommitdiffstats
path: root/so-cnfm/so-cnfm-lcm
diff options
context:
space:
mode:
authorwaqas.ikram <waqas.ikram@est.tech>2023-01-23 11:58:29 +0000
committerwaqas.ikram <waqas.ikram@est.tech>2023-01-23 11:58:40 +0000
commitbd591af78a4ab97af4f65d6b7094d9c60f7879c4 (patch)
treed16a23906298c6b1875712ab2acae64716531ff5 /so-cnfm/so-cnfm-lcm
parent80d8598e1013ddee747957adf7d96ec7fb901f0b (diff)
Adding common classes for workflows
Change-Id: Id86256ee21ee8c78da82ae3141f7936191593597 Issue-ID: SO-4068 Signed-off-by: waqas.ikram <waqas.ikram@est.tech>
Diffstat (limited to 'so-cnfm/so-cnfm-lcm')
-rw-r--r--so-cnfm/so-cnfm-lcm/pom.xml1
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/pom.xml145
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaCustomConfiguration.java49
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaDatabaseConfiguration.java89
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaVariableNameConstants.java53
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/Constants.java45
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/GsonProvider.java45
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/AsRequestProcessingException.java55
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/BasicAuthConfigException.java37
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/FileNotFoundInCsarException.java44
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/PropertyNotFoundException.java44
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/SdcPackageRequestFailureException.java42
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java34
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java108
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java68
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java211
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/kubernetes/KubernetesResource.java209
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/DeploymentItem.java143
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcClientConfigurationProvider.java79
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPackageParser.java201
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPropertiesConstants.java37
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcHttpRestServiceProviderConfiguration.java108
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcPackageProvider.java33
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcPackageProviderImpl.java80
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/JobExecutorService.java376
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/WorkflowExecutorService.java59
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/WorkflowQueryService.java111
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java59
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/OffsetDateTimeTypeAdapter.java68
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/PropertiesToYamlConverter.java59
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/META-INF/services/org.onap.so.client.RestProperties1
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPackageParserTest.java83
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapterTest.java64
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/OffsetDateTimeTypeAdapterTest.java66
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/PropertiesToYamlConverterTest.java45
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/application.yaml52
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/request.json25
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/resource-Generatedasdpackage-csar.csarbin0 -> 72173 bytes
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/beans/AsLifecycleParam.java2
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/beans/utils/Utils.java21
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/config/CnfmDatabaseConfiguration.java5
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/test/java/org/onap/so/cnfm/lcm/database/beans/utils/UtilsTest.java5
-rw-r--r--so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/test/java/org/onap/so/cnfm/lcm/database/service/DatabaseServiceProviderTest.java2
43 files changed, 3047 insertions, 16 deletions
diff --git a/so-cnfm/so-cnfm-lcm/pom.xml b/so-cnfm/so-cnfm-lcm/pom.xml
index 4d6df9e..ad758d1 100644
--- a/so-cnfm/so-cnfm-lcm/pom.xml
+++ b/so-cnfm/so-cnfm-lcm/pom.xml
@@ -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
index 0000000..3982680
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/pom.xml
@@ -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
index 0000000..765d25b
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaCustomConfiguration.java
@@ -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
index 0000000..cc8bb01
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaDatabaseConfiguration.java
@@ -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
index 0000000..47c5795
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/CamundaVariableNameConstants.java
@@ -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
index 0000000..45c36be
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/Constants.java
@@ -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
index 0000000..486c528
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/GsonProvider.java
@@ -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
index 0000000..991c3c3
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/AsRequestProcessingException.java
@@ -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
index 0000000..4b9bfb1
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/BasicAuthConfigException.java
@@ -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
index 0000000..4bad50c
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/FileNotFoundInCsarException.java
@@ -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
index 0000000..908a04d
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/PropertyNotFoundException.java
@@ -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
index 0000000..d33c51f
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/SdcPackageRequestFailureException.java
@@ -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
index 0000000..aceafe7
--- /dev/null
+++ 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
@@ -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
index 0000000..b0986d8
--- /dev/null
+++ 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
@@ -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
index 0000000..fae677d
--- /dev/null
+++ 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
@@ -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
index 0000000..4f5ec8d
--- /dev/null
+++ 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
@@ -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
index 0000000..7ec50f0
--- /dev/null
+++ 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
@@ -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
index 0000000..1062cb7
--- /dev/null
+++ 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
@@ -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
index 0000000..4ae1d43
--- /dev/null
+++ 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
@@ -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
index 0000000..0ade7bf
--- /dev/null
+++ 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
@@ -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
index 0000000..40a0d0d
--- /dev/null
+++ 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
@@ -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
index 0000000..f727e07
--- /dev/null
+++ 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
@@ -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
index 0000000..f75d5f5
--- /dev/null
+++ 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
@@ -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
index 0000000..5e69661
--- /dev/null
+++ 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
@@ -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
index 0000000..c4bd210
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/JobExecutorService.java
@@ -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
index 0000000..57a8a41
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/WorkflowExecutorService.java
@@ -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
index 0000000..b6dbd77
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/WorkflowQueryService.java
@@ -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
index 0000000..57a4dd6
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java
@@ -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
index 0000000..1f63cc1
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/OffsetDateTimeTypeAdapter.java
@@ -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
index 0000000..4cc1f8a
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/PropertiesToYamlConverter.java
@@ -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
index 0000000..90c1ca7
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/META-INF/services/org.onap.so.client.RestProperties
@@ -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
index 0000000..7de9bdc
--- /dev/null
+++ 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
@@ -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
index 0000000..3015d87
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapterTest.java
@@ -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
index 0000000..0adbef0
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/OffsetDateTimeTypeAdapterTest.java
@@ -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
index 0000000..2410d73
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/PropertiesToYamlConverterTest.java
@@ -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
index 0000000..404bbdb
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/application.yaml
@@ -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
index 0000000..042247f
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/request.json
@@ -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
index 0000000..b3c629d
--- /dev/null
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/resources/resource-Generatedasdpackage-csar.csar
Binary files differ
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/beans/AsLifecycleParam.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/beans/AsLifecycleParam.java
index 607886c..ed8b098 100644
--- a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/beans/AsLifecycleParam.java
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/beans/AsLifecycleParam.java
@@ -54,7 +54,7 @@ public class AsLifecycleParam {
private String lifecycleParam;
public AsLifecycleParam() {
-
+ // default constructor
}
public void setAsLifecycleParamId(final Integer asLifecycleParamId) {
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/beans/utils/Utils.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/beans/utils/Utils.java
index 4d40087..5e1c638 100644
--- a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/beans/utils/Utils.java
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/beans/utils/Utils.java
@@ -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;
}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/config/CnfmDatabaseConfiguration.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/config/CnfmDatabaseConfiguration.java
index 62a90f8..043b846 100644
--- a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/config/CnfmDatabaseConfiguration.java
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/main/java/org/onap/so/cnfm/lcm/database/config/CnfmDatabaseConfiguration.java
@@ -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);
}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/test/java/org/onap/so/cnfm/lcm/database/beans/utils/UtilsTest.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/test/java/org/onap/so/cnfm/lcm/database/beans/utils/UtilsTest.java
index ab24f94..9d9714e 100644
--- a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/test/java/org/onap/so/cnfm/lcm/database/beans/utils/UtilsTest.java
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/test/java/org/onap/so/cnfm/lcm/database/beans/utils/UtilsTest.java
@@ -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() {
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/test/java/org/onap/so/cnfm/lcm/database/service/DatabaseServiceProviderTest.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/test/java/org/onap/so/cnfm/lcm/database/service/DatabaseServiceProviderTest.java
index d353ea6..4397fb5 100644
--- a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/test/java/org/onap/so/cnfm/lcm/database/service/DatabaseServiceProviderTest.java
+++ b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-database-service/src/test/java/org/onap/so/cnfm/lcm/database/service/DatabaseServiceProviderTest.java
@@ -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.