aboutsummaryrefslogtreecommitdiffstats
path: root/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap
diff options
context:
space:
mode:
Diffstat (limited to 'so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap')
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaCustomConfiguration.java49
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaDatabaseConfiguration.java92
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaVariableNameConstants.java55
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/Constants.java39
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/GsonProvider.java44
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/EtsiCatalogManagerRequestFailureException.java41
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/NsRequestProcessingException.java54
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java34
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java109
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java47
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java106
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java39
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java107
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java188
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogUrlProvider.java49
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterConfiguration.java148
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProvider.java37
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProviderImpl.java150
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterUrlProvider.java74
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java112
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptor.java121
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java75
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java123
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/FileParser.java33
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/NetworkServiceDescriptorParser.java213
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/ToscaMetadataParser.java70
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/YamlFileParser.java40
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java399
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowExecutorService.java59
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowQueryService.java108
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/AbstractNetworkServiceTask.java188
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateRequest.java167
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateVnfTask.java221
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateNsTask.java221
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/DeleteNsTask.java140
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/InstantiateNsTask.java328
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorInstantiateSol003AdapterNodeTask.java52
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterCreateJobTask.java105
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterJobTask.java96
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterNodeTask.java96
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateJobTask.java106
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateNodeTask.java55
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateNsTask.java134
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateVnfTask.java180
-rw-r--r--so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java59
45 files changed, 4963 insertions, 0 deletions
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaCustomConfiguration.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaCustomConfiguration.java
new file mode 100644
index 0000000..33923f4
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaCustomConfiguration.java
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.NS_WORKFLOW_ENGINE;
+import static org.onap.so.etsi.nfvo.ns.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, NS_WORKFLOW_ENGINE);
+ processEngineConfiguration.setDeploymentTenantId(TENANT_ID);
+ processEngineConfiguration.setDeploymentName(NS_WORKFLOW_ENGINE);
+ super.preInit(processEngineConfiguration);
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaDatabaseConfiguration.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaDatabaseConfiguration.java
new file mode 100644
index 0000000..770e91c
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaDatabaseConfiguration.java
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.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);
+
+ @Autowired(required = false)
+ private MBeanExporter mBeanExporter;
+
+ @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() {
+ 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-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaVariableNameConstants.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaVariableNameConstants.java
new file mode 100644
index 0000000..a7acc3e
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaVariableNameConstants.java
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class CamundaVariableNameConstants {
+
+ public static final String JOB_ID_PARAM_NAME = "jobId";
+ public static final String JOB_BUSINESS_KEY_PARAM_NAME = "jobBusinessKey";
+ public static final String CREATE_NS_REQUEST_PARAM_NAME = "createNsRequest";
+ public static final String GLOBAL_CUSTOMER_ID_PARAM_NAME = "globalCustomerId";
+ public static final String SERVICE_TYPE_PARAM_NAME = "serviceType";
+
+ public static final String NS_PACKAGE_MODEL_PARAM_NAME = "NSPackageModel";
+ public static final String NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME = "NsWorkflowProcessingException";
+ public static final String CREATE_NS_RESPONSE_PARAM_NAME = "createNsResponse";
+
+ public static final String INSTANTIATE_NS_REQUEST_PARAM_NAME = "instantiateNsRequest";
+ public static final String OCC_ID_PARAM_NAME = "occId";
+ public static final String NS_INSTANCE_ID_PARAM_NAME = "NsInstanceId";
+ public static final String NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME = "NetworkServiceDescriptor";
+ public static final String VNF_CREATE_INSTANTIATE_REQUESTS = "vnfCreateInstantiateRequests";
+
+ public static final String NF_INST_ID_PARAM_NAME = "NF_INST_ID";
+ public static final String CREATE_VNF_RESPONSE_PARAM_NAME = "createVnfResponse";
+ public static final String OPERATION_STATUS_PARAM_NAME = "operationStatus";
+
+ public static final String TERMINATE_NS_REQUEST_PARAM_NAME = "terminateNsRequest";
+ public static final String NFVO_NF_INST_IDS_PARAM_NAME = "nfvoNfInstIds";
+ public static final String DELETE_VNF_RESPONSE_PARAM_NAME = "deleteVnfResponse";
+ public static final String TERMINATE_VNF_VNFID_PARAM_NAME = "vnfId";
+
+ private CamundaVariableNameConstants() {}
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/Constants.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/Constants.java
new file mode 100644
index 0000000..c6c56c9
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/Constants.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class Constants {
+
+ public static final String TENANT_ID = "ns-workflow-engine-tenant";
+ public static final String NS_WORKFLOW_ENGINE = "NS-WORKFLOW-ENGINE";
+ public static final String CREATE_NS_WORKFLOW_NAME = "CreateNs";
+ public static final String INSTANTIATE_NS_WORKFLOW_NAME = "InstantiateNs";
+ public static final String TERMINATE_NS_WORKFLOW_NAME = "TerminateNs";
+ public static final String DELETE_NS_WORKFLOW_NAME = "DeleteNs";
+ public static final String GET_NS_OCCURRENCE_OPERATION_STATUS_NAME = "GetNsOccurrenceOperationStatus";
+
+
+ private Constants() {}
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/GsonProvider.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/GsonProvider.java
new file mode 100644
index 0000000..31961d5
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/GsonProvider.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows;
+
+import java.time.LocalDateTime;
+import org.onap.so.etsi.nfvo.ns.lcm.JSON;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.utils.LocalDateTimeTypeAdapter;
+import org.springframework.stereotype.Component;
+import org.threeten.bp.OffsetDateTime;
+import com.google.gson.Gson;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+public class GsonProvider {
+
+ private final JSON.OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new JSON.OffsetDateTimeTypeAdapter();
+
+ public Gson getGson() {
+ return JSON.createGson().registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter)
+ .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()).create();
+ }
+
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/EtsiCatalogManagerRequestFailureException.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/EtsiCatalogManagerRequestFailureException.java
new file mode 100644
index 0000000..553d2f1
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/EtsiCatalogManagerRequestFailureException.java
@@ -0,0 +1,41 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.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 EtsiCatalogManagerRequestFailureException extends RuntimeException {
+
+ private static final long serialVersionUID = 66862444537194516L;
+
+ public EtsiCatalogManagerRequestFailureException(final String message) {
+ super(message);
+ }
+
+ public EtsiCatalogManagerRequestFailureException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/NsRequestProcessingException.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/NsRequestProcessingException.java
new file mode 100644
index 0000000..0901f07
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/NsRequestProcessingException.java
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.exceptions;
+
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
+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 NsRequestProcessingException extends RuntimeException {
+
+ private static final long serialVersionUID = 66862444537194516L;
+ private final InlineResponse400 problemDetails;
+
+ public NsRequestProcessingException(final String message) {
+ super(message);
+ problemDetails = null;
+ }
+
+ public NsRequestProcessingException(final String message, final InlineResponse400 problemDetails) {
+ super(message);
+ this.problemDetails = problemDetails;
+ }
+
+ @Override
+ public synchronized Throwable fillInStackTrace() {
+ return this;
+ }
+
+ public InlineResponse400 getProblemDetails() {
+ return problemDetails;
+ }
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java
new file mode 100644
index 0000000..673662a
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.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-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java
new file mode 100644
index 0000000..25a43a8
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java
@@ -0,0 +1,109 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.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-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java
new file mode 100644
index 0000000..a54a6f4
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai;
+
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.aai.domain.yang.ServiceInstance;
+import java.util.Optional;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface AaiServiceProvider {
+
+ void createServiceInstance(final String globalCustomerId, final String serviceType,
+ final ServiceInstance aaiServiceInstance);
+
+ 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 deleteServiceInstance(final String globalCustomerId, final String serviceType, final String serviceInstanceId);
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java
new file mode 100644
index 0000000..a3b3fa9
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java
@@ -0,0 +1,106 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai;
+
+import java.util.Optional;
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.aai.domain.yang.ServiceInstance;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @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;
+
+ @Autowired
+ public AaiServiceProviderImpl(final AaiClientProvider aaiClientProvider) {
+ this.aaiClientProvider = aaiClientProvider;
+ }
+
+ @Override
+ public void createServiceInstance(final String globalCustomerId, final String serviceType,
+ final ServiceInstance aaiServiceInstance) {
+ logger.info("Creating service instance in AAI: {}", aaiServiceInstance);
+ final AAIResourceUri serviceInstanceURI =
+ AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalCustomerId)
+ .serviceSubscription(serviceType).serviceInstance(aaiServiceInstance.getServiceInstanceId()));
+ aaiClientProvider.getAaiClient().createIfNotExists(serviceInstanceURI, Optional.of(aaiServiceInstance));
+
+ }
+
+ @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 deleteServiceInstance(final String globalCustomerId, final String serviceType,
+ final String serviceInstanceId) {
+ logger.info(
+ "Deleting Service Instance with \nGlobal Customer Id: {}, \nService Type: {}, and \nService Instance Id: {} \nfrom AAI.",
+ globalCustomerId, serviceType, serviceInstanceId);
+ final AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business()
+ .customer(globalCustomerId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId));
+ aaiClientProvider.getAaiClient().delete(serviceInstanceUri);
+ }
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java
new file mode 100644
index 0000000..65d982c
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog;
+
+import java.util.Optional;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface EtsiCatalogPackageManagementServiceProvider {
+
+ Optional<NsdInfo> getNSPackageModel(final String nsdId);
+
+ Optional<VnfPkgInfo> getVnfPkgInfo(final String vnfPkgId);
+
+ Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor(final String nsdId);
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java
new file mode 100644
index 0000000..749e85e
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java
@@ -0,0 +1,107 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_SERVICE_PROVIDER_BEAN;
+import java.util.Optional;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.EtsiCatalogManagerRequestFailureException;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.parser.NetworkServiceDescriptorParser;
+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.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class EtsiCatalogPackageManagementServiceProviderImpl implements EtsiCatalogPackageManagementServiceProvider {
+
+ private static final Logger logger = LoggerFactory.getLogger(EtsiCatalogPackageManagementServiceProviderImpl.class);
+
+ private final HttpRestServiceProvider httpServiceProvider;
+ private final EtsiCatalogUrlProvider etsiCatalogUrlProvider;
+ private final NetworkServiceDescriptorParser networkServiceDescriptorParser;
+
+ @Autowired
+ public EtsiCatalogPackageManagementServiceProviderImpl(final EtsiCatalogUrlProvider etsiCatalogUrlProvider,
+ @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider,
+ final NetworkServiceDescriptorParser networkServiceDescriptorParser) {
+ this.etsiCatalogUrlProvider = etsiCatalogUrlProvider;
+ this.httpServiceProvider = httpServiceProvider;
+ this.networkServiceDescriptorParser = networkServiceDescriptorParser;
+ }
+
+ @Override
+ public Optional<NsdInfo> getNSPackageModel(final String nsdId) {
+ try {
+ final ResponseEntity<NsdInfo> response =
+ httpServiceProvider.getHttpResponse(etsiCatalogUrlProvider.getNsPackageUrl(nsdId), NsdInfo.class);
+ if (response.getStatusCode().is2xxSuccessful()) {
+ return Optional.ofNullable(response.getBody());
+ }
+ return Optional.empty();
+ } catch (final Exception restProcessingException) {
+ final String message = "Caught exception while getting NS package model for: " + nsdId;
+ throw new EtsiCatalogManagerRequestFailureException(message, restProcessingException);
+ }
+ }
+
+ @Override
+ public Optional<VnfPkgInfo> getVnfPkgInfo(final String vnfPkgId) {
+ try {
+ final ResponseEntity<VnfPkgInfo> response = httpServiceProvider
+ .getHttpResponse(etsiCatalogUrlProvider.getVnfPackageUrl(vnfPkgId), VnfPkgInfo.class);
+ if (response.getStatusCode().is2xxSuccessful()) {
+ return Optional.ofNullable(response.getBody());
+ }
+ return Optional.empty();
+ } catch (final Exception restProcessingException) {
+ final String message = "Caught exception while getting VNF package model for: " + vnfPkgId;
+ throw new EtsiCatalogManagerRequestFailureException(message, restProcessingException);
+ }
+ }
+
+ @Override
+ public Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor(final String nsdId) {
+ try {
+ final ResponseEntity<byte[]> response = httpServiceProvider
+ .getHttpResponse(etsiCatalogUrlProvider.getNsPackageContentUrl(nsdId), byte[].class);
+ if (response.getStatusCode().is2xxSuccessful()) {
+ if (response.hasBody()) {
+ return networkServiceDescriptorParser.parse(response.getBody());
+ }
+ logger.error("Received response without body ...");
+ }
+ return Optional.empty();
+ } catch (final Exception restProcessingException) {
+ final String message = "Caught exception while getting NS package content for: " + nsdId;
+ throw new EtsiCatalogManagerRequestFailureException(message, restProcessingException);
+ }
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java
new file mode 100644
index 0000000..7adf87a
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java
@@ -0,0 +1,188 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog;
+
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.Iterator;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.onap.logging.filter.spring.SpringClientPayloadFilter;
+import org.onap.so.configuration.rest.BasicHttpHeadersProvider;
+import org.onap.so.configuration.rest.HttpClientConnectionConfiguration;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider;
+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.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.Resource;
+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;
+
+/**
+ * Configures the HttpRestServiceProvider to make REST calls to the ETSI Catalog Manager
+ *
+ * @author gareth.roper@est.tech
+ */
+
+@Configuration
+public class EtsiCatalogServiceProviderConfiguration {
+ private static final Logger LOGGER = LoggerFactory.getLogger(EtsiCatalogServiceProviderConfiguration.class);
+
+ public static final String ETSI_CATALOG_SERVICE_PROVIDER_BEAN = "etsiCatalogServiceProvider";
+
+ public static final String ETSI_CATALOG_REST_TEMPLATE_BEAN = "etsiCatalogRestTemplate";
+
+ private final HttpClientConnectionConfiguration clientConnectionConfiguration;
+
+ @Value("${etsi-catalog-manager.http.client.ssl.trust-store:#{null}}")
+ private Resource trustStore;
+ @Value("${etsi-catalog-manager.http.client.ssl.trust-store-password:#{null}}")
+ private String trustStorePassword;
+
+ private final GsonProvider gsonProvider;
+
+ @Autowired
+ public EtsiCatalogServiceProviderConfiguration(
+ final HttpClientConnectionConfiguration clientConnectionConfiguration, final GsonProvider gsonProvider) {
+ this.clientConnectionConfiguration = clientConnectionConfiguration;
+ this.gsonProvider = gsonProvider;
+ }
+
+ @Bean
+ @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN)
+ public RestTemplate etsiCatalogRestTemplate() {
+ final RestTemplate restTemplate = new RestTemplate();
+ restTemplate.getInterceptors().add(new SOSpringClientFilter());
+ restTemplate.getInterceptors().add((new SpringClientPayloadFilter()));
+ return restTemplate;
+ }
+
+ @Bean
+ @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN)
+ public HttpRestServiceProvider etsiCatalogHttpRestServiceProvider(
+ @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) final RestTemplate restTemplate) {
+ setGsonMessageConverter(restTemplate);
+
+ final HttpClientBuilder httpClientBuilder = getHttpClientBuilder();
+ if (trustStore != null) {
+ try {
+ LOGGER.debug("Setting up HttpComponentsClientHttpRequestFactory with SSL Context");
+ LOGGER.debug("Setting client trust-store: {}", trustStore.getURL());
+ LOGGER.debug("Creating SSLConnectionSocketFactory with AllowAllHostsVerifier ... ");
+ final SSLContext sslContext = new SSLContextBuilder()
+ .loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()).build();
+ final SSLConnectionSocketFactory sslConnectionSocketFactory =
+ new SSLConnectionSocketFactory(sslContext, AllowAllHostsVerifier.INSTANCE);
+ httpClientBuilder.setSSLSocketFactory(sslConnectionSocketFactory);
+ final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
+ .<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE)
+ .register("https", sslConnectionSocketFactory).build();
+
+ httpClientBuilder.setConnectionManager(getConnectionManager(socketFactoryRegistry));
+ } catch (final KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException
+ | IOException exception) {
+ LOGGER.error("Error reading truststore, TLS connection will fail.", exception);
+ }
+
+ } else {
+ LOGGER.debug("Setting connection manager without SSL ConnectionSocketFactory ...");
+ httpClientBuilder.setConnectionManager(getConnectionManager());
+ }
+
+ final HttpComponentsClientHttpRequestFactory factory =
+ new HttpComponentsClientHttpRequestFactory(httpClientBuilder.build());
+ restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory));
+
+ return new HttpRestServiceProviderImpl(restTemplate, new BasicHttpHeadersProvider().getHttpHeaders());
+ }
+
+ private PoolingHttpClientConnectionManager getConnectionManager(
+ final Registry<ConnectionSocketFactory> socketFactoryRegistry) {
+ return new PoolingHttpClientConnectionManager(socketFactoryRegistry, null, null, null,
+ clientConnectionConfiguration.getTimeToLiveInMins(), TimeUnit.MINUTES);
+ }
+
+ private PoolingHttpClientConnectionManager getConnectionManager() {
+ return new PoolingHttpClientConnectionManager(clientConnectionConfiguration.getTimeToLiveInMins(),
+ TimeUnit.MINUTES);
+ }
+
+ private HttpClientBuilder getHttpClientBuilder() {
+ return HttpClientBuilder.create().setMaxConnPerRoute(clientConnectionConfiguration.getMaxConnectionsPerRoute())
+ .setMaxConnTotal(clientConnectionConfiguration.getMaxConnections())
+ .setDefaultRequestConfig(getRequestConfig());
+ }
+
+ private RequestConfig getRequestConfig() {
+ return RequestConfig.custom().setSocketTimeout(clientConnectionConfiguration.getSocketTimeOutInMiliSeconds())
+ .setConnectTimeout(clientConnectionConfiguration.getConnectionTimeOutInMilliSeconds()).build();
+ }
+
+ private static final class AllowAllHostsVerifier implements HostnameVerifier {
+
+ private static final AllowAllHostsVerifier INSTANCE = new AllowAllHostsVerifier();
+
+ @Override
+ public boolean verify(final String hostname, final SSLSession session) {
+ LOGGER.debug("Skipping hostname verification ...");
+ return true;
+ }
+
+ }
+
+ public 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-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogUrlProvider.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogUrlProvider.java
new file mode 100644
index 0000000..54f6ad6
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogUrlProvider.java
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class EtsiCatalogUrlProvider {
+
+ @Value("${etsi-catalog-manager.base.endpoint}")
+ private String etsiCatalogManagerEndpoint;
+
+ public String getNsPackageUrl(final String nsdId) {
+ return etsiCatalogManagerEndpoint + "/nsd/v1/ns_descriptors/" + nsdId;
+ }
+
+ public String getNsPackageContentUrl(final String nsdId) {
+ return etsiCatalogManagerEndpoint + "/nsd/v1/ns_descriptors/" + nsdId + "/nsd_content";
+ }
+
+ public String getVnfPackageUrl(final String vnfPkgId) {
+ return etsiCatalogManagerEndpoint + "/vnfpkgm/v1/vnf_packages/" + vnfPkgId;
+ }
+
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterConfiguration.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterConfiguration.java
new file mode 100644
index 0000000..6776d8b
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterConfiguration.java
@@ -0,0 +1,148 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm;
+
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+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.apache.http.ssl.SSLContextBuilder;
+import org.onap.logging.filter.spring.SpringClientPayloadFilter;
+import org.onap.so.configuration.rest.BasicHttpHeadersProvider;
+import org.onap.so.configuration.rest.HttpComponentsClientConfiguration;
+import org.onap.so.configuration.rest.HttpHeadersProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider;
+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.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.Resource;
+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 Sol003AdapterConfiguration {
+
+ private static final Logger logger = LoggerFactory.getLogger(Sol003AdapterConfiguration.class);
+
+ public static final String SOL003_ADAPTER_REST_TEMPLATE_BEAN = "Sol003AdapterRestTemplateBean";
+ public static final String SOL003_ADAPTER_HTTP_REST_SERVICE_PROVIDER_BEAN =
+ "Sol003AdapterHttpRestServiceProviderBean";
+
+ @Value("${rest.http.client.configuration.ssl.trustStore:#{null}}")
+ private Resource trustStore;
+
+ @Value("${rest.http.client.configuration.ssl.trustStorePassword:#{null}}")
+ private String trustStorePassword;
+
+ @Value("${so.adapters.sol003-adapter.auth:Basic dm5mbTpwYXNzd29yZDEk}")
+ private String sol003AdapterBasicAuth;
+
+ @Autowired
+ private GsonProvider gsonProvider;
+
+ @Bean
+ @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN)
+ public RestTemplate sol003AdapterRestTemplate(
+ @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(SOL003_ADAPTER_HTTP_REST_SERVICE_PROVIDER_BEAN)
+ public HttpRestServiceProvider sol003AdapaterHttpRestServiceProvider(
+ @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN) @Autowired final RestTemplate restTemplate) {
+
+ if (trustStore != null) {
+ setTrustStore(restTemplate);
+ }
+ setGsonMessageConverter(restTemplate);
+ return getHttpRestServiceProvider(restTemplate, new BasicHttpHeadersProvider(sol003AdapterBasicAuth));
+ }
+
+ private void setTrustStore(final RestTemplate restTemplate) {
+ try {
+ final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(getSSLContext());
+ 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 VNFM will fail.", exception);
+ }
+ }
+
+ private SSLContext getSSLContext() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException,
+ CertificateException, IOException {
+ if (trustStore != null) {
+ logger.info("Setting truststore: {}", trustStore.getURL());
+ return new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray())
+ .build();
+ }
+ logger.info("Setting Default SSL ...");
+ return SSLContext.getDefault();
+
+ }
+
+ private HttpRestServiceProvider getHttpRestServiceProvider(final RestTemplate restTemplate,
+ final HttpHeadersProvider httpHeadersProvider) {
+ return new HttpRestServiceProviderImpl(restTemplate, httpHeadersProvider.getHttpHeaders());
+ }
+
+ 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-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProvider.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProvider.java
new file mode 100644
index 0000000..4f98e2c
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProvider.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm;
+
+import java.util.Optional;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfRequest;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.DeleteVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse;
+
+public interface Sol003AdapterServiceProvider {
+
+ Optional<CreateVnfResponse> invokeCreateInstantiationRequest(final String vnfId, final CreateVnfRequest request);
+
+ Optional<QueryJobResponse> getInstantiateOperationJobStatus(final String jobId);
+
+ Optional<DeleteVnfResponse> invokeTerminationRequest(final String vnfId);
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProviderImpl.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProviderImpl.java
new file mode 100644
index 0000000..df3a0c2
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProviderImpl.java
@@ -0,0 +1,150 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterConfiguration.SOL003_ADAPTER_HTTP_REST_SERVICE_PROVIDER_BEAN;
+import java.util.Optional;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfRequest;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.DeleteVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse;
+import org.onap.so.rest.exceptions.HttpResouceNotFoundException;
+import org.onap.so.rest.exceptions.InvalidRestRequestException;
+import org.onap.so.rest.exceptions.RestProcessingException;
+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.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+@Service
+public class Sol003AdapterServiceProviderImpl implements Sol003AdapterServiceProvider {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(Sol003AdapterServiceProviderImpl.class);
+ public static final String RECEIVED_RESPONSE_WITHOUT_BODY = "Received response without body: {}";
+
+ private final Sol003AdapterUrlProvider urlProvider;
+ private final HttpRestServiceProvider httpServiceProvider;
+
+ @Autowired
+ public Sol003AdapterServiceProviderImpl(final Sol003AdapterUrlProvider urlProvider,
+ @Qualifier(SOL003_ADAPTER_HTTP_REST_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider) {
+ this.urlProvider = urlProvider;
+ this.httpServiceProvider = httpServiceProvider;
+ }
+
+ @Override
+ public Optional<CreateVnfResponse> invokeCreateInstantiationRequest(final String vnfId,
+ final CreateVnfRequest request) {
+ try {
+ final String url = urlProvider.getCreateInstantiateUrl(vnfId);
+
+ final ResponseEntity<CreateVnfResponse> response =
+ httpServiceProvider.postHttpRequest(request, url, CreateVnfResponse.class);
+
+ final HttpStatus httpStatus = response.getStatusCode();
+ if (!(httpStatus.equals(HttpStatus.ACCEPTED)) && !(httpStatus.equals(HttpStatus.OK))) {
+ LOGGER.error("Unable to invoke HTTP POST using URL: {}, Response Code: {}", url, httpStatus.value());
+ return Optional.empty();
+ }
+
+ if (!response.hasBody()) {
+ LOGGER.error(RECEIVED_RESPONSE_WITHOUT_BODY, response);
+ return Optional.empty();
+ }
+
+ final CreateVnfResponse createVnfResponse = response.getBody();
+
+ if (StringUtils.isBlank(createVnfResponse.getJobId())) {
+ LOGGER.error("Received invalid instantiation response: {}", response);
+ return Optional.empty();
+ }
+
+ return Optional.of(createVnfResponse);
+ } catch (final RestProcessingException | InvalidRestRequestException
+ | HttpResouceNotFoundException httpInvocationException) {
+ LOGGER.error("Unexpected error while processing create and instantiation request", httpInvocationException);
+ return Optional.empty();
+ }
+
+ }
+
+ @Override
+ public Optional<QueryJobResponse> getInstantiateOperationJobStatus(final String jobId) {
+ try {
+ final String url = urlProvider.getJobStatusUrl(jobId);
+
+ final ResponseEntity<QueryJobResponse> response =
+ httpServiceProvider.getHttpResponse(url, QueryJobResponse.class);
+
+ final HttpStatus httpStatus = response.getStatusCode();
+
+ if (!(httpStatus.equals(HttpStatus.ACCEPTED)) && !(httpStatus.equals(HttpStatus.OK))) {
+ LOGGER.error("Unable to invoke HTTP GET using URL: {}, Response Code: ", url, httpStatus.value());
+ return Optional.empty();
+ }
+
+ if (!response.hasBody()) {
+ LOGGER.error(RECEIVED_RESPONSE_WITHOUT_BODY, response);
+ return Optional.empty();
+ }
+ return Optional.of(response.getBody());
+ } catch (final RestProcessingException | InvalidRestRequestException | HttpResouceNotFoundException exception) {
+ LOGGER.error("Unexpected error while processing job request", exception);
+ throw exception;
+ }
+ }
+
+ @Override
+ public Optional<DeleteVnfResponse> invokeTerminationRequest(final String vnfId) {
+ try {
+ final String url = urlProvider.getTerminateVnfUrl(vnfId);
+
+ final ResponseEntity<DeleteVnfResponse> response =
+ httpServiceProvider.deleteHttpRequest(url, DeleteVnfResponse.class);
+ final HttpStatus httpStatus = response.getStatusCode();
+ if (!(httpStatus.equals(HttpStatus.ACCEPTED)) && !(httpStatus.equals(HttpStatus.OK))) {
+ LOGGER.error("Unable to invoke HTTP DELETE using URL: {}, Response Code: {}", url, httpStatus.value());
+ return Optional.empty();
+ }
+ if (!response.hasBody()) {
+ LOGGER.error(RECEIVED_RESPONSE_WITHOUT_BODY, response);
+ return Optional.empty();
+ }
+
+ final DeleteVnfResponse deleteVnfResponse = response.getBody();
+ if (StringUtils.isBlank(deleteVnfResponse.getJobId())) {
+ LOGGER.error("Received invalid terminate response: {}", response);
+ return Optional.empty();
+ }
+
+ return Optional.of(deleteVnfResponse);
+ } catch (final RestProcessingException | InvalidRestRequestException
+ | HttpResouceNotFoundException httpInvocationException) {
+ LOGGER.error("Unexpected error while processing terminate request", httpInvocationException);
+ return Optional.empty();
+ }
+ }
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterUrlProvider.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterUrlProvider.java
new file mode 100644
index 0000000..e3abc05
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterUrlProvider.java
@@ -0,0 +1,74 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm;
+
+import java.net.URI;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.util.UriComponentsBuilder;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class Sol003AdapterUrlProvider {
+
+ private final URI baseUri;
+
+ @Autowired
+ public Sol003AdapterUrlProvider(
+ @Value("${so.adapters.sol003-adapter.url:https://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1/}") final String sol003AdapterUrl) {
+ this.baseUri = UriComponentsBuilder.fromHttpUrl(sol003AdapterUrl).build().toUri();
+ }
+
+ /**
+ * Get VNFM create and instantiate URL
+ *
+ * @param vnfId The identifier of the VNF. This must be the vnf-id of an existing generic-vnf in AAI.
+ * @return VNFM create and instantiate URL
+ */
+ public String getCreateInstantiateUrl(final String vnfId) {
+ return UriComponentsBuilder.fromUri(baseUri).pathSegment("vnfs").pathSegment(vnfId).build().toString();
+ }
+
+ /**
+ * Get job status URL
+ *
+ * @param jobId The instantiation job identifier
+ * @return job status URL
+ */
+ public String getJobStatusUrl(final String jobId) {
+ return UriComponentsBuilder.fromUri(baseUri).pathSegment("jobs").pathSegment(jobId).build().toString();
+ }
+
+ /**
+ * Get VNFM terminate vnf URL
+ *
+ * @param vnfId
+ * @return
+ */
+ public String getTerminateVnfUrl(final String vnfId) {
+ return UriComponentsBuilder.fromUri(baseUri).pathSegment("vnfs").pathSegment(vnfId).build().toString();
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java
new file mode 100644
index 0000000..cfe5b94
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java
@@ -0,0 +1,112 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class FileEntry {
+
+ private boolean isDirectory;
+ private String filePath;
+ private byte[] fileContent;
+
+ public boolean isDirectory() {
+ return isDirectory;
+ }
+
+ public void setDirectory(final boolean isDirectory) {
+ this.isDirectory = isDirectory;
+ }
+
+ public FileEntry isDirectory(final boolean isDirectory) {
+ this.isDirectory = isDirectory;
+ return this;
+ }
+
+ public String getFilePath() {
+ return filePath;
+ }
+
+ public void setFilename(final String filePath) {
+ this.filePath = filePath;
+ }
+
+ public FileEntry filePath(final String filePath) {
+ this.filePath = filePath;
+ return this;
+ }
+
+ public byte[] getFileContent() {
+ return fileContent;
+ }
+
+ public void setFileContent(final byte[] fileContent) {
+ this.fileContent = fileContent;
+ }
+
+ public FileEntry fileContent(final byte[] fileContent) {
+ this.fileContent = fileContent;
+ return this;
+ }
+
+ public InputStream getFileContentAsStream() {
+ if (fileContent == null || fileContent.length == 0) {
+ return null;
+ }
+ return new ByteArrayInputStream(fileContent);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(isDirectory, filePath) + Arrays.hashCode(fileContent);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof FileEntry) {
+ final FileEntry other = (FileEntry) obj;
+ return Objects.equals(isDirectory, other.isDirectory) && Objects.equals(filePath, other.filePath)
+ && Arrays.equals(fileContent, other.fileContent);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class FileEntry {\n");
+ sb.append(" isDirectory: ").append(toIndentedString(isDirectory)).append("\n");
+ sb.append(" filePath: ").append(toIndentedString(filePath)).append("\n");
+ sb.append(" fileContent size: ").append(toIndentedString(fileContent != null ? fileContent.length : 0))
+ .append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptor.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptor.java
new file mode 100644
index 0000000..6b4fee7
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptor.java
@@ -0,0 +1,121 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class NetworkServiceDescriptor implements Serializable {
+
+ private static final long serialVersionUID = -1739293595041180242L;
+
+ private String type;
+
+ private Map<String, Object> properties = new HashMap<>();
+
+ private List<VirtualNetworkFunction> vnfs = new ArrayList<>();
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ public NetworkServiceDescriptor type(final String type) {
+ this.type = type;
+ return this;
+ }
+
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(final Map<String, Object> properties) {
+ this.properties = properties;
+ }
+
+ public NetworkServiceDescriptor properties(final Map<String, Object> properties) {
+ this.properties = properties;
+ return this;
+ }
+
+ public List<VirtualNetworkFunction> getVnfs() {
+ return vnfs;
+ }
+
+ public void setVnfs(final List<VirtualNetworkFunction> vnfs) {
+ if (vnfs != null) {
+ this.vnfs = vnfs;
+ } else {
+ this.vnfs = new ArrayList<>();
+ }
+ }
+
+ public NetworkServiceDescriptor addVnfPkgIdsItem(final VirtualNetworkFunction vnf) {
+ if (this.vnfs == null) {
+ this.vnfs = new ArrayList<>();
+ }
+ this.vnfs.add(vnf);
+ return this;
+ }
+
+ public NetworkServiceDescriptor vnfs(final List<VirtualNetworkFunction> vnfs) {
+ this.vnfs = vnfs;
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, properties, vnfs);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof NetworkServiceDescriptor) {
+ final NetworkServiceDescriptor other = (NetworkServiceDescriptor) obj;
+ return Objects.equals(type, other.type) && Objects.equals(properties, other.properties)
+ && Objects.equals(vnfs, other.vnfs);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class NetworkServiceDescriptor {\n");
+ sb.append(" type: ").append(toIndentedString(type)).append("\n");
+ sb.append(" properties: ").append(toIndentedString(properties)).append("\n");
+ sb.append(" vnfs: ").append(toIndentedString(vnfs)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java
new file mode 100644
index 0000000..c07a55c
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class ToscaMetadata {
+
+ private Map<String, String> entries = new HashMap<>();
+
+ public Map<String, String> getEntries() {
+ return entries;
+ }
+
+ public void addEntry(final String name, final String value) {
+ this.entries.put(name, value);
+ }
+
+ public boolean hasEntry(final String name) {
+ return this.entries.containsKey(name);
+ }
+
+ public String getEntry(final String name) {
+ return this.entries.get(name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(entries);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof ToscaMetadata) {
+ final ToscaMetadata other = (ToscaMetadata) obj;
+ return Objects.equals(entries, other.entries);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class ToscaMetadata {\n");
+ sb.append(" entries: ").append(toIndentedString(entries)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java
new file mode 100644
index 0000000..f4c3632
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java
@@ -0,0 +1,123 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class VirtualNetworkFunction implements Serializable {
+
+ private static final long serialVersionUID = 3164293220359211834L;
+
+ private String vnfdId;
+ private String vnfName;
+ private List<String> vnfmInfoList;
+ private Map<String, Object> properties = new HashMap<>();
+
+ public String getVnfdId() {
+ return vnfdId;
+ }
+
+ public void setVnfdId(final String vnfdId) {
+ this.vnfdId = vnfdId;
+ }
+
+ public VirtualNetworkFunction vnfdId(final String vnfdId) {
+ this.vnfdId = vnfdId;
+ return this;
+ }
+
+ public String getVnfName() {
+ return vnfName;
+ }
+
+ public void setVnfName(final String vnfName) {
+ this.vnfName = vnfName;
+ }
+
+ public VirtualNetworkFunction vnfName(final String vnfName) {
+ this.vnfName = vnfName;
+ return this;
+ }
+
+ public List<String> getVnfmInfoList() {
+ return vnfmInfoList;
+ }
+
+ public void setVnfmInfoList(final List<String> vnfmInfoList) {
+ this.vnfmInfoList = vnfmInfoList;
+ }
+
+ public VirtualNetworkFunction vnfmInfoList(final List<String> vnfmInfoList) {
+ this.vnfmInfoList = vnfmInfoList;
+ return this;
+ }
+
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(final Map<String, Object> properties) {
+ this.properties = properties;
+ }
+
+ public VirtualNetworkFunction properties(final Map<String, Object> properties) {
+ this.properties = properties;
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(vnfdId, vnfName, vnfmInfoList, properties);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof VirtualNetworkFunction) {
+ final VirtualNetworkFunction other = (VirtualNetworkFunction) obj;
+ return Objects.equals(vnfdId, other.vnfdId) && Objects.equals(vnfName, other.vnfName)
+ && Objects.equals(vnfmInfoList, other.vnfmInfoList) && Objects.equals(properties, other.properties);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class VirtualNetworkFunction {\n");
+ sb.append(" vnfdId: ").append(toIndentedString(vnfdId)).append("\n");
+ sb.append(" vnfName: ").append(toIndentedString(vnfName)).append("\n");
+ sb.append(" vnfmInfo: ").append(toIndentedString(vnfmInfoList)).append("\n");
+ sb.append(" properties: ").append(toIndentedString(properties)).append("\n");
+
+ sb.append("}");
+ return sb.toString();
+ }
+
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/FileParser.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/FileParser.java
new file mode 100644
index 0000000..2a37922
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/FileParser.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.nsd.parser;
+
+import java.util.Map;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.FileEntry;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface FileParser {
+
+ Map<String, Object> getFileContent(final FileEntry entryDefinitionFileEntry);
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/NetworkServiceDescriptorParser.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/NetworkServiceDescriptorParser.java
new file mode 100644
index 0000000..cc92234
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/NetworkServiceDescriptorParser.java
@@ -0,0 +1,213 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.nsd.parser;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import org.apache.commons.io.IOUtils;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.FileEntry;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.ToscaMetadata;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.VirtualNetworkFunction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class NetworkServiceDescriptorParser {
+ public static final String NS_NODE_TYPE = "tosca.nodes.nfv.NS";
+ private static final String NODE_TYPE = "node_type";
+ private static final String SUBSTITUTION_MAPPINGS = "substitution_mappings";
+ private static final Logger logger = LoggerFactory.getLogger(NetworkServiceDescriptorParser.class);
+ private static final String VNF_TYPE = "tosca.nodes.nfv.VNF";
+ private static final String PROPERTIES = "properties";
+ private static final String TYPE = "type";
+ private static final String NODE_TEMPLATES = "node_templates";
+ private static final String TOPOLOGY_TEMPLATE = "topology_template";
+ private static final String ENTRY_DEFINITIONS = "Entry-Definitions";
+ private static final String TOSCA_META_PATH_FILE_NAME = "TOSCA-Metadata/TOSCA.meta";
+ private final ToscaMetadataParser toscaMetadataParser;
+ private final FileParser fileParser;
+
+ @Autowired
+ public NetworkServiceDescriptorParser(final ToscaMetadataParser toscaMetadataParser, final FileParser fileParser) {
+ this.toscaMetadataParser = toscaMetadataParser;
+ this.fileParser = fileParser;
+ }
+
+ public Optional<NetworkServiceDescriptor> parse(final byte[] zipBytes) {
+ try {
+ final Map<String, FileEntry> files = getZipContent(zipBytes);
+ if (isMetaFilePresent(files)) {
+ final Optional<ToscaMetadata> optional =
+ toscaMetadataParser.parse(files.get(TOSCA_META_PATH_FILE_NAME));
+ if (optional.isPresent()) {
+ final ToscaMetadata toscaMetadata = optional.get();
+ logger.info("Parsed ToscaMetadata {}", toscaMetadata);
+ final String entryDefinitionFile = toscaMetadata.getEntry(ENTRY_DEFINITIONS);
+ if (entryDefinitionFile != null && files.containsKey(entryDefinitionFile)) {
+ final Map<String, Object> fileContent =
+ fileParser.getFileContent(files.get(entryDefinitionFile));
+ final Map<String, Object> topologyTemplates = getTopologyTemplates(fileContent);
+ final Map<String, Object> nodeTemplates = getNodeTemplates(topologyTemplates);
+
+ final Optional<NetworkServiceDescriptor> nsdOptional =
+ getNetworkServiceDescriptor(topologyTemplates);
+ if (nsdOptional.isPresent()) {
+ final NetworkServiceDescriptor networkServiceDescriptor = nsdOptional.get();
+ networkServiceDescriptor.setVnfs(getVirtualNetworkFunctions(nodeTemplates));
+ return Optional.of(networkServiceDescriptor);
+ }
+
+ }
+ }
+
+ }
+
+ logger.error("Unable to find {} file in {}", TOSCA_META_PATH_FILE_NAME, files);
+ } catch (final Exception exception) {
+ logger.error("Unable to parse nsd zip content", exception);
+ }
+ return Optional.empty();
+ }
+
+ @SuppressWarnings("unchecked")
+ private Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor(
+ final Map<String, Object> topologyTemplates) {
+ final Map<String, Object> substitutionMappings =
+ (Map<String, Object>) topologyTemplates.get(SUBSTITUTION_MAPPINGS);
+ final Object nodeType = substitutionMappings.get(NODE_TYPE);
+ if (substitutionMappings != null && NS_NODE_TYPE.equals(nodeType)) {
+ final NetworkServiceDescriptor networkServiceDescriptor = new NetworkServiceDescriptor();
+ networkServiceDescriptor.setType(nodeType.toString());
+ networkServiceDescriptor.setProperties((Map<String, Object>) substitutionMappings.get(PROPERTIES));
+ return Optional.of(networkServiceDescriptor);
+ }
+ logger.error("No {} found in fileContent: {}", SUBSTITUTION_MAPPINGS, topologyTemplates);
+
+ return Optional.empty();
+ }
+
+ private List<VirtualNetworkFunction> getVirtualNetworkFunctions(final Map<String, Object> nodeTemplates) {
+ final List<VirtualNetworkFunction> vnfs = new ArrayList<>();
+ for (final Entry<String, Object> entry : nodeTemplates.entrySet()) {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> entryValue = (Map<String, Object>) entry.getValue();
+ final Object type = entryValue.get(TYPE);
+ if (type != null && type.equals(VNF_TYPE)) {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> vnfProperties = (Map<String, Object>) entryValue.get(PROPERTIES);
+ final VirtualNetworkFunction vnf = new VirtualNetworkFunction();
+ vnf.setVnfName(entry.getKey());
+
+ if (vnfProperties != null && !vnfProperties.isEmpty()) {
+ final Object vnfDescriptorId = vnfProperties.get("descriptor_id");
+ @SuppressWarnings("unchecked")
+ final List<String> vnfmInfoList = (List<String>) vnfProperties.get("vnfm_info");
+ if (vnfDescriptorId != null && vnfmInfoList != null) {
+ vnf.setVnfmInfoList(vnfmInfoList);
+ vnf.setVnfdId(vnfDescriptorId.toString());
+ vnf.setProperties(vnfProperties);
+ vnfs.add(vnf);
+ } else {
+ logger.warn("descriptor_id missing {}", entryValue);
+ }
+ }
+ }
+
+ }
+ return vnfs;
+ }
+
+ private Map<String, Object> getNodeTemplates(final Map<String, Object> topologyTemplates) {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> nodeTemplates = (Map<String, Object>) topologyTemplates.get(NODE_TEMPLATES);
+ if (nodeTemplates != null) {
+ logger.debug("Found nodeTemplates: {}", topologyTemplates);
+ return nodeTemplates;
+ }
+ logger.error("No {} found in fileContent: {}", NODE_TEMPLATES, topologyTemplates);
+ return Collections.emptyMap();
+ }
+
+ private Map<String, Object> getTopologyTemplates(final Map<String, Object> fileContent) {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> topologyTemplates = (Map<String, Object>) fileContent.get(TOPOLOGY_TEMPLATE);
+ if (topologyTemplates != null) {
+ logger.debug("Found {}: {}", TOPOLOGY_TEMPLATE, topologyTemplates);
+
+ return topologyTemplates;
+ }
+ logger.error("No {} found in fileContent: {}", TOPOLOGY_TEMPLATE, fileContent);
+ return Collections.emptyMap();
+ }
+
+ private boolean isMetaFilePresent(final Map<String, FileEntry> files) {
+ return files.containsKey(TOSCA_META_PATH_FILE_NAME);
+ }
+
+ private Map<String, FileEntry> getZipContent(final byte[] zipBytes) {
+ final Map<String, FileEntry> files = new HashMap<>();
+ try (final ZipInputStream inputZipStream = new ZipInputStream(new ByteArrayInputStream(zipBytes));) {
+ ZipEntry zipEntry;
+ while ((zipEntry = inputZipStream.getNextEntry()) != null) {
+ logger.info("{} : {}", zipEntry.getName(), zipEntry.isDirectory());
+ if (files.get(zipEntry.getName()) != null) {
+ logger.warn("{} File entry already exists ...", zipEntry.getName());
+ } else {
+ final FileEntry fileEntry = new FileEntry().filePath(zipEntry.getName())
+ .fileContent(getBytes(inputZipStream)).isDirectory(zipEntry.isDirectory());
+ files.put(zipEntry.getName(), fileEntry);
+
+ }
+
+ }
+ return files;
+ } catch (final Exception exception) {
+ logger.error("Unable to parse nsd zip content", exception);
+ return Collections.emptyMap();
+ }
+ }
+
+ private byte[] getBytes(final ZipInputStream inputZipStream) throws IOException {
+ try {
+ return IOUtils.toByteArray(inputZipStream);
+ } catch (final IOException exception) {
+ logger.error("Could not read bytes from file", exception);
+ throw exception;
+ }
+ }
+
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/ToscaMetadataParser.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/ToscaMetadataParser.java
new file mode 100644
index 0000000..746416c
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/ToscaMetadataParser.java
@@ -0,0 +1,70 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.nsd.parser;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import java.util.List;
+import java.util.Optional;
+import org.apache.commons.io.IOUtils;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.FileEntry;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.ToscaMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class ToscaMetadataParser {
+ private static final String ATTRIBUTE_VALUE_SEPARATOR = ":";
+ private static final Logger logger = LoggerFactory.getLogger(ToscaMetadataParser.class);
+
+ public Optional<ToscaMetadata> parse(final FileEntry toscaMetaFile) {
+ try {
+ final ToscaMetadata toscaMetadata = new ToscaMetadata();
+ final List<String> lines = IOUtils.readLines(toscaMetaFile.getFileContentAsStream(), UTF_8);
+ for (final String line : lines) {
+ final String trimmedLine = line.trim();
+ if (!trimmedLine.isEmpty() && trimmedLine.contains(ATTRIBUTE_VALUE_SEPARATOR)) {
+ final String[] entry = trimmedLine.split(ATTRIBUTE_VALUE_SEPARATOR);
+ if (entry.length >= 2 && isNotBlank(entry[0]) && isNotBlank(entry[1])) {
+ toscaMetadata.addEntry(entry[0].trim(), entry[1].trim());
+ } else {
+ logger.warn("Unexpected line in metadata file: {}", line);
+ }
+ } else {
+ logger.warn("Unexpected line does not contain valid separator {} in metadata file: {}",
+ ATTRIBUTE_VALUE_SEPARATOR, line);
+ }
+
+ }
+ return Optional.of(toscaMetadata);
+
+ } catch (final Exception exception) {
+ logger.error("Unable to parser metadata file content", exception);
+ }
+ return Optional.empty();
+ }
+
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/YamlFileParser.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/YamlFileParser.java
new file mode 100644
index 0000000..eab6974
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/parser/YamlFileParser.java
@@ -0,0 +1,40 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.nsd.parser;
+
+import java.util.Map;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.FileEntry;
+import org.springframework.stereotype.Service;
+import org.yaml.snakeyaml.Yaml;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class YamlFileParser implements FileParser {
+
+ @Override
+ public Map<String, Object> getFileContent(final FileEntry entryDefinitionFileEntry) {
+ final Yaml yaml = new Yaml();
+ return yaml.load(entryDefinitionFileEntry.getFileContentAsStream());
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java
new file mode 100644
index 0000000..14d4fa2
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java
@@ -0,0 +1,399 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.service;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_REQUEST_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.GLOBAL_CUSTOMER_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.INSTANTIATE_NS_REQUEST_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.JOB_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OCC_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.SERVICE_TYPE_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.TERMINATE_NS_REQUEST_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.CREATE_NS_WORKFLOW_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.DELETE_NS_WORKFLOW_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.INSTANTIATE_NS_WORKFLOW_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.TERMINATE_NS_WORKFLOW_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction.DELETE;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction.INSTANTIATE;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction.TERMINATE;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.ERROR;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED_WITH_ERROR;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.STARTING;
+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.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.NsRequestProcessingException;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpType;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance;
+import org.onap.so.etsi.nfvo.ns.lcm.model.TerminateNsRequest;
+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-etsi-ns-lcm-workflow-engine.requesttimeout.timeoutInSeconds:300}")
+ private int timeOutInSeconds;
+
+ private final DatabaseServiceProvider databaseServiceProvider;
+ private final WorkflowExecutorService workflowExecutorService;
+ private final WorkflowQueryService workflowQueryService;
+ private 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;
+ gson = gsonProvider.getGson();
+ }
+
+ public NsInstancesNsInstance runCreateNsJob(final CreateNsRequest createNsRequest, final String globalCustomerId,
+ final String serviceType) {
+ logger.info("Starting 'Create NS' workflow job for request:\n{}", createNsRequest);
+ final NfvoJob newJob = new NfvoJob().startTime(LocalDateTime.now()).jobType("NS").jobAction(JobAction.CREATE)
+ .resourceId(createNsRequest.getNsdId()).resourceName(createNsRequest.getNsName())
+ .status(JobStatusEnum.STARTING).progress(5);
+ databaseServiceProvider.addJob(newJob);
+
+ logger.info("New job created in database :\n{}", newJob);
+
+ workflowExecutorService.executeWorkflow(newJob.getJobId(), CREATE_NS_WORKFLOW_NAME,
+ getVariables(newJob.getJobId(), createNsRequest, globalCustomerId, serviceType));
+
+ final ImmutablePair<String, JobStatusEnum> immutablePair =
+ waitForJobToFinish(newJob.getJobId(), JOB_FINISHED_STATES);
+
+ if (immutablePair.getRight() == null) {
+ final String message = "Failed to create NS for request: \n" + createNsRequest;
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+ final JobStatusEnum finalJobStatus = immutablePair.getRight();
+ final String processInstanceId = immutablePair.getLeft();
+
+ if (!FINISHED.equals(finalJobStatus)) {
+
+ final Optional<InlineResponse400> optional = workflowQueryService.getProblemDetails(processInstanceId);
+ if (optional.isPresent()) {
+ final InlineResponse400 problemDetails = optional.get();
+ final String message =
+ "Failed to create NS for request: \n" + createNsRequest + " due to \n" + problemDetails;
+ logger.error(message);
+ throw new NsRequestProcessingException(message, problemDetails);
+ }
+
+ final String message = "Received unexpected Job Status: " + finalJobStatus
+ + " Failed to Create NS for request: \n" + createNsRequest;
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+
+ logger.debug("Will query for CreateNsResponse using processInstanceId:{}", processInstanceId);
+ final Optional<NsInstancesNsInstance> optional = workflowQueryService.getCreateNsResponse(processInstanceId);
+ if (optional.isEmpty()) {
+ final String message =
+ "Unable to find CreateNsReponse in Camunda History for process instance: " + processInstanceId;
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+ return optional.get();
+ }
+
+ public String runInstantiateNsJob(final String nsInstanceId, final InstantiateNsRequest instantiateNsRequest) {
+
+ final NfvoJob newJob = new NfvoJob().startTime(LocalDateTime.now()).jobType("NS").jobAction(INSTANTIATE)
+ .resourceId(nsInstanceId).status(STARTING).progress(0);
+ databaseServiceProvider.addJob(newJob);
+ logger.info("New job created in database :\n{}", newJob);
+
+ final LocalDateTime currentDateTime = LocalDateTime.now();
+ final NsLcmOpOcc newNsLcmOpOcc = new NsLcmOpOcc().id(nsInstanceId).operation(NsLcmOpType.INSTANTIATE)
+ .operationState(OperationStateEnum.PROCESSING).stateEnteredTime(currentDateTime)
+ .startTime(currentDateTime).nfvoNsInst(getNfvoNsInst(nsInstanceId)).isAutoInvocation(false)
+ .isCancelPending(false).operationParams(gson.toJson(instantiateNsRequest));
+ databaseServiceProvider.addNSLcmOpOcc(newNsLcmOpOcc);
+ logger.info("New NSLcmOpOcc created in database :\n{}", newNsLcmOpOcc);
+
+ workflowExecutorService.executeWorkflow(newJob.getJobId(), INSTANTIATE_NS_WORKFLOW_NAME,
+ getVariables(nsInstanceId, newJob.getJobId(), newNsLcmOpOcc.getId(), instantiateNsRequest));
+
+ 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 NS for request: \n" + instantiateNsRequest;
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+
+ final JobStatusEnum finalJobStatus = immutablePair.getRight();
+
+ if (IN_PROGRESS.equals(finalJobStatus) || FINISHED.equals(finalJobStatus)) {
+ logger.info("Instantiation Job status: {}", finalJobStatus);
+
+
+ return newNsLcmOpOcc.getId();
+ }
+
+ final String message = "Received unexpected Job Status: " + finalJobStatus
+ + " Failed to instantiate NS for request: \n" + instantiateNsRequest;
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+
+ public String runTerminateNsJob(final String nsInstanceId, final TerminateNsRequest terminateNsRequest) {
+ doInitialTerminateChecks(nsInstanceId, terminateNsRequest);
+
+ final NfvoJob nfvoJob = new NfvoJob().startTime(LocalDateTime.now()).jobType("NS").jobAction(TERMINATE)
+ .resourceId(nsInstanceId).status(STARTING).progress(0);
+ databaseServiceProvider.addJob(nfvoJob);
+ logger.info("New job created in database :\n{}", nfvoJob);
+
+ final LocalDateTime currentDateTime = LocalDateTime.now();
+ final NsLcmOpOcc nsLcmOpOcc = new NsLcmOpOcc().id(nsInstanceId).operation(NsLcmOpType.TERMINATE)
+ .operationState(OperationStateEnum.PROCESSING).stateEnteredTime(currentDateTime)
+ .startTime(currentDateTime).nfvoNsInst(getNfvoNsInst(nsInstanceId)).isAutoInvocation(false)
+ .isCancelPending(false).operationParams(gson.toJson(terminateNsRequest));
+ databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc);
+ logger.info("New NSLcmOpOcc created in database :\n{}", nsLcmOpOcc);
+
+ workflowExecutorService.executeWorkflow(nfvoJob.getJobId(), TERMINATE_NS_WORKFLOW_NAME,
+ getVariables(nsInstanceId, nfvoJob.getJobId(), nsLcmOpOcc.getId(), terminateNsRequest));
+
+ final ImmutableSet<JobStatusEnum> jobFinishedStates =
+ ImmutableSet.of(FINISHED, ERROR, FINISHED_WITH_ERROR, IN_PROGRESS);
+ final ImmutablePair<String, JobStatusEnum> immutablePair =
+ waitForJobToFinish(nfvoJob.getJobId(), jobFinishedStates);
+
+ if (immutablePair.getRight() == null) {
+ final String message =
+ "Failed to Terminate NS with id: " + nsInstanceId + " for request: \n" + terminateNsRequest;
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+
+ final JobStatusEnum finalJobStatus = immutablePair.getRight();
+
+ if (IN_PROGRESS.equals(finalJobStatus) || FINISHED.equals(finalJobStatus)) {
+ logger.info("Termination Job status: {}", finalJobStatus);
+ return nsLcmOpOcc.getId();
+ }
+
+ final String message = "Received unexpected Job Status: " + finalJobStatus + " Failed to Terminate NS with id: "
+ + nsInstanceId + " for request: \n" + terminateNsRequest;
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+
+ public void runDeleteNsJob(final String nsInstanceId) {
+ final NfvoJob nfvoJob = new NfvoJob().startTime(LocalDateTime.now()).jobType("NS").jobAction(DELETE)
+ .resourceId(nsInstanceId).status(STARTING).progress(0);
+ databaseServiceProvider.addJob(nfvoJob);
+ logger.info("New job created in database :\n{}", nfvoJob);
+
+ workflowExecutorService.executeWorkflow(nfvoJob.getJobId(), DELETE_NS_WORKFLOW_NAME,
+ getVariables(nsInstanceId, nfvoJob.getJobId()));
+
+ final ImmutablePair<String, JobStatusEnum> immutablePair =
+ waitForJobToFinish(nfvoJob.getJobId(), JOB_FINISHED_STATES);
+
+ if (immutablePair.getRight() == null) {
+ final String message = "Failed to Delete NS with id: " + nsInstanceId;
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+
+ final JobStatusEnum finalJobStatus = immutablePair.getRight();
+ final String processInstanceId = immutablePair.getLeft();
+
+ if (FINISHED.equals(finalJobStatus)) {
+ logger.info("Delete Job status: {}", finalJobStatus);
+ return;
+ }
+
+ final Optional<InlineResponse400> optional = workflowQueryService.getProblemDetails(processInstanceId);
+ if (optional.isPresent()) {
+ final InlineResponse400 problemDetails = optional.get();
+ final String message = "Failed to Delete NS with id: " + nsInstanceId + " due to:\n" + problemDetails;
+ logger.error(message);
+ throw new NsRequestProcessingException(message, problemDetails);
+ }
+
+ final String message =
+ "Received unexpected Job Status: " + finalJobStatus + " Failed to Delete NS with id: " + nsInstanceId;
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+
+ private void doInitialTerminateChecks(final String nsInstanceId, final TerminateNsRequest terminateNsRequest) {
+ if (isNotImmediateTerminateRequest(terminateNsRequest)) {
+ final String message = "TerminateNsRequest received with terminateTime: "
+ + terminateNsRequest.getTerminationTime()
+ + "\nOnly immediate Terminate requests are currently supported \n(i.e., terminateTime field must not be set).";
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+
+ final NfvoNsInst nfvoNsInst = getNfvoNsInst(nsInstanceId);
+ if (isNotInstantiated(nfvoNsInst)) {
+ final String message = "TerminateNsRequest received: " + terminateNsRequest + " for nsInstanceId: "
+ + nsInstanceId + "\nUnable to terminate. NS Instance is already in NOT_INSTANTIATED state."
+ + "\nThis method can only be used with an NS instance in the INSTANTIATED state.";
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+ }
+
+ private boolean isNotImmediateTerminateRequest(final TerminateNsRequest terminateNsRequest) {
+ return terminateNsRequest != null && terminateNsRequest.getTerminationTime() != null;
+ }
+
+ private boolean isNotInstantiated(final NfvoNsInst nfvoNsInst) {
+ return State.NOT_INSTANTIATED.equals(nfvoNsInst.getStatus());
+ }
+
+ private NfvoNsInst getNfvoNsInst(final String nsInstId) {
+ logger.info("Getting NfvoNsInst with nsInstId: {}", nsInstId);
+ final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstId);
+
+ if (optionalNfvoNsInst.isEmpty()) {
+ final String message = "No matching NS Instance for id: " + nsInstId + " found in database.";
+ throw new NsRequestProcessingException(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<NfvoJob> optional = databaseServiceProvider.getRefreshedJob(jobId);
+
+ if (optional.isEmpty()) {
+ logger.error("Unable to find Job using jobId: {}", jobId);
+ return ImmutablePair.nullPair();
+ }
+
+ final NfvoJob nfvoJob = optional.get();
+ currentJobStatus = nfvoJob.getStatus();
+ logger.debug("Received job status response: \n {}", nfvoJob);
+ if (jobFinishedStates.contains(currentJobStatus)) {
+ logger.info("Job finished \n {}", currentJobStatus);
+ return ImmutablePair.of(nfvoJob.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 Map<String, Object> getVariables(final String jobId, final CreateNsRequest createNsRequest,
+ final String globalCustomerId, final String serviceType) {
+ final Map<String, Object> variables = new HashMap<>();
+ variables.put(JOB_ID_PARAM_NAME, jobId);
+ variables.put(CREATE_NS_REQUEST_PARAM_NAME, createNsRequest);
+ variables.put(GLOBAL_CUSTOMER_ID_PARAM_NAME, globalCustomerId);
+ variables.put(SERVICE_TYPE_PARAM_NAME, serviceType);
+ return variables;
+ }
+
+ private Map<String, Object> getVariables(final String nsInstanceId, final String jobId, final String occId,
+ final InstantiateNsRequest instantiateNsRequest) {
+ final Map<String, Object> variables = new HashMap<>();
+ variables.put(NS_INSTANCE_ID_PARAM_NAME, nsInstanceId);
+ variables.put(JOB_ID_PARAM_NAME, jobId);
+ variables.put(OCC_ID_PARAM_NAME, occId);
+ variables.put(INSTANTIATE_NS_REQUEST_PARAM_NAME, instantiateNsRequest);
+ return variables;
+ }
+
+ private Map<String, Object> getVariables(final String nsInstanceId, final String jobId, final String occId,
+ final TerminateNsRequest terminateNsRequest) {
+ final Map<String, Object> variables = new HashMap<>();
+ variables.put(NS_INSTANCE_ID_PARAM_NAME, nsInstanceId);
+ variables.put(JOB_ID_PARAM_NAME, jobId);
+ variables.put(OCC_ID_PARAM_NAME, occId);
+ variables.put(TERMINATE_NS_REQUEST_PARAM_NAME, terminateNsRequest);
+ return variables;
+ }
+
+ private Map<String, Object> getVariables(final String nsInstanceId, final String jobId) {
+ final Map<String, Object> variables = new HashMap<>();
+ variables.put(NS_INSTANCE_ID_PARAM_NAME, nsInstanceId);
+ variables.put(JOB_ID_PARAM_NAME, jobId);
+ return variables;
+ }
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowExecutorService.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowExecutorService.java
new file mode 100644
index 0000000..fa2b8d5
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowExecutorService.java
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.service;
+
+import static org.onap.so.etsi.nfvo.ns.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-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowQueryService.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowQueryService.java
new file mode 100644
index 0000000..a6180b0
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowQueryService.java
@@ -0,0 +1,108 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.service;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.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.etsi.nfvo.ns.lcm.model.InlineResponse400;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance;
+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<NsInstancesNsInstance> getCreateNsResponse(final String processInstanceId) {
+ try {
+
+ if (Strings.isNullOrEmpty(processInstanceId)) {
+ logger.error("Invalid processInstanceId: {}", processInstanceId);
+ return Optional.empty();
+ }
+
+ final HistoricVariableInstance historicVariableInstance =
+ getVariable(processInstanceId, CREATE_NS_RESPONSE_PARAM_NAME);
+
+ if (historicVariableInstance != null) {
+ logger.info("Found HistoricVariableInstance : {}", historicVariableInstance);
+ final Object variableValue = historicVariableInstance.getValue();
+ if (variableValue instanceof NsInstancesNsInstance) {
+ return Optional.ofNullable((NsInstancesNsInstance) variableValue);
+ }
+ logger.error("Unknown CreateNsResponse object type {} received value: {}",
+ historicVariableInstance.getValue() != null ? variableValue.getClass() : null, variableValue);
+ }
+ } catch (final ProcessEngineException processEngineException) {
+ logger.error("Unable to find {} variable using processInstanceId: {}", CREATE_NS_RESPONSE_PARAM_NAME,
+ processInstanceId, processEngineException);
+ }
+ logger.error("Unable to find {} variable using processInstanceId: {}", CREATE_NS_RESPONSE_PARAM_NAME,
+ processInstanceId);
+ return Optional.empty();
+
+ }
+
+ public Optional<InlineResponse400> getProblemDetails(final String processInstanceId) {
+ try {
+ final HistoricVariableInstance historicVariableInstance =
+ getVariable(processInstanceId, NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME);
+
+ logger.info("Found HistoricVariableInstance : {}", historicVariableInstance);
+ final Object variableValue = historicVariableInstance.getValue();
+ if (variableValue instanceof InlineResponse400) {
+ return Optional.ofNullable((InlineResponse400) variableValue);
+ }
+ logger.error("Unknown ProblemDetails object type {} received value: {}",
+ historicVariableInstance.getValue() != null ? variableValue.getClass() : null, variableValue);
+ } catch (final ProcessEngineException processEngineException) {
+ logger.error("Unable to find {} variable using processInstanceId: {}",
+ NS_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-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/AbstractNetworkServiceTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/AbstractNetworkServiceTask.java
new file mode 100644
index 0000000..a785a51
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/AbstractNetworkServiceTask.java
@@ -0,0 +1,188 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.JOB_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OCC_ID_PARAM_NAME;
+import java.time.LocalDateTime;
+import java.util.Optional;
+import org.camunda.bpm.engine.delegate.BpmnError;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJobStatus;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ *
+ */
+public abstract class AbstractNetworkServiceTask {
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+ protected final DatabaseServiceProvider databaseServiceProvider;
+
+ protected AbstractNetworkServiceTask(final DatabaseServiceProvider jobServiceProvider) {
+ this.databaseServiceProvider = jobServiceProvider;
+ }
+
+ public void addJobStatus(final DelegateExecution execution, final JobStatusEnum jobStatus,
+ final String description) {
+ final NfvoJobStatus nfvoJobStatus =
+ new NfvoJobStatus().status(jobStatus).description(description).updatedTime(LocalDateTime.now());
+ logger.info("Adding NfvoJobStatus {}", nfvoJobStatus);
+ final NfvoJob nfvoJob = getNfvoJob(execution);
+ nfvoJob.nfvoJobStatus(nfvoJobStatus);
+ databaseServiceProvider.addJob(nfvoJob);
+ }
+
+ public void setJobStatus(final DelegateExecution execution, final JobStatusEnum jobStatus,
+ final String description) {
+ logger.info("Setting Job Status to {}", jobStatus);
+ final NfvoJob nfvoJob = getNfvoJob(execution);
+ nfvoJob.status(jobStatus);
+ if (JobStatusEnum.STARTED.equals(jobStatus)) {
+ nfvoJob.processInstanceId(execution.getProcessInstanceId());
+ }
+
+ if (JobStatusEnum.FINISHED.equals(jobStatus)) {
+ nfvoJob.endTime(LocalDateTime.now());
+ }
+
+ nfvoJob.nfvoJobStatus(
+ new NfvoJobStatus().status(jobStatus).description(description).updatedTime(LocalDateTime.now()));
+ databaseServiceProvider.addJob(nfvoJob);
+
+ }
+
+ public void setJobStatusToError(final DelegateExecution execution, final String description) {
+ logger.info("Setting Job Status to {}", JobStatusEnum.ERROR);
+
+ final String jobId = (String) execution.getVariable(JOB_ID_PARAM_NAME);
+ final Optional<NfvoJob> optional = databaseServiceProvider.getJob(jobId);
+ if (optional.isPresent()) {
+ final InlineResponse400 problemDetails =
+ (InlineResponse400) execution.getVariable(NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME);
+
+ final NfvoJob nfvoJob = optional.get();
+ nfvoJob.status(JobStatusEnum.ERROR).endTime(LocalDateTime.now());
+
+ if (problemDetails != null) {
+ logger.error("Found failed reason: {}", problemDetails);
+ nfvoJob.nfvoJobStatus(new NfvoJobStatus().status(JobStatusEnum.ERROR)
+ .description(problemDetails.getDetail()).updatedTime(LocalDateTime.now()));
+ }
+ nfvoJob.nfvoJobStatus(new NfvoJobStatus().status(JobStatusEnum.ERROR).description(description)
+ .updatedTime(LocalDateTime.now()));
+
+ databaseServiceProvider.addJob(nfvoJob);
+ }
+ logger.info("Finished setting Job Status to {}", JobStatusEnum.ERROR);
+
+ }
+
+ public void updateNsLcmOpOccStatusToCompleted(final DelegateExecution execution) {
+ logger.info("Executing updateNsLcmOpOccStatusToCompleted ...");
+
+ updateNsLcmOpOccOperationState(execution, OperationStateEnum.COMPLETED);
+
+ logger.info("Finished executing updateNsLcmOpOccStatusToCompleted ...");
+
+ }
+
+ public void updateNsLcmOpOccStatusToFailed(final DelegateExecution execution) {
+ logger.info("Executing updateNsLcmOpOccStatusToFailed ...");
+
+ updateNsLcmOpOccOperationState(execution, OperationStateEnum.FAILED);
+
+ logger.info("Finished executing updateNsLcmOpOccStatusToFailed ...");
+
+ }
+
+ protected void abortOperation(final DelegateExecution execution, final String message) {
+ abortOperation(execution, message, new InlineResponse400().detail(message));
+ }
+
+ private void updateNsLcmOpOccOperationState(final DelegateExecution execution,
+ final OperationStateEnum operationState) {
+ final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME);
+
+ final boolean isSuccessful = databaseServiceProvider.updateNsLcmOpOccOperationState(occId, operationState);
+ if (!isSuccessful) {
+ final String message =
+ "Unable to update NsLcmOpOcc " + occId + " operationState to" + operationState + " in database";
+ logger.error(message);
+ abortOperation(execution, message);
+ }
+ }
+
+ protected void abortOperation(final DelegateExecution execution, final String message,
+ final InlineResponse400 problemDetails) {
+ logger.error(message);
+ execution.setVariable(NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, problemDetails);
+ throw new BpmnError("WORKFLOW_FAILED");
+ }
+
+ private NfvoJob getNfvoJob(final DelegateExecution execution) {
+ final String jobId = (String) execution.getVariable(JOB_ID_PARAM_NAME);
+ final Optional<NfvoJob> optional = databaseServiceProvider.getJob(jobId);
+ if (optional.isEmpty()) {
+ final String message = "Unable to find job using job id: " + jobId;
+ logger.error(message);
+ execution.setVariable(NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, new InlineResponse400().detail(message));
+ throw new BpmnError("WORKFLOW_FAILED");
+
+ }
+ return optional.get();
+ }
+
+ protected void updateNsInstanceStatus(final DelegateExecution execution, final State nsStatus) {
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+
+ logger.info("Updating NfvoNsInst Status to {} and saving to DB", nsStatus);
+ databaseServiceProvider.updateNsInstState(nsInstId, nsStatus);
+ }
+
+ protected NfvoNsInst getNfvoNsInst(final DelegateExecution execution) {
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ return getNfvoNsInst(execution, nsInstId);
+ }
+
+ protected NfvoNsInst getNfvoNsInst(final DelegateExecution execution, final String nsInstId) {
+ logger.info("Getting NfvoNsInst to update with nsInstId: {}", nsInstId);
+ final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstId);
+
+ if (optionalNfvoNsInst.isEmpty()) {
+ final String message = "Unable to find NS Instance in database using id: " + nsInstId;
+ abortOperation(execution, message);
+ }
+
+ return optionalNfvoNsInst.get();
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateRequest.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateRequest.java
new file mode 100644
index 0000000..569d9b3
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateRequest.java
@@ -0,0 +1,167 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Objects;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.Tenant;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class CreateInstantiateRequest implements Serializable {
+ private static final long serialVersionUID = -4371264952509580468L;
+ private String nsInstId;
+ private String vnfdId;
+ private String vnfName;
+ private String vnfPkgId;
+ private String nfType;
+ private Tenant tenant;
+ private Map<String, String> additionalParams;
+
+ public String getNsInstId() {
+ return nsInstId;
+ }
+
+ public void setNsInstId(final String nsInstId) {
+ this.nsInstId = nsInstId;
+ }
+
+ public CreateInstantiateRequest nsInstId(final String nsInstId) {
+ this.nsInstId = nsInstId;
+ return this;
+ }
+
+ public final String getVnfdId() {
+ return vnfdId;
+ }
+
+ public final void setVnfdId(final String vnfdId) {
+ this.vnfdId = vnfdId;
+ }
+
+ public CreateInstantiateRequest vnfdId(final String vnfdId) {
+ this.vnfdId = vnfdId;
+ return this;
+ }
+
+ public final String getVnfName() {
+ return vnfName;
+ }
+
+ public final void setVnfName(final String vnfName) {
+ this.vnfName = vnfName;
+ }
+
+ public CreateInstantiateRequest vnfName(final String vnfName) {
+ this.vnfName = vnfName;
+ return this;
+ }
+
+ public final String getVnfPkgId() {
+ return vnfPkgId;
+ }
+
+ public final void setVnfPkgId(final String vnfPkgId) {
+ this.vnfPkgId = vnfPkgId;
+ }
+
+ public CreateInstantiateRequest vnfPkgId(final String vnfPkgId) {
+ this.vnfPkgId = vnfPkgId;
+ return this;
+ }
+
+ public final String getNfType() {
+ return nfType;
+ }
+
+ public final void setNfType(final String nfType) {
+ this.nfType = nfType;
+ }
+
+ public CreateInstantiateRequest nfType(final String nfType) {
+ this.nfType = nfType;
+ return this;
+ }
+
+ public final Tenant getTenant() {
+ return tenant;
+ }
+
+ public final void setTenant(final Tenant tenant) {
+ this.tenant = tenant;
+ }
+
+ public CreateInstantiateRequest tenant(final Tenant tenant) {
+ this.tenant = tenant;
+ return this;
+ }
+
+ public final Map<String, String> getAdditionalParams() {
+ return additionalParams;
+ }
+
+ public final void setAdditionalParams(final Map<String, String> additionalParams) {
+ this.additionalParams = additionalParams;
+ }
+
+ public CreateInstantiateRequest additionalParams(final Map<String, String> additionalParams) {
+ this.additionalParams = additionalParams;
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(nsInstId, vnfdId, vnfName, vnfPkgId, nfType, tenant, additionalParams);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof CreateInstantiateRequest) {
+ final CreateInstantiateRequest other = (CreateInstantiateRequest) obj;
+ return Objects.equals(nsInstId, other.nsInstId) && Objects.equals(vnfdId, other.vnfdId)
+ && Objects.equals(vnfName, other.vnfName) && Objects.equals(vnfPkgId, other.vnfPkgId)
+ && Objects.equals(nfType, other.nfType) && Objects.equals(tenant, other.tenant)
+ && Objects.equals(additionalParams, other.additionalParams);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class CreateInstantiateRequest {\n");
+ sb.append(" nsInstId: ").append(toIndentedString(nsInstId)).append("\n");
+ sb.append(" vnfdId: ").append(toIndentedString(vnfdId)).append("\n");
+ sb.append(" vnfName: ").append(toIndentedString(vnfName)).append("\n");
+ sb.append(" vnfPkgId: ").append(toIndentedString(vnfPkgId)).append("\n");
+ sb.append(" nfType: ").append(toIndentedString(nfType)).append("\n");
+ sb.append(" tenant: ").append(toIndentedString(tenant)).append("\n");
+ sb.append(" additionalParams: ").append(toIndentedString(additionalParams)).append("\n");
+
+ sb.append("}");
+ return sb.toString();
+ }
+
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateVnfTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateVnfTask.java
new file mode 100644
index 0000000..0d4cbbe
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateVnfTask.java
@@ -0,0 +1,221 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.ERROR;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS;
+import java.time.LocalDateTime;
+import java.util.Optional;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfRequest;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.Tenant;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ */
+@Component
+public class CreateInstantiateVnfTask extends AbstractNetworkServiceTask {
+ private static final String CREATE_INSTANTIATE_REQUEST_PARAM_NAME = "request";
+ private static final Logger logger = LoggerFactory.getLogger(CreateInstantiateVnfTask.class);
+ private static final String NF_INST_ID_PARAM_NAME = "NF_INST_ID";
+ public static final String CREATE_VNF_RESPONSE_PARAM_NAME = "createVnfResponse";
+ private final AaiServiceProvider aaiServiceProvider;
+ private final Sol003AdapterServiceProvider sol003AdapterServiceProvider;
+
+ @Autowired
+ public CreateInstantiateVnfTask(final DatabaseServiceProvider databaseServiceProvider,
+ final AaiServiceProvider aaiServiceProvider,
+ final Sol003AdapterServiceProvider sol003AdapterServiceProvider) {
+ super(databaseServiceProvider);
+ this.aaiServiceProvider = aaiServiceProvider;
+ this.sol003AdapterServiceProvider = sol003AdapterServiceProvider;
+ }
+
+ public void checkIfNfInstanceExistsInDb(final DelegateExecution execution) {
+ logger.info("Executing checkIfNfInstanceInDb");
+ final CreateInstantiateRequest request =
+ (CreateInstantiateRequest) execution.getVariable(CREATE_INSTANTIATE_REQUEST_PARAM_NAME);
+ logger.info("request: {}", request);
+
+ addJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Checking if NF Instance record exists in database for "
+ + request.getNsInstId() + " and " + request.getVnfName());
+ if (!databaseServiceProvider.isNsInstExists(request.getNsInstId(), request.getVnfName())) {
+ abortOperation(execution,
+ request.getNsInstId() + " " + request.getVnfName() + " VNF instance already exists");
+ }
+ logger.info("Finished executing checkIfNfInstanceInDb ...");
+
+ }
+
+ public void createNfInstanceInDb(final DelegateExecution execution) {
+ logger.info("Executing createNfInstanceInDb");
+ final CreateInstantiateRequest request =
+ (CreateInstantiateRequest) execution.getVariable(CREATE_INSTANTIATE_REQUEST_PARAM_NAME);
+ logger.info("request: {}", request);
+
+ addJobStatus(execution, IN_PROGRESS, "Creating NF Instance record in database for " + request.getVnfName());
+
+ final Optional<NfvoNsInst> optional = databaseServiceProvider.getNfvoNsInst(request.getNsInstId());
+
+ if (optional.isEmpty()) {
+ abortOperation(execution, "NfvoNsInst: " + request.getNsInstId() + "not founda");
+ }
+
+ final NfvoNsInst nfvoNsInst = optional.get();
+ final LocalDateTime now = LocalDateTime.now();
+ final NfvoNfInst nfvoNfInst = new NfvoNfInst().status(State.NOT_INSTANTIATED).createTime(now)
+ .lastUpdateTime(now).name(request.getVnfName()).vnfdId(request.getVnfdId())
+ .packageId(request.getVnfPkgId()).nfvoNsInst(nfvoNsInst);
+ databaseServiceProvider.saveNfvoNfInst(nfvoNfInst);
+ execution.setVariable(NF_INST_ID_PARAM_NAME, nfvoNfInst.getNfInstId());
+ logger.info("Finished executing createNfInstanceInDb ...");
+
+ }
+
+ public void createGenericVnfInAai(final DelegateExecution execution) {
+ logger.info("Executing createGenericVnfInAai");
+ try {
+ final CreateInstantiateRequest request =
+ (CreateInstantiateRequest) execution.getVariable(CREATE_INSTANTIATE_REQUEST_PARAM_NAME);
+
+ addJobStatus(execution, IN_PROGRESS, "Creating GenericVnf record in AAI for " + request.getVnfName());
+
+ final String nfInstId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME);
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId);
+
+ final GenericVnf genericVnf = new GenericVnf();
+ genericVnf.setVnfId(nfInstId);
+ genericVnf.setVnfName(request.getVnfName());
+ genericVnf.setVnfType(nfvoNsInst.getName() + "/" + request.getVnfName());
+ genericVnf.setServiceId(request.getNsInstId());
+ genericVnf.setNfType(request.getNfType());
+ genericVnf.setOperationalStatus("Created");
+ genericVnf.setIsClosedLoopDisabled(false);
+
+ aaiServiceProvider.createGenericVnfAndConnectServiceInstance(nsInstId, nfInstId, genericVnf);
+
+ final Tenant tenant = request.getTenant();
+ aaiServiceProvider.connectGenericVnfToTenant(nfInstId, tenant.getCloudOwner(), tenant.getRegionName(),
+ tenant.getTenantId());
+
+ } catch (final Exception exception) {
+ final String message = "Unable to Create GenericVnf in AAI";
+ logger.error(message, exception);
+ abortOperation(execution, message);
+ }
+
+ logger.info("Finished executing createGenericVnfInAai ...");
+ }
+
+ public void invokeCreateInstantiationRequest(final DelegateExecution execution) {
+ logger.info("Executing invokeCreateInstantiationRequest");
+
+ try {
+ final CreateInstantiateRequest request =
+ (CreateInstantiateRequest) execution.getVariable(CREATE_INSTANTIATE_REQUEST_PARAM_NAME);
+ logger.info("request: {}", request);
+
+ addJobStatus(execution, IN_PROGRESS,
+ "Invoking SOL003 adapter for creating and instantiating VNF: " + request.getVnfName());
+
+ final CreateVnfRequest vnfRequest = new CreateVnfRequest();
+ vnfRequest.setTenant(request.getTenant());
+ vnfRequest.setName(request.getVnfName());
+ vnfRequest.setPkgId(request.getVnfPkgId());
+ vnfRequest.setAdditionalParams(request.getAdditionalParams());
+ final String vnfId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME);
+ final Optional<CreateVnfResponse> optional =
+ sol003AdapterServiceProvider.invokeCreateInstantiationRequest(vnfId, vnfRequest);
+
+ if (!optional.isPresent()) {
+ final String errorMessage = "Unexpected error while processing create and instantiation request";
+ logger.error(errorMessage);
+ abortOperation(execution, errorMessage);
+ }
+
+ final CreateVnfResponse vnfResponse = optional.get();
+
+ logger.info("Vnf instantiation response: {}", vnfResponse);
+ execution.setVariable(CREATE_VNF_RESPONSE_PARAM_NAME, vnfResponse);
+ addJobStatus(execution, IN_PROGRESS, "Successfully invoked SOL003 adapater creating and instantiating VNF: "
+ + request.getVnfName() + " CreaetVnfResponse Job Id: " + vnfResponse.getJobId());
+ logger.debug("Finished executing invokeCreateInstantiationRequest ...");
+ } catch (final Exception exception) {
+ final String message = "Unable to invoke create and instantiation request";
+ logger.error(message, exception);
+ abortOperation(execution, message);
+ }
+
+ }
+
+ public void updateNfInstanceStatusToInstantiated(final DelegateExecution execution) {
+ logger.info("Executing updateNfInstanceStatusToInstantiated");
+
+ updateNfInstanceStatus(execution, State.INSTANTIATED);
+ final CreateInstantiateRequest request =
+ (CreateInstantiateRequest) execution.getVariable(CREATE_INSTANTIATE_REQUEST_PARAM_NAME);
+ addJobStatus(execution, FINISHED, "Successfully created and Instantiated VNF: " + request.getVnfName()
+ + " will set status to " + State.INSTANTIATED);
+
+ logger.info("Finished executing updateNfInstanceStatusToInstantiated ...");
+
+ }
+
+ public void updateNfInstanceStatusToFailed(final DelegateExecution execution) {
+ logger.info("Executing updateNfInstanceStatusToFailed");
+
+ updateNfInstanceStatus(execution, State.FAILED);
+ final CreateInstantiateRequest request =
+ (CreateInstantiateRequest) execution.getVariable(CREATE_INSTANTIATE_REQUEST_PARAM_NAME);
+ addJobStatus(execution, ERROR, "Failed to create and instantiate VNF: " + request.getVnfName()
+ + " will set status to " + State.FAILED);
+
+ logger.info("Finished executing updateNfInstanceStatusToFailed ...");
+
+ }
+
+ private void updateNfInstanceStatus(final DelegateExecution execution, final State vnfStatus) {
+ final String nfInstId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME);
+ final boolean isSuccessful = databaseServiceProvider.updateNfInstState(nfInstId, vnfStatus);
+ if (!isSuccessful) {
+ final String message =
+ "Unable to update NfvoNfInst " + nfInstId + " status to" + vnfStatus + " in database";
+ logger.error(message);
+ abortOperation(execution, message);
+ }
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateNsTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateNsTask.java
new file mode 100644
index 0000000..2cf68be
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateNsTask.java
@@ -0,0 +1,221 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_REQUEST_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.GLOBAL_CUSTOMER_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_PACKAGE_MODEL_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.SERVICE_TYPE_PARAM_NAME;
+import java.time.LocalDateTime;
+import java.util.Optional;
+import java.util.UUID;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.aai.domain.yang.ServiceInstance;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.EtsiCatalogManagerRequestFailureException;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogPackageManagementServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance.NsStateEnum;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+public class CreateNsTask extends AbstractNetworkServiceTask {
+ private static final String NETWORK_SERVICE_NAME = "NetworkService";
+ private static final String NETWORK_SERVICE_ROLE = "NetworkService";
+ private static final String DOES_NS_PACKAGE_EXISTS_PARAM_NAME = "doesNsPackageExists";
+ private static final String DOES_NS_INSTANCE_EXISTS_PARAM_NAME = "doesNsInstanceExists";
+ private static final Logger logger = LoggerFactory.getLogger(CreateNsTask.class);
+ private final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider;
+ private final AaiServiceProvider aaiServiceProvider;
+
+ @Autowired
+ public CreateNsTask(final DatabaseServiceProvider databaseServiceProvider,
+ final AaiServiceProvider aaiServiceProvider,
+ final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider) {
+ super(databaseServiceProvider);
+ this.aaiServiceProvider = aaiServiceProvider;
+ this.etsiCatalogPackageManagementServiceProvider = etsiCatalogPackageManagementServiceProvider;
+ }
+
+ public void setJobStatusToStarted(final DelegateExecution execution) {
+ setJobStatus(execution, JobStatusEnum.STARTED, "Create NS workflow process started");
+ }
+
+ public void setJobStatusToFinished(final DelegateExecution execution) {
+ setJobStatus(execution, JobStatusEnum.FINISHED, "Create NS workflow process finished");
+ }
+
+ public void setJobStatusToError(final DelegateExecution execution) {
+ setJobStatusToError(execution, "Create NS workflow process failed");
+ }
+
+ public void getNsPackage(final DelegateExecution execution) {
+ logger.info("Retrieving NS package from ETSI Catalog Manager ...");
+ setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Retrieving NS package from ETSI Catalog Manager");
+
+ final CreateNsRequest createNsRequest = (CreateNsRequest) execution.getVariable(CREATE_NS_REQUEST_PARAM_NAME);
+
+ try {
+ final Optional<NsdInfo> optional =
+ etsiCatalogPackageManagementServiceProvider.getNSPackageModel(createNsRequest.getNsdId());
+
+ if (optional.isPresent()) {
+ final NsdInfo packageModel = optional.get();
+ logger.info("NS Package exists {}", packageModel);
+ execution.setVariable(NS_PACKAGE_MODEL_PARAM_NAME, packageModel);
+ execution.setVariable(DOES_NS_PACKAGE_EXISTS_PARAM_NAME, true);
+ } else {
+ final String message = "Unable to find NS package using NsdId: " + createNsRequest.getNsdId();
+ logger.error(message);
+ execution.setVariable(DOES_NS_PACKAGE_EXISTS_PARAM_NAME, false);
+ execution.setVariable(NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME,
+ new InlineResponse400().detail(message));
+ }
+
+ } catch (final EtsiCatalogManagerRequestFailureException failureException) {
+ final String message =
+ "Unexpected exception occured while getting ns package using nsdId: " + createNsRequest.getNsdId();
+ logger.error(message, failureException);
+
+ execution.setVariable(DOES_NS_PACKAGE_EXISTS_PARAM_NAME, false);
+
+ execution.setVariable(NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME,
+ new InlineResponse400().title(message).detail(message));
+ }
+
+ }
+
+ public void doesNsInstanceExistsInDb(final DelegateExecution execution) {
+ logger.info("Executing doesNsInstanceExistsInDb ...");
+
+ setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Checking if NS package exists in database");
+
+ final CreateNsRequest createNsRequest =
+ (CreateNsRequest) execution.getVariables().get(CREATE_NS_REQUEST_PARAM_NAME);
+
+ final boolean exists = databaseServiceProvider.isNsInstExists(createNsRequest.getNsName());
+ logger.info("Ns Instance entry {} exists in database", exists ? "does" : "doesn't");
+ execution.setVariable(DOES_NS_INSTANCE_EXISTS_PARAM_NAME, exists);
+
+ if (exists) {
+ final Optional<NfvoNsInst> optional =
+ databaseServiceProvider.getNfvoNsInstByName(createNsRequest.getNsName());
+ final NfvoNsInst nfvoNsInst = optional.get();
+ execution.setVariable(NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, new InlineResponse400()
+ .detail("Ns Instance already exists in database : " + nfvoNsInst.toString()));
+ }
+
+ logger.info("Finished executing doesNsInstanceExistsInDb ...");
+
+ }
+
+ public void createNsInstanceInDb(final DelegateExecution execution) {
+ logger.info("Executing createNsInstanceInDb ...");
+
+ setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Checking if NS package exists");
+
+ final CreateNsRequest createNsRequest = (CreateNsRequest) execution.getVariable(CREATE_NS_REQUEST_PARAM_NAME);
+ final NsdInfo packageMode = (NsdInfo) execution.getVariable(NS_PACKAGE_MODEL_PARAM_NAME);
+
+ final String globalCustomerId = (String) execution.getVariable(GLOBAL_CUSTOMER_ID_PARAM_NAME);
+ final String serviceType = (String) execution.getVariable(SERVICE_TYPE_PARAM_NAME);
+
+ final String nsInstId = UUID.randomUUID().toString();
+ execution.setVariable(NS_INSTANCE_ID_PARAM_NAME, nsInstId);
+
+ databaseServiceProvider.saveNfvoNsInst(new NfvoNsInst().nsInstId(nsInstId).name(createNsRequest.getNsName())
+ .nsPackageId(packageMode.getId()).nsdId(packageMode.getNsdId())
+ .nsdInvariantId(packageMode.getNsdInvariantId()).description(createNsRequest.getNsDescription())
+ .status(State.NOT_INSTANTIATED).statusUpdatedTime(LocalDateTime.now())
+ .globalCustomerId(globalCustomerId).serviceType(serviceType));
+ logger.info("Finished executing createNsInstanceInDb ...");
+
+ }
+
+
+ public void createNsInstanceInAai(final DelegateExecution execution) {
+ logger.info("Executing createNsInstanceInAai ...");
+ try {
+ setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Creating NS Instance in AAI");
+
+ final CreateNsRequest createNsRequest =
+ (CreateNsRequest) execution.getVariable(CREATE_NS_REQUEST_PARAM_NAME);
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+
+ final String globalCustomerId = (String) execution.getVariable(GLOBAL_CUSTOMER_ID_PARAM_NAME);
+ final String serviceType = (String) execution.getVariable(SERVICE_TYPE_PARAM_NAME);
+
+ final ServiceInstance aaiServiceInstance = new ServiceInstance();
+ aaiServiceInstance.setServiceInstanceId(nsInstId);
+ aaiServiceInstance.setServiceInstanceName(createNsRequest.getNsName());
+ aaiServiceInstance.setServiceType(NETWORK_SERVICE_NAME);
+ aaiServiceInstance.setServiceRole(NETWORK_SERVICE_ROLE);
+
+ aaiServiceProvider.createServiceInstance(globalCustomerId, serviceType, aaiServiceInstance);
+ } catch (final Exception exception) {
+ final String message = "Unable to Create Service Instance in AAI";
+ logger.error(message, exception);
+ abortOperation(execution, message, new InlineResponse400().detail(message));
+ }
+ logger.info("Finished executing createNsInstanceInAai ...");
+
+ }
+
+ public void setCreateNsResponse(final DelegateExecution execution) {
+ logger.info("Executing setCreateNsResponse ...");
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final Optional<NfvoNsInst> optional = databaseServiceProvider.getNfvoNsInst(nsInstId);
+
+ if (optional.isPresent()) {
+ final NfvoNsInst nfvoNsInst = optional.get();
+ final NsInstancesNsInstance response = new NsInstancesNsInstance().id(nfvoNsInst.getNsInstId())
+ .nsInstanceName(nfvoNsInst.getName()).nsdId(nfvoNsInst.getNsdId())
+ .nsdInfoId(nfvoNsInst.getNsPackageId()).nsInstanceDescription(nfvoNsInst.getDescription())
+ .nsState(NsStateEnum.fromValue(nfvoNsInst.getStatus().toString()));
+ logger.info("Saving CreateNsResponse: {} in Execution ...", response);
+ execution.setVariable(CREATE_NS_RESPONSE_PARAM_NAME, response);
+ } else {
+ final String message = "Unable to find NS Instance in datababse using id: " + nsInstId;
+ logger.error(message);
+ abortOperation(execution, message);
+ }
+
+ logger.info("Finished executing setCreateNsResponse ...");
+
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/DeleteNsTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/DeleteNsTask.java
new file mode 100644
index 0000000..cd711fb
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/DeleteNsTask.java
@@ -0,0 +1,140 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import java.util.Optional;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.STARTED;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.State.NOT_INSTANTIATED;
+
+/**
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ *
+ */
+@Component
+public class DeleteNsTask extends AbstractNetworkServiceTask {
+
+ private static final String NS_INSTANCE_EXISTS_PARAM_NAME = "nsInstanceExists";
+ private static final String NS_INSTANCE_IS_IN_NOT_INSTANTIATED_STATE_PARAM_NAME = "isInNotInstantiatedState";
+ private static final Logger logger = LoggerFactory.getLogger(DeleteNsTask.class);
+ private final AaiServiceProvider aaiServiceProvider;
+
+ @Autowired
+ public DeleteNsTask(final DatabaseServiceProvider databaseServiceProvider,
+ final AaiServiceProvider aaiServiceProvider) {
+ super(databaseServiceProvider);
+ this.aaiServiceProvider = aaiServiceProvider;
+ }
+
+ public void setJobStatusToStarted(final DelegateExecution execution) {
+ setJobStatus(execution, STARTED, "Delete NS workflow process started");
+ }
+
+ public void setJobStatusToFinished(final DelegateExecution execution) {
+ setJobStatus(execution, FINISHED, "Delete NS workflow process finished");
+ }
+
+ public void setJobStatusInProgress(final DelegateExecution execution, final String message) {
+ setJobStatus(execution, IN_PROGRESS, message);
+ }
+
+ public void setJobStatusToError(final DelegateExecution execution) {
+ setJobStatusToError(execution, "Delete NS workflow process failed");
+ }
+
+ public void checkIfNsInstanceExistsInDb(final DelegateExecution execution) {
+ logger.info("Executing checkIfNsInstanceExistsInDb ...");
+ setJobStatusInProgress(execution, "Checking that NS Instance Exists in DB");
+
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstId);
+ final boolean nsInstanceExists = optionalNfvoNsInst.isPresent();
+ logger.info("NS Instance entry with id: {} {} exist in database", nsInstId,
+ nsInstanceExists ? "does" : "doesn't");
+ execution.setVariable(NS_INSTANCE_EXISTS_PARAM_NAME, nsInstanceExists);
+
+ if (!nsInstanceExists) {
+ final String message =
+ "NS Instance with id: " + nsInstId + " does not exist in database, so will not be deleted.";
+ logger.info(message);
+ execution.setVariable(NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, new InlineResponse400().detail(message));
+ }
+
+ logger.info("Finished executing checkIfNsInstanceExistsInDb ...");
+ }
+
+ public void checkthatNsInstanceInDbIsInNotInstantiatedState(final DelegateExecution execution) {
+ logger.info("Executing checkthatNsInstanceInDbIsInNotInstantiatedState ...");
+ setJobStatusInProgress(execution, "Checking that NS Instance is in NOT_INSTANTIATED state in Db");
+
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId);
+ final State nfvoNsInstState = nfvoNsInst.getStatus();
+ final boolean nsInstanceIsNotInstantiated = NOT_INSTANTIATED.equals(nfvoNsInstState);
+ logger.info("Ns Instance entry with nsInstId: {} is in state: {}", nsInstId, nfvoNsInstState);
+ execution.setVariable(NS_INSTANCE_IS_IN_NOT_INSTANTIATED_STATE_PARAM_NAME, nsInstanceIsNotInstantiated);
+
+ if (!nsInstanceIsNotInstantiated) {
+ final String message =
+ "Cannot Delete NS Instance with id: " + nsInstId + " in the state: " + nfvoNsInstState;
+ logger.info(message);
+ execution.setVariable(NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, new InlineResponse400().detail(message));
+ }
+
+ logger.info("Finished executing checkthatNsInstanceInDbIsInNotInstantiatedState ...");
+ }
+
+ public void deleteNsInstanceFromAai(final DelegateExecution execution) {
+ logger.info("Executing deleteNsInstanceFromAAI ...");
+ setJobStatusInProgress(execution, "Deleting NS Instance from AAI");
+
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId);
+ final String globalCustomerId = nfvoNsInst.getGlobalCustomerId();
+ final String serviceType = nfvoNsInst.getServiceType();
+
+ aaiServiceProvider.deleteServiceInstance(globalCustomerId, serviceType, nsInstId);
+
+ logger.info("Finished executing deleteNsInstanceFromAAI ...");
+ }
+
+ public void deleteNsInstanceFromDb(final DelegateExecution execution) {
+ logger.info("Executing deleteNsInstanceFromDb ...");
+ setJobStatusInProgress(execution, "Deleting NS Instance from Db");
+
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ databaseServiceProvider.deleteNfvoNsInst(nsInstId);
+
+ logger.info("Finished executing deleteNsInstanceFromDb ...");
+ }
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/InstantiateNsTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/InstantiateNsTask.java
new file mode 100644
index 0000000..a6d35e3
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/InstantiateNsTask.java
@@ -0,0 +1,328 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.INSTANTIATE_NS_REQUEST_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.VNF_CREATE_INSTANTIATE_REQUESTS;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.STARTED;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import org.apache.commons.lang.StringUtils;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.Tenant;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.EtsiCatalogManagerRequestFailureException;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogPackageManagementServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.VirtualNetworkFunction;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ *
+ */
+@Component
+public class InstantiateNsTask extends AbstractNetworkServiceTask {
+
+ private static final String IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME = "isNsInstantiationSuccessful";
+ private static final String VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME = "vnfdIdToVnfPkgIdMapping";
+ private static final Logger logger = LoggerFactory.getLogger(InstantiateNsTask.class);
+ private final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider;
+
+ @Autowired
+ public InstantiateNsTask(final DatabaseServiceProvider databaseServiceProvider,
+ final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider) {
+ super(databaseServiceProvider);
+ this.etsiCatalogPackageManagementServiceProvider = etsiCatalogPackageManagementServiceProvider;
+
+ }
+
+ public void setJobStatusToStarted(final DelegateExecution execution) {
+ setJobStatus(execution, STARTED, "Instantiate NS workflow process started");
+ }
+
+ public void setJobStatusToFinished(final DelegateExecution execution) {
+ setJobStatus(execution, FINISHED, "Instantiate NS workflow process finished");
+ }
+
+ public void updateNsInstanceStatusToInstantiating(final DelegateExecution execution) {
+ logger.info("Executing updateNsInstanceStatusToInstantiating");
+ setJobStatus(execution, IN_PROGRESS, "Updating NfvoNsInst Status to " + State.INSTANTIATING);
+ updateNsInstanceStatus(execution, State.INSTANTIATING);
+
+ logger.info("Finished executing updateNsInstanceStatusToInstantiating ...");
+ }
+
+
+ public void checkIfVnfInstantiationWasSuccessful(final DelegateExecution execution) {
+ logger.info("Executing checkIfVnfInstantiationWasSuccessful");
+
+ @SuppressWarnings("unchecked")
+ final List<CreateInstantiateRequest> requests =
+ (List<CreateInstantiateRequest>) execution.getVariable(VNF_CREATE_INSTANTIATE_REQUESTS);
+
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId);
+
+ if (nfInstances == null || nfInstances.isEmpty()) {
+ final String message = "Found empty nf instances";
+ abortOperation(execution, message);
+ }
+
+ if (requests.size() != nfInstances.size()) {
+ final String message = "Missing nf Instance. Request triggered: " + requests.size()
+ + " Nf Instace reqeust found in database " + nfInstances.size();
+ abortOperation(execution, message);
+ }
+
+ execution.setVariable(IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME, true);
+
+ nfInstances.stream().forEach(instance -> {
+ if (!State.INSTANTIATED.equals(instance.getStatus())) {
+ logger.error("VNF : {} {} instantiation failed", instance.getNfInstId(), instance.getName());
+ execution.setVariable(IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME, false);
+ }
+ });
+
+ logger.info("Finished executing checkIfVnfInstantiationWasSuccessful ...");
+ }
+
+ public void updateNsInstanceStatusToInstantiated(final DelegateExecution execution) {
+ logger.info("Executing updateNsInstanceStatusToInstantiated");
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ setJobStatus(execution, FINISHED, "Successfully " + State.INSTANTIATED + " NS: " + nsInstId);
+
+ updateNsInstanceStatus(execution, State.INSTANTIATED);
+ logger.info("Finished executing updateNsInstanceStatusToInstantiated ...");
+ }
+
+ public void getAndParseNsdFromEtsiCatalog(final DelegateExecution execution) {
+ logger.info("Executing getAndParseNsdFromEtsiCatalog");
+ setJobStatus(execution, IN_PROGRESS, "Retrieving and parsing NSD from ETSI Catalog Manager");
+ final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution);
+ final String nsPackageId = nfvoNsInst.getNsPackageId();
+
+ try {
+ final Optional<NetworkServiceDescriptor> optional =
+ etsiCatalogPackageManagementServiceProvider.getNetworkServiceDescriptor(nsPackageId);
+
+ if (optional.isEmpty()) {
+ final String message = "Unable to parse NSD " + nsPackageId;
+ logger.error(message);
+ abortOperation(execution, message);
+ }
+
+ final NetworkServiceDescriptor networkServiceDescriptor = optional.get();
+ logger.info("Found {}", networkServiceDescriptor);
+ execution.setVariable(NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME, networkServiceDescriptor);
+
+ } catch (final EtsiCatalogManagerRequestFailureException failureException) {
+ final String message =
+ "Unexpected exception occured while getting nsd content using nsPackageId: " + nsPackageId;
+ logger.error(message, failureException);
+
+ abortOperation(execution, message);
+ }
+
+ logger.info("Finished executing getAndParseNsdFromEtsiCatalog ...");
+
+ }
+
+ public void prepareCreateInstantiateRequests(final DelegateExecution execution) {
+ logger.info("Executing prepareCreateInstantiateRequests ...");
+ setJobStatus(execution, IN_PROGRESS, "Preparing VNF CreateInstantiate requests");
+ final NetworkServiceDescriptor networkServiceDescriptor =
+ (NetworkServiceDescriptor) execution.getVariable(NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME);
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId);
+
+ final InstantiateNsRequest instantiateNsRequest =
+ (InstantiateNsRequest) execution.getVariable(INSTANTIATE_NS_REQUEST_PARAM_NAME);
+
+ final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList =
+ instantiateNsRequest.getAdditionalParamsForVnf();
+
+ @SuppressWarnings("unchecked")
+ final Map<String, String> vnfdIdToVnfPkgIdMapping =
+ (Map<String, String>) execution.getVariable(VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME);
+
+ final List<CreateInstantiateRequest> requests = new ArrayList<>();
+
+ for (final VirtualNetworkFunction vnf : networkServiceDescriptor.getVnfs()) {
+ final List<String> vnfmInfoList = vnf.getVnfmInfoList();
+
+ final String vnfdId = vnf.getVnfdId();
+ final String vnfPkgId = vnfdIdToVnfPkgIdMapping.get(vnfdId);
+ if (vnfdId == null || vnfmInfoList.isEmpty() || vnfPkgId == null) {
+ final String message = "Unable to find VnfdId/vnfmInfo/VnfPkgId for vnf: " + vnf;
+ abortOperation(execution, message);
+ }
+
+ final Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfOptional =
+ getAdditionalParamsForVnf(vnfdId, additionalParamsForVnfList);
+
+ if (additionalParamsForVnfOptional.isEmpty()) {
+ final String message = "Unable to find AdditionalParamsForVnf for " + vnfdId
+ + " in instantiateNsRequest : " + instantiateNsRequest;
+ abortOperation(execution, message);
+ }
+
+ final NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf additionalParamsForVnf =
+ additionalParamsForVnfOptional.get();
+
+ @SuppressWarnings("unchecked")
+ final Map<String, String> additionalParams =
+ (Map<String, String>) additionalParamsForVnf.getAdditionalParams();
+
+ final Optional<Tenant> optional = getTenant(additionalParams);
+ if (optional.isEmpty()) {
+ final String message = "Unable to find Tenant information for " + vnfdId + " in instantiateNsRequest : "
+ + instantiateNsRequest;
+ abortOperation(execution, message);
+ }
+
+ final String vnfInstanceName = additionalParamsForVnf.getVnfInstanceName();
+ final String vnfName = StringUtils.isNotBlank(vnfInstanceName) ? vnfInstanceName
+ : nfvoNsInst.getName() + "." + vnf.getVnfName();
+
+ final CreateInstantiateRequest createInstantiateRequest =
+ new CreateInstantiateRequest().nsInstId(nsInstId).vnfdId(vnfdId).vnfName(vnfName).vnfPkgId(vnfPkgId)
+ .nfType(vnfmInfoList.get(0)).tenant(optional.get()).additionalParams(additionalParams);
+
+ logger.info("Adding request to list: {}", createInstantiateRequest);
+ requests.add(createInstantiateRequest);
+
+ }
+ execution.setVariable(VNF_CREATE_INSTANTIATE_REQUESTS, requests);
+
+ logger.info("Finished executing prepareCreateInstantiateRequests ...");
+ }
+
+ public void getVnfPkgIdForEachVnfdId(final DelegateExecution execution) {
+ logger.info("Executing getVnfPkgIdForEachVnfdId ...");
+
+ setJobStatus(execution, IN_PROGRESS, "Getting VnfPkgId for each VnfdId");
+
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId);
+ final String nsPackageId = nfvoNsInst.getNsPackageId();
+
+ final Map<String, String> vnfdIdToVnfPkgIdMapping = new HashMap<>();
+ try {
+ final Optional<NsdInfo> nsdInfoOptional =
+ etsiCatalogPackageManagementServiceProvider.getNSPackageModel(nsPackageId);
+
+ if (nsdInfoOptional.isEmpty()) {
+ final String message = "Unable to find NS package using NS package id: " + nsPackageId;
+ logger.error(message);
+ abortOperation(execution, message);
+ }
+
+ final NsdInfo nsdInfo = nsdInfoOptional.get();
+ for (final String vnfPkgId : nsdInfo.getVnfPkgIds()) {
+ final Optional<VnfPkgInfo> optional =
+ etsiCatalogPackageManagementServiceProvider.getVnfPkgInfo(vnfPkgId);
+
+ if (optional.isEmpty()) {
+ final String message = "Unable to find VNF package using NS vnfPkgId: " + vnfPkgId;
+ logger.error(message);
+ abortOperation(execution, message);
+ }
+ final VnfPkgInfo vnfPkgInfo = optional.get();
+ vnfdIdToVnfPkgIdMapping.put(vnfPkgInfo.getVnfdId(), vnfPkgId);
+
+ }
+ logger.info("vnfdIdToVnfPkgIdMapping: {}", vnfdIdToVnfPkgIdMapping);
+ execution.setVariable(VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME, vnfdIdToVnfPkgIdMapping);
+
+ } catch (final EtsiCatalogManagerRequestFailureException failureException) {
+ final String message =
+ "Unexpected exception occured while getting VNF package using nsPackageId: " + nsPackageId;
+ logger.error(message, failureException);
+
+ abortOperation(execution, message);
+ }
+
+ logger.info("Finished executing getVnfPkgIdForEachVnfdId ...");
+
+ }
+
+ public void logTimeOut(final DelegateExecution execution) {
+ logger.error("Vnf instantiation timedOut ...");
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId);
+ if (nfInstances != null) {
+ nfInstances.stream().forEach(instance -> {
+ logger.info("Current status {} of vnf: {}", instance.getStatus(), instance.getName());
+ });
+ }
+ }
+
+ public void setJobStatusToError(final DelegateExecution execution) {
+ updateNsInstanceStatus(execution, State.FAILED);
+ setJobStatusToError(execution, "Instantiate NS workflow process failed");
+ }
+
+ private Optional<Tenant> getTenant(final Map<String, String> additionalParams) {
+ final String vimId = additionalParams.get("vim_id");
+ if (vimId != null) {
+ final String[] splitString = vimId.split("_");
+ if (splitString.length == 3) {
+ logger.info("Found Tenant in additionalParams: {}", additionalParams);
+ return Optional.of(
+ new Tenant().cloudOwner(splitString[0]).regionName(splitString[1]).tenantId(splitString[2]));
+ }
+
+ }
+ logger.error("Unable to find Tenant in additionalParams: {}", additionalParams);
+ return Optional.empty();
+ }
+
+ private Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> getAdditionalParamsForVnf(
+ final String vnfdId,
+ final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList) {
+ final Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> optional =
+ additionalParamsForVnfList.stream().filter(entry -> vnfdId.equals(entry.getVnfProfileId())).findFirst();
+ if (optional.isPresent()) {
+ logger.info("Found AdditionalParamsForVnf in instantiateNsRequest using vnfdId: {}", vnfdId);
+
+ }
+ return optional;
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorInstantiateSol003AdapterNodeTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorInstantiateSol003AdapterNodeTask.java
new file mode 100644
index 0000000..51fa6b9
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorInstantiateSol003AdapterNodeTask.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+public class MonitorInstantiateSol003AdapterNodeTask extends MonitorSol003AdapterNodeTask {
+ public static final String CREATE_VNF_NODE_STATUS = "createVnfNodeStatus";
+ public static final String VNF_CREATED = "Created";
+
+ @Autowired
+ public MonitorInstantiateSol003AdapterNodeTask(final DatabaseServiceProvider databaseServiceProvider,
+ final AaiServiceProvider aaiServiceProvider) {
+ super(databaseServiceProvider, aaiServiceProvider);
+ }
+
+ @Override
+ public String getNodeStatusVariableName() {
+ return CREATE_VNF_NODE_STATUS;
+ }
+
+ @Override
+ public boolean isOrchestrationStatusValid(final String orchestrationStatus) {
+ return VNF_CREATED.equalsIgnoreCase(orchestrationStatus);
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterCreateJobTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterCreateJobTask.java
new file mode 100644
index 0000000..3c91598
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterCreateJobTask.java
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_VNF_RESPONSE_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+public class MonitorSol003AdapterCreateJobTask extends MonitorSol003AdapterJobTask {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MonitorSol003AdapterCreateJobTask.class);
+
+ @Autowired
+ public MonitorSol003AdapterCreateJobTask(final Sol003AdapterServiceProvider sol003AdapterServiceProvider,
+ final DatabaseServiceProvider databaseServiceProvider) {
+ super(sol003AdapterServiceProvider, databaseServiceProvider);
+ }
+
+ public void getCurrentOperationStatus(final DelegateExecution execution) {
+ try {
+ LOGGER.debug("Executing getCurrentOperationStatus ...");
+ final CreateVnfResponse vnfInstantiateResponse =
+ (CreateVnfResponse) execution.getVariable(CREATE_VNF_RESPONSE_PARAM_NAME);
+ execution.setVariable(OPERATION_STATUS_PARAM_NAME,
+ getOperationStatus(execution, vnfInstantiateResponse.getJobId()));
+ LOGGER.debug("Finished executing getCurrentOperationStatus ...");
+ } catch (final Exception exception) {
+ final String message = "Unable to invoke get current Operation status";
+ LOGGER.error(message, exception);
+ abortOperation(execution, message);
+
+ }
+ }
+
+ /**
+ * Log and throw exception on timeout for job status
+ *
+ * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl}
+ */
+ public void timeOutLogFailue(final DelegateExecution execution) {
+ final String message = "Instantiation operation time out";
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+
+ /**
+ * Check the final status of instantiation throw exception if not completed successfully
+ *
+ * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl}
+ */
+ public void checkIfOperationWasSuccessful(final DelegateExecution execution) {
+ LOGGER.debug("Executing checkIfOperationWasSuccessful ...");
+ final OperationStateEnum operationStatus =
+ (OperationStateEnum) execution.getVariable(OPERATION_STATUS_PARAM_NAME);
+ final CreateVnfResponse vnfInstantiateResponse =
+ (CreateVnfResponse) execution.getVariable(CREATE_VNF_RESPONSE_PARAM_NAME);
+
+ if (operationStatus == null) {
+ final String message = "Unable to instantiate jobId: "
+ + (vnfInstantiateResponse != null ? vnfInstantiateResponse.getJobId() : "null")
+ + "Unable to retrieve OperationStatus";
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+ if (operationStatus != OperationStateEnum.COMPLETED) {
+ final String message = "Unable to instantiate jobId: "
+ + (vnfInstantiateResponse != null ? vnfInstantiateResponse.getJobId() : "null")
+ + " OperationStatus: " + operationStatus;
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+
+ LOGGER.debug("Successfully completed instatiation of job {}", vnfInstantiateResponse);
+ }
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterJobTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterJobTask.java
new file mode 100644
index 0000000..bac79df
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterJobTask.java
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME;
+import java.util.Optional;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStatusRetrievalStatusEnum;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+public class MonitorSol003AdapterJobTask extends AbstractNetworkServiceTask {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MonitorSol003AdapterJobTask.class);
+ public static final ImmutableSet<OperationStateEnum> OPERATION_FINISHED_STATES =
+ ImmutableSet.of(OperationStateEnum.COMPLETED, OperationStateEnum.FAILED, OperationStateEnum.ROLLED_BACK);
+ public static final ImmutableSet<OperationStatusRetrievalStatusEnum> OPERATION_RETRIEVAL_STATES = ImmutableSet
+ .of(OperationStatusRetrievalStatusEnum.STATUS_FOUND, OperationStatusRetrievalStatusEnum.WAITING_FOR_STATUS);
+ protected final Sol003AdapterServiceProvider sol003AdapterServiceProvider;
+
+ @Autowired
+ public MonitorSol003AdapterJobTask(final Sol003AdapterServiceProvider sol003AdapterServiceProvider,
+ final DatabaseServiceProvider databaseServiceProvider) {
+ super(databaseServiceProvider);
+ this.sol003AdapterServiceProvider = sol003AdapterServiceProvider;
+ }
+
+ public boolean hasOperationFinished(final DelegateExecution execution) {
+ LOGGER.debug("Executing hasOperationFinished ...");
+
+ final OperationStateEnum operationStatus =
+ (OperationStateEnum) execution.getVariable(OPERATION_STATUS_PARAM_NAME);
+ if (operationStatus != null) {
+ return OPERATION_FINISHED_STATES.contains(operationStatus);
+ }
+ LOGGER.debug("OperationStatus is not present yet... ");
+ LOGGER.debug("Finished executing hasOperationFinished ...");
+ return false;
+ }
+
+ protected OperationStateEnum getOperationStatus(final DelegateExecution execution, final String jobId) {
+
+ final Optional<QueryJobResponse> instantiateOperationJobStatus =
+ sol003AdapterServiceProvider.getInstantiateOperationJobStatus(jobId);
+
+ if (instantiateOperationJobStatus.isPresent()) {
+ final QueryJobResponse queryJobResponse = instantiateOperationJobStatus.get();
+
+ if (!OPERATION_RETRIEVAL_STATES.contains(queryJobResponse.getOperationStatusRetrievalStatus())) {
+ final String message = "Received invalid operation retrieval state: "
+ + queryJobResponse.getOperationStatusRetrievalStatus();
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+ if (queryJobResponse.getOperationState() != null) {
+ final OperationStateEnum operationStatus = queryJobResponse.getOperationState();
+ LOGGER.debug("Operation {} with {} and operation retrieval status : {}", queryJobResponse.getId(),
+ operationStatus, queryJobResponse.getOperationStatusRetrievalStatus());
+ return queryJobResponse.getOperationState();
+ }
+
+ LOGGER.debug("Operation {} without operationStatus and operation retrieval status :{}",
+ queryJobResponse.getId(), queryJobResponse.getOperationStatusRetrievalStatus());
+ }
+ return null;
+ }
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterNodeTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterNodeTask.java
new file mode 100644
index 0000000..001c369
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterNodeTask.java
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NF_INST_ID_PARAM_NAME;
+import java.util.Optional;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public abstract class MonitorSol003AdapterNodeTask extends AbstractNetworkServiceTask {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MonitorSol003AdapterNodeTask.class);
+ private final AaiServiceProvider aaiServiceProvider;
+
+ protected MonitorSol003AdapterNodeTask(final DatabaseServiceProvider databaseServiceProvider,
+ final AaiServiceProvider aaiServiceProvider) {
+ super(databaseServiceProvider);
+ this.aaiServiceProvider = aaiServiceProvider;
+ }
+
+ /**
+ * Check the final status of vnf in A&AI
+ *
+ * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl}
+ */
+ public void getNodeStatus(final DelegateExecution execution) {
+ try {
+ LOGGER.debug("Executing getNodeStatus ...");
+ final String vnfId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME);
+
+ LOGGER.debug("Query A&AI for generic VNF using vnfID: {}", vnfId);
+ final Optional<GenericVnf> aaiGenericVnfOptional = aaiServiceProvider.getGenericVnf(vnfId);
+
+ if (aaiGenericVnfOptional.isEmpty()) {
+ abortOperation(execution, "Unable to find generic vnf in A&AI using vnfId" + vnfId);
+ }
+ final GenericVnf genericVnf = aaiGenericVnfOptional.get();
+ final String orchestrationStatus = genericVnf.getOrchestrationStatus();
+ LOGGER.debug("Found generic vnf with orchestration status : {}", orchestrationStatus);
+
+ execution.setVariable(getNodeStatusVariableName(), isOrchestrationStatusValid(orchestrationStatus));
+
+ } catch (final Exception exception) {
+ LOGGER.error("Unable to get vnf from AAI", exception);
+ abortOperation(execution, "Unable to get vnf from AAI");
+ }
+ }
+
+ /**
+ * Get variable to store in execution context
+ *
+ * @return the variable name
+ */
+ public abstract String getNodeStatusVariableName();
+
+ /**
+ * @param orchestrationStatus the orchestration status from A&AI
+ * @return true if valid
+ */
+ public abstract boolean isOrchestrationStatusValid(final String orchestrationStatus);
+
+ public void timeOutLogFailue(final DelegateExecution execution) {
+ final String message = "Node operation time out";
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+
+ AaiServiceProvider getAaiServiceProvider() {
+ return aaiServiceProvider;
+ }
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateJobTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateJobTask.java
new file mode 100644
index 0000000..d854444
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateJobTask.java
@@ -0,0 +1,106 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.DeleteVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.DELETE_VNF_RESPONSE_PARAM_NAME;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ *
+ */
+@Component
+public class MonitorSol003AdapterTerminateJobTask extends MonitorSol003AdapterJobTask {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MonitorSol003AdapterTerminateJobTask.class);
+
+ @Autowired
+ public MonitorSol003AdapterTerminateJobTask(final Sol003AdapterServiceProvider sol003AdapterServiceProvider,
+ final DatabaseServiceProvider databaseServiceProvider) {
+ super(sol003AdapterServiceProvider, databaseServiceProvider);
+ }
+
+ public void getCurrentOperationStatus(final DelegateExecution execution) {
+ try {
+ LOGGER.debug("Executing getCurrentOperationStatus ...");
+ final DeleteVnfResponse deleteVnfResponse =
+ (DeleteVnfResponse) execution.getVariable(DELETE_VNF_RESPONSE_PARAM_NAME);
+ execution.setVariable(OPERATION_STATUS_PARAM_NAME,
+ getOperationStatus(execution, deleteVnfResponse.getJobId()));
+ LOGGER.debug("Finished executing getCurrentOperationStatus ...");
+ } catch (final Exception exception) {
+ final String message = "Unable to invoke get current Operation status";
+ LOGGER.error(message, exception);
+ abortOperation(execution, message);
+
+ }
+ }
+
+ /**
+ * Log and throw exception on timeout for job status
+ *
+ * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl}
+ */
+ public void timeOutLogFailure(final DelegateExecution execution) {
+ final String message = "Termination operation time out";
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+
+ /**
+ * Check the final status of termination throw exception if not completed successfully
+ *
+ * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl}
+ */
+ public void checkIfOperationWasSuccessful(final DelegateExecution execution) {
+ LOGGER.debug("Executing checkIfOperationWasSuccessful ...");
+ final OperationStateEnum operationStatus =
+ (OperationStateEnum) execution.getVariable(OPERATION_STATUS_PARAM_NAME);
+ final DeleteVnfResponse deleteVnfResponse =
+ (DeleteVnfResponse) execution.getVariable(DELETE_VNF_RESPONSE_PARAM_NAME);
+
+ if (operationStatus == null) {
+ final String message =
+ "Unable to terminate, jobId: " + (deleteVnfResponse != null ? deleteVnfResponse.getJobId() : "null")
+ + "Unable to retrieve OperationStatus";
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+ if (operationStatus != OperationStateEnum.COMPLETED) {
+ final String message =
+ "Unable to terminate, jobId: " + (deleteVnfResponse != null ? deleteVnfResponse.getJobId() : "null")
+ + " OperationStatus: " + operationStatus;
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+
+ LOGGER.debug("Successfully completed termination of job {}", deleteVnfResponse);
+ }
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateNodeTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateNodeTask.java
new file mode 100644
index 0000000..f38bdba
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateNodeTask.java
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ *
+ */
+@Component
+public class MonitorSol003AdapterTerminateNodeTask extends MonitorSol003AdapterNodeTask {
+
+ public static final String DELETE_VNF_NODE_STATUS = "deleteVnfNodeStatus";
+ public static final String VNF_ASSIGNED = "Assigned";
+
+ @Autowired
+ public MonitorSol003AdapterTerminateNodeTask(final DatabaseServiceProvider databaseServiceProvider,
+ final AaiServiceProvider aaiServiceProvider) {
+ super(databaseServiceProvider, aaiServiceProvider);
+ }
+
+ @Override
+ public String getNodeStatusVariableName() {
+ return DELETE_VNF_NODE_STATUS;
+ }
+
+ @Override
+ public boolean isOrchestrationStatusValid(final String orchestrationStatus) {
+ return VNF_ASSIGNED.equalsIgnoreCase(orchestrationStatus);
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateNsTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateNsTask.java
new file mode 100644
index 0000000..c0d1df8
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateNsTask.java
@@ -0,0 +1,134 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import java.util.ArrayList;
+import java.util.List;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.STARTED;
+
+/**
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ *
+ */
+@Component
+public class TerminateNsTask extends AbstractNetworkServiceTask {
+
+ private static final String IS_NS_TERMINATION_SUCCESSFUL_PARAM_NAME = "isNsTerminationSuccessful";
+ private static final Logger logger = LoggerFactory.getLogger(TerminateNsTask.class);
+
+ @Autowired
+ public TerminateNsTask(final DatabaseServiceProvider databaseServiceProvider) {
+ super(databaseServiceProvider);
+ }
+
+ public void setJobStatusToStarted(final DelegateExecution execution) {
+ setJobStatus(execution, STARTED, "Terminate NS workflow process started");
+ }
+
+ public void setJobStatusToFinished(final DelegateExecution execution) {
+ setJobStatus(execution, FINISHED, "Terminate NS workflow process finished");
+ }
+
+ public void setJobStatusToError(final DelegateExecution execution) {
+ updateNsInstanceStatus(execution, State.FAILED);
+ setJobStatusToError(execution, "Terminate NS workflow process failed");
+ }
+
+ public void updateNsInstanceStatusToTerminating(final DelegateExecution execution) {
+ logger.info("Executing updateNsInstanceStatusToTerminating");
+ setJobStatus(execution, IN_PROGRESS, "Updating NfvoNsInst Status to " + State.TERMINATING);
+ updateNsInstanceStatus(execution, State.TERMINATING);
+ logger.info("Finished executing updateNsInstanceStatusToTerminating ...");
+ }
+
+ public void updateNsInstanceStatusToNotInstantiated(final DelegateExecution execution) {
+ logger.info("Executing updateNsInstanceStatusToNotInstantiated");
+ setJobStatus(execution, IN_PROGRESS, "Updating NfvoNsInst Status to " + State.NOT_INSTANTIATED);
+ updateNsInstanceStatus(execution, State.NOT_INSTANTIATED);
+ logger.info("Finished executing updateNsInstanceStatusToNotInstantiated ...");
+ }
+
+ public void getVnfIdsInNs(final DelegateExecution execution) {
+ logger.info("Executing getVnfIdsInNs ...");
+ setJobStatus(execution, IN_PROGRESS, "Getting Each VnfId In Ns");
+ final List<String> nfvoNfInstIds = getNfvoNfInstIds(execution);
+ execution.setVariable(CamundaVariableNameConstants.NFVO_NF_INST_IDS_PARAM_NAME, nfvoNfInstIds);
+ logger.info("Finished executing getVnfIdsInNs ...");
+ }
+
+ public void checkIfVnfTerminationWasSuccessful(final DelegateExecution execution) {
+ logger.info("Executing checkIfVnfTerminationWasSuccessful");
+
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId);
+
+ if ((nfInstances != null) && !(nfInstances.isEmpty())) {
+ final String message = "Found NF Instances";
+ nfInstances.stream().forEach(instance -> {
+ logger.error("VNF : {} {} termination failed", instance.getNfInstId(), instance.getName());
+ execution.setVariable(IS_NS_TERMINATION_SUCCESSFUL_PARAM_NAME, false);
+ });
+ abortOperation(execution, message);
+ }
+
+ execution.setVariable(IS_NS_TERMINATION_SUCCESSFUL_PARAM_NAME, true);
+ logger.info("Finished executing checkIfVnfTerminationWasSuccessful");
+ }
+
+ public void logTimeOut(final DelegateExecution execution) {
+ logger.error("Vnf termination timedOut ...");
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId);
+ if (nfInstances != null) {
+ nfInstances.stream().forEach(
+ instance -> logger.info("Current status {} of vnf: {}", instance.getStatus(), instance.getName()));
+ }
+ }
+
+ private List<String> getNfvoNfInstIds(final DelegateExecution execution) {
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ logger.info("Getting NfvoNfInstList using nsInstId: {}", nsInstId);
+ final List<NfvoNfInst> nfvoNfInstList = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId);
+
+ if (nfvoNfInstList == null || nfvoNfInstList.isEmpty()) {
+ final String message = "Unable to find NF Instances in database using id: " + nsInstId;
+ abortOperation(execution, message);
+ }
+
+ final List<String> vnfIdsList = new ArrayList<>();
+
+ nfvoNfInstList.stream().forEach(nfvoNfInst -> vnfIdsList.add(nfvoNfInst.getNfInstId()));
+
+ return vnfIdsList;
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateVnfTask.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateVnfTask.java
new file mode 100644
index 0000000..f3e7eea
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateVnfTask.java
@@ -0,0 +1,180 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.DELETE_VNF_RESPONSE_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NF_INST_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.TERMINATE_VNF_VNFID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.ERROR;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS;
+import java.util.Optional;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.DeleteVnfResponse;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ */
+@Component
+public class TerminateVnfTask extends AbstractNetworkServiceTask {
+ private static final Logger logger = LoggerFactory.getLogger(TerminateVnfTask.class);
+ private final AaiServiceProvider aaiServiceProvider;
+ private final Sol003AdapterServiceProvider sol003AdapterServiceProvider;
+
+ @Autowired
+ public TerminateVnfTask(final DatabaseServiceProvider databaseServiceProvider,
+ final AaiServiceProvider aaiServiceProvider,
+ final Sol003AdapterServiceProvider sol003AdapterServiceProvider) {
+ super(databaseServiceProvider);
+ this.aaiServiceProvider = aaiServiceProvider;
+ this.sol003AdapterServiceProvider = sol003AdapterServiceProvider;
+ }
+
+ public void checkIfNfInstanceExistsInDb(final DelegateExecution execution) {
+ logger.info("Executing checkIfNfInstanceInDb");
+ final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+ logger.info("vnfId: {}", vnfId);
+ execution.setVariable(NF_INST_ID_PARAM_NAME, vnfId);
+
+ addJobStatus(execution, JobStatusEnum.IN_PROGRESS,
+ "Checking if VNF Instance with id: " + vnfId + " exists in database.");
+ if (!databaseServiceProvider.isNfInstExists(vnfId)) {
+ abortOperation(execution,
+ "VNF instance with id: " + vnfId + " does not exist in database, so will not be terminated.");
+ }
+ logger.info("Finished executing checkIfNfInstanceInDb ...");
+
+ }
+
+ public void invokeTerminateRequest(final DelegateExecution execution) {
+ logger.info("Executing invokeTerminateRequest");
+ final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+
+ try {
+ addJobStatus(execution, IN_PROGRESS, "Invoking SOL003 adapter for terminating VNF with vnfId: " + vnfId);
+
+ final Optional<DeleteVnfResponse> optional = sol003AdapterServiceProvider.invokeTerminationRequest(vnfId);
+
+ if (optional.isEmpty()) {
+ final String errorMessage = "Unexpected error while processing terminate request for vnfId: " + vnfId;
+ logger.error(errorMessage);
+ abortOperation(execution, errorMessage);
+ }
+
+ final DeleteVnfResponse vnfResponse = optional.get();
+
+ logger.info("Vnf delete response: {}", vnfResponse);
+ execution.setVariable(DELETE_VNF_RESPONSE_PARAM_NAME, vnfResponse);
+ addJobStatus(execution, IN_PROGRESS, "Successfully invoked SOL003 adapter terminate VNF with vnfId: "
+ + vnfId + " DeleteVnfResponse Job Id: " + vnfResponse.getJobId());
+ logger.debug("Finished executing invokeTerminateRequest ...");
+ } catch (final Exception exception) {
+ final String message = "Unable to invoke terminate request for vnfId: " + vnfId;
+ logger.error(message, exception);
+ abortOperation(execution, message);
+ }
+
+ }
+
+ public void deleteGenericVnfFromAai(final DelegateExecution execution) {
+ logger.info("Executing deleteGenericVnfFromAai");
+ final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+
+ try {
+ addJobStatus(execution, IN_PROGRESS, "Deleting GenericVnf record from AAI for vnfId: " + vnfId);
+ aaiServiceProvider.deleteGenericVnf(vnfId);
+
+ } catch (final Exception exception) {
+ final String message = "Unable to Delete GenericVnf from AAI for vnfId: " + vnfId;
+ logger.error(message, exception);
+ abortOperation(execution, message);
+ }
+
+ logger.info("Finished executing deleteGenericVnfFromAai ...");
+ }
+
+ public void deleteNfInstanceFromDb(final DelegateExecution execution) {
+ logger.info("Executing deleteNfInstanceFromDb");
+ final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+
+ addJobStatus(execution, IN_PROGRESS, "Deleting NF Instance record from Database for vnfId: " + vnfId);
+ databaseServiceProvider.deleteNfvoNfInst(vnfId);
+
+ addJobStatus(execution, FINISHED, "Successfully finished terminating VNF with vnfId: " + vnfId);
+ logger.info("Finished executing deleteNfInstanceFromDb ...");
+ }
+
+ public void updateNfInstanceStatusToTerminating(final DelegateExecution execution) {
+ logger.info("Executing updateNfInstanceStatusToTerminating");
+
+ updateNfInstanceStatus(execution, State.TERMINATING);
+ final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+ addJobStatus(execution, IN_PROGRESS,
+ "Terminating VNF with vnfId: " + vnfId + " will set status to " + State.TERMINATING);
+
+ logger.info("Finished executing updateNfInstanceStatusToTerminating ...");
+
+ }
+
+ public void updateNfInstanceStatusToNotInstantiated(final DelegateExecution execution) {
+ logger.info("Executing updateNfInstanceStatusToNotInstantiated");
+
+ updateNfInstanceStatus(execution, State.NOT_INSTANTIATED);
+ final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+ addJobStatus(execution, IN_PROGRESS,
+ "Successfully terminated VNF with vnfId: " + vnfId + " will set status to " + State.NOT_INSTANTIATED);
+
+ logger.info("Finished executing updateNfInstanceStatusToInstantiated ...");
+
+ }
+
+ public void updateNfInstanceStatusToFailed(final DelegateExecution execution) {
+ logger.info("Executing updateNfInstanceStatusToFailed");
+
+ updateNfInstanceStatus(execution, State.FAILED);
+ final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+ addJobStatus(execution, ERROR,
+ "Failed to terminate VNF with vnfId: " + vnfId + " will set status to " + State.FAILED);
+
+ logger.info("Finished executing updateNfInstanceStatusToFailed ...");
+
+ }
+
+ private void updateNfInstanceStatus(final DelegateExecution execution, final State vnfStatus) {
+ final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+
+ final boolean isSuccessful = databaseServiceProvider.updateNfInstState(vnfId, vnfStatus);
+ if (!isSuccessful) {
+ final String message = "Unable to update NfvoNfInst " + vnfId + " status to" + vnfStatus + " in database";
+ logger.error(message);
+ abortOperation(execution, message);
+ }
+ }
+
+}
diff --git a/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java
new file mode 100644
index 0000000..9f21d2b
--- /dev/null
+++ b/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.etsi.nfvo.ns.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);
+
+ }
+
+}