aboutsummaryrefslogtreecommitdiffstats
path: root/bpmn
diff options
context:
space:
mode:
authoralexanb <alexander.borovitzky@guest.telecomitalia.it>2020-09-10 17:21:15 +0300
committeralexanb <alexander.borovitzky@guest.telecomitalia.it>2020-09-13 15:18:51 +0300
commit8f64ccbefb08a58a8078186f385165a77e8e882d (patch)
treeb51625330b1b91828f1d304c18ca849f5c0b1e99 /bpmn
parenta714a448501d30fee850f878e85023db72b71f14 (diff)
Implement Modify Core NSSMF workflow
Issue-ID: SO-3239 Signed-off-by: alexanb <alexander.borovitzky@guest.telecomitalia.it> Change-Id: Ice1f528d5fe155ea0e84cb3fa7502be32626ba31
Diffstat (limited to 'bpmn')
-rw-r--r--bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoModifyCoreNSSI.groovy732
-rw-r--r--bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoModifyCoreNSSI.bpmn311
2 files changed, 1043 insertions, 0 deletions
diff --git a/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoModifyCoreNSSI.groovy b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoModifyCoreNSSI.groovy
new file mode 100644
index 0000000000..6c12a656f4
--- /dev/null
+++ b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoModifyCoreNSSI.groovy
@@ -0,0 +1,732 @@
+package org.onap.so.bpmn.infrastructure.scripts
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import org.camunda.bpm.engine.delegate.BpmnError
+import org.camunda.bpm.engine.delegate.DelegateExecution
+import org.onap.aai.domain.yang.CloudRegion
+import org.onap.aai.domain.yang.Customer
+import org.onap.aai.domain.yang.GenericVnf
+import org.onap.aai.domain.yang.ModelVer
+import org.onap.aai.domain.yang.ServiceInstance
+import org.onap.aai.domain.yang.ServiceSubscription
+import org.onap.aai.domain.yang.SliceProfile
+import org.onap.aai.domain.yang.Tenant
+import org.onap.aai.domain.yang.VfModule
+import org.onap.aaiclient.client.aai.AAIObjectType
+import org.onap.aaiclient.client.aai.AAIResourcesClient
+import org.onap.aaiclient.client.aai.entities.AAIEdgeLabel
+import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
+import org.onap.aaiclient.client.aai.entities.Relationships
+import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
+import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
+import org.onap.logging.filter.base.ONAPComponents
+import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
+import org.onap.so.bpmn.common.scripts.ExceptionUtil
+import org.onap.so.bpmn.common.scripts.MsoUtils
+import org.onap.so.bpmn.common.scripts.RequestDBUtil
+import org.onap.so.bpmn.core.UrnPropertiesReader
+import org.onap.so.bpmn.core.json.JsonUtils
+import org.onap.so.client.HttpClient
+import org.onap.so.db.request.beans.OperationStatus
+import org.onap.so.requestsdb.RequestsDbConstant
+import org.onap.so.serviceinstancebeans.CloudConfiguration
+import org.onap.so.serviceinstancebeans.ModelInfo
+import org.onap.so.serviceinstancebeans.ModelType
+import org.onap.so.serviceinstancebeans.OwningEntity
+import org.onap.so.serviceinstancebeans.Project
+import org.onap.so.serviceinstancebeans.RequestDetails
+import org.onap.so.serviceinstancebeans.RequestInfo
+import org.onap.so.serviceinstancebeans.RequestParameters
+import org.onap.so.serviceinstancebeans.Resources
+import org.onap.so.serviceinstancebeans.Service
+import org.onap.so.serviceinstancebeans.SubscriberInfo
+import org.onap.so.serviceinstancebeans.VfModules
+import org.onap.so.serviceinstancebeans.Vnfs
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+import javax.ws.rs.core.Response
+
+class DoModifyCoreNSSI extends AbstractServiceTaskProcessor {
+
+ private final String PREFIX ="DoModifyCoreNSSI"
+
+ private ExceptionUtil exceptionUtil = new ExceptionUtil()
+ private RequestDBUtil requestDBUtil = new RequestDBUtil()
+ private MsoUtils utils = new MsoUtils()
+ private JsonUtils jsonUtil = new JsonUtils()
+
+ private static final Logger LOGGER = LoggerFactory.getLogger( DoModifyCoreNSSI.class)
+
+ @Override
+ void preProcessRequest(DelegateExecution execution) {
+ LOGGER.trace("${PREFIX} Start preProcessRequest")
+
+ def currentNSSI = execution.getVariable("currentNSSI")
+ if (!currentNSSI) {
+ String msg = "currentNSSI is null"
+ LOGGER.error(msg)
+ exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
+ }
+
+ LOGGER.trace("***** ${PREFIX} Exit preProcessRequest")
+ }
+
+
+ /**
+ * Queries Network Service Instance in AAI
+ * @param execution
+ */
+ void getNetworkServiceInstance(DelegateExecution execution) {
+ LOGGER.trace("${PREFIX} Start getNetworkServiceInstance")
+
+ AAIResourcesClient client = getAAIClient()
+
+ def currentNSSI = execution.getVariable("currentNSSI")
+
+ String globalSubscriberId = currentNSSI['globalSubscriberId']
+ String serviceType = currentNSSI['serviceType']
+ String nssiId = currentNSSI['nssiServiceInstanceId']
+
+ AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, nssiId) //AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, globalSubscriberId, serviceType, nssiId)
+ Optional<ServiceInstance> nssiOpt = client.get(ServiceInstance.class, nssiUri)
+
+ if (nssiOpt.isPresent()) {
+ ServiceInstance nssi = nssiOpt.get()
+ execution.setVariable("nssi", nssi)
+
+ execution.setVariable("nssiUri", nssiUrl)
+
+ // Network Service Instance
+ AAIResultWrapper wrapper = client.get(nssiUri);
+ Optional<Relationships> relationships = wrapper.getRelationships()
+ if (relationships.isPresent()) {
+ for(AAIResourceUri networkServiceInstanceUri: relationships.get().getRelatedAAIUris(AAIObjectType.SERVICE_INSTANCE)){ // ???
+ Optional<ServiceInstance> networkServiceInstanceOpt = client.get(ServiceInstance.class, networkServiceInstanceUri)
+ if(networkServiceInstanceOpt.isPresent()) {
+ ServiceInstance networkServiceInstance = networkServiceInstanceOpt.get()
+
+ if(networkServiceInstance.getServiceRole().equals("Network Service")) { // Network Service
+ execution.setVariable("networkServiceInstance", networkServiceInstance)
+
+ execution.setVariable("networkServiceInstanceUri", networkServiceInstanceUri)
+ break // Should be only one Network Service Instance
+ }
+ }
+ else {
+ String msg = String.format("No Network Service Instance found for NSSI %s in AAI", nssiId)
+ LOGGER.error(msg)
+ exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
+ }
+
+ }
+ }
+ else {
+ String msg = String.format("No relationship presented for NSSI %s in AAI", nssiId)
+ LOGGER.error(msg)
+ exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
+ }
+ }
+ else {
+ String msg = String.format("NSSI %s not found in AAI", nssiId)
+ LOGGER.error(msg)
+ exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
+ }
+
+
+ LOGGER.trace("***** ${PREFIX} Exit getNetworkServiceInstance")
+ }
+
+
+ /**
+ * Queries constitute VNF from Network Service Instance
+ * @param execution
+ */
+ void getConstituteVNFFromNetworkServiceInst(DelegateExecution execution) {
+ LOGGER.trace("${PREFIX} Start getConstituteVNFFromNetworkServiceInst")
+
+ AAIResourcesClient client = getAAIClient()
+
+ AAIResourceUri networkServiceInstanceUri = (AAIResourceUri)execution.getVariable("networkServiceInstanceUri")
+ AAIResultWrapper wrapper = client.get(networkServiceInstanceUri);
+ Optional<Relationships> relationships = wrapper.getRelationships()
+ if (relationships.isPresent()) {
+ for (AAIResourceUri constituteVnfUri : relationships.get().getRelatedAAIUris(AAIObjectType.GENERIC_VNF)) { // ???
+ execution.setVariable("constituteVnfUri", constituteVnfUri)
+ Optional<GenericVnf> constituteVnfOpt = client.get(GenericVnf.class, constituteVnfUri)
+ if(constituteVnfOpt.isPresent()) {
+ GenericVnf constituteVnf = constituteVnfOpt.get()
+ execution.setVariable("constituteVnf", constituteVnf)
+ }
+ else {
+ String msg = String.format("No constitute VNF found for Network Service Instance %s in AAI", ((ServiceInstance)execution.getVariable("networkServiceInstance")).getServiceInstanceId())
+ LOGGER.error(msg)
+ exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
+ }
+
+ execution.setVariable("networkServiceInstanceUri", networkServiceInstanceUri)
+ break // Should be only one constitute VNF
+ }
+ }
+ else {
+ String msg = String.format("No relationship presented for Network Service Instance %s in AAI", ((ServiceInstance)execution.getVariable("networkServiceInstance")).getServiceInstanceId())
+ LOGGER.error(msg)
+ exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
+ }
+
+ LOGGER.trace("${PREFIX} Exit getConstituteVNFFromNetworkServiceInst")
+
+ }
+
+
+ /**
+ * Retrieves NSSI associated profiles from AAI
+ * @param execution
+ */
+ void getNSSIAssociatedProfiles(DelegateExecution execution) {
+ LOGGER.trace("${PREFIX} Start getNSSIAssociatedProfiles")
+
+ AAIResourcesClient client = getAAIClient()
+
+ ServiceInstance nssi = (ServiceInstance)execution.getVariable("nssi")
+
+ List<SliceProfile> associatedProfiles = nssi.getSliceProfiles().getSliceProfile()
+
+ if(associatedProfiles.isEmpty()) {
+ String msg = String.format("No associated profiles found for NSSI %s in AAI", nssi.getServiceInstanceId())
+ LOGGER.error(msg)
+ exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
+ }
+ else {
+ execution.setVariable("associatedProfiles", associatedProfiles)
+ }
+
+ LOGGER.trace("${PREFIX} Exit getNSSIAssociatedProfiles")
+ }
+
+
+ /**
+ * Calculates a final list of S-NSSAI
+ * @param execution
+ */
+ void calculateSNSSAI(DelegateExecution execution) {
+ LOGGER.trace("${PREFIX} Start calculateSNSSAI")
+
+ List<SliceProfile> associatedProfiles = (List<SliceProfile>)execution.getVariable("associatedProfiles")
+
+ def currentNSSI = execution.getVariable("currentNSSI")
+
+ String currentSNSSAI = currentNSSI['S-NSSAI']
+
+ List<String> snssais = new ArrayList<>()
+
+ if((Boolean)execution.getVariable("isCreateSliceProfileInstance" ).equals(Boolean.TRUE)) { // Slice Profile Instance has to be created
+ for (SliceProfile associatedProfile : associatedProfiles) {
+ snssais.add(associatedProfile.getSNssai())
+ }
+
+ snssais.add(currentSNSSAI)
+ }
+ else { // Slice profile instance has to be deleted
+ for (SliceProfile associatedProfile : associatedProfiles) {
+ if (!associatedProfile.getSNssai().equals(currentNSSI)) { // not current S-NSSAI
+ snssais.add(associatedProfile.getSNssai())
+ }
+ }
+ }
+
+ execution.setVariable("S-NSSAIs", snssais)
+
+ LOGGER.trace("${PREFIX} Exit calculateSNSSAI")
+ }
+
+
+ /**
+ * Invoke PUT Service Instance API
+ * @param execution
+ */
+ void invokePUTServiceInstance(DelegateExecution execution) {
+ LOGGER.trace("${PREFIX} Start invokePUTServiceInstance")
+
+ try {
+ //url:/onap/so/infra/serviceInstantiation/v7/serviceInstances/{serviceInstanceId}/vnfs/{vnfId}"
+ def nsmfЕndpoint = UrnPropertiesReader.getVariable("mso.infra.endpoint.url", execution) // ???
+
+ ServiceInstance networkServiceInstance = (ServiceInstance)execution.getVariable("networkServiceInstance")
+
+ GenericVnf constituteVnf = (GenericVnf)execution.getVariable("constituteVnf")
+
+ String url = String.format("${nsmfЕndpoint}/serviceInstantiation/v7/serviceInstances/%s/vnfs/%s", networkServiceInstance.getServiceInstanceId(), constituteVnf.getVnfId()) // ???
+
+ String msoKey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
+ String basicAuth = UrnPropertiesReader.getVariable("mso.infra.endpoint.auth", execution)
+ String basicAuthValue = utils.encrypt(basicAuth, msoKey)
+ String encodeString = utils.getBasicAuth(basicAuthValue, msoKey)
+
+ HttpClient httpClient = getHttpClientFactory().newJsonClient(new URL(url), ONAPComponents.EXTERNAL)
+ httpClient.addAdditionalHeader("Authorization", encodeString)
+ httpClient.addAdditionalHeader("Accept", "application/json")
+
+ RequestDetails requestDetails = prepareRequestDetails(execution)
+ ObjectMapper mapper = new ObjectMapper()
+ String requestDetailsStr = mapper.writeValueAsString(requestDetails)
+
+ Response httpResponse = httpClient.put(requestDetailsStr) // check http code ???
+ } catch (any) {
+ String msg = "Exception in DoDeallocateCoreNSSI.deleteServiceOrder. " + any.getCause()
+ LOGGER.error(msg)
+ exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
+ }
+
+ LOGGER.trace("${PREFIX} Exit invokePUTServiceInstance")
+ }
+
+
+ /**
+ * Prepare model info
+ * @param execution
+ * @param requestDetails
+ * @return
+ */
+ private ModelInfo prepareModelInfo(DelegateExecution execution) {
+ ModelInfo modelInfo = new ModelInfo()
+
+ modelInfo.setModelType(ModelType.service)
+ modelInfo.setModelInvariantId(networkServiceInstance.getModelInvariantId())
+
+ AAIResourceUri modelVerUrl = AAIUriFactory.createResourceUri(AAIObjectType.MODEL_VER, networkServiceInstance.getModelInvariantId()) // model of Network Service Instance ???
+ Optional<ModelVer> modelVerOpt = client.get(ModelVer.class, modelVerUrl)
+
+ if (modelVerOpt.isPresent()) {
+ modelInfo.setModelVersionId(modelVerOpt.get().getModelVersionId())
+ modelInfo.setModelName(modelVerOpt.get().getModelName())
+ modelInfo.setModelVersion(modelVerOpt.get().getModelVersion())
+ }
+
+
+ return modelInfo
+ }
+
+
+ /**
+ * Prepares RequestDetails object
+ * @param execution
+ * @return
+ */
+ private RequestDetails prepareRequestDetails(DelegateExecution execution) {
+ RequestDetails requestDetails = new RequestDetails()
+
+ def currentNSSI = execution.getVariable("currentNSSI")
+
+ String globalSubscriberId = currentNSSI['globalSubscriberId']
+
+ ServiceInstance networkServiceInstance = (ServiceInstance)execution.getVariable("networkServiceInstance")
+
+
+ AAIResourcesClient client = getAAIClient()
+
+ // Model Info
+ requestDetails.setModelInfo(prepareModelInfo(execution))
+
+ // Subscriber Info
+ SubscriberInfo subscriberInfo = new SubscriberInfo()
+ subscriberInfo.setGlobalSubscriberId(globalSubscriberId)
+
+ Customer customer = null
+ ServiceSubscription serviceSubscription = null
+
+ AAIResourceUri networkServiceInstanceUri = execution.getVariable("networkServiceInstanceUri")
+ AAIResultWrapper wrapper = client.get(networkServiceInstanceUri)
+ Optional<Relationships> serviceSubscriptionRelationshipsOps = wrapper.getRelationships()
+ if(serviceSubscriptionRelationshipsOps.isPresent()) {
+ List<AAIResourceUri> serviceSubscriptionRelatedAAIUris = serviceSubscriptionRelationshipsOps.get().getRelatedAAIUris(AAIObjectType.SERVICE_SUBSCRIPTION)
+ if(!(serviceSubscriptionRelatedAAIUris == null || serviceSubscriptionRelatedAAIUris.isEmpty())) {
+ AAIResourceUri serviceSubscriptionUri = serviceSubscriptionRelatedAAIUris.get(0) // Many-To-One relation
+ Optional<ServiceSubscription> serviceSubscriptionOpt = client.get(ServiceSubscription.class, serviceSubscriptionUri)
+ if(serviceSubscriptionOpt.isPresent()) {
+ serviceSubscription = serviceSubscriptionOpt.get()
+ }
+
+ wrapper = client.get(serviceSubscriptionUri)
+ Optional<Relationships> customerRelationshipsOps = wrapper.getRelationships()
+ if(customerRelationshipsOps.isPresent()) {
+ List<AAIResourceUri> customerRelatedAAIUris = customerRelationshipsOps.get().getRelatedAAIUris(AAIObjectType.CUSTOMER)
+ if(!(customerRelatedAAIUris == null || customerRelatedAAIUris.isEmpty())) {
+ Optional<Customer> customerOpt = client.get(Customer.class, customerRelatedAAIUris.get(0)) // Many-To-One relation
+ if(customerOpt.isPresent()) {
+ customer = customerOpt.get()
+ subscriberInfo.setSubscriberName(customer.getSubscriberName())
+ }
+ }
+ }
+ }
+
+ }
+ requestDetails.setSubscriberInfo(subscriberInfo)
+
+ // Request Info
+ RequestInfo requestInfo = new RequestInfo()
+ requestInfo.setInstanceName(networkServiceInstance.getServiceInstanceName())
+
+ /* No found data to provide ???
+ requestInfo.setSource()
+ requestInfo.setSuppressRollback()
+ requestInfo.setRequestorId()
+ requestInfo.setProductFamilyId()
+ */
+
+ requestDetails.setRequestInfo(requestInfo)
+
+
+ // Request Parameters
+ RequestParameters requestParameters = new RequestParameters()
+
+ // No found data to provide ??? requestParameters.setaLaCarte()
+ requestParameters.setSubscriptionServiceType(serviceSubscription.getServiceType())
+
+ // User params
+ List<Map<String, Object>> userParams = new ArrayList<>()
+ // Service
+ Service service = new Service()
+ // Model Info
+ ModelInfo serviceModelInfo = new ModelInfo()
+ serviceModelInfo.setModelType(ModelType.service)
+ serviceModelInfo.setModelInvariantId(networkServiceInstance.getModelInvariantId())
+
+ serviceModelInfo.setModelVersionId(modelInfo.get().getModelVersionId())
+ serviceModelInfo.setModelName(modelInfo.get().getModelName())
+ serviceModelInfo.setModelVersion(modelInfo.get().getModelVersion())
+
+ service.setModelInfo(serviceModelInfo)
+
+ // Resources
+ Resources resources = new Resources()
+
+ CloudRegion cloudRegion = null
+ AAIResourceUri cloudRegionRelatedAAIUri = null
+ // VNFs
+ List<Vnfs> vnfs = new ArrayList<>()
+ // VNF
+ Vnfs vnf = new Vnfs()
+
+ // Cloud configuration
+ CloudConfiguration cloudConfiguration = new CloudConfiguration()
+
+ AAIResourceUri constituteVnfUri = (AAIResourceUri)execution.getVariable("constituteVnfUri")
+ wrapper = client.get(constituteVnfUri)
+ Optional<Relationships> constituteVnfOps = wrapper.getRelationships()
+ if(constituteVnfOps.isPresent()) {
+ List<AAIResourceUri> cloudRegionRelatedAAIUris = serviceSubscriptionRelationshipsOps.get().getRelatedAAIUris(AAIObjectType.CLOUD_REGION)
+ if(!(cloudRegionRelatedAAIUris == null || cloudRegionRelatedAAIUris.isEmpty())) {
+ cloudRegionRelatedAAIUri = cloudRegionRelatedAAIUris.get(0)
+ Optional<CloudRegion> cloudRegionrOpt = client.get(CloudRegion.class, cloudRegionRelatedAAIUris.get(0))
+ if(cloudRegionrOpt.isPresent()) {
+ cloudRegion = cloudRegionrOpt.get()
+ cloudConfiguration.setLcpCloudRegionId(cloudRegion.getCloudRegionId())
+ for(Tenant tenant:cloudRegion.getTenants()) {
+ cloudConfiguration.setTenantId(tenant.getTenantId())
+ break // only one is required
+ }
+
+ cloudConfiguration.setCloudOwner(cloudRegion.getCloudOwner())
+ }
+ }
+ }
+
+ vnf.setCloudConfiguration(cloudConfiguration)
+
+ // VF Modules
+ GenericVnf constituteVnf = execution.getVariable("constituteVnf")
+ List<VfModules> vfModuless = new ArrayList<>()
+ for(VfModule vfModule:constituteVnf.getVfModules()) {
+ VfModules vfmodules = new VfModules()
+
+ ModelInfo vfModuleModelInfo = new ModelInfo()
+ vfModuleModelInfo.setModelInvariantUuid(vfModule.getModelInvariantId())
+
+ AAIResourceUri vfModuleUrl = AAIUriFactory.createResourceUri(AAIObjectType.MODEL_VER, vfModule.getModelInvariantId()) // ???
+ Optional<ModelVer> vfModuleModelVerOpt = client.get(ModelVer.class, vfModuleUrl)
+
+ if (vfModuleModelVerOpt.isPresent()) {
+ vfModuleModelInfo.setModelVersionId(vfModuleModelVerOpt.get().getModelVersionId())
+ vfModuleModelInfo.setModelName(vfModuleModelVerOpt.get().getModelName())
+ vfModuleModelInfo.setModelVersion(vfModuleModelVerOpt.get().getModelVersion())
+
+ // No model customization ID
+ }
+ vfmodules.setModelInfo(vfModuleModelInfo)
+
+ vfmodules.setInstanceName(vfModule.getVfModuleName()) // ???
+
+ vfModuless.add(vfmodules)
+ }
+ vnf.setVfModules(vfModuless)
+
+ // Model Info
+ ModelInfo vnfModelInfo = new ModelInfo()
+ vnfModelInfo.setModelInvariantUuid(constituteVnf.getModelInvariantId())
+ AAIResourceUri vnfModelUrl = AAIUriFactory.createResourceUri(AAIObjectType.MODEL_VER, constituteVnf.getModelInvariantId()) // ???
+ Optional<ModelVer> vnfModelVerOpt = client.get(ModelVer.class, vnfModelUrl)
+
+ if (vnfModelVerOpt.isPresent()) {
+ vnfModelInfo.setModelVersionId(vnfModelVerOpt.get().getModelVersionId())
+ vnfModelInfo.setModelName(vnfModelVerOpt.get().getModelName())
+ vnfModelInfo.setModelVersion(vnfModelVerOpt.get().getModelVersion())
+
+ // No model customization ID
+ // No model instance name
+ }
+
+ vnf.setModelInfo(vnfModelInfo)
+
+ // Instance name
+ vnf.setInstanceName(constituteVnf.getVnfInstanceId())
+
+ // Instance params
+ List<Map<String, Object>> instanceParams = new ArrayList<>()
+ Map<String, Object> supporrtedNSSAIMap = new HashMap<>()
+
+ // Supported S-NSSAI
+ List<String> snssais = ( List<String>)execution.getVariable("S-NSSAIs")
+ supporrtedNSSAIMap.put("supporrtedNSSAI", snssais) // remaining S-NSSAIs ??? there is no status for each s-nssai
+ instanceParams.add(supporrtedNSSAIMap)
+
+ // No other instance params, e.g. config-type
+
+ vnf.setInstanceParams(instanceParams)
+
+ // No platform data
+
+ vnfs.add(vnf)
+ resources.setVnfs(vnfs)
+
+ service.setResources(resources)
+
+ Map<String, Object> serviceMap = new HashMap<>()
+ serviceMap.put("service", service)
+ userParams.add(serviceMap)
+ requestParameters.setUserParams(userParams)
+
+ // No other user params
+
+ requestDetails.setRequestParameters(requestParameters)
+
+ // No other request params
+
+ // Cloud configuration
+ requestDetails.setCloudConfiguration(cloudConfiguration)
+
+ // Owning entity
+ OwningEntity owningEntity = new OwningEntity()
+ wrapper = client.get(networkServiceInstanceUri)
+ Optional<Relationships> owningEntityRelationshipsOps = wrapper.getRelationships()
+ if(owningEntityRelationshipsOps.isPresent()) {
+ List<AAIResourceUri> owningEntityRelatedAAIUris = owningEntityRelationshipsOps.get().getRelatedAAIUris(AAIObjectType.OWNING_ENTITY)
+
+ if(!(owningEntityRelatedAAIUris == null || owningEntityRelatedAAIUris.isEmpty())) {
+ Optional<org.onap.aai.domain.yang.OwningEntity> owningEntityOpt = client.get(org.onap.aai.domain.yang.OwningEntity.class, owningEntityRelatedAAIUris.get(0)) // Many-To-One relation
+ if(owningEntityOpt.isPresent()) {
+ owningEntity.setOwningEntityId(owningEntityOpt.get().getOwningEntityId())
+ owningEntity.setOwningEntityName(owningEntityOpt.get().getOwningEntityName())
+ requestDetails.setOwningEntity(owningEntity)
+ }
+ }
+ }
+
+ // Project
+ Project project = new Project()
+ if(cloudRegionRelatedAAIUri != null) {
+ wrapper = client.get(cloudRegionRelatedAAIUri)
+ Optional<Relationships> cloudRegionOps = wrapper.getRelationships()
+ if(cloudRegionOps.isPresent()) {
+ List<AAIResourceUri> projectAAIUris = cloudRegionOps.get().getRelatedAAIUris(AAIObjectType.PROJECT)
+ if (!(projectAAIUris == null || projectAAIUris.isEmpty())) {
+ Optional<org.onap.aai.domain.yang.Project> projectOpt = client.get(org.onap.aai.domain.yang.Project.class, projectAAIUris.get(0))
+ if(projectOpt.isPresent()) {
+ project.setProjectName(projectOpt.get().getProjectName())
+ }
+ }
+ }
+ }
+ requestDetails.setProject(project)
+
+ return requestDetails
+ }
+
+
+ /**
+ * Creates Slice Profile Instance
+ * @param execution
+ */
+ void createSliceProfileInstance(DelegateExecution execution) {
+ LOGGER.trace("${PREFIX} Start createSliceProfileInstance")
+
+ String sliceProfileID = execution.getVariable("sliceProfileID")
+ Map<String, Object> sliceProfileMap = execution.getVariable("sliceProfileCn")
+ Map<String, Object> serviceProfileMap = execution.getVariable("serviceProfile")
+
+ SliceProfile sliceProfile = new SliceProfile()
+ sliceProfile.setServiceAreaDimension("")
+ sliceProfile.setPayloadSize(0)
+ sliceProfile.setJitter(0)
+ sliceProfile.setSurvivalTime(0)
+ sliceProfile.setExpDataRate(0)
+ sliceProfile.setTrafficDensity(0)
+ sliceProfile.setConnDensity(0)
+ sliceProfile.setSNssai(sliceProfileMap.get("sNSSAI").toString())
+ sliceProfile.setExpDataRateUL(Integer.parseInt(sliceProfileMap.get("expDataRateUL").toString()))
+ sliceProfile.setExpDataRateDL(Integer.parseInt(sliceProfileMap.get("expDataRateDL").toString()))
+ sliceProfile.setActivityFactor(Integer.parseInt(sliceProfileMap.get("activityFactor").toString()))
+ sliceProfile.setResourceSharingLevel(sliceProfileMap.get("activityFactor").toString())
+ sliceProfile.setUeMobilityLevel(serviceProfileMap.get("uEMobilityLevel").toString())
+ sliceProfile.setCoverageAreaTAList(serviceProfileMap.get("coverageAreaTAList").toString())
+ sliceProfile.setMaxNumberOfUEs(Integer.parseInt(sliceProfileMap.get("activityFactor").toString()))
+ sliceProfile.setLatency(Integer.parseInt(sliceProfileMap.get("latency").toString()))
+ sliceProfile.setProfileId(sliceProfileID)
+ sliceProfile.setE2ELatency(0)
+
+ try {
+ AAIResourcesClient client = getAAIClient()
+ AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SLICE_PROFILE, sliceProfileID)
+ client.create(uri, sliceProfile)
+
+ execution.setVariable("createdSliceProfile", sliceProfile)
+ } catch (Exception ex) {
+ exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occured while Slice Profile create call:" + ex.getMessage())
+ }
+
+ LOGGER.trace("${PREFIX} Exit createSliceProfileInstance")
+ }
+
+
+ /**
+ * Creates Slice Profile association with NSSI
+ * @param execution
+ */
+ void associateSliceProfileInstanceWithNSSI(DelegateExecution execution) {
+ LOGGER.trace("${PREFIX} Start associateSliceProfileInstanceWithNSSI")
+
+ String sliceProfileID = execution.getVariable("sliceProfileID")
+
+ def currentNSSI = execution.getVariable("currentNSSI")
+
+ String nssiId = currentNSSI['nssiServiceInstanceId']
+
+ AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, nssiId)
+ AAIResourceUri sliceProfileUri = AAIUriFactory.createResourceUri(AAIObjectType.SLICE_PROFILE, sliceProfileID)
+
+ try {
+ SliceProfile createdSliceProfile = (SliceProfile)execution.getVariable("createdSliceProfile")
+ ServiceInstance nssi = (ServiceInstance)execution.getVariable("nssi")
+ List<SliceProfile> associatedProfiles = nssi.getSliceProfiles().getSliceProfile()
+ associatedProfiles.add(createdSliceProfile)
+
+ getAAIClient().update(nssiUri, nssi)
+
+ getAAIClient().connect(sliceProfileUri, nsiUri, AAIEdgeLabel.BELONGS_TO)
+ }catch(Exception e){
+ exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occured while Slice Profile association with NSSI disconnect call: " + e.getMessage())
+ }
+
+ LOGGER.trace("${PREFIX} Exit associateSliceProfileInstanceWithNSSI")
+ }
+
+
+ /**
+ * Removes Slice Profile association with NSSI
+ * @param execution
+ */
+ void removeSPAssociationWithNSSI(DelegateExecution execution) {
+ LOGGER.trace("${PREFIX} Start removeSPAssociationWithNSSI")
+
+ AAIResourcesClient client = getAAIClient()
+
+ def currentNSSI = execution.getVariable("currentNSSI")
+
+ ServiceInstance nssi = (ServiceInstance)execution.getVariable("nssi")
+
+ String nssiId = currentNSSI['nssiServiceInstanceId']
+ AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, nssiId)
+
+ List<SliceProfile> associatedProfiles = nssi.getSliceProfiles().getSliceProfile()
+
+ String currentSNSSAI = currentNSSI['S-NSSAI']
+
+ associatedProfiles.removeIf({ associatedProfile -> (associatedProfile.getSNssai().equals(currentSNSSAI)) })
+
+ try {
+ getAAIClient().update(nssiUri, nssi)
+ }catch(Exception e){
+ exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occured while Slice Profile association with NSSI update call: " + e.getMessage())
+ }
+
+ LOGGER.trace("${PREFIX} Exit removeSPAssociationWithNSSI")
+ }
+
+
+ /**
+ * Deletes Slice Profile Instance
+ * @param execution
+ */
+ void deleteSliceProfileInstance(DelegateExecution execution) {
+ LOGGER.trace("${PREFIX} Start deleteSliceProfileInstance")
+
+ AAIResourcesClient client = getAAIClient()
+
+ def currentNSSI = execution.getVariable("currentNSSI")
+
+ ServiceInstance nssi = (ServiceInstance)execution.getVariable("nssi")
+
+ List<SliceProfile> associatedProfiles = nssi.getSliceProfiles().getSliceProfile()
+
+ String currentSNSSAI = currentNSSI['S-NSSAI']
+
+ AAIResourceUri sliceProfileUri = null
+
+ for(SliceProfile associatedProfile:associatedProfiles) {
+ if(!associatedProfile.getSNssai().equals(currentNSSI)) { // not current S-NSSAI
+ sliceProfileUri = AAIUriFactory.createResourceUri(AAIObjectType.SLICE_PROFILE, associatedProfile.getProfileId())
+ break
+ }
+ }
+
+ try {
+ getAAIClient().delete(sliceProfileUri)
+ }catch(Exception e){
+ exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occured while Slice Profile Instance delete call: " + e.getMessage())
+ }
+
+ LOGGER.trace("${PREFIX} Exit deleteSliceProfileInstance")
+ }
+
+
+ /**
+ * Updates operation status
+ * @param execution
+ */
+ void updateServiceOperationStatus(DelegateExecution execution) {
+ LOGGER.trace("${PREFIX} Start updateServiceOperationStatus")
+
+ def currentNSSI = execution.getVariable("currentNSSI")
+
+ OperationStatus operationStatus = new OperationStatus()
+ operationStatus.setServiceId(currentNSSI['e2eServiceInstanceId'] as String)
+ operationStatus.setOperationId(currentNSSI['operationId'] as String)
+ operationStatus.setOperation(currentNSSI['operationType'] as String)
+ operationStatus.setResult(RequestsDbConstant.Status.FINISHED)
+
+ requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
+
+ LOGGER.trace("${PREFIX} Exit updateServiceOperationStatus")
+ }
+
+
+ /**
+ * Returns AAI client
+ * @return AAI client
+ */
+ AAIResourcesClient getAAIClient() {
+ return new AAIResourcesClient()
+ }
+
+}
diff --git a/bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoModifyCoreNSSI.bpmn b/bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoModifyCoreNSSI.bpmn
new file mode 100644
index 0000000000..fa167d4515
--- /dev/null
+++ b/bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoModifyCoreNSSI.bpmn
@@ -0,0 +1,311 @@
+<?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:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1ejx57e" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.1.1">
+ <bpmn:process id="Process_1nmtzzp" isExecutable="true">
+ <bpmn:startEvent id="Event_0fbqt56" name="Modify Core NSSI Flow">
+ <bpmn:outgoing>Flow_0e007rx</bpmn:outgoing>
+ </bpmn:startEvent>
+ <bpmn:scriptTask id="Activity_0tf735w" name="Get Network Service Instance" scriptFormat="groovy">
+ <bpmn:incoming>Flow_06j2avj</bpmn:incoming>
+ <bpmn:outgoing>Flow_1mqjtfk</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def mcnssi= new DoModifyCoreNSSI()
+ mcnssi.getNetworkServiceInstance(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:scriptTask id="Activity_1ce41n6" name="Get constitute VNF from Network Service Instance" scriptFormat="groovy">
+ <bpmn:incoming>Flow_1mqjtfk</bpmn:incoming>
+ <bpmn:outgoing>Flow_184tfp7</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def mcnssi= new DoModifyCoreNSSI()
+ mcnssi.getConstituteVNFFromNetworkServiceInst(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:sequenceFlow id="Flow_1mqjtfk" sourceRef="Activity_0tf735w" targetRef="Activity_1ce41n6" />
+ <bpmn:scriptTask id="Activity_02skgkj" name="Get NSSI associated profiles" scriptFormat="groovy">
+ <bpmn:incoming>Flow_184tfp7</bpmn:incoming>
+ <bpmn:outgoing>Flow_0s31teg</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def mcnssi= new DoModifyCoreNSSI()
+ mcnssi.getNSSIAssociatedProfiles(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:sequenceFlow id="Flow_184tfp7" sourceRef="Activity_1ce41n6" targetRef="Activity_02skgkj" />
+ <bpmn:exclusiveGateway id="Gateway_1hadnun" name="Is Slice Profile Instance has to be created" default="Flow_03gf14v">
+ <bpmn:incoming>Flow_0s31teg</bpmn:incoming>
+ <bpmn:outgoing>Flow_1pls2hu</bpmn:outgoing>
+ <bpmn:outgoing>Flow_03gf14v</bpmn:outgoing>
+ </bpmn:exclusiveGateway>
+ <bpmn:sequenceFlow id="Flow_0s31teg" sourceRef="Activity_02skgkj" targetRef="Gateway_1hadnun" />
+ <bpmn:intermediateThrowEvent id="Event_1243wg1" name="Goto Slice Profile Instance has to be created">
+ <bpmn:incoming>Flow_1pls2hu</bpmn:incoming>
+ <bpmn:linkEventDefinition id="LinkEventDefinition_14qnw6y" name="SliceProfileInstanceHasToBeCreated" />
+ </bpmn:intermediateThrowEvent>
+ <bpmn:sequenceFlow id="Flow_1pls2hu" name="yes" sourceRef="Gateway_1hadnun" targetRef="Event_1243wg1">
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{(execution.getVariable("isCreateSliceProfileInstance" ) == true)}</bpmn:conditionExpression>
+ </bpmn:sequenceFlow>
+ <bpmn:intermediateThrowEvent id="Event_1gjhrcq" name="Goto Slice profile instance has to be deleted">
+ <bpmn:incoming>Flow_03gf14v</bpmn:incoming>
+ <bpmn:linkEventDefinition id="LinkEventDefinition_0ecwvhj" name="SliceProfileInstanceHasToBeDeleted" />
+ </bpmn:intermediateThrowEvent>
+ <bpmn:sequenceFlow id="Flow_03gf14v" name="no" sourceRef="Gateway_1hadnun" targetRef="Event_1gjhrcq" />
+ <bpmn:scriptTask id="Activity_0oph5am" name="Update Service Operation Status" scriptFormat="groovy">
+ <bpmn:incoming>Flow_0l7hcnf</bpmn:incoming>
+ <bpmn:incoming>Flow_0lrenyo</bpmn:incoming>
+ <bpmn:outgoing>Flow_0yq24um</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def mcnssi= new DoDeallocateCoreNSSI()
+ mcnssi.updateServiceOperationStatus(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:endEvent id="Event_1p0mogo" name="End">
+ <bpmn:incoming>Flow_0yq24um</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:sequenceFlow id="Flow_0yq24um" sourceRef="Activity_0oph5am" targetRef="Event_1p0mogo" />
+ <bpmn:intermediateCatchEvent id="Event_0z9mer1" name="Slice Profile Instance has to be created">
+ <bpmn:outgoing>Flow_1xysykm</bpmn:outgoing>
+ <bpmn:linkEventDefinition id="LinkEventDefinition_0fbskyk" name="SliceProfileInstanceHasToBeCreated" />
+ </bpmn:intermediateCatchEvent>
+ <bpmn:intermediateCatchEvent id="Event_0m2jn7c" name="Slice profile instance has to be deleted">
+ <bpmn:outgoing>Flow_11vf6ik</bpmn:outgoing>
+ <bpmn:linkEventDefinition id="LinkEventDefinition_1lptuqv" name="SliceProfileInstanceHasToBeDeleted" />
+ </bpmn:intermediateCatchEvent>
+ <bpmn:scriptTask id="Activity_0ouov98" name="Calculate S-NSSAI" scriptFormat="groovy">
+ <bpmn:incoming>Flow_1xysykm</bpmn:incoming>
+ <bpmn:outgoing>Flow_1nxaeez</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def mcnssi= new DoModifyCoreNSSI()
+ mcnssi.calculateSNSSAI(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:sequenceFlow id="Flow_1xysykm" sourceRef="Event_0z9mer1" targetRef="Activity_0ouov98" />
+ <bpmn:scriptTask id="Activity_00t4mmi" name="Invoke PUT Service Instance API" scriptFormat="groovy">
+ <bpmn:incoming>Flow_1nxaeez</bpmn:incoming>
+ <bpmn:outgoing>Flow_0ccqmju</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def mcnssi= new ModifyCoreNSSI()
+ mcnssi.invokePUTServiceInstance(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:sequenceFlow id="Flow_1nxaeez" sourceRef="Activity_0ouov98" targetRef="Activity_00t4mmi" />
+ <bpmn:scriptTask id="Activity_1q02wiz" name="Create a slice profile instance " scriptFormat="groovy">
+ <bpmn:incoming>Flow_0ccqmju</bpmn:incoming>
+ <bpmn:outgoing>Flow_1fdpbsx</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def mcnssi= new ModifyCoreNSSI()
+ mcnssi.createSliceProfileInstance(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:sequenceFlow id="Flow_0ccqmju" sourceRef="Activity_00t4mmi" targetRef="Activity_1q02wiz" />
+ <bpmn:scriptTask id="Activity_1josmor" name="Associate slice profile instance the same with the NSSI " scriptFormat="groovy">
+ <bpmn:incoming>Flow_1fdpbsx</bpmn:incoming>
+ <bpmn:outgoing>Flow_0l7hcnf</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def mcnssi= new ModifyCoreNSSI()
+ mcnssi.associateSliceProfileInstanceWithNSSI(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:sequenceFlow id="Flow_1fdpbsx" sourceRef="Activity_1q02wiz" targetRef="Activity_1josmor" />
+ <bpmn:scriptTask id="Activity_0j4c22q" name="Calculate S-NSSAI" scriptFormat="groovy">
+ <bpmn:incoming>Flow_11vf6ik</bpmn:incoming>
+ <bpmn:outgoing>Flow_1oeokwy</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def mcnssi= new DoModifyCoreNSSI()
+ mcnssi.calculateSNSSAI(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:sequenceFlow id="Flow_11vf6ik" sourceRef="Event_0m2jn7c" targetRef="Activity_0j4c22q" />
+ <bpmn:scriptTask id="Activity_0c4wmiz" name="Invoke PUT Service Instance API" scriptFormat="groovy">
+ <bpmn:incoming>Flow_1oeokwy</bpmn:incoming>
+ <bpmn:outgoing>Flow_15fi92t</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def mcnssi= new ModifyCoreNSSI()
+ mcnssi.invokePUTServiceInstance(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:sequenceFlow id="Flow_1oeokwy" sourceRef="Activity_0j4c22q" targetRef="Activity_0c4wmiz" />
+ <bpmn:scriptTask id="Activity_1iegufd" name="Remove the NSSI to slice instance association " scriptFormat="groovy">
+ <bpmn:incoming>Flow_15fi92t</bpmn:incoming>
+ <bpmn:outgoing>Flow_1wtv1zj</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def mcnssi= new ModifyCoreNSSI()
+ mcnssi.removeNSSIToSliceInstanceAssociation(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:sequenceFlow id="Flow_15fi92t" sourceRef="Activity_0c4wmiz" targetRef="Activity_1iegufd" />
+ <bpmn:scriptTask id="Activity_010nkjp" name="Delete the slice profile instance " scriptFormat="groovy">
+ <bpmn:incoming>Flow_1wtv1zj</bpmn:incoming>
+ <bpmn:outgoing>Flow_0lrenyo</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def mcnssi= new ModifyCoreNSSI()
+ mcnssi.deleteSliceProfileInstance(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:sequenceFlow id="Flow_1wtv1zj" sourceRef="Activity_1iegufd" targetRef="Activity_010nkjp" />
+ <bpmn:sequenceFlow id="Flow_0l7hcnf" sourceRef="Activity_1josmor" targetRef="Activity_0oph5am" />
+ <bpmn:sequenceFlow id="Flow_0lrenyo" sourceRef="Activity_010nkjp" targetRef="Activity_0oph5am" />
+ <bpmn:scriptTask id="Activity_0klj7y1" name="PreProcess Incoming Request" scriptFormat="groovy">
+ <bpmn:incoming>Flow_0e007rx</bpmn:incoming>
+ <bpmn:outgoing>Flow_06j2avj</bpmn:outgoing>
+ <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+ def mcnssi= new DoModifyCoreNSSI()
+ mcnssi.preProcessRequest(execution)</bpmn:script>
+ </bpmn:scriptTask>
+ <bpmn:sequenceFlow id="Flow_0e007rx" sourceRef="Event_0fbqt56" targetRef="Activity_0klj7y1" />
+ <bpmn:sequenceFlow id="Flow_06j2avj" sourceRef="Activity_0klj7y1" targetRef="Activity_0tf735w" />
+ </bpmn:process>
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1nmtzzp">
+ <bpmndi:BPMNEdge id="Flow_0lrenyo_di" bpmnElement="Flow_0lrenyo">
+ <di:waypoint x="890" y="600" />
+ <di:waypoint x="930" y="600" />
+ <di:waypoint x="930" y="540" />
+ <di:waypoint x="970" y="540" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0l7hcnf_di" bpmnElement="Flow_0l7hcnf">
+ <di:waypoint x="890" y="430" />
+ <di:waypoint x="930" y="430" />
+ <di:waypoint x="930" y="500" />
+ <di:waypoint x="970" y="500" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1wtv1zj_di" bpmnElement="Flow_1wtv1zj">
+ <di:waypoint x="730" y="600" />
+ <di:waypoint x="790" y="600" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_15fi92t_di" bpmnElement="Flow_15fi92t">
+ <di:waypoint x="560" y="600" />
+ <di:waypoint x="630" y="600" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1oeokwy_di" bpmnElement="Flow_1oeokwy">
+ <di:waypoint x="380" y="600" />
+ <di:waypoint x="460" y="600" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_11vf6ik_di" bpmnElement="Flow_11vf6ik">
+ <di:waypoint x="218" y="600" />
+ <di:waypoint x="280" y="600" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1fdpbsx_di" bpmnElement="Flow_1fdpbsx">
+ <di:waypoint x="730" y="430" />
+ <di:waypoint x="790" y="430" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0ccqmju_di" bpmnElement="Flow_0ccqmju">
+ <di:waypoint x="560" y="430" />
+ <di:waypoint x="630" y="430" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1nxaeez_di" bpmnElement="Flow_1nxaeez">
+ <di:waypoint x="390" y="430" />
+ <di:waypoint x="460" y="430" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1xysykm_di" bpmnElement="Flow_1xysykm">
+ <di:waypoint x="218" y="430" />
+ <di:waypoint x="290" y="430" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0yq24um_di" bpmnElement="Flow_0yq24um">
+ <di:waypoint x="1070" y="520" />
+ <di:waypoint x="1132" y="520" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_03gf14v_di" bpmnElement="Flow_03gf14v">
+ <di:waypoint x="1010" y="175" />
+ <di:waypoint x="1010" y="252" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="1019" y="190" width="13" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1pls2hu_di" bpmnElement="Flow_1pls2hu">
+ <di:waypoint x="1035" y="150" />
+ <di:waypoint x="1132" y="150" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="1049" y="132" width="17" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0s31teg_di" bpmnElement="Flow_0s31teg">
+ <di:waypoint x="910" y="150" />
+ <di:waypoint x="985" y="150" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_184tfp7_di" bpmnElement="Flow_184tfp7">
+ <di:waypoint x="720" y="150" />
+ <di:waypoint x="810" y="150" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1mqjtfk_di" bpmnElement="Flow_1mqjtfk">
+ <di:waypoint x="540" y="150" />
+ <di:waypoint x="620" y="150" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0e007rx_di" bpmnElement="Flow_0e007rx">
+ <di:waypoint x="218" y="150" />
+ <di:waypoint x="280" y="150" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_06j2avj_di" bpmnElement="Flow_06j2avj">
+ <di:waypoint x="380" y="150" />
+ <di:waypoint x="440" y="150" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="Event_0fbqt56_di" bpmnElement="Event_0fbqt56">
+ <dc:Bounds x="182" y="132" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="158" y="175" width="89" height="27" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0oph5am_di" bpmnElement="Activity_0oph5am">
+ <dc:Bounds x="970" y="480" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_1p0mogo_di" bpmnElement="Event_1p0mogo">
+ <dc:Bounds x="1132" y="502" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="1140" y="478" width="20" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_0z9mer1_di" bpmnElement="Event_0z9mer1">
+ <dc:Bounds x="182" y="412" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="162" y="455" width="90" height="40" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_0m2jn7c_di" bpmnElement="Event_0m2jn7c">
+ <dc:Bounds x="182" y="582" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="155" y="625" width="90" height="40" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0ouov98_di" bpmnElement="Activity_0ouov98">
+ <dc:Bounds x="290" y="390" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_00t4mmi_di" bpmnElement="Activity_00t4mmi">
+ <dc:Bounds x="460" y="390" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1q02wiz_di" bpmnElement="Activity_1q02wiz">
+ <dc:Bounds x="630" y="390" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1josmor_di" bpmnElement="Activity_1josmor">
+ <dc:Bounds x="790" y="390" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0j4c22q_di" bpmnElement="Activity_0j4c22q">
+ <dc:Bounds x="280" y="560" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0c4wmiz_di" bpmnElement="Activity_0c4wmiz">
+ <dc:Bounds x="460" y="560" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1iegufd_di" bpmnElement="Activity_1iegufd">
+ <dc:Bounds x="630" y="560" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_010nkjp_di" bpmnElement="Activity_010nkjp">
+ <dc:Bounds x="790" y="560" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_1243wg1_di" bpmnElement="Event_1243wg1">
+ <dc:Bounds x="1132" y="132" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="1113" y="173" width="90" height="40" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Gateway_1hadnun_di" bpmnElement="Gateway_1hadnun" isMarkerVisible="true">
+ <dc:Bounds x="985" y="125" width="50" height="50" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="974" y="86" width="75" height="40" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_1gjhrcq_di" bpmnElement="Event_1gjhrcq">
+ <dc:Bounds x="992" y="252" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="973" y="293" width="90" height="40" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_02skgkj_di" bpmnElement="Activity_02skgkj">
+ <dc:Bounds x="810" y="110" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1ce41n6_di" bpmnElement="Activity_1ce41n6">
+ <dc:Bounds x="620" y="110" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0tf735w_di" bpmnElement="Activity_0tf735w">
+ <dc:Bounds x="440" y="110" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0klj7y1_di" bpmnElement="Activity_0klj7y1">
+ <dc:Bounds x="280" y="110" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</bpmn:definitions>