summaryrefslogtreecommitdiffstats
path: root/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src
diff options
context:
space:
mode:
Diffstat (limited to 'so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src')
-rw-r--r--so-etsi-nfvo/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.java3
-rw-r--r--so-etsi-nfvo/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.java26
-rw-r--r--so-etsi-nfvo/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.java72
-rw-r--r--so-etsi-nfvo/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/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.java234
-rw-r--r--so-etsi-nfvo/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.java416
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn159
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/InstantiateNs.bpmn331
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/InstantiateNsTaskTest.java319
9 files changed, 1725 insertions, 2 deletions
diff --git a/so-etsi-nfvo/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/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
index a373df43e7..65d982c6cc 100644
--- a/so-etsi-nfvo/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/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
@@ -22,6 +22,7 @@ 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)
@@ -33,4 +34,6 @@ public interface EtsiCatalogPackageManagementServiceProvider {
Optional<VnfPkgInfo> getVnfPkgInfo(final String vnfPkgId);
+ Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor(final String nsdId);
+
}
diff --git a/so-etsi-nfvo/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/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
index 32f7cc1182..75dd7107a7 100644
--- a/so-etsi-nfvo/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/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
@@ -24,6 +24,8 @@ 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.NetworkServiceDescriptorParser;
import org.onap.so.rest.service.HttpRestServiceProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,12 +45,15 @@ public class EtsiCatalogPackageManagementServiceProviderImpl implements EtsiCata
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) {
+ @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider,
+ final NetworkServiceDescriptorParser networkServiceDescriptorParser) {
this.etsiCatalogUrlProvider = etsiCatalogUrlProvider;
this.httpServiceProvider = httpServiceProvider;
+ this.networkServiceDescriptorParser = networkServiceDescriptorParser;
}
@Override
@@ -83,4 +88,23 @@ public class EtsiCatalogPackageManagementServiceProviderImpl implements EtsiCata
}
}
+ @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) {
+ logger.error("Caught exception while getting NS package content for: {}", nsdId, restProcessingException);
+ throw new EtsiCatalogManagerRequestFailureException("Internal Server Error Occurred.",
+ restProcessingException);
+ }
+ }
+
}
diff --git a/so-etsi-nfvo/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/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
index 692aff62cd..f3c38e537f 100644
--- a/so-etsi-nfvo/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/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
@@ -21,12 +21,19 @@ 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.Constants.CREATE_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.database.beans.JobAction.INSTANTIATE;
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;
@@ -35,19 +42,25 @@ 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.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.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.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)
@@ -69,13 +82,16 @@ public class JobExecutorService {
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 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,
@@ -130,6 +146,50 @@ public class JobExecutorService {
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).isAutoInnovation(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);
+ }
+
private ImmutablePair<String, JobStatusEnum> waitForJobToFinish(final String jobId,
final ImmutableSet<JobStatusEnum> jobFinishedStates) {
try {
@@ -179,4 +239,14 @@ public class JobExecutorService {
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;
+ }
+
}
diff --git a/so-etsi-nfvo/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/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 0000000000..569d9b3352
--- /dev/null
+++ b/so-etsi-nfvo/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/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/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 0000000000..c33c67e540
--- /dev/null
+++ b/so-etsi-nfvo/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,234 @@
+/*-
+ * ============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 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("request");
+ logger.info("request: {}", request);
+
+ setJobStatus(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("request");
+ logger.info("request: {}", request);
+
+ setJobStatus(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("request");
+
+ setJobStatus(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("request");
+ logger.info("request: {}", request);
+
+ setJobStatus(execution, IN_PROGRESS,
+ "Invoking SOL003 adapter for creating and instantiating VNF: " + request.getVnfName());
+
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId);
+ final CreateVnfRequest vnfRequest = new CreateVnfRequest();
+ vnfRequest.setTenant(request.getTenant());
+ vnfRequest.setName(nfvoNsInst.getName() + "." + 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);
+ setJobStatus(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("request");
+ setJobStatus(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 updateNfInstanceStatusToActive");
+
+ updateNfInstanceStatus(execution, State.FAILED);
+ final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request");
+ setJobStatus(execution, ERROR, "Failed to create and instantiate VNF: " + request.getVnfName()
+ + " will set status to " + State.FAILED);
+
+ logger.info("Finished executing updateNfInstanceStatusToInstantiated ...");
+
+ }
+
+ private void updateNfInstanceStatus(final DelegateExecution execution, final State vnfStatus) {
+ final String nfInstId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME);
+
+ final Optional<NfvoNfInst> optional = databaseServiceProvider.getNfvoNfInst(nfInstId);
+ if (!optional.isPresent()) {
+ final String message = "Unable to find NfvoNfInst record in database using nfInstId: " + nfInstId;
+ logger.error(message);
+
+ abortOperation(execution, message);
+
+ }
+
+ final NfvoNfInst nfvoNfInst = optional.get();
+ nfvoNfInst.setStatus(vnfStatus);
+ databaseServiceProvider.saveNfvoNfInst(nfvoNfInst);
+ }
+
+ private 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.isPresent()) {
+ final String message = "Unable to find NS Instance in datababse using id: " + nsInstId;
+ abortOperation(execution, message);
+ }
+
+ return optionalNfvoNsInst.get();
+ }
+
+}
diff --git a/so-etsi-nfvo/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/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 0000000000..8d212045ad
--- /dev/null
+++ b/so-etsi-nfvo/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,416 @@
+/*-
+ * ============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.OCC_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.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+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.NsLcmOpOcc;
+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.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 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.isPresent()) {
+ 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 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<Tenant> optional = getTenant(vnfPkgId, additionalParamsForVnfList);
+ if (!optional.isPresent()) {
+ final String message = "Unable to find Tenant information for " + vnfdId + " in instantiateNsRequest : "
+ + instantiateNsRequest;
+ abortOperation(execution, message);
+ }
+
+ final Tenant tenant = optional.get();
+ final CreateInstantiateRequest createInstantiateRequest = new CreateInstantiateRequest().nsInstId(nsInstId)
+ .vnfdId(vnfdId).vnfName(vnf.getVnfName()).vnfPkgId(vnfPkgId).nfType(vnfmInfoList.get(0))
+ .tenant(tenant).additionalParams(getAdditionalParams(vnfPkgId, additionalParamsForVnfList));
+
+ 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 NsdInfo nsdInfo = getNsdInfo(execution, nsPackageId);
+
+ final Map<String, String> vnfdIdToVnfPkgIdMapping = new HashMap<>();
+ try {
+ for (final String vnfPkgId : nsdInfo.getVnfPkgIds()) {
+ final Optional<VnfPkgInfo> optional =
+ etsiCatalogPackageManagementServiceProvider.getVnfPkgInfo(vnfPkgId);
+
+ if (!optional.isPresent()) {
+ 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");
+ }
+
+
+ public void updateNsLcmOpOccStatusToCompleted(final DelegateExecution execution) {
+ logger.info("Executing updateNsLcmOpOccStatusToCompleted ...");
+ final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME);
+
+ final Optional<NsLcmOpOcc> optional = databaseServiceProvider.getNsLcmOpOcc(occId);
+
+ if (!optional.isPresent()) {
+ final String message = "Unable to find record for NSLcmOpOcc in database using id: " + occId;
+ logger.error(message);
+ abortOperation(execution, message);
+ }
+
+ final NsLcmOpOcc nsLcmOpOcc = optional.get();
+ final OperationStateEnum operationStateCompleted = OperationStateEnum.COMPLETED;
+ logger.info("Setting operation state to {} for id: {}", operationStateCompleted, occId);
+ nsLcmOpOcc.setOperationState(operationStateCompleted);
+ databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc);
+
+ logger.info("Finished executing updateNsLcmOpOccStatusToCompleted ...");
+
+ }
+
+ public void updateNsLcmOpOccStatusToFailed(final DelegateExecution execution) {
+ logger.info("Executing updateNsLcmOpOccStatusToFailed ...");
+ final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME);
+
+ final Optional<NsLcmOpOcc> optional = databaseServiceProvider.getNsLcmOpOcc(occId);
+
+ if (optional.isPresent()) {
+ final NsLcmOpOcc nsLcmOpOcc = optional.get();
+ final OperationStateEnum operationStateFailed = OperationStateEnum.FAILED;
+ logger.info("Setting operation state to {} for id: {}", operationStateFailed, occId);
+ nsLcmOpOcc.setOperationState(operationStateFailed);
+
+ databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc);
+ } else {
+ logger.error("Unable to find record for NSLcmOpOcc in database using id: {}", occId);
+ }
+
+ logger.info("Finished executing updateNsLcmOpOccStatusToFailed ...");
+
+ }
+
+ private NsdInfo getNsdInfo(final DelegateExecution execution, final String nsPackageId) {
+ try {
+ final Optional<NsdInfo> optional =
+ etsiCatalogPackageManagementServiceProvider.getNSPackageModel(nsPackageId);
+
+ if (optional.isPresent()) {
+ final NsdInfo packageModel = optional.get();
+ logger.info("NS Package exists {}", packageModel);
+ return packageModel;
+ }
+
+ } catch (final EtsiCatalogManagerRequestFailureException failureException) {
+ final String message =
+ "Unexpected exception occured while getting ns package using nsPackageId: " + nsPackageId;
+ logger.error(message, failureException);
+
+ abortOperation(execution, message);
+ }
+
+ final String message = "Unable to find NS package using NS package id: " + nsPackageId;
+ logger.error(message);
+ abortOperation(execution, message);
+ return null;
+
+ }
+
+ private void updateNsInstanceStatus(final DelegateExecution execution, final State nsStatus) {
+ final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution);
+ logger.info("Updating NfvoNsInst Status to {} and saving to DB", nsStatus);
+ nfvoNsInst.setStatus(nsStatus);
+ databaseServiceProvider.saveNfvoNsInst(nfvoNsInst);
+ }
+
+ private Optional<Tenant> getTenant(final String vnfPkgId,
+ final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList) {
+
+ final Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> optional = additionalParamsForVnfList
+ .stream().filter(entry -> vnfPkgId.equals(entry.getVnfProfileId())).findFirst();
+
+ if (optional.isPresent()) {
+ final NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf additionalParamsForVnf = optional.get();
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> additionalParams =
+ (Map<String, Object>) additionalParamsForVnf.getAdditionalParams();
+ final String vimId = (String) additionalParams.get("vim_id");
+ if (vimId != null) {
+ final String[] splitString = vimId.split("_");
+ if (splitString.length == 3) {
+ logger.info("Found Tenant in instantiateNsRequest using vnfPkgId: {}", vnfPkgId);
+ return Optional.of(new Tenant().cloudOwner(splitString[0]).regionName(splitString[1])
+ .tenantId(splitString[2]));
+ }
+
+ }
+ }
+
+ logger.error("Unable to find Tenant in instantiateNsRequest using vnfPkgId: {}", vnfPkgId);
+ return Optional.empty();
+ }
+
+ @SuppressWarnings("unchecked")
+ private Map<String, String> getAdditionalParams(final String vnfPkgId,
+ final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList) {
+
+ final Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> optional = additionalParamsForVnfList
+ .stream().filter(entry -> vnfPkgId.equals(entry.getVnfProfileId())).findFirst();
+
+ if (optional.isPresent()) {
+ final NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf additionalParamsForVnf = optional.get();
+ if (additionalParamsForVnf instanceof Map) {
+ logger.info("Found AdditionalParams in instantiateNsRequest using vnfPkgId: {}", vnfPkgId);
+ return (Map<String, String>) additionalParamsForVnf.getAdditionalParams();
+ }
+ }
+
+ return Collections.emptyMap();
+
+ }
+
+ private NfvoNsInst getNfvoNsInst(final DelegateExecution execution) {
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ return getNfvoNsInst(execution, nsInstId);
+ }
+
+ private 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.isPresent()) {
+ 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/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn
new file mode 100644
index 0000000000..025faa4128
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1uf6nd9" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.0.0">
+ <bpmn:process id="CreateInstantiateVnf" name="CreateInstantiateVnf" isExecutable="true">
+ <bpmn:startEvent id="StartEvent_1">
+ <bpmn:outgoing>Flow_02bjz2v</bpmn:outgoing>
+ </bpmn:startEvent>
+ <bpmn:serviceTask id="Activity_19rmtjr" name="Create NF Instance (VNF) record in DB" camunda:expression="${CreateInstantiateVnfTask.createNfInstanceInDb(execution)}">
+ <bpmn:incoming>Flow_123uagz</bpmn:incoming>
+ <bpmn:outgoing>Flow_03p6ifi</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_02bjz2v" sourceRef="StartEvent_1" targetRef="Activity_1cluqgp" />
+ <bpmn:endEvent id="Event_14qdixj">
+ <bpmn:incoming>Flow_0srinh7</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:sequenceFlow id="Flow_03p6ifi" sourceRef="Activity_19rmtjr" targetRef="Activity_0rto3n3" />
+ <bpmn:serviceTask id="Activity_0rto3n3" name="Create Generic VNF and Connect to Service Instance in AAI" camunda:expression="${CreateInstantiateVnfTask.createGenericVnfInAai(execution)}">
+ <bpmn:incoming>Flow_03p6ifi</bpmn:incoming>
+ <bpmn:outgoing>Flow_1c3kc4e</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_1c3kc4e" sourceRef="Activity_0rto3n3" targetRef="ServiceTask_0iry5yw" />
+ <bpmn:serviceTask id="Activity_1cluqgp" name="Check If NF Instance (VNF) exists in DB" camunda:expression="${CreateInstantiateVnfTask.checkIfNfInstanceExistsInDb(execution)}">
+ <bpmn:incoming>Flow_02bjz2v</bpmn:incoming>
+ <bpmn:outgoing>Flow_123uagz</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_123uagz" sourceRef="Activity_1cluqgp" targetRef="Activity_19rmtjr" />
+ <bpmn:serviceTask id="ServiceTask_0iry5yw" name="&#10;Invoke VNFM Adaptor&#10;" camunda:asyncAfter="true" camunda:expression="${CreateInstantiateVnfTask.invokeCreateInstantiationRequest(execution)}">
+ <bpmn:incoming>Flow_1c3kc4e</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_0xzptc2</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:callActivity id="CallActivity_1yilxx3" name="Monitor Sol003 adapter Instantiation Job" calledElement="MonitorSol003AdapterCreateJob">
+ <bpmn:extensionElements>
+ <camunda:in source="createVnfResponse" target="createVnfResponse" />
+ <camunda:in source="jobId" target="jobId" />
+ </bpmn:extensionElements>
+ <bpmn:incoming>SequenceFlow_0xzptc2</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_053tvct</bpmn:outgoing>
+ </bpmn:callActivity>
+ <bpmn:callActivity id="CallActivity_0p84lpt" name="Monitor Sol003 adapter Create Node Status" calledElement="MonitorSol003AdapterCreateNodeStatus">
+ <bpmn:extensionElements>
+ <camunda:in source="NF_INST_ID" target="NF_INST_ID" />
+ <camunda:in source="createVnfResponse" target="createVnfResponse" />
+ </bpmn:extensionElements>
+ <bpmn:incoming>SequenceFlow_053tvct</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_0h7yluk</bpmn:outgoing>
+ </bpmn:callActivity>
+ <bpmn:sequenceFlow id="SequenceFlow_0xzptc2" sourceRef="ServiceTask_0iry5yw" targetRef="CallActivity_1yilxx3" />
+ <bpmn:sequenceFlow id="SequenceFlow_053tvct" sourceRef="CallActivity_1yilxx3" targetRef="CallActivity_0p84lpt" />
+ <bpmn:sequenceFlow id="SequenceFlow_0h7yluk" sourceRef="CallActivity_0p84lpt" targetRef="Activity_0g3dip7" />
+ <bpmn:serviceTask id="Activity_0g3dip7" name="Update NF Instance (VNF) Status to INSTANTIATED" camunda:expression="${CreateInstantiateVnfTask.updateNfInstanceStatusToInstantiated(execution)}">
+ <bpmn:incoming>SequenceFlow_0h7yluk</bpmn:incoming>
+ <bpmn:outgoing>Flow_0srinh7</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_0srinh7" sourceRef="Activity_0g3dip7" targetRef="Event_14qdixj" />
+ <bpmn:subProcess id="Activity_0qtgdm9" name="Error Handling" triggeredByEvent="true">
+ <bpmn:startEvent id="Event_08zcwc2" name="error">
+ <bpmn:outgoing>Flow_06q1m6i</bpmn:outgoing>
+ <bpmn:errorEventDefinition id="ErrorEventDefinition_1ppvn77" />
+ </bpmn:startEvent>
+ <bpmn:endEvent id="Event_1wkm29u" name="end">
+ <bpmn:incoming>Flow_0anjylz</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:serviceTask id="Activity_0ltxcii" name="Update NF Instance (VNF) Status to FAILED" camunda:asyncBefore="true" camunda:expression="${CreateInstantiateVnfTask.updateNfInstanceStatusToFailed(execution)}">
+ <bpmn:incoming>Flow_06q1m6i</bpmn:incoming>
+ <bpmn:outgoing>Flow_0anjylz</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_06q1m6i" sourceRef="Event_08zcwc2" targetRef="Activity_0ltxcii" />
+ <bpmn:sequenceFlow id="Flow_0anjylz" sourceRef="Activity_0ltxcii" targetRef="Event_1wkm29u" />
+ </bpmn:subProcess>
+ </bpmn:process>
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="CreateInstantiateVnf">
+ <bpmndi:BPMNEdge id="SequenceFlow_0h7yluk_di" bpmnElement="SequenceFlow_0h7yluk">
+ <di:waypoint x="1030" y="117" />
+ <di:waypoint x="1080" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_053tvct_di" bpmnElement="SequenceFlow_053tvct">
+ <di:waypoint x="880" y="117" />
+ <di:waypoint x="930" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_0xzptc2_di" bpmnElement="SequenceFlow_0xzptc2">
+ <di:waypoint x="740" y="117" />
+ <di:waypoint x="780" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_123uagz_di" bpmnElement="Flow_123uagz">
+ <di:waypoint x="350" y="117" />
+ <di:waypoint x="380" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1c3kc4e_di" bpmnElement="Flow_1c3kc4e">
+ <di:waypoint x="610" y="117" />
+ <di:waypoint x="640" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_03p6ifi_di" bpmnElement="Flow_03p6ifi">
+ <di:waypoint x="480" y="117" />
+ <di:waypoint x="510" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_02bjz2v_di" bpmnElement="Flow_02bjz2v">
+ <di:waypoint x="215" y="117" />
+ <di:waypoint x="250" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0srinh7_di" bpmnElement="Flow_0srinh7">
+ <di:waypoint x="1180" y="117" />
+ <di:waypoint x="1232" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+ <dc:Bounds x="179" y="99" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_19rmtjr_di" bpmnElement="Activity_19rmtjr">
+ <dc:Bounds x="380" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0rto3n3_di" bpmnElement="Activity_0rto3n3">
+ <dc:Bounds x="510" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1cluqgp_di" bpmnElement="Activity_1cluqgp">
+ <dc:Bounds x="250" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="ServiceTask_0iry5yw_di" bpmnElement="ServiceTask_0iry5yw">
+ <dc:Bounds x="640" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="CallActivity_1yilxx3_di" bpmnElement="CallActivity_1yilxx3">
+ <dc:Bounds x="780" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="CallActivity_0p84lpt_di" bpmnElement="CallActivity_0p84lpt">
+ <dc:Bounds x="930" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_14qdixj_di" bpmnElement="Event_14qdixj">
+ <dc:Bounds x="1232" y="99" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0g3dip7_di" bpmnElement="Activity_0g3dip7">
+ <dc:Bounds x="1080" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0qtgdm9_di" bpmnElement="Activity_0qtgdm9" isExpanded="true">
+ <dc:Bounds x="430" y="270" width="438" height="130" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="Flow_06q1m6i_di" bpmnElement="Flow_06q1m6i">
+ <di:waypoint x="488" y="333" />
+ <di:waypoint x="580" y="333" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0anjylz_di" bpmnElement="Flow_0anjylz">
+ <di:waypoint x="680" y="333" />
+ <di:waypoint x="812" y="333" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="Event_08zcwc2_di" bpmnElement="Event_08zcwc2">
+ <dc:Bounds x="452" y="315" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="458" y="358" width="24" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_1wkm29u_di" bpmnElement="Event_1wkm29u">
+ <dc:Bounds x="812" y="315" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="822" y="357" width="19" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0ltxcii_di" bpmnElement="Activity_0ltxcii">
+ <dc:Bounds x="580" y="293" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</bpmn:definitions>
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/InstantiateNs.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/InstantiateNs.bpmn
new file mode 100644
index 0000000000..ba9e641d84
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/InstantiateNs.bpmn
@@ -0,0 +1,331 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_0mdda96" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.0.0">
+ <bpmn:process id="InstantiateNs" name="InstantiateNs" isExecutable="true">
+ <bpmn:startEvent id="StartEvent_1" name="Start Process">
+ <bpmn:outgoing>SequenceFlow_16k0f61</bpmn:outgoing>
+ </bpmn:startEvent>
+ <bpmn:sequenceFlow id="SequenceFlow_16k0f61" sourceRef="StartEvent_1" targetRef="Activity_194tqy0" />
+ <bpmn:serviceTask id="Task_0opnwx0" name="Update NS Instance status to INSTANTIATING" camunda:expression="${InstantiateNsTask.updateNsInstanceStatusToInstantiating(execution)}">
+ <bpmn:incoming>Flow_04pxtdd</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_0bdznyp</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:endEvent id="EndEvent_0szswbo" name="End Process">
+ <bpmn:incoming>Flow_1pcu8aa</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:sequenceFlow id="SequenceFlow_0bdznyp" sourceRef="Task_0opnwx0" targetRef="Activity_1jrym1e" />
+ <bpmn:serviceTask id="Activity_194tqy0" name="Set Job Status to STARTED" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.setJobStatusToStarted(execution)}">
+ <bpmn:incoming>SequenceFlow_16k0f61</bpmn:incoming>
+ <bpmn:outgoing>Flow_04pxtdd</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_04pxtdd" sourceRef="Activity_194tqy0" targetRef="Task_0opnwx0" />
+ <bpmn:subProcess id="Activity_0pjxszh" name="Error Handling" triggeredByEvent="true">
+ <bpmn:startEvent id="Event_1rpzcl3" name="error">
+ <bpmn:outgoing>Flow_07bh7l7</bpmn:outgoing>
+ <bpmn:errorEventDefinition id="ErrorEventDefinition_0m2e0oa" />
+ </bpmn:startEvent>
+ <bpmn:endEvent id="Event_1fcw3ei" name="end">
+ <bpmn:incoming>Flow_1wa1jpl</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:serviceTask id="Activity_0ddja9m" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.setJobStatusToError(execution)}">
+ <bpmn:incoming>Flow_0n3dai5</bpmn:incoming>
+ <bpmn:outgoing>Flow_1wa1jpl</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_1wa1jpl" sourceRef="Activity_0ddja9m" targetRef="Event_1fcw3ei" />
+ <bpmn:sequenceFlow id="Flow_07bh7l7" sourceRef="Event_1rpzcl3" targetRef="Activity_1miy3hw" />
+ <bpmn:serviceTask id="Activity_1miy3hw" name="Update NSLcmOpOcc operation status to FAILED" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.updateNsLcmOpOccStatusToFailed(execution)}">
+ <bpmn:incoming>Flow_07bh7l7</bpmn:incoming>
+ <bpmn:outgoing>Flow_0n3dai5</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_0n3dai5" sourceRef="Activity_1miy3hw" targetRef="Activity_0ddja9m" />
+ </bpmn:subProcess>
+ <bpmn:subProcess id="Activity_0mtscwq" name="Java Exception Handling" triggeredByEvent="true">
+ <bpmn:startEvent id="Event_0lqr6al" name="error">
+ <bpmn:outgoing>Flow_05lo00r</bpmn:outgoing>
+ <bpmn:errorEventDefinition id="ErrorEventDefinition_02lwl19" errorRef="Error_0jsct8p" camunda:errorCodeVariable="BPMN_javaExpCode" camunda:errorMessageVariable="BPMN_javaExpMsg" />
+ </bpmn:startEvent>
+ <bpmn:endEvent id="Event_05ty7c4">
+ <bpmn:incoming>Flow_16aryg5</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:serviceTask id="Activity_1ezu7d4" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.setJobStatusToError(execution)}">
+ <bpmn:incoming>Flow_09zcw2a</bpmn:incoming>
+ <bpmn:outgoing>Flow_16aryg5</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_16aryg5" sourceRef="Activity_1ezu7d4" targetRef="Event_05ty7c4" />
+ <bpmn:sequenceFlow id="Flow_05lo00r" sourceRef="Event_0lqr6al" targetRef="Activity_17leldb" />
+ <bpmn:serviceTask id="Activity_17leldb" name="Update NSLcmOpOcc operation status to FAILED" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.updateNsLcmOpOccStatusToFailed(execution)}">
+ <bpmn:incoming>Flow_05lo00r</bpmn:incoming>
+ <bpmn:outgoing>Flow_09zcw2a</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_09zcw2a" sourceRef="Activity_17leldb" targetRef="Activity_1ezu7d4" />
+ </bpmn:subProcess>
+ <bpmn:serviceTask id="Activity_1w09i1k" name="Set Job Status to FINISHED" camunda:expression="${InstantiateNsTask.setJobStatusToFinished(execution)}">
+ <bpmn:incoming>Flow_1i36dw4</bpmn:incoming>
+ <bpmn:outgoing>Flow_1pcu8aa</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_1pcu8aa" sourceRef="Activity_1w09i1k" targetRef="EndEvent_0szswbo" />
+ <bpmn:serviceTask id="Activity_1jrym1e" name="Get and parse NSD from ETSI Catalog" camunda:expression="${InstantiateNsTask.getAndParseNsdFromEtsiCatalog(execution)}">
+ <bpmn:incoming>SequenceFlow_0bdznyp</bpmn:incoming>
+ <bpmn:outgoing>Flow_10zjw0w</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_10zjw0w" sourceRef="Activity_1jrym1e" targetRef="Activity_1kikjaf" />
+ <bpmn:callActivity id="Activity_1b2s2wr" name="Create and Instantiate each Vnf" calledElement="CreateInstantiateVnf">
+ <bpmn:extensionElements>
+ <camunda:in source="request" target="request" />
+ <camunda:in source="jobId" target="jobId" />
+ <camunda:in source="NsInstanceId" target="NsInstanceId" />
+ </bpmn:extensionElements>
+ <bpmn:incoming>Flow_1irbp9b</bpmn:incoming>
+ <bpmn:outgoing>Flow_0mi4nqa</bpmn:outgoing>
+ <bpmn:multiInstanceLoopCharacteristics camunda:asyncAfter="true" camunda:collection="${vnfCreateInstantiateRequests}" camunda:elementVariable="request" />
+ </bpmn:callActivity>
+ <bpmn:boundaryEvent id="Event_0rbb817" name="Overall Wait" attachedToRef="Activity_1b2s2wr">
+ <bpmn:outgoing>Flow_17zn7we</bpmn:outgoing>
+ <bpmn:timerEventDefinition id="TimerEventDefinition_13ud1f4">
+ <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT3H</bpmn:timeDuration>
+ </bpmn:timerEventDefinition>
+ </bpmn:boundaryEvent>
+ <bpmn:sequenceFlow id="Flow_17zn7we" sourceRef="Event_0rbb817" targetRef="Activity_16z66xm" />
+ <bpmn:serviceTask id="Activity_0eou3y4" name="Prepare Create Instantiate requests" camunda:expression="${InstantiateNsTask.prepareCreateInstantiateRequests(execution)}">
+ <bpmn:incoming>Flow_01ju1mj</bpmn:incoming>
+ <bpmn:outgoing>Flow_1irbp9b</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_1irbp9b" sourceRef="Activity_0eou3y4" targetRef="Activity_1b2s2wr" />
+ <bpmn:serviceTask id="Activity_1kikjaf" name="Get Vnf Pkg ID for each VNFD ID" camunda:expression="${InstantiateNsTask.getVnfPkgIdForEachVnfdId(execution)}">
+ <bpmn:incoming>Flow_10zjw0w</bpmn:incoming>
+ <bpmn:outgoing>Flow_01ju1mj</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_01ju1mj" sourceRef="Activity_1kikjaf" targetRef="Activity_0eou3y4" />
+ <bpmn:serviceTask id="Activity_16cvdbw" name="Update NS Instance status to INSTANTIATED" camunda:expression="${InstantiateNsTask.updateNsInstanceStatusToInstantiated(execution)}">
+ <bpmn:incoming>Flow_1nieng0</bpmn:incoming>
+ <bpmn:outgoing>Flow_0xptc0r</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_0xptc0r" sourceRef="Activity_16cvdbw" targetRef="Activity_0gkpdft" />
+ <bpmn:endEvent id="Event_1e4bwip">
+ <bpmn:incoming>Flow_10oprxr</bpmn:incoming>
+ <bpmn:incoming>Flow_1p21p1m</bpmn:incoming>
+ <bpmn:errorEventDefinition id="ErrorEventDefinition_0vg6v5r" errorRef="Error_0jsct8p" />
+ </bpmn:endEvent>
+ <bpmn:exclusiveGateway id="Gateway_0nxf0rv" name="is Successful?">
+ <bpmn:incoming>Flow_15m4nm1</bpmn:incoming>
+ <bpmn:outgoing>Flow_1nieng0</bpmn:outgoing>
+ <bpmn:outgoing>Flow_10oprxr</bpmn:outgoing>
+ </bpmn:exclusiveGateway>
+ <bpmn:sequenceFlow id="Flow_1nieng0" name="Yes" sourceRef="Gateway_0nxf0rv" targetRef="Activity_16cvdbw">
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{isNsInstantiationSuccessful}</bpmn:conditionExpression>
+ </bpmn:sequenceFlow>
+ <bpmn:serviceTask id="Activity_14iwa8x" name="Check if VNF Instantiation was Successful" camunda:expression="${InstantiateNsTask.checkIfVnfInstantiationWasSuccessful(execution)}">
+ <bpmn:incoming>Flow_0mi4nqa</bpmn:incoming>
+ <bpmn:outgoing>Flow_15m4nm1</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_0mi4nqa" sourceRef="Activity_1b2s2wr" targetRef="Activity_14iwa8x" />
+ <bpmn:sequenceFlow id="Flow_15m4nm1" sourceRef="Activity_14iwa8x" targetRef="Gateway_0nxf0rv" />
+ <bpmn:serviceTask id="Activity_16z66xm" name="Log TimeOut" camunda:expression="${InstantiateNsTask.logTimeOut(execution)}">
+ <bpmn:incoming>Flow_17zn7we</bpmn:incoming>
+ <bpmn:outgoing>Flow_1p21p1m</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_10oprxr" name="No" sourceRef="Gateway_0nxf0rv" targetRef="Event_1e4bwip">
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{not isNsInstantiationSuccessful}</bpmn:conditionExpression>
+ </bpmn:sequenceFlow>
+ <bpmn:sequenceFlow id="Flow_1p21p1m" sourceRef="Activity_16z66xm" targetRef="Event_1e4bwip" />
+ <bpmn:serviceTask id="Activity_0gkpdft" name="Update NSLcmOpOcc operation status to COMPLETED" camunda:expression="${InstantiateNsTask.updateNsLcmOpOccStatusToCompleted(execution)}">
+ <bpmn:incoming>Flow_0xptc0r</bpmn:incoming>
+ <bpmn:outgoing>Flow_1i36dw4</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_1i36dw4" sourceRef="Activity_0gkpdft" targetRef="Activity_1w09i1k" />
+ </bpmn:process>
+ <bpmn:error id="Error_0jsct8p" name="InstantiateNsProcessingException" errorCode="INSTANTIATE_NS_PROCESSING_EXCEPTION" />
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="InstantiateNs">
+ <bpmndi:BPMNEdge id="Flow_1p21p1m_di" bpmnElement="Flow_1p21p1m">
+ <di:waypoint x="1250" y="270" />
+ <di:waypoint x="1332" y="270" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_10oprxr_di" bpmnElement="Flow_10oprxr">
+ <di:waypoint x="1350" y="146" />
+ <di:waypoint x="1350" y="252" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="1358" y="196" width="14" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_15m4nm1_di" bpmnElement="Flow_15m4nm1">
+ <di:waypoint x="1250" y="121" />
+ <di:waypoint x="1325" y="121" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0mi4nqa_di" bpmnElement="Flow_0mi4nqa">
+ <di:waypoint x="1090" y="121" />
+ <di:waypoint x="1150" y="121" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1nieng0_di" bpmnElement="Flow_1nieng0">
+ <di:waypoint x="1375" y="121" />
+ <di:waypoint x="1430" y="121" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="1393" y="103" width="19" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0xptc0r_di" bpmnElement="Flow_0xptc0r">
+ <di:waypoint x="1530" y="121" />
+ <di:waypoint x="1580" y="121" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_01ju1mj_di" bpmnElement="Flow_01ju1mj">
+ <di:waypoint x="800" y="121" />
+ <di:waypoint x="850" y="121" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1irbp9b_di" bpmnElement="Flow_1irbp9b">
+ <di:waypoint x="950" y="121" />
+ <di:waypoint x="990" y="121" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_17zn7we_di" bpmnElement="Flow_17zn7we">
+ <di:waypoint x="1070" y="179" />
+ <di:waypoint x="1070" y="270" />
+ <di:waypoint x="1150" y="270" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_10zjw0w_di" bpmnElement="Flow_10zjw0w">
+ <di:waypoint x="649" y="121" />
+ <di:waypoint x="700" y="121" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1pcu8aa_di" bpmnElement="Flow_1pcu8aa">
+ <di:waypoint x="1820" y="121" />
+ <di:waypoint x="1862" y="121" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_04pxtdd_di" bpmnElement="Flow_04pxtdd">
+ <di:waypoint x="360" y="121" />
+ <di:waypoint x="400" y="121" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_0bdznyp_di" bpmnElement="SequenceFlow_0bdznyp">
+ <di:waypoint x="500" y="121" />
+ <di:waypoint x="549" y="121" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_16k0f61_di" bpmnElement="SequenceFlow_16k0f61">
+ <di:waypoint x="208" y="121" />
+ <di:waypoint x="260" y="121" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1i36dw4_di" bpmnElement="Flow_1i36dw4">
+ <di:waypoint x="1680" y="121" />
+ <di:waypoint x="1720" y="121" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+ <dc:Bounds x="172" y="103" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="157" y="146" width="67" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="ServiceTask_1y7xfqt_di" bpmnElement="Task_0opnwx0">
+ <dc:Bounds x="400" y="81" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_194tqy0_di" bpmnElement="Activity_194tqy0">
+ <dc:Bounds x="260" y="81" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="EndEvent_0szswbo_di" bpmnElement="EndEvent_0szswbo">
+ <dc:Bounds x="1862" y="103" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="1848" y="79" width="63" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1w09i1k_di" bpmnElement="Activity_1w09i1k">
+ <dc:Bounds x="1720" y="81" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0gkpdft_di" bpmnElement="Activity_0gkpdft">
+ <dc:Bounds x="1580" y="81" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0pjxszh_di" bpmnElement="Activity_0pjxszh" isExpanded="true">
+ <dc:Bounds x="380" y="270" width="510" height="130" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="Flow_07bh7l7_di" bpmnElement="Flow_07bh7l7">
+ <di:waypoint x="438" y="333" />
+ <di:waypoint x="500" y="333" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1wa1jpl_di" bpmnElement="Flow_1wa1jpl">
+ <di:waypoint x="760" y="333" />
+ <di:waypoint x="822" y="333" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0n3dai5_di" bpmnElement="Flow_0n3dai5">
+ <di:waypoint x="600" y="333" />
+ <di:waypoint x="660" y="333" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="Event_1rpzcl3_di" bpmnElement="Event_1rpzcl3">
+ <dc:Bounds x="402" y="315" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="408" y="358" width="24" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1miy3hw_di" bpmnElement="Activity_1miy3hw">
+ <dc:Bounds x="500" y="293" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0ddja9m_di" bpmnElement="Activity_0ddja9m">
+ <dc:Bounds x="660" y="293" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_1fcw3ei_di" bpmnElement="Event_1fcw3ei">
+ <dc:Bounds x="822" y="315" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="832" y="357" width="19" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0mtscwq_di" bpmnElement="Activity_0mtscwq" isExpanded="true">
+ <dc:Bounds x="380" y="430" width="510" height="130" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="Flow_05lo00r_di" bpmnElement="Flow_05lo00r">
+ <di:waypoint x="438" y="493" />
+ <di:waypoint x="500" y="493" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_16aryg5_di" bpmnElement="Flow_16aryg5">
+ <di:waypoint x="760" y="493" />
+ <di:waypoint x="822" y="493" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_09zcw2a_di" bpmnElement="Flow_09zcw2a">
+ <di:waypoint x="600" y="493" />
+ <di:waypoint x="660" y="493" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="Event_0lqr6al_di" bpmnElement="Event_0lqr6al">
+ <dc:Bounds x="402" y="475" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="409" y="518" width="24" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_17leldb_di" bpmnElement="Activity_17leldb">
+ <dc:Bounds x="500" y="453" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1ezu7d4_di" bpmnElement="Activity_1ezu7d4">
+ <dc:Bounds x="660" y="453" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_05ty7c4_di" bpmnElement="Event_05ty7c4">
+ <dc:Bounds x="822" y="475" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1jrym1e_di" bpmnElement="Activity_1jrym1e">
+ <dc:Bounds x="549" y="81" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1xjmizv_di" bpmnElement="Activity_1b2s2wr">
+ <dc:Bounds x="990" y="81" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0eou3y4_di" bpmnElement="Activity_0eou3y4">
+ <dc:Bounds x="850" y="81" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1kikjaf_di" bpmnElement="Activity_1kikjaf">
+ <dc:Bounds x="700" y="81" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_16cvdbw_di" bpmnElement="Activity_16cvdbw">
+ <dc:Bounds x="1430" y="81" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_16umj30_di" bpmnElement="Event_1e4bwip">
+ <dc:Bounds x="1332" y="252" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Gateway_0nxf0rv_di" bpmnElement="Gateway_0nxf0rv" isMarkerVisible="true">
+ <dc:Bounds x="1325" y="96" width="50" height="50" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="1320" y="66" width="71" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_14iwa8x_di" bpmnElement="Activity_14iwa8x">
+ <dc:Bounds x="1150" y="81" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_16z66xm_di" bpmnElement="Activity_16z66xm">
+ <dc:Bounds x="1150" y="230" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_0rbb817_di" bpmnElement="Event_0rbb817">
+ <dc:Bounds x="1052" y="143" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="1000" y="183" width="60" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</bpmn:definitions>
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/InstantiateNsTaskTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/InstantiateNsTaskTest.java
new file mode 100644
index 0000000000..bfccddcbcc
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/InstantiateNsTaskTest.java
@@ -0,0 +1,319 @@
+/*-
+ * ============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.workflow.engine.tasks;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.notFound;
+import static com.github.tomakehurst.wiremock.client.WireMock.ok;
+import static com.github.tomakehurst.wiremock.client.WireMock.okJson;
+import static com.github.tomakehurst.wiremock.client.WireMock.put;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+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.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_REST_TEMPLATE_BEAN;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterConfiguration.SOL003_ADAPTER_REST_TEMPLATE_BEAN;
+import static org.springframework.test.web.client.ExpectedCount.times;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
+import org.camunda.bpm.engine.history.HistoricVariableInstance;
+import org.hamcrest.text.MatchesPattern;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStatusRetrievalStatusEnum;
+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.BaseTest;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.JobExecutorService;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
+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.NsLcmOpOcc;
+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.InstantiateNsRequest;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.json.GsonHttpMessageConverter;
+import org.springframework.test.web.client.MockRestServiceServer;
+import org.springframework.web.client.RestTemplate;
+import com.google.gson.Gson;
+
+/**
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class InstantiateNsTaskTest extends BaseTest {
+
+ private static final String TENANT_ID = "6ca8680feba04dad9254f423c6e28e1c";
+ private static final String CLOUD_REGION = "regionOne";
+ private static final String CLOUD_OWNER = "CloudOwner";
+ private static final String UUID_REGEX =
+ "[0-9a-zA-Z]{8}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{12}";
+ private static final String VCPE_VBRGEMU_VNFD_ID = "b1bb0ce7-2222-4fa7-95ed-4840d70a1102";
+ private static final String VCPE_VBNG = "b1bb0ce7-2222-4fa7-95ed-4840d70a1101";
+ private static final String VCPE_INFRA_VNFD_ID = "b1bb0ce7-2222-4fa7-95ed-4840d70a1100";
+ private static final String VGMUX_VNFD_ID = "0408f076-e6c0-4c82-9940-272fddbb82de";
+ private static final String VGW_VNFD_ID = "3fca3543-07f5-492f-812c-ed462e4f94f4";
+ private static final String[] VCPE_VNFDS =
+ new String[] {VGW_VNFD_ID, VGMUX_VNFD_ID, VCPE_INFRA_VNFD_ID, VCPE_VBNG, VCPE_VBRGEMU_VNFD_ID};
+ private static final String SAMPLE_NSD_FILE = "src/test/resources/ns.csar";
+ private static final String NS_NAME = "InstantiateNetworkService";
+
+ @Autowired
+ private DatabaseServiceProvider databaseServiceProvider;
+
+ @Autowired
+ @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN)
+ private RestTemplate etsiCatalogRestTemplate;
+
+ @Autowired
+ @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN)
+ private RestTemplate sol003AdapterRestTemplate;
+
+ private MockRestServiceServer mockEtsiCatalogRestServiceServer;
+
+ private MockRestServiceServer mockSol003AdapterRestServiceServer;
+
+ @Autowired
+ private JobExecutorService objUnderTest;
+
+ @Autowired
+ private GsonProvider gsonProvider;
+
+ private Gson gson;
+
+ private static final Map<String, String> VNFD_ID_TO_VNFPKG_ID_MAPPING = new HashMap<>();
+ static {
+ for (final String vnfd : VCPE_VNFDS) {
+ VNFD_ID_TO_VNFPKG_ID_MAPPING.put(vnfd, UUID.randomUUID().toString());
+ }
+ }
+
+ @Before
+ public void before() {
+ wireMockServer.resetAll();
+ gson = gsonProvider.getGson();
+
+ mockEtsiCatalogRestServiceServer =
+ MockRestServiceServer.bindTo(etsiCatalogRestTemplate).ignoreExpectOrder(true).build();
+ mockSol003AdapterRestServiceServer =
+ MockRestServiceServer.bindTo(sol003AdapterRestTemplate).ignoreExpectOrder(true).build();
+
+ etsiCatalogRestTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson));
+ sol003AdapterRestTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson));
+
+ }
+
+ @After
+ public void after() {
+ wireMockServer.resetAll();
+ mockEtsiCatalogRestServiceServer.reset();
+ }
+
+ @Test
+ public void testInstantiateNsWorkflow_JustUpdateStatus_SuccessfullCase() throws InterruptedException, IOException {
+ final String nsdId = UUID.randomUUID().toString();
+ final String nsdName = NS_NAME + "-" + System.currentTimeMillis();
+
+ final NfvoNsInst newNfvoNsInst = new NfvoNsInst().nsInstId(nsdId).name(nsdName)
+ .nsPackageId(UUID.randomUUID().toString()).nsPackageId(nsdId).nsdId(nsdId).nsdInvariantId(nsdId)
+ .status(State.NOT_INSTANTIATED).statusUpdatedTime(LocalDateTime.now());
+
+ databaseServiceProvider.saveNfvoNsInst(newNfvoNsInst);
+
+ mockSol003AdapterEndpoints();
+ mockAAIEndpoints(nsdId);
+ mockEtsiCatalogEndpoints(nsdId);
+
+ final String nsLcmOpOccId =
+ objUnderTest.runInstantiateNsJob(newNfvoNsInst.getNsInstId(), getInstantiateNsRequest());
+
+ final Optional<NfvoJob> optional = getJobByResourceId(newNfvoNsInst.getNsInstId());
+ assertTrue(optional.isPresent());
+ final NfvoJob nfvoJob = optional.get();
+
+ assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId()));
+
+ final HistoricProcessInstance historicProcessInstance =
+ getHistoricProcessInstance(nfvoJob.getProcessInstanceId());
+ assertNotNull(historicProcessInstance);
+
+ assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+
+ // check if value in database has updated
+ final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsdId);
+ final NfvoNsInst nfvoNsInst = optionalNfvoNsInst.get();
+ assertEquals(State.INSTANTIATED, nfvoNsInst.getStatus());
+
+ final HistoricVariableInstance historicVariableInstance =
+ getVariable(nfvoJob.getProcessInstanceId(), NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME);
+ assertNotNull(historicVariableInstance);
+ final NetworkServiceDescriptor nsd = (NetworkServiceDescriptor) historicVariableInstance.getValue();
+ assertNotNull(nsd);
+
+ assertEquals(VNFD_ID_TO_VNFPKG_ID_MAPPING.size(), nsd.getVnfs().size());
+
+ final List<NfvoNfInst> nfvoNfInsts = databaseServiceProvider.getNfvoNfInstByNsInstId(nsdId);
+ assertNotNull(nsd);
+ assertEquals(VNFD_ID_TO_VNFPKG_ID_MAPPING.size(), nfvoNfInsts.size());
+
+ final Optional<NsLcmOpOcc> optionalNsLcmOpOcc = databaseServiceProvider.getNsLcmOpOcc(nsLcmOpOccId);
+ assertTrue(optionalNsLcmOpOcc.isPresent());
+
+ assertEquals(OperationStateEnum.COMPLETED, optionalNsLcmOpOcc.get().getOperationState());
+
+ final Map<String, NfvoNfInst> nfvoNfInstsMap =
+ nfvoNfInsts.stream().collect(Collectors.toMap(NfvoNfInst::getVnfdId, nfvoNfInst -> nfvoNfInst));
+
+ for (final Entry<String, String> entry : VNFD_ID_TO_VNFPKG_ID_MAPPING.entrySet()) {
+ assertTrue(nfvoNfInstsMap.containsKey(entry.getKey()));
+ assertEquals(State.INSTANTIATED, nfvoNfInstsMap.get(entry.getKey()).getStatus());
+
+ }
+
+ }
+
+ private void mockSol003AdapterEndpoints() {
+ mockSol003AdapterRestServiceServer
+ .expect(times(VNFD_ID_TO_VNFPKG_ID_MAPPING.size()),
+ requestTo(MatchesPattern.matchesPattern(SOL003_ADAPTER_ENDPOINT_URL + "/vnfs/.*")))
+ .andExpect(method(HttpMethod.POST))
+ .andRespond(withSuccess(gson.toJson(new CreateVnfResponse().jobId(UUID.randomUUID().toString())),
+ MediaType.APPLICATION_JSON));
+
+ mockSol003AdapterRestServiceServer
+ .expect(times(VNFD_ID_TO_VNFPKG_ID_MAPPING.size()),
+ requestTo(MatchesPattern.matchesPattern(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/.*")))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withSuccess(gson.toJson(
+ new org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse().operationState(
+ org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum.COMPLETED)
+ .operationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.STATUS_FOUND)),
+ MediaType.APPLICATION_JSON));
+ }
+
+ private void mockEtsiCatalogEndpoints(final String nsdId) throws IOException {
+ mockEtsiCatalogRestServiceServer.expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withSuccess(gson.toJson(getNSPackageModel(nsdId)), MediaType.APPLICATION_JSON));
+ mockEtsiCatalogRestServiceServer
+ .expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId + "/nsd_content"))
+ .andExpect(method(HttpMethod.GET)).andRespond(withSuccess(
+ getFileContent(getAbsolutePath(SAMPLE_NSD_FILE)), MediaType.APPLICATION_OCTET_STREAM));
+
+ for (final Entry<String, String> entry : VNFD_ID_TO_VNFPKG_ID_MAPPING.entrySet()) {
+ mockEtsiCatalogRestServiceServer
+ .expect(requestTo(ETSI_CATALOG_URL + "/vnfpkgm/v1/vnf_packages/" + entry.getValue()))
+ .andExpect(method(HttpMethod.GET)).andRespond(withSuccess(
+ gson.toJson(getVnfPkgInfo(entry.getKey(), entry.getValue())), MediaType.APPLICATION_JSON));
+ }
+
+ }
+
+ private VnfPkgInfo getVnfPkgInfo(final String vnfdId, final String vnfPkgId) {
+ return new VnfPkgInfo().id(vnfPkgId).vnfdId(vnfdId);
+ }
+
+ private InstantiateNsRequest getInstantiateNsRequest() {
+ final Map<String, Object> additionalParams = new HashMap<>();
+ additionalParams.put("vim_id", CLOUD_OWNER + "_" + CLOUD_REGION + "_" + TENANT_ID);
+
+ final InstantiateNsRequest instantiateNsRequest = new InstantiateNsRequest().nsFlavourId("default");
+
+ for (final Entry<String, String> entry : VNFD_ID_TO_VNFPKG_ID_MAPPING.entrySet()) {
+ instantiateNsRequest
+ .addAdditionalParamsForVnfItem(new NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf()
+ .vnfProfileId(entry.getValue()).additionalParams(additionalParams));
+ }
+
+ return instantiateNsRequest;
+ }
+
+ private NsdInfo getNSPackageModel(final String nsdId) {
+ return new NsdInfo().id(nsdId).nsdId(nsdId).nsdInvariantId(NSD_INVARIANT_ID).nsdName("vcpe").nsdDesigner("ONAP")
+ .vnfPkgIds(new ArrayList<>(VNFD_ID_TO_VNFPKG_ID_MAPPING.values()));
+ }
+
+ private byte[] getFileContent(final String path) throws IOException {
+ return Files.readAllBytes(Paths.get(path));
+ }
+
+
+ private String getAbsolutePath(final String path) {
+ return new File(path).getAbsolutePath();
+ }
+
+ private void mockAAIEndpoints(final String nsdId) {
+ final String modelEndpoint = "/aai/v[0-9]+/network/generic-vnfs/generic-vnf/" + UUID_REGEX;
+ wireMockServer.stubFor(
+ get(urlMatching(modelEndpoint + "\\?resultIndex=0&resultSize=1&format=count")).willReturn(notFound()));
+
+ wireMockServer.stubFor(put(urlMatching(modelEndpoint)).willReturn(ok()));
+ wireMockServer.stubFor(put(urlMatching(modelEndpoint + "/relationship-list/relationship")).willReturn(ok()));
+
+ wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(ok())
+ .willReturn(okJson("{\"orchestration-status\": \"Created\"}")));
+
+ final String resourceType = "service-instance";
+ final String resourceLink = "/aai/v20/business/customers/customer/" + GLOBAL_CUSTOMER_ID
+ + "/service-subscriptions/service-subscription/NetworkService/service-instances/service-instance/"
+ + nsdId;
+
+ final String body = "{\n" + " \"results\": [{\n" + " \"resource-type\": \"" + resourceType + "\",\n"
+ + " \"resource-link\": \"" + resourceLink + "\"\n" + " }]\n" + "}";
+
+ wireMockServer.stubFor(
+ get(urlMatching("/aai/v[0-9]+/nodes/service-instances/service-instance/" + nsdId + "\\?format=pathed"))
+ .willReturn(okJson(body)));
+
+ wireMockServer
+ .stubFor(put(urlMatching("/aai/v[0-9]+/cloud-infrastructure/cloud-regions/cloud-region/" + CLOUD_OWNER
+ + "/" + CLOUD_REGION + "/tenants/tenant/" + TENANT_ID + "/relationship-list/relationship"))
+ .willReturn(ok()));
+
+ }
+
+}