diff options
Diffstat (limited to 'so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows')
10 files changed, 1731 insertions, 2 deletions
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/pom.xml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/pom.xml index 39acdd8f50..1c13ecac25 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/pom.xml +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/pom.xml @@ -96,5 +96,11 @@ <artifactId>h2</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest</artifactId> + <version>${hamcrest-version}</version> + <scope>test</scope> + </dependency> </dependencies> </project>
\ No newline at end of file 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=" Invoke VNFM Adaptor " 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())); + + } + +} |