summaryrefslogtreecommitdiffstats
path: root/so-etsi-nfvo/so-etsi-nfvo-ns-lcm
diff options
context:
space:
mode:
Diffstat (limited to 'so-etsi-nfvo/so-etsi-nfvo-ns-lcm')
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/Application.java8
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/AsyncThreadExecutorConfiguration.java8
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/DefaultToShortClassNameBeanNameGenerator.java9
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/resources/application.yaml43
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/pom.xml95
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaCustomConfiguration.java49
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaDatabaseConfiguration.java69
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaVariableNameConstants.java52
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/Constants.java37
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/GsonProvider.java44
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/EtsiCatalogManagerRequestFailureException.java41
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/NsRequestProcessingException.java53
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java34
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java76
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java44
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java83
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java39
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java110
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java188
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogUrlProvider.java51
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterConfiguration.java148
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProvider.java34
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProviderImpl.java117
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterUrlProvider.java64
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java111
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileParser.java32
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptor.java121
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParser.java209
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java75
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadataParser.java67
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java123
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/YamlFileParser.java39
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java252
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowExecutorService.java59
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowQueryService.java108
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/AbstractNetworkServiceTask.java117
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateRequest.java167
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateVnfTask.java234
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateNsTask.java221
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/InstantiateNsTask.java416
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorInstantiateSol003AdapterNodeTask.java52
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterCreateJobTask.java105
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterJobTask.java96
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterNodeTask.java92
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java58
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn159
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateNs.bpmn266
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/InstantiateNs.bpmn331
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/META-INF/services/org.onap.so.client.RestProperties1
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterCreateJob.bpmn160
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterCreateNodeStatus.bpmn138
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/BaseTest.java150
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/DefaultToShortClassNameBeanNameGenerator.java37
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/TestApplication.java45
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParserTest.java87
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/CreateNsTaskTest.java387
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/InstantiateNsTaskTest.java327
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/MonitorInstantiateSol003AdapterNodeTaskTest.java93
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/MonitorSol003AdapterCreateJobTaskTest.java156
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml49
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/invalid_ns.csarbin0 -> 778 bytes
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csarbin0 -> 2952 bytes
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/pom.xml24
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobAction.java29
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobStatusEnum.java29
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJob.java274
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJobStatus.java147
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNfInst.java213
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNsInst.java289
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpOcc.java233
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpType.java28
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/OperationStateEnum.java29
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/State.java29
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/Utils.java58
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/config/NfvoDatabaseConfiguration.java87
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NSLcmOpOccRepository.java33
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobRepository.java35
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobStatusRepository.java30
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNfInstRepository.java38
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNsInstRepository.java39
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/service/DatabaseServiceProvider.java141
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/resources/db/migration/V1_1__create_nfvo_tables.sql74
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/DatabaseServiceProviderTest.java176
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/TestApplication.java45
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/UtilsTest.java65
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/resources/application.yaml31
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/pom.xml20
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/Constants.java8
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/EtsiSoNsLcmManagerUrlProvider.java53
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/GsonSerializerConfiguration.java42
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/lifecycle/NsLifeCycleManager.java77
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesController.java8
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementController.java36
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/exceptions/NsLcmControllerExceptionHandler.java58
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/TestApplication.java8
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesControllerTest.java8
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementControllerTest.java152
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/resources/application.yaml39
98 files changed, 9269 insertions, 52 deletions
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/Application.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/Application.java
index 24c09d489e..12f3bfc119 100644
--- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/Application.java
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/Application.java
@@ -1,19 +1,19 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Ericsson. All rights reserved.
+ * 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=========================================================
*/
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/AsyncThreadExecutorConfiguration.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/AsyncThreadExecutorConfiguration.java
index 2eaa710191..4427e1ac2f 100644
--- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/AsyncThreadExecutorConfiguration.java
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/AsyncThreadExecutorConfiguration.java
@@ -1,19 +1,19 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Ericsson. All rights reserved.
+ * 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=========================================================
*/
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/DefaultToShortClassNameBeanNameGenerator.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/DefaultToShortClassNameBeanNameGenerator.java
index 13649ac80c..2546c9c23f 100644
--- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/DefaultToShortClassNameBeanNameGenerator.java
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/DefaultToShortClassNameBeanNameGenerator.java
@@ -1,23 +1,22 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix. All rights reserved.
+ * 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.app;
import org.springframework.beans.factory.config.BeanDefinition;
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/resources/application.yaml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/resources/application.yaml
index 457e956f71..7f0fd93c8d 100644
--- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/resources/application.yaml
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/resources/application.yaml
@@ -11,6 +11,19 @@
# 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.
+aai:
+ auth: 2A11B07DB6214A839394AA1EC5844695F5114FC407FF5422625FB00175A3DCB8A1FF745F22867EFA72D5369D599BBD88DA8BED4233CF5586
+ version: v19
+ endpoint: https://aai.onap:8443
+camunda:
+ bpm:
+ admin-user:
+ id: admin
+ password: admin
+ history-level: full
+ job-execution:
+ max-pool-size: 30
+ core-pool-size: 3
spring:
security:
usercredentials:
@@ -22,7 +35,35 @@ spring:
preferred-json-mapper: gson
main:
allow-bean-definition-overriding: true
+ datasource:
+ hikari:
+ camunda:
+ jdbcUrl: jdbc:mariadb://${DB_HOST}:${DB_PORT}/camundabpmn
+ username: ${DB_USERNAME}
+ password: ${DB_PASSWORD}
+ driver-class-name: org.mariadb.jdbc.Driver
+ pool-name: bpmn-pool
+ registerMbeans: true
+ nfvo:
+ jdbcUrl: jdbc:mariadb://${DB_HOST}:${DB_PORT}/nfvo
+ username: ${NFVO_USERNAME}
+ password: ${NFVO_PASSWORD}
+ driver-class-name: org.mariadb.jdbc.Driver
+ pool-name: nfvo-pool
+ registerMbeans: true
server:
port: 9095
tomcat:
- max-threads: 50 \ No newline at end of file
+ max-threads: 50
+mso:
+ key: 07a7159d3bf51a0e53be7a8f89699be7
+so:
+ adapters:
+ sol003-adapter:
+ url: https://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1
+ auth: Basic dm5mbTpwYXNzd29yZDEk
+etsi-catalog-manager:
+ base:
+ endpoint: http://modeling-etsicatalog.onap:8806/api
+so-etsi-nfvo-ns-lcm:
+ endpoint: http://so-etsi-nfvo-ns-lcm.onap:9095 \ No newline at end of file
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 734d4e071e..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
@@ -8,4 +8,99 @@
</parent>
<artifactId>so-etsi-nfvo-ns-lcm-bpmn-flows</artifactId>
<name>SO ETSI NFVO NS LCM BPMN Flows</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemPropertyVariables>
+ <so.log.level>DEBUG</so.log.level>
+ </systemPropertyVariables>
+ <rerunFailingTestsCount>2</rerunFailingTestsCount>
+ <parallel>suites</parallel>
+ <useUnlimitedThreads>false</useUnlimitedThreads>
+ <threadCount>1</threadCount>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.so.etsi.nfvo</groupId>
+ <artifactId>so-etsi-nfvo-ns-lcm-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.so.etsi.nfvo</groupId>
+ <artifactId>so-etsi-nfvo-ns-lcm-database-service</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.so.adapters</groupId>
+ <artifactId>etsi-sol003-pkgm-ext-clients</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.so.adapters</groupId>
+ <artifactId>etsi-sol003-lcm-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.so</groupId>
+ <artifactId>aai-client</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.camunda.bpm.springboot</groupId>
+ <artifactId>camunda-bpm-spring-boot-starter-rest</artifactId>
+ <version>${camunda.springboot.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.camunda.bpmn</groupId>
+ <artifactId>camunda-engine-rest-core</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.yaml</groupId>
+ <artifactId>snakeyaml</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.shazam</groupId>
+ <artifactId>shazamcrest</artifactId>
+ <version>${snakeyaml-version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.vaadin.external.google</groupId>
+ <artifactId>android-json</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest</artifactId>
+ <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/CamundaCustomConfiguration.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/CamundaCustomConfiguration.java
new file mode 100644
index 0000000000..33923f400e
--- /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/CamundaCustomConfiguration.java
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.NS_WORKFLOW_ENGINE;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.TENANT_ID;
+import static org.slf4j.LoggerFactory.getLogger;
+import org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration;
+import org.camunda.bpm.spring.boot.starter.configuration.Ordering;
+import org.camunda.bpm.spring.boot.starter.configuration.impl.AbstractCamundaConfiguration;
+import org.slf4j.Logger;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+@Order(Ordering.DEFAULT_ORDER + 1)
+public class CamundaCustomConfiguration extends AbstractCamundaConfiguration {
+ private static final Logger logger = getLogger(CamundaCustomConfiguration.class);
+
+ @Override
+ public void preInit(final SpringProcessEngineConfiguration processEngineConfiguration) {
+ logger.info("Setting DeploymentTenantId to {} and DeploymentName to {}", TENANT_ID, NS_WORKFLOW_ENGINE);
+ processEngineConfiguration.setDeploymentTenantId(TENANT_ID);
+ processEngineConfiguration.setDeploymentName(NS_WORKFLOW_ENGINE);
+ super.preInit(processEngineConfiguration);
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaDatabaseConfiguration.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaDatabaseConfiguration.java
new file mode 100644
index 0000000000..946bd38cbe
--- /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/CamundaDatabaseConfiguration.java
@@ -0,0 +1,69 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows;
+
+
+import static org.slf4j.LoggerFactory.getLogger;
+import javax.sql.DataSource;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.Profile;
+import org.springframework.jmx.export.MBeanExporter;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Configuration
+@EnableTransactionManagement
+@Profile({"!test"})
+public class CamundaDatabaseConfiguration {
+
+ private static final Logger logger = getLogger(CamundaDatabaseConfiguration.class);
+
+ @Autowired(required = false)
+ private MBeanExporter mBeanExporter;
+
+ @Bean
+ @ConfigurationProperties(prefix = "spring.datasource.hikari.camunda")
+ public HikariConfig camundaDbConfig() {
+ logger.debug("Creating HikariConfig bean ... ");
+ return new HikariConfig();
+ }
+
+ @Primary
+ @Bean(name = "dataSource")
+ public DataSource dataSource() {
+ if (mBeanExporter != null) {
+ mBeanExporter.addExcludedBean("dataSource");
+ }
+ logger.debug("Creating HikariDataSource bean ... ");
+ final HikariConfig hikariConfig = this.camundaDbConfig();
+ return new HikariDataSource(hikariConfig);
+ }
+
+}
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/CamundaVariableNameConstants.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/CamundaVariableNameConstants.java
new file mode 100644
index 0000000000..e90391d51a
--- /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/CamundaVariableNameConstants.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class CamundaVariableNameConstants {
+
+ public static final String JOB_ID_PARAM_NAME = "jobId";
+ public static final String JOB_BUSINESS_KEY_PARAM_NAME = "jobBusinessKey";
+ public static final String CREATE_NS_REQUEST_PARAM_NAME = "createNsRequest";
+ public static final String GLOBAL_CUSTOMER_ID_PARAM_NAME = "globalCustomerId";
+ public static final String SERVICE_TYPE_PARAM_NAME = "serviceType";
+
+
+ public static final String NS_PACKAGE_MODEL_PARAM_NAME = "NSPackageModel";
+ public static final String CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME =
+ "CreateNsWorkflowProcessingException";
+ public static final String CREATE_NS_RESPONSE_PARAM_NAME = "createNsResponse";
+
+ public static final String INSTANTIATE_NS_REQUEST_PARAM_NAME = "instantiateNsRequest";
+ public static final String OCC_ID_PARAM_NAME = "occId";
+ public static final String NS_INSTANCE_ID_PARAM_NAME = "NsInstanceId";
+ public static final String NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME = "NetworkServiceDescriptor";
+ public static final String VNF_CREATE_INSTANTIATE_REQUESTS = "vnfCreateInstantiateRequests";
+
+ public static final String NF_INST_ID_PARAM_NAME = "NF_INST_ID";
+ public static final String CREATE_VNF_RESPONSE_PARAM_NAME = "createVnfResponse";
+ public static final String OPERATION_STATUS_PARAM_NAME = "operationStatus";
+
+ private CamundaVariableNameConstants() {}
+
+}
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/Constants.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/Constants.java
new file mode 100644
index 0000000000..a2128fc2af
--- /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/Constants.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class Constants {
+
+ public static final String TENANT_ID = "ns-workflow-engine-tenant";
+ public static final String NS_WORKFLOW_ENGINE = "NS-WORKFLOW-ENGINE";
+ public static final String CREATE_NS_WORKFLOW_NAME = "CreateNs";
+ public static final String INSTANTIATE_NS_WORKFLOW_NAME = "InstantiateNs";
+ public static final String GET_NS_OCCURRENCE_OPERATION_STATUS_NAME = "GetNsOccurrenceOperationStatus";
+
+
+ private Constants() {}
+
+}
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/GsonProvider.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/GsonProvider.java
new file mode 100644
index 0000000000..31961d5b86
--- /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/GsonProvider.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows;
+
+import java.time.LocalDateTime;
+import org.onap.so.etsi.nfvo.ns.lcm.JSON;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.utils.LocalDateTimeTypeAdapter;
+import org.springframework.stereotype.Component;
+import org.threeten.bp.OffsetDateTime;
+import com.google.gson.Gson;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+public class GsonProvider {
+
+ private final JSON.OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new JSON.OffsetDateTimeTypeAdapter();
+
+ public Gson getGson() {
+ return JSON.createGson().registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter)
+ .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()).create();
+ }
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/EtsiCatalogManagerRequestFailureException.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/EtsiCatalogManagerRequestFailureException.java
new file mode 100644
index 0000000000..553d2f1cf8
--- /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/exceptions/EtsiCatalogManagerRequestFailureException.java
@@ -0,0 +1,41 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
+public class EtsiCatalogManagerRequestFailureException extends RuntimeException {
+
+ private static final long serialVersionUID = 66862444537194516L;
+
+ public EtsiCatalogManagerRequestFailureException(final String message) {
+ super(message);
+ }
+
+ public EtsiCatalogManagerRequestFailureException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/NsRequestProcessingException.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/NsRequestProcessingException.java
new file mode 100644
index 0000000000..0dcadfd4d8
--- /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/exceptions/NsRequestProcessingException.java
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions;
+
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ */
+@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
+public class NsRequestProcessingException extends RuntimeException {
+
+ private static final long serialVersionUID = 66862444537194516L;
+ private InlineResponse400 problemDetails;
+
+ public NsRequestProcessingException(final String message) {
+ super(message);
+ }
+
+ public NsRequestProcessingException(final String message, final InlineResponse400 problemDetails) {
+ super(message);
+ this.problemDetails = problemDetails;
+ }
+
+ @Override
+ public synchronized Throwable fillInStackTrace() {
+ return this;
+ }
+
+ public InlineResponse400 getProblemDetails() {
+ return problemDetails;
+ }
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java
new file mode 100644
index 0000000000..673662aae8
--- /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/extclients/aai/AaiClientProvider.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai;
+
+import org.onap.aaiclient.client.aai.AAIResourcesClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AaiClientProvider {
+
+ @Bean
+ public AAIResourcesClient getAaiClient() {
+ return new AAIResourcesClient();
+ }
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java
new file mode 100644
index 0000000000..3df3580907
--- /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/extclients/aai/AaiPropertiesImpl.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai;
+
+import org.onap.aaiclient.client.aai.AAIProperties;
+import org.onap.aaiclient.client.aai.AAIVersion;
+import org.onap.so.spring.SpringContextHelper;
+import org.springframework.context.ApplicationContext;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public class AaiPropertiesImpl implements AAIProperties {
+
+ private final String endpoint;
+ private final String encryptedBasicAuth;
+ private final String encryptionKey;
+ private final String aaiVersion;
+
+ public AaiPropertiesImpl() {
+
+ final ApplicationContext context = SpringContextHelper.getAppContext();
+ this.endpoint = context.getEnvironment().getProperty("aai.endpoint");
+ this.encryptedBasicAuth = context.getEnvironment().getProperty("aai.auth");
+ this.encryptionKey = context.getEnvironment().getProperty("mso.key");
+ this.aaiVersion = context.getEnvironment().getProperty("aai.version");
+ }
+
+ @Override
+ public URL getEndpoint() throws MalformedURLException {
+ return new URL(endpoint);
+ }
+
+ @Override
+ public String getSystemName() {
+ return "MSO";
+ }
+
+ @Override
+ public AAIVersion getDefaultVersion() {
+ for (final AAIVersion version : AAIVersion.values()) {
+ if (version.toString().equalsIgnoreCase(this.aaiVersion)) {
+ return version;
+ } ;
+
+ }
+ return AAIVersion.LATEST;
+ }
+
+ @Override
+ public String getAuth() {
+ return encryptedBasicAuth;
+ }
+
+ @Override
+ public String getKey() {
+ return encryptionKey;
+ }
+}
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/aai/AaiServiceProvider.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/aai/AaiServiceProvider.java
new file mode 100644
index 0000000000..53062395cf
--- /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/extclients/aai/AaiServiceProvider.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai;
+
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.aai.domain.yang.ServiceInstance;
+import java.util.Optional;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface AaiServiceProvider {
+
+ void createServiceInstance(final String globalCustomerId, final String serviceType,
+ final ServiceInstance aaiServiceInstance);
+
+ void createGenericVnfAndConnectServiceInstance(final String serviceInstanceId, final String vnfId,
+ final GenericVnf genericVnf);
+
+ void connectGenericVnfToTenant(final String vnfId, final String cloudOwner, final String cloudRegion,
+ final String tenantId);
+
+ Optional<GenericVnf> getGenericVnf(final String vnfId);
+
+}
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/aai/AaiServiceProviderImpl.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/aai/AaiServiceProviderImpl.java
new file mode 100644
index 0000000000..049746c6ab
--- /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/extclients/aai/AaiServiceProviderImpl.java
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai;
+
+import java.util.Optional;
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.aai.domain.yang.ServiceInstance;
+import org.onap.aaiclient.client.aai.AAIObjectType;
+import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
+import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ */
+@Service
+public class AaiServiceProviderImpl implements AaiServiceProvider {
+ private static final Logger logger = LoggerFactory.getLogger(AaiServiceProviderImpl.class);
+ private final AaiClientProvider aaiClientProvider;
+
+ @Autowired
+ public AaiServiceProviderImpl(final AaiClientProvider aaiClientProvider) {
+ this.aaiClientProvider = aaiClientProvider;
+ }
+
+ @Override
+ public void createServiceInstance(final String globalCustomerId, final String serviceType,
+ final ServiceInstance aaiServiceInstance) {
+ logger.info("Creating service instance in AAI: {}", aaiServiceInstance);
+ final AAIResourceUri serviceInstanceURI = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE,
+ globalCustomerId, serviceType, aaiServiceInstance.getServiceInstanceId());
+ aaiClientProvider.getAaiClient().createIfNotExists(serviceInstanceURI, Optional.of(aaiServiceInstance));
+
+ }
+
+ @Override
+ public void createGenericVnfAndConnectServiceInstance(final String serviceInstanceId, final String vnfId,
+ final GenericVnf genericVnf) {
+ logger.info("Creating GenericVnf in AAI: {}", genericVnf);
+ final AAIResourceUri genericVnfURI = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId);
+ final AAIResourceUri serviceInstanceURI =
+ AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, serviceInstanceId);
+ aaiClientProvider.getAaiClient().createIfNotExists(genericVnfURI, Optional.of(genericVnf))
+ .connect(genericVnfURI, serviceInstanceURI);
+
+ }
+
+ @Override
+ public void connectGenericVnfToTenant(final String vnfId, final String cloudOwner, final String cloudRegion,
+ final String tenantId) {
+ logger.info("Connecting GenericVnf {} to {}/{}/{} in AAI", vnfId, cloudOwner, cloudRegion, tenantId);
+ final AAIResourceUri tenantURI =
+ AAIUriFactory.createResourceUri(AAIObjectType.TENANT, cloudOwner, cloudRegion, tenantId);
+ final AAIResourceUri genericVnfURI = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId);
+ aaiClientProvider.getAaiClient().connect(tenantURI, genericVnfURI);
+ }
+
+ @Override
+ public Optional<GenericVnf> getGenericVnf(final String vnfId) {
+ return aaiClientProvider.getAaiClient().get(GenericVnf.class,
+ AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId));
+ }
+}
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
new file mode 100644
index 0000000000..65d982c6cc
--- /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/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog;
+
+import java.util.Optional;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface EtsiCatalogPackageManagementServiceProvider {
+
+ Optional<NsdInfo> getNSPackageModel(final String nsdId);
+
+ Optional<VnfPkgInfo> getVnfPkgInfo(final String vnfPkgId);
+
+ Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor(final String nsdId);
+
+}
diff --git a/so-etsi-nfvo/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
new file mode 100644
index 0000000000..75dd7107a7
--- /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/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_SERVICE_PROVIDER_BEAN;
+import java.util.Optional;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.EtsiCatalogManagerRequestFailureException;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptorParser;
+import org.onap.so.rest.service.HttpRestServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class EtsiCatalogPackageManagementServiceProviderImpl implements EtsiCatalogPackageManagementServiceProvider {
+
+ private static final Logger logger = LoggerFactory.getLogger(EtsiCatalogPackageManagementServiceProviderImpl.class);
+
+ private final HttpRestServiceProvider httpServiceProvider;
+ private final EtsiCatalogUrlProvider etsiCatalogUrlProvider;
+ private final NetworkServiceDescriptorParser networkServiceDescriptorParser;
+
+ @Autowired
+ public EtsiCatalogPackageManagementServiceProviderImpl(final EtsiCatalogUrlProvider etsiCatalogUrlProvider,
+ @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider,
+ final NetworkServiceDescriptorParser networkServiceDescriptorParser) {
+ this.etsiCatalogUrlProvider = etsiCatalogUrlProvider;
+ this.httpServiceProvider = httpServiceProvider;
+ this.networkServiceDescriptorParser = networkServiceDescriptorParser;
+ }
+
+ @Override
+ public Optional<NsdInfo> getNSPackageModel(final String nsdId) {
+ try {
+ final ResponseEntity<NsdInfo> response =
+ httpServiceProvider.getHttpResponse(etsiCatalogUrlProvider.getNsPackageUrl(nsdId), NsdInfo.class);
+ if (response.getStatusCode().is2xxSuccessful()) {
+ return Optional.ofNullable(response.getBody());
+ }
+ return Optional.empty();
+ } catch (final Exception restProcessingException) {
+ logger.error("Caught exception while getting NS package model for: {}", nsdId, restProcessingException);
+ throw new EtsiCatalogManagerRequestFailureException("Internal Server Error Occurred.",
+ restProcessingException);
+ }
+ }
+
+ @Override
+ public Optional<VnfPkgInfo> getVnfPkgInfo(final String vnfPkgId) {
+ try {
+ final ResponseEntity<VnfPkgInfo> response = httpServiceProvider
+ .getHttpResponse(etsiCatalogUrlProvider.getVnfPackageUrl(vnfPkgId), VnfPkgInfo.class);
+ if (response.getStatusCode().is2xxSuccessful()) {
+ return Optional.ofNullable(response.getBody());
+ }
+ return Optional.empty();
+ } catch (final Exception restProcessingException) {
+ logger.error("Caught exception while getting VNF package model for: {}", vnfPkgId, restProcessingException);
+ throw new EtsiCatalogManagerRequestFailureException("Internal Server Error Occurred.",
+ restProcessingException);
+ }
+ }
+
+ @Override
+ public Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor(final String nsdId) {
+ try {
+ final ResponseEntity<byte[]> response = httpServiceProvider
+ .getHttpResponse(etsiCatalogUrlProvider.getNsPackageContentUrl(nsdId), byte[].class);
+ if (response.getStatusCode().is2xxSuccessful()) {
+ if (response.hasBody()) {
+ return networkServiceDescriptorParser.parse(response.getBody());
+ }
+ logger.error("Received response without body ...");
+ }
+ return Optional.empty();
+ } catch (final Exception restProcessingException) {
+ 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/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.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/EtsiCatalogServiceProviderConfiguration.java
new file mode 100644
index 0000000000..8c6ea92428
--- /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/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java
@@ -0,0 +1,188 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog;
+
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.Iterator;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.onap.logging.filter.spring.SpringClientPayloadFilter;
+import org.onap.so.configuration.rest.BasicHttpHeadersProvider;
+import org.onap.so.configuration.rest.HttpClientConnectionConfiguration;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider;
+import org.onap.so.logging.jaxrs.filter.SOSpringClientFilter;
+import org.onap.so.rest.service.HttpRestServiceProvider;
+import org.onap.so.rest.service.HttpRestServiceProviderImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.Resource;
+import org.springframework.http.client.BufferingClientHttpRequestFactory;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.GsonHttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * Configures the HttpRestServiceProvider to make REST calls to the ETSI Catalog Manager
+ *
+ * @author gareth.roper@est.tech
+ */
+
+@Configuration
+public class EtsiCatalogServiceProviderConfiguration {
+ public static final String ETSI_CATALOG_REST_TEMPLATE_BEAN = "etsiCatalogRestTemplate";
+
+ public static final String ETSI_CATALOG_SERVICE_PROVIDER_BEAN = "etsiCatalogServiceProvider";
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(EtsiCatalogServiceProviderConfiguration.class);
+
+ private final HttpClientConnectionConfiguration clientConnectionConfiguration;
+
+ @Value("${etsi-catalog-manager.http.client.ssl.trust-store:#{null}}")
+ private Resource trustStore;
+ @Value("${etsi-catalog-manager.http.client.ssl.trust-store-password:#{null}}")
+ private String trustStorePassword;
+
+ private final GsonProvider gsonProvider;
+
+ @Autowired
+ public EtsiCatalogServiceProviderConfiguration(
+ final HttpClientConnectionConfiguration clientConnectionConfiguration, final GsonProvider gsonProvider) {
+ this.clientConnectionConfiguration = clientConnectionConfiguration;
+ this.gsonProvider = gsonProvider;
+ }
+
+ @Bean
+ @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN)
+ public RestTemplate etsiCatalogRestTemplate() {
+ final RestTemplate restTemplate = new RestTemplate();
+ restTemplate.getInterceptors().add(new SOSpringClientFilter());
+ restTemplate.getInterceptors().add((new SpringClientPayloadFilter()));
+ return restTemplate;
+ }
+
+ @Bean
+ @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN)
+ public HttpRestServiceProvider etsiCatalogHttpRestServiceProvider(
+ @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) final RestTemplate restTemplate) {
+ setGsonMessageConverter(restTemplate);
+
+ final HttpClientBuilder httpClientBuilder = getHttpClientBuilder();
+ if (trustStore != null) {
+ try {
+ LOGGER.debug("Setting up HttpComponentsClientHttpRequestFactory with SSL Context");
+ LOGGER.debug("Setting client trust-store: {}", trustStore.getURL());
+ LOGGER.debug("Creating SSLConnectionSocketFactory with AllowAllHostsVerifier ... ");
+ final SSLContext sslContext = new SSLContextBuilder()
+ .loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()).build();
+ final SSLConnectionSocketFactory sslConnectionSocketFactory =
+ new SSLConnectionSocketFactory(sslContext, AllowAllHostsVerifier.INSTANCE);
+ httpClientBuilder.setSSLSocketFactory(sslConnectionSocketFactory);
+ final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
+ .<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE)
+ .register("https", sslConnectionSocketFactory).build();
+
+ httpClientBuilder.setConnectionManager(getConnectionManager(socketFactoryRegistry));
+ } catch (final KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException
+ | IOException exception) {
+ LOGGER.error("Error reading truststore, TLS connection will fail.", exception);
+ }
+
+ } else {
+ LOGGER.debug("Setting connection manager without SSL ConnectionSocketFactory ...");
+ httpClientBuilder.setConnectionManager(getConnectionManager());
+ }
+
+ final HttpComponentsClientHttpRequestFactory factory =
+ new HttpComponentsClientHttpRequestFactory(httpClientBuilder.build());
+ restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory));
+
+ return new HttpRestServiceProviderImpl(restTemplate, new BasicHttpHeadersProvider().getHttpHeaders());
+ }
+
+ private PoolingHttpClientConnectionManager getConnectionManager(
+ final Registry<ConnectionSocketFactory> socketFactoryRegistry) {
+ return new PoolingHttpClientConnectionManager(socketFactoryRegistry, null, null, null,
+ clientConnectionConfiguration.getTimeToLiveInMins(), TimeUnit.MINUTES);
+ }
+
+ private PoolingHttpClientConnectionManager getConnectionManager() {
+ return new PoolingHttpClientConnectionManager(clientConnectionConfiguration.getTimeToLiveInMins(),
+ TimeUnit.MINUTES);
+ }
+
+ private HttpClientBuilder getHttpClientBuilder() {
+ return HttpClientBuilder.create().setMaxConnPerRoute(clientConnectionConfiguration.getMaxConnectionsPerRoute())
+ .setMaxConnTotal(clientConnectionConfiguration.getMaxConnections())
+ .setDefaultRequestConfig(getRequestConfig());
+ }
+
+ private RequestConfig getRequestConfig() {
+ return RequestConfig.custom().setSocketTimeout(clientConnectionConfiguration.getSocketTimeOutInMiliSeconds())
+ .setConnectTimeout(clientConnectionConfiguration.getConnectionTimeOutInMilliSeconds()).build();
+ }
+
+ private static final class AllowAllHostsVerifier implements HostnameVerifier {
+
+ private static final AllowAllHostsVerifier INSTANCE = new AllowAllHostsVerifier();
+
+ @Override
+ public boolean verify(final String hostname, final SSLSession session) {
+ LOGGER.debug("Skipping hostname verification ...");
+ return true;
+ }
+
+ }
+
+ public void setGsonMessageConverter(final RestTemplate restTemplate) {
+ final Iterator<HttpMessageConverter<?>> iterator = restTemplate.getMessageConverters().iterator();
+ while (iterator.hasNext()) {
+ if (iterator.next() instanceof MappingJackson2HttpMessageConverter) {
+ iterator.remove();
+ }
+ }
+ restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gsonProvider.getGson()));
+ }
+
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogUrlProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogUrlProvider.java
new file mode 100644
index 0000000000..e3c159c7b0
--- /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/extclients/etsicatalog/EtsiCatalogUrlProvider.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class EtsiCatalogUrlProvider {
+
+ @Value("${etsi-catalog-manager.base.endpoint}")
+ private String etsiCatalogManagerEndpoint;
+
+ public EtsiCatalogUrlProvider() {}
+
+ public String getNsPackageUrl(final String nsdId) {
+ return etsiCatalogManagerEndpoint + "/nsd/v1/ns_descriptors/" + nsdId;
+ }
+
+ public String getNsPackageContentUrl(final String nsdId) {
+ return etsiCatalogManagerEndpoint + "/nsd/v1/ns_descriptors/" + nsdId + "/nsd_content";
+ }
+
+ public String getVnfPackageUrl(final String vnfPkgId) {
+ return etsiCatalogManagerEndpoint + "/vnfpkgm/v1/vnf_packages/" + vnfPkgId;
+ }
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterConfiguration.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterConfiguration.java
new file mode 100644
index 0000000000..fe710ec00b
--- /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/extclients/vnfm/Sol003AdapterConfiguration.java
@@ -0,0 +1,148 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm;
+
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.Iterator;
+import javax.net.ssl.SSLContext;
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.onap.logging.filter.spring.SpringClientPayloadFilter;
+import org.onap.so.configuration.rest.BasicHttpHeadersProvider;
+import org.onap.so.configuration.rest.HttpComponentsClientConfiguration;
+import org.onap.so.configuration.rest.HttpHeadersProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider;
+import org.onap.so.logging.jaxrs.filter.SOSpringClientFilter;
+import org.onap.so.rest.service.HttpRestServiceProvider;
+import org.onap.so.rest.service.HttpRestServiceProviderImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.Resource;
+import org.springframework.http.client.BufferingClientHttpRequestFactory;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.GsonHttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Configuration
+public class Sol003AdapterConfiguration {
+
+ private static final Logger logger = LoggerFactory.getLogger(Sol003AdapterConfiguration.class);
+
+ public static final String SOL003_ADAPTER_REST_TEMPLATE_BEAN = "Sol003AdapterRestTemplateBean";
+ public static final String SOL003_ADAPTER_HTTP_REST_SERVICE_PROVIDER_BEAN =
+ "Sol003AdapterHttpRestServiceProviderBean";
+
+ @Value("${rest.http.client.configuration.ssl.trustStore:#{null}}")
+ private Resource trustStore;
+
+ @Value("${rest.http.client.configuration.ssl.trustStorePassword:#{null}}")
+ private String trustStorePassword;
+
+ @Value("so.adapters.sol003-adapter.auth:Basic dm5mbTpwYXNzd29yZDEk")
+ private String sol003AdapterBasicAuth;
+
+ @Autowired
+ private GsonProvider gsonProvider;
+
+ @Autowired
+ private HttpComponentsClientConfiguration httpComponentsClientConfiguration;
+
+ @Bean
+ @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN)
+ public RestTemplate sol003AdapterRestTemplate() {
+ final HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =
+ httpComponentsClientConfiguration.httpComponentsClientHttpRequestFactory();
+ final RestTemplate restTemplate =
+ new RestTemplate(new BufferingClientHttpRequestFactory(clientHttpRequestFactory));
+ restTemplate.getInterceptors().add(new SOSpringClientFilter());
+ restTemplate.getInterceptors().add((new SpringClientPayloadFilter()));
+ return restTemplate;
+
+ }
+
+ @Bean
+ @Qualifier(SOL003_ADAPTER_HTTP_REST_SERVICE_PROVIDER_BEAN)
+ public HttpRestServiceProvider sol003AdapaterHttpRestServiceProvider(
+ @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN) @Autowired final RestTemplate restTemplate) {
+
+ if (trustStore != null) {
+ setTrustStore(restTemplate);
+ }
+ setGsonMessageConverter(restTemplate);
+ return getHttpRestServiceProvider(restTemplate, new BasicHttpHeadersProvider(sol003AdapterBasicAuth));
+ }
+
+ private void setTrustStore(final RestTemplate restTemplate) {
+ try {
+ final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(getSSLContext());
+ final HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
+ final HttpComponentsClientHttpRequestFactory factory =
+ new HttpComponentsClientHttpRequestFactory(httpClient);
+ restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory));
+ } catch (Exception exception) {
+ logger.error("Error reading truststore, TLS connection to VNFM will fail.", exception);
+ }
+ }
+
+ private SSLContext getSSLContext() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException,
+ CertificateException, IOException {
+ if (trustStore != null) {
+ logger.info("Setting truststore: {}", trustStore.getURL());
+ return new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray())
+ .build();
+ }
+ logger.info("Setting Default SSL ...");
+ return SSLContext.getDefault();
+
+ }
+
+ private HttpRestServiceProvider getHttpRestServiceProvider(final RestTemplate restTemplate,
+ final HttpHeadersProvider httpHeadersProvider) {
+ return new HttpRestServiceProviderImpl(restTemplate, httpHeadersProvider.getHttpHeaders());
+ }
+
+ private void setGsonMessageConverter(final RestTemplate restTemplate) {
+ final Iterator<HttpMessageConverter<?>> iterator = restTemplate.getMessageConverters().iterator();
+ while (iterator.hasNext()) {
+ if (iterator.next() instanceof MappingJackson2HttpMessageConverter) {
+ iterator.remove();
+ }
+ }
+ restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gsonProvider.getGson()));
+ }
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProvider.java
new file mode 100644
index 0000000000..c053ba94f1
--- /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/extclients/vnfm/Sol003AdapterServiceProvider.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm;
+
+import java.util.Optional;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfRequest;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse;
+
+public interface Sol003AdapterServiceProvider {
+
+ Optional<CreateVnfResponse> invokeCreateInstantiationRequest(final String vnfId, final CreateVnfRequest request);
+
+ Optional<QueryJobResponse> getInstantiateOperationJobStatus(final String jobId);
+
+}
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/vnfm/Sol003AdapterServiceProviderImpl.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/vnfm/Sol003AdapterServiceProviderImpl.java
new file mode 100644
index 0000000000..09fecc64ae
--- /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/extclients/vnfm/Sol003AdapterServiceProviderImpl.java
@@ -0,0 +1,117 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterConfiguration.SOL003_ADAPTER_HTTP_REST_SERVICE_PROVIDER_BEAN;
+import java.util.Optional;
+import org.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.QueryJobResponse;
+import org.onap.so.rest.exceptions.HttpResouceNotFoundException;
+import org.onap.so.rest.exceptions.InvalidRestRequestException;
+import org.onap.so.rest.exceptions.RestProcessingException;
+import org.onap.so.rest.service.HttpRestServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+@Service
+public class Sol003AdapterServiceProviderImpl implements Sol003AdapterServiceProvider {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(Sol003AdapterServiceProviderImpl.class);
+ public static final String RECEIVED_RESPONSE_WITHOUT_BODY = "Received response without body: {}";
+
+ private final Sol003AdapterUrlProvider urlProvider;
+ private final HttpRestServiceProvider httpServiceProvider;
+
+ @Autowired
+ public Sol003AdapterServiceProviderImpl(final Sol003AdapterUrlProvider urlProvider,
+ @Qualifier(SOL003_ADAPTER_HTTP_REST_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider) {
+ this.urlProvider = urlProvider;
+ this.httpServiceProvider = httpServiceProvider;
+ }
+
+ @Override
+ public Optional<CreateVnfResponse> invokeCreateInstantiationRequest(final String vnfId,
+ final CreateVnfRequest request) {
+ try {
+ final String url = urlProvider.getCreateInstantiateUrl(vnfId);
+
+ final ResponseEntity<CreateVnfResponse> response =
+ httpServiceProvider.postHttpRequest(request, url, CreateVnfResponse.class);
+
+ final HttpStatus httpStatus = response.getStatusCode();
+ if (!(httpStatus.equals(HttpStatus.ACCEPTED)) && !(httpStatus.equals(HttpStatus.OK))) {
+ LOGGER.error("Unable to invoke HTTP POST using URL: {}, Response Code: {}", url, httpStatus.value());
+ return Optional.empty();
+ }
+
+ if (!response.hasBody()) {
+ LOGGER.error(RECEIVED_RESPONSE_WITHOUT_BODY, response);
+ return Optional.empty();
+ }
+
+ final CreateVnfResponse createVnfResponse = response.getBody();
+
+ if (createVnfResponse.getJobId() == null || createVnfResponse.getJobId().isEmpty()) {
+ LOGGER.error("Received invalid instantiation response: {}", response);
+ return Optional.empty();
+ }
+
+ return Optional.of(createVnfResponse);
+ } catch (final RestProcessingException | InvalidRestRequestException
+ | HttpResouceNotFoundException httpInvocationException) {
+ LOGGER.error("Unexpected error while processing create and instantiation request", httpInvocationException);
+ return Optional.empty();
+ }
+
+ }
+
+ @Override
+ public Optional<QueryJobResponse> getInstantiateOperationJobStatus(final String jobId) {
+ try {
+ final String url = urlProvider.getJobStatusUrl(jobId);
+
+ final ResponseEntity<QueryJobResponse> response =
+ httpServiceProvider.getHttpResponse(url, QueryJobResponse.class);
+
+ final HttpStatus httpStatus = response.getStatusCode();
+
+ if (!(httpStatus.equals(HttpStatus.ACCEPTED)) && !(httpStatus.equals(HttpStatus.OK))) {
+ LOGGER.error("Unable to invoke HTTP GET using URL: {}, Response Code: ", url, httpStatus.value());
+ return Optional.empty();
+ }
+
+ if (!response.hasBody()) {
+ LOGGER.error(RECEIVED_RESPONSE_WITHOUT_BODY, response);
+ return Optional.empty();
+ }
+ return Optional.of(response.getBody());
+ } catch (final RestProcessingException | InvalidRestRequestException | HttpResouceNotFoundException exception) {
+ LOGGER.error("Unexpected error while processing job request", exception);
+ throw exception;
+ }
+ }
+}
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/vnfm/Sol003AdapterUrlProvider.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/vnfm/Sol003AdapterUrlProvider.java
new file mode 100644
index 0000000000..351d4bf88c
--- /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/extclients/vnfm/Sol003AdapterUrlProvider.java
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm;
+
+import java.net.URI;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.util.UriComponentsBuilder;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class Sol003AdapterUrlProvider {
+
+ private final URI baseUri;
+
+ @Autowired
+ public Sol003AdapterUrlProvider(
+ @Value("${so.adapters.sol003-adapter.url:https://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1/}") final String sol003AdapterUrl) {
+ this.baseUri = UriComponentsBuilder.fromHttpUrl(sol003AdapterUrl).build().toUri();
+ }
+
+ /**
+ * Get VNFM create and instantiate URL
+ *
+ * @param vnfId The identifier of the VNF. This must be the vnf-id of an existing generic-vnf in AAI.
+ * @return VNFM create and instantiate URL
+ */
+ public String getCreateInstantiateUrl(final String vnfId) {
+ return UriComponentsBuilder.fromUri(baseUri).pathSegment("vnfs").pathSegment(vnfId).build().toString();
+ }
+
+ /**
+ * Get job status URL
+ *
+ * @param jobId The instantiation job identifier
+ * @return job status URL
+ */
+ public String getJobStatusUrl(final String jobId) {
+ return UriComponentsBuilder.fromUri(baseUri).pathSegment("jobs").pathSegment(jobId).build().toString();
+ }
+
+}
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/nsd/FileEntry.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/nsd/FileEntry.java
new file mode 100644
index 0000000000..58ca2507bd
--- /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/nsd/FileEntry.java
@@ -0,0 +1,111 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Objects;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class FileEntry {
+
+ private boolean isDirectory;
+ private String filePath;
+ private byte[] fileContent;
+
+ public boolean isDirectory() {
+ return isDirectory;
+ }
+
+ public void setDirectory(final boolean isDirectory) {
+ this.isDirectory = isDirectory;
+ }
+
+ public FileEntry isDirectory(final boolean isDirectory) {
+ this.isDirectory = isDirectory;
+ return this;
+ }
+
+ public String getFilePath() {
+ return filePath;
+ }
+
+ public void setFilename(final String filePath) {
+ this.filePath = filePath;
+ }
+
+ public FileEntry filePath(final String filePath) {
+ this.filePath = filePath;
+ return this;
+ }
+
+ public byte[] getFileContent() {
+ return fileContent;
+ }
+
+ public void setFileContent(final byte[] fileContent) {
+ this.fileContent = fileContent;
+ }
+
+ public FileEntry fileContent(final byte[] fileContent) {
+ this.fileContent = fileContent;
+ return this;
+ }
+
+ public InputStream getFileContentAsStream() {
+ if (fileContent == null || fileContent.length == 0) {
+ return null;
+ }
+ return new ByteArrayInputStream(fileContent);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(isDirectory, filePath, fileContent);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof FileEntry) {
+ final FileEntry other = (FileEntry) obj;
+ return Objects.equals(isDirectory, other.isDirectory) && Objects.equals(filePath, other.filePath)
+ && Objects.equals(fileContent, other.fileContent);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class FileEntry {\n");
+ sb.append(" isDirectory: ").append(toIndentedString(isDirectory)).append("\n");
+ sb.append(" filePath: ").append(toIndentedString(filePath)).append("\n");
+ sb.append(" fileContent size: ").append(toIndentedString(fileContent != null ? fileContent.length : 0))
+ .append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileParser.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/nsd/FileParser.java
new file mode 100644
index 0000000000..9df5262302
--- /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/nsd/FileParser.java
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import java.util.Map;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface FileParser {
+
+ Map<String, Object> getFileContent(final FileEntry entryDefinitionFileEntry);
+
+}
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/nsd/NetworkServiceDescriptor.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/nsd/NetworkServiceDescriptor.java
new file mode 100644
index 0000000000..6b4fee7151
--- /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/nsd/NetworkServiceDescriptor.java
@@ -0,0 +1,121 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class NetworkServiceDescriptor implements Serializable {
+
+ private static final long serialVersionUID = -1739293595041180242L;
+
+ private String type;
+
+ private Map<String, Object> properties = new HashMap<>();
+
+ private List<VirtualNetworkFunction> vnfs = new ArrayList<>();
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ public NetworkServiceDescriptor type(final String type) {
+ this.type = type;
+ return this;
+ }
+
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(final Map<String, Object> properties) {
+ this.properties = properties;
+ }
+
+ public NetworkServiceDescriptor properties(final Map<String, Object> properties) {
+ this.properties = properties;
+ return this;
+ }
+
+ public List<VirtualNetworkFunction> getVnfs() {
+ return vnfs;
+ }
+
+ public void setVnfs(final List<VirtualNetworkFunction> vnfs) {
+ if (vnfs != null) {
+ this.vnfs = vnfs;
+ } else {
+ this.vnfs = new ArrayList<>();
+ }
+ }
+
+ public NetworkServiceDescriptor addVnfPkgIdsItem(final VirtualNetworkFunction vnf) {
+ if (this.vnfs == null) {
+ this.vnfs = new ArrayList<>();
+ }
+ this.vnfs.add(vnf);
+ return this;
+ }
+
+ public NetworkServiceDescriptor vnfs(final List<VirtualNetworkFunction> vnfs) {
+ this.vnfs = vnfs;
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, properties, vnfs);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof NetworkServiceDescriptor) {
+ final NetworkServiceDescriptor other = (NetworkServiceDescriptor) obj;
+ return Objects.equals(type, other.type) && Objects.equals(properties, other.properties)
+ && Objects.equals(vnfs, other.vnfs);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class NetworkServiceDescriptor {\n");
+ sb.append(" type: ").append(toIndentedString(type)).append("\n");
+ sb.append(" properties: ").append(toIndentedString(properties)).append("\n");
+ sb.append(" vnfs: ").append(toIndentedString(vnfs)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParser.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/nsd/NetworkServiceDescriptorParser.java
new file mode 100644
index 0000000000..33737f4c17
--- /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/nsd/NetworkServiceDescriptorParser.java
@@ -0,0 +1,209 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class NetworkServiceDescriptorParser {
+ public static final String NS_NODE_TYPE = "tosca.nodes.nfv.NS";
+ private static final String NODE_TYPE = "node_type";
+ private static final String SUBSTITUTION_MAPPINGS = "substitution_mappings";
+ private static final Logger logger = LoggerFactory.getLogger(NetworkServiceDescriptorParser.class);
+ private static final String VNF_TYPE = "tosca.nodes.nfv.VNF";
+ private static final String PROPERTIES = "properties";
+ private static final String TYPE = "type";
+ private static final String NODE_TEMPLATES = "node_templates";
+ private static final String TOPOLOGY_TEMPLATE = "topology_template";
+ private static final String ENTRY_DEFINITIONS = "Entry-Definitions";
+ private static final String TOSCA_META_PATH_FILE_NAME = "TOSCA-Metadata/TOSCA.meta";
+ private final ToscaMetadataParser toscaMetadataParser;
+ private final FileParser fileParser;
+
+ @Autowired
+ public NetworkServiceDescriptorParser(final ToscaMetadataParser toscaMetadataParser, final FileParser fileParser) {
+ this.toscaMetadataParser = toscaMetadataParser;
+ this.fileParser = fileParser;
+ }
+
+ public Optional<NetworkServiceDescriptor> parse(final byte[] zipBytes) {
+ try {
+ final Map<String, FileEntry> files = getZipContent(zipBytes);
+ if (isMetaFilePresent(files)) {
+ final Optional<ToscaMetadata> optional =
+ toscaMetadataParser.parse(files.get(TOSCA_META_PATH_FILE_NAME));
+ if (optional.isPresent()) {
+ final ToscaMetadata toscaMetadata = optional.get();
+ logger.info("Parsed ToscaMetadata {}", toscaMetadata);
+ final String entryDefinitionFile = toscaMetadata.getEntry(ENTRY_DEFINITIONS);
+ if (entryDefinitionFile != null && files.containsKey(entryDefinitionFile)) {
+ final Map<String, Object> fileContent =
+ fileParser.getFileContent(files.get(entryDefinitionFile));
+ final Map<String, Object> topologyTemplates = getTopologyTemplates(fileContent);
+ final Map<String, Object> nodeTemplates = getNodeTemplates(topologyTemplates);
+
+ final Optional<NetworkServiceDescriptor> nsdOptional =
+ getNetworkServiceDescriptor(topologyTemplates);;
+ if (nsdOptional.isPresent()) {
+ final NetworkServiceDescriptor networkServiceDescriptor = nsdOptional.get();
+ networkServiceDescriptor.setVnfs(getVirtualNetworkFunctions(nodeTemplates));
+ return Optional.of(networkServiceDescriptor);
+ }
+
+ }
+ }
+
+ }
+
+ } catch (final Exception exception) {
+ logger.error("Unable to parser nsd zip content", exception);
+ }
+ logger.error("Unable to parser nsd zip content");
+ return Optional.empty();
+ }
+
+ @SuppressWarnings("unchecked")
+ private Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor(
+ final Map<String, Object> topologyTemplates) {
+ final Map<String, Object> substitutionMappings =
+ (Map<String, Object>) topologyTemplates.get(SUBSTITUTION_MAPPINGS);
+ final Object nodeType = substitutionMappings.get(NODE_TYPE);
+ if (substitutionMappings != null && nodeType != null && NS_NODE_TYPE.equals(nodeType)) {
+ final NetworkServiceDescriptor networkServiceDescriptor = new NetworkServiceDescriptor();
+ networkServiceDescriptor.setType(nodeType.toString());
+ networkServiceDescriptor.setProperties((Map<String, Object>) substitutionMappings.get(PROPERTIES));
+ return Optional.of(networkServiceDescriptor);
+ }
+ logger.error("No {} found in fileContent: {}", SUBSTITUTION_MAPPINGS, topologyTemplates);
+
+ return Optional.empty();
+ }
+
+ private List<VirtualNetworkFunction> getVirtualNetworkFunctions(final Map<String, Object> nodeTemplates) {
+ final List<VirtualNetworkFunction> vnfs = new ArrayList<>();
+ for (final Entry<String, Object> entry : nodeTemplates.entrySet()) {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> entryValue = (Map<String, Object>) entry.getValue();
+ final Object type = entryValue.get(TYPE);
+ if (type != null && type.equals(VNF_TYPE)) {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> vnfProperties = (Map<String, Object>) entryValue.get(PROPERTIES);
+ final VirtualNetworkFunction vnf = new VirtualNetworkFunction();
+ vnf.setVnfName(entry.getKey());
+
+ if (vnfProperties != null && !vnfProperties.isEmpty()) {
+ final Object vnfDescriptorId = vnfProperties.get("descriptor_id");
+ @SuppressWarnings("unchecked")
+ final List<String> vnfmInfoList = (List<String>) vnfProperties.get("vnfm_info");
+ if (vnfDescriptorId != null && vnfmInfoList != null) {
+ vnf.setVnfmInfoList(vnfmInfoList);
+ vnf.setVnfdId(vnfDescriptorId.toString());
+ vnf.setProperties(vnfProperties);
+ vnfs.add(vnf);
+ } else {
+ logger.warn("descriptor_id missing {}", entryValue);
+ }
+ }
+ }
+
+ }
+ return vnfs;
+ }
+
+ private Map<String, Object> getNodeTemplates(final Map<String, Object> topologyTemplates) {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> nodeTemplates = (Map<String, Object>) topologyTemplates.get(NODE_TEMPLATES);
+ if (nodeTemplates != null) {
+ logger.debug("Found nodeTemplates: {}", topologyTemplates);
+ return nodeTemplates;
+ }
+ logger.error("No {} found in fileContent: {}", NODE_TEMPLATES, topologyTemplates);
+ return Collections.emptyMap();
+ }
+
+ private Map<String, Object> getTopologyTemplates(final Map<String, Object> fileContent) {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> topologyTemplates = (Map<String, Object>) fileContent.get(TOPOLOGY_TEMPLATE);
+ if (topologyTemplates != null) {
+ logger.debug("Found {}: {}", TOPOLOGY_TEMPLATE, topologyTemplates);
+
+ return topologyTemplates;
+ }
+ logger.error("No {} found in fileContent: {}", TOPOLOGY_TEMPLATE, fileContent);
+ return Collections.emptyMap();
+ }
+
+ private boolean isMetaFilePresent(final Map<String, FileEntry> files) {
+ return files.containsKey(TOSCA_META_PATH_FILE_NAME);
+ }
+
+ private Map<String, FileEntry> getZipContent(final byte[] zipBytes) {
+ final Map<String, FileEntry> files = new HashMap<>();
+ try (final ZipInputStream inputZipStream = new ZipInputStream(new ByteArrayInputStream(zipBytes));) {
+ ZipEntry zipEntry;
+ while ((zipEntry = inputZipStream.getNextEntry()) != null) {
+ logger.info("{} : {}", zipEntry.getName(), zipEntry.isDirectory());
+ if (files.get(zipEntry.getName()) != null) {
+ logger.warn("{} File entry already exists ...", zipEntry.getName());
+ } else {
+ final FileEntry fileEntry = new FileEntry().filePath(zipEntry.getName())
+ .fileContent(getBytes(inputZipStream)).isDirectory(zipEntry.isDirectory());
+ files.put(zipEntry.getName(), fileEntry);
+
+ }
+
+ }
+ return files;
+ } catch (final Exception exception) {
+ logger.error("Unable to parser nsd zip content", exception);
+ return Collections.emptyMap();
+ }
+ }
+
+ private byte[] getBytes(final ZipInputStream inputZipStream) throws IOException {
+ try {
+ return IOUtils.toByteArray(inputZipStream);
+ } catch (final IOException exception) {
+ logger.error("Could not read bytes from file", exception);
+ throw exception;
+ }
+ }
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java
new file mode 100644
index 0000000000..c07a55c459
--- /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/nsd/ToscaMetadata.java
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class ToscaMetadata {
+
+ private Map<String, String> entries = new HashMap<>();
+
+ public Map<String, String> getEntries() {
+ return entries;
+ }
+
+ public void addEntry(final String name, final String value) {
+ this.entries.put(name, value);
+ }
+
+ public boolean hasEntry(final String name) {
+ return this.entries.containsKey(name);
+ }
+
+ public String getEntry(final String name) {
+ return this.entries.get(name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(entries);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof ToscaMetadata) {
+ final ToscaMetadata other = (ToscaMetadata) obj;
+ return Objects.equals(entries, other.entries);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class ToscaMetadata {\n");
+ sb.append(" entries: ").append(toIndentedString(entries)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadataParser.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/nsd/ToscaMetadataParser.java
new file mode 100644
index 0000000000..fe23f5ef8d
--- /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/nsd/ToscaMetadataParser.java
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import java.util.List;
+import java.util.Optional;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class ToscaMetadataParser {
+ private static final String ATTRIBUTE_VALUE_SEPARATOR = ":";
+ private static final Logger logger = LoggerFactory.getLogger(ToscaMetadataParser.class);
+
+ public Optional<ToscaMetadata> parse(final FileEntry toscaMetaFile) {
+ try {
+ final ToscaMetadata toscaMetadata = new ToscaMetadata();
+ final List<String> lines = IOUtils.readLines(toscaMetaFile.getFileContentAsStream(), "utf-8");
+ for (final String line : lines) {
+ final String trimmedLine = line.trim();
+ if (!trimmedLine.isEmpty() && trimmedLine.contains(ATTRIBUTE_VALUE_SEPARATOR)) {
+ final String[] entry = trimmedLine.split(ATTRIBUTE_VALUE_SEPARATOR);
+ if (entry.length >= 2 && isNotBlank(entry[0]) && isNotBlank(entry[1])) {
+ toscaMetadata.addEntry(entry[0].trim(), entry[1].trim());
+ } else {
+ logger.warn("Unexpected line in metadata file: {}", line);
+ }
+ } else {
+ logger.warn("Unexpected line does not contain valid separator {} in metadata file: {}",
+ ATTRIBUTE_VALUE_SEPARATOR, line);
+ }
+
+ }
+ return Optional.of(toscaMetadata);
+
+ } catch (final Exception exception) {
+ logger.error("Unable to parser metadata file content", exception);
+ }
+ return Optional.empty();
+ }
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java
new file mode 100644
index 0000000000..f4c3632589
--- /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/nsd/VirtualNetworkFunction.java
@@ -0,0 +1,123 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class VirtualNetworkFunction implements Serializable {
+
+ private static final long serialVersionUID = 3164293220359211834L;
+
+ private String vnfdId;
+ private String vnfName;
+ private List<String> vnfmInfoList;
+ private Map<String, Object> properties = new HashMap<>();
+
+ public String getVnfdId() {
+ return vnfdId;
+ }
+
+ public void setVnfdId(final String vnfdId) {
+ this.vnfdId = vnfdId;
+ }
+
+ public VirtualNetworkFunction vnfdId(final String vnfdId) {
+ this.vnfdId = vnfdId;
+ return this;
+ }
+
+ public String getVnfName() {
+ return vnfName;
+ }
+
+ public void setVnfName(final String vnfName) {
+ this.vnfName = vnfName;
+ }
+
+ public VirtualNetworkFunction vnfName(final String vnfName) {
+ this.vnfName = vnfName;
+ return this;
+ }
+
+ public List<String> getVnfmInfoList() {
+ return vnfmInfoList;
+ }
+
+ public void setVnfmInfoList(final List<String> vnfmInfoList) {
+ this.vnfmInfoList = vnfmInfoList;
+ }
+
+ public VirtualNetworkFunction vnfmInfoList(final List<String> vnfmInfoList) {
+ this.vnfmInfoList = vnfmInfoList;
+ return this;
+ }
+
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(final Map<String, Object> properties) {
+ this.properties = properties;
+ }
+
+ public VirtualNetworkFunction properties(final Map<String, Object> properties) {
+ this.properties = properties;
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(vnfdId, vnfName, vnfmInfoList, properties);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof VirtualNetworkFunction) {
+ final VirtualNetworkFunction other = (VirtualNetworkFunction) obj;
+ return Objects.equals(vnfdId, other.vnfdId) && Objects.equals(vnfName, other.vnfName)
+ && Objects.equals(vnfmInfoList, other.vnfmInfoList) && Objects.equals(properties, other.properties);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class VirtualNetworkFunction {\n");
+ sb.append(" vnfdId: ").append(toIndentedString(vnfdId)).append("\n");
+ sb.append(" vnfName: ").append(toIndentedString(vnfName)).append("\n");
+ sb.append(" vnfmInfo: ").append(toIndentedString(vnfmInfoList)).append("\n");
+ sb.append(" properties: ").append(toIndentedString(properties)).append("\n");
+
+ sb.append("}");
+ return sb.toString();
+ }
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/YamlFileParser.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/nsd/YamlFileParser.java
new file mode 100644
index 0000000000..ac8f782a99
--- /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/nsd/YamlFileParser.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import java.util.Map;
+import org.springframework.stereotype.Service;
+import org.yaml.snakeyaml.Yaml;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class YamlFileParser implements FileParser {
+
+ @Override
+ public Map<String, Object> getFileContent(final FileEntry entryDefinitionFileEntry) {
+ final Yaml yaml = new Yaml();
+ return yaml.load(entryDefinitionFileEntry.getFileContentAsStream());
+ }
+
+}
diff --git a/so-etsi-nfvo/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
new file mode 100644
index 0000000000..13cdc60b1b
--- /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/service/JobExecutorService.java
@@ -0,0 +1,252 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_REQUEST_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.GLOBAL_CUSTOMER_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.INSTANTIATE_NS_REQUEST_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.JOB_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OCC_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.SERVICE_TYPE_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.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;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.NsRequestProcessingException;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.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)
+ *
+ */
+@Service
+public class JobExecutorService {
+
+ private static final Logger logger = getLogger(JobExecutorService.class);
+
+ private static final ImmutableSet<JobStatusEnum> JOB_FINISHED_STATES =
+ ImmutableSet.of(FINISHED, ERROR, FINISHED_WITH_ERROR);
+
+ private static final int SLEEP_TIME_IN_SECONDS = 5;
+
+ @Value("${so-etsi-ns-lcm-workflow-engine.requesttimeout.timeoutInSeconds:300}")
+ private int timeOutInSeconds;
+
+ private final DatabaseServiceProvider databaseServiceProvider;
+ private final WorkflowExecutorService workflowExecutorService;
+ private final WorkflowQueryService workflowQueryService;
+ private Gson gson;
+
+ @Autowired
+ public JobExecutorService(final DatabaseServiceProvider databaseServiceProvider,
+ final WorkflowExecutorService workflowExecutorService, final WorkflowQueryService workflowQueryService,
+ final GsonProvider gsonProvider) {
+ this.databaseServiceProvider = databaseServiceProvider;
+ this.workflowExecutorService = workflowExecutorService;
+ this.workflowQueryService = workflowQueryService;
+ gson = gsonProvider.getGson();
+ }
+
+ public NsInstancesNsInstance runCreateNsJob(final CreateNsRequest createNsRequest, final String globalCustomerId,
+ final String serviceType) {
+ logger.info("Starting 'Create NS' workflow job for request:\n{}", createNsRequest);
+ final NfvoJob newJob = new NfvoJob().startTime(LocalDateTime.now()).jobType("NS").jobAction(JobAction.CREATE)
+ .resourceId(createNsRequest.getNsdId()).resourceName(createNsRequest.getNsName())
+ .status(JobStatusEnum.STARTING).progress(5);
+ databaseServiceProvider.addJob(newJob);
+
+ logger.info("New job created in database :\n{}", newJob);
+
+ workflowExecutorService.executeWorkflow(newJob.getJobId(), CREATE_NS_WORKFLOW_NAME,
+ getVariables(newJob.getJobId(), createNsRequest, globalCustomerId, serviceType));
+
+ final ImmutablePair<String, JobStatusEnum> immutablePair =
+ waitForJobToFinish(newJob.getJobId(), JOB_FINISHED_STATES);
+
+ if (immutablePair.getRight() == null) {
+ final String message = "Failed to create NS for request: \n" + createNsRequest;
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+ final JobStatusEnum finalJobStatus = immutablePair.getRight();
+ final String processInstanceId = immutablePair.getLeft();
+
+ if (!FINISHED.equals(finalJobStatus)) {
+
+ final Optional<InlineResponse400> optional = workflowQueryService.getProblemDetails(processInstanceId);
+ if (optional.isPresent()) {
+ final InlineResponse400 problemDetails = optional.get();
+ final String message =
+ "Failed to create NS for request: \n" + createNsRequest + " due to \n" + problemDetails;
+ logger.error(message);
+ throw new NsRequestProcessingException(message, problemDetails);
+ }
+
+ final String message = "Received unexpected Job Status: " + finalJobStatus
+ + " Failed to Create NS for request: \n" + createNsRequest;
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+
+ logger.debug("Will query for CreateNsResponse using processInstanceId:{}", processInstanceId);
+ final Optional<NsInstancesNsInstance> optional = workflowQueryService.getCreateNsResponse(processInstanceId);
+ if (optional.isEmpty()) {
+ final String message =
+ "Unable to find CreateNsReponse in Camunda History for process instance: " + processInstanceId;
+ logger.error(message);
+ throw new NsRequestProcessingException(message);
+ }
+ return optional.get();
+ }
+
+ public String runInstantiateNsJob(final String nsInstanceId, final InstantiateNsRequest instantiateNsRequest) {
+
+ final NfvoJob newJob = new NfvoJob().startTime(LocalDateTime.now()).jobType("NS").jobAction(INSTANTIATE)
+ .resourceId(nsInstanceId).status(STARTING).progress(0);
+ databaseServiceProvider.addJob(newJob);
+ logger.info("New job created in database :\n{}", newJob);
+
+ final LocalDateTime currentDateTime = LocalDateTime.now();
+ final NsLcmOpOcc newNsLcmOpOcc = new NsLcmOpOcc().id(nsInstanceId).operation(NsLcmOpType.INSTANTIATE)
+ .operationState(OperationStateEnum.PROCESSING).stateEnteredTime(currentDateTime)
+ .startTime(currentDateTime).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 {
+ final long startTimeInMillis = System.currentTimeMillis();
+ final long timeOutTime = startTimeInMillis + TimeUnit.SECONDS.toMillis(timeOutInSeconds);
+
+ logger.info("Will wait till {} for {} job to finish", Instant.ofEpochMilli(timeOutTime).toString(), jobId);
+ JobStatusEnum currentJobStatus = null;
+ while (timeOutTime > System.currentTimeMillis()) {
+
+ final Optional<NfvoJob> optional = databaseServiceProvider.getJob(jobId);
+
+ if (optional.isEmpty()) {
+ logger.error("Unable to find Job using jobId: {}", jobId);
+ return ImmutablePair.nullPair();
+ }
+
+ final NfvoJob nfvoJob = optional.get();
+ currentJobStatus = nfvoJob.getStatus();
+ logger.info("Received job status response: \n ", nfvoJob);
+ if (jobFinishedStates.contains(nfvoJob.getStatus())) {
+ logger.info("Job finished \n {}", currentJobStatus);
+ return ImmutablePair.of(nfvoJob.getProcessInstanceId(), currentJobStatus);
+ }
+
+ logger.info("Haven't received one of finish state {} yet, will try again in {} seconds",
+ jobFinishedStates, SLEEP_TIME_IN_SECONDS);
+ TimeUnit.SECONDS.sleep(SLEEP_TIME_IN_SECONDS);
+
+ }
+ logger.warn("Timeout current job status: {}", currentJobStatus);
+ return ImmutablePair.nullPair();
+ } catch (final InterruptedException interruptedException) {
+ Thread.currentThread().interrupt();
+ logger.error("Sleep was interrupted", interruptedException);
+ return ImmutablePair.nullPair();
+ }
+ }
+
+ private Map<String, Object> getVariables(final String jobId, final CreateNsRequest createNsRequest,
+ final String globalCustomerId, final String serviceType) {
+ final Map<String, Object> variables = new HashMap<>();
+ variables.put(JOB_ID_PARAM_NAME, jobId);
+ variables.put(CREATE_NS_REQUEST_PARAM_NAME, createNsRequest);
+ variables.put(GLOBAL_CUSTOMER_ID_PARAM_NAME, globalCustomerId);
+ variables.put(SERVICE_TYPE_PARAM_NAME, serviceType);
+ return variables;
+ }
+
+ private Map<String, Object> getVariables(final String nsInstanceId, final String jobId, final String occId,
+ final InstantiateNsRequest instantiateNsRequest) {
+ final Map<String, Object> variables = new HashMap<>();
+ variables.put(NS_INSTANCE_ID_PARAM_NAME, nsInstanceId);
+ variables.put(JOB_ID_PARAM_NAME, jobId);
+ variables.put(OCC_ID_PARAM_NAME, occId);
+ variables.put(INSTANTIATE_NS_REQUEST_PARAM_NAME, instantiateNsRequest);
+ return variables;
+ }
+
+}
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/WorkflowExecutorService.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/WorkflowExecutorService.java
new file mode 100644
index 0000000000..fa2b8d5507
--- /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/service/WorkflowExecutorService.java
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.TENANT_ID;
+import static org.slf4j.LoggerFactory.getLogger;
+import java.util.Map;
+import org.camunda.bpm.engine.RuntimeService;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class WorkflowExecutorService {
+
+ private static final Logger logger = getLogger(WorkflowExecutorService.class);
+
+ private final RuntimeService runtimeService;
+
+ @Autowired
+ public WorkflowExecutorService(final RuntimeService runtimeService) {
+ this.runtimeService = runtimeService;
+ }
+
+ @Async
+ public void executeWorkflow(final String jobId, final String processDefinitionKey,
+ final Map<String, Object> variables) {
+ logger.info("Executing {} workflow with business key: {}", processDefinitionKey, jobId);
+ final ProcessInstance processInstance = runtimeService.createProcessInstanceByKey(processDefinitionKey)
+ .businessKey(jobId).setVariables(variables).processDefinitionTenantId(TENANT_ID).execute();
+
+ logger.info("Workflow running with processInstanceId: {} and business key: {}",
+ processInstance.getProcessInstanceId(), processInstance.getBusinessKey());
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowQueryService.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowQueryService.java
new file mode 100644
index 0000000000..297e9c34af
--- /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/service/WorkflowQueryService.java
@@ -0,0 +1,108 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.TENANT_ID;
+import static org.slf4j.LoggerFactory.getLogger;
+import java.util.Optional;
+import org.camunda.bpm.engine.HistoryService;
+import org.camunda.bpm.engine.ProcessEngineException;
+import org.camunda.bpm.engine.history.HistoricVariableInstance;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.google.common.base.Strings;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class WorkflowQueryService {
+
+ private static final Logger logger = getLogger(WorkflowQueryService.class);
+
+ private final HistoryService camundaHistoryService;
+
+ @Autowired
+ public WorkflowQueryService(final HistoryService camundaHistoryService) {
+ this.camundaHistoryService = camundaHistoryService;
+ }
+
+ public Optional<NsInstancesNsInstance> getCreateNsResponse(final String processInstanceId) {
+ try {
+
+ if (Strings.isNullOrEmpty(processInstanceId)) {
+ logger.error("Invalid processInstanceId: {}", processInstanceId);
+ return Optional.empty();
+ }
+
+ final HistoricVariableInstance historicVariableInstance =
+ getVariable(processInstanceId, CREATE_NS_RESPONSE_PARAM_NAME);
+
+ if (historicVariableInstance != null) {
+ logger.info("Found HistoricVariableInstance : {}", historicVariableInstance);
+ final Object variableValue = historicVariableInstance.getValue();
+ if (variableValue instanceof NsInstancesNsInstance) {
+ return Optional.ofNullable((NsInstancesNsInstance) variableValue);
+ }
+ logger.error("Unknown CreateNsResponse object type {} received value: {}",
+ historicVariableInstance.getValue() != null ? variableValue.getClass() : null, variableValue);
+ }
+ } catch (final ProcessEngineException processEngineException) {
+ logger.error("Unable to find {} variable using processInstanceId: {}", CREATE_NS_RESPONSE_PARAM_NAME,
+ processInstanceId, processEngineException);
+ }
+ logger.error("Unable to find {} variable using processInstanceId: {}", CREATE_NS_RESPONSE_PARAM_NAME,
+ processInstanceId);
+ return Optional.empty();
+
+ }
+
+ public Optional<InlineResponse400> getProblemDetails(final String processInstanceId) {
+ try {
+ final HistoricVariableInstance historicVariableInstance =
+ getVariable(processInstanceId, CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME);
+
+ logger.info("Found HistoricVariableInstance : {}", historicVariableInstance);
+ final Object variableValue = historicVariableInstance.getValue();
+ if (variableValue instanceof InlineResponse400) {
+ return Optional.ofNullable((InlineResponse400) variableValue);
+ }
+ logger.error("Unknown ProblemDetails object type {} received value: {}",
+ historicVariableInstance.getValue() != null ? variableValue.getClass() : null, variableValue);
+ } catch (final ProcessEngineException processEngineException) {
+ logger.error("Unable to find {} variable using processInstanceId: {}",
+ CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, processInstanceId, processEngineException);
+ }
+ return Optional.empty();
+ }
+
+
+ private HistoricVariableInstance getVariable(final String processInstanceId, final String name) {
+ return camundaHistoryService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId)
+ .variableName(name).tenantIdIn(TENANT_ID).singleResult();
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/AbstractNetworkServiceTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/AbstractNetworkServiceTask.java
new file mode 100644
index 0000000000..99116dacad
--- /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/AbstractNetworkServiceTask.java
@@ -0,0 +1,117 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.JOB_ID_PARAM_NAME;
+import java.time.LocalDateTime;
+import java.util.Optional;
+import org.camunda.bpm.engine.delegate.BpmnError;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJobStatus;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public abstract class AbstractNetworkServiceTask {
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+ protected final DatabaseServiceProvider databaseServiceProvider;
+
+ public AbstractNetworkServiceTask(final DatabaseServiceProvider jobServiceProvider) {
+ this.databaseServiceProvider = jobServiceProvider;
+ }
+
+ public void setJobStatus(final DelegateExecution execution, final JobStatusEnum jobStatus,
+ final String description) {
+ logger.info("Setting Job Status to {}", jobStatus);
+ final NfvoJob nfvoJob = getNfvoJob(execution);
+ nfvoJob.status(jobStatus);
+ if (JobStatusEnum.STARTED.equals(jobStatus)) {
+ nfvoJob.processInstanceId(execution.getProcessInstanceId());
+ }
+
+ if (JobStatusEnum.FINISHED.equals(jobStatus)) {
+ nfvoJob.endTime(LocalDateTime.now());
+ }
+
+ nfvoJob.nfvoJobStatus(
+ new NfvoJobStatus().status(jobStatus).description(description).updatedTime(LocalDateTime.now()));
+ databaseServiceProvider.addJob(nfvoJob);
+
+ }
+
+ public void setJobStatusToError(final DelegateExecution execution, final String description) {
+ logger.info("Setting Job Status to {}", JobStatusEnum.ERROR);
+
+ final String jobId = (String) execution.getVariable(JOB_ID_PARAM_NAME);
+ final Optional<NfvoJob> optional = databaseServiceProvider.getJob(jobId);
+ if (optional.isPresent()) {
+ final InlineResponse400 problemDetails =
+ (InlineResponse400) execution.getVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME);
+
+ final NfvoJob nfvoJob = optional.get();
+ nfvoJob.status(JobStatusEnum.ERROR).endTime(LocalDateTime.now());
+
+ if (problemDetails != null) {
+ logger.error("Found failed reason: {}", problemDetails);
+ nfvoJob.nfvoJobStatus(new NfvoJobStatus().status(JobStatusEnum.ERROR)
+ .description(problemDetails.getDetail()).updatedTime(LocalDateTime.now()));
+ }
+ nfvoJob.nfvoJobStatus(new NfvoJobStatus().status(JobStatusEnum.ERROR).description(description)
+ .updatedTime(LocalDateTime.now()));
+
+ databaseServiceProvider.addJob(nfvoJob);
+ }
+ logger.info("Finished setting Job Status to {}", JobStatusEnum.ERROR);
+
+ }
+
+ protected void abortOperation(final DelegateExecution execution, final String message) {
+ abortOperation(execution, message, new InlineResponse400().detail(message));
+ }
+
+ protected void abortOperation(final DelegateExecution execution, final String message,
+ final InlineResponse400 problemDetails) {
+ logger.error(message);
+ execution.setVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, problemDetails);
+ throw new BpmnError("WORKFLOW_FAILED");
+ }
+
+ private NfvoJob getNfvoJob(final DelegateExecution execution) {
+ final String jobId = (String) execution.getVariable(JOB_ID_PARAM_NAME);
+ final Optional<NfvoJob> optional = databaseServiceProvider.getJob(jobId);
+ if (!optional.isPresent()) {
+ final String message = "Unable to find job using job id: " + jobId;
+ logger.error(message);
+ execution.setVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME,
+ new InlineResponse400().detail(message));
+ throw new BpmnError("WORKFLOW_FAILED");
+
+ }
+ return optional.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/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/CreateNsTask.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/CreateNsTask.java
new file mode 100644
index 0000000000..fa7187b388
--- /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/CreateNsTask.java
@@ -0,0 +1,221 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_REQUEST_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.GLOBAL_CUSTOMER_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_PACKAGE_MODEL_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.SERVICE_TYPE_PARAM_NAME;
+import java.time.LocalDateTime;
+import java.util.Optional;
+import java.util.UUID;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.aai.domain.yang.ServiceInstance;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.EtsiCatalogManagerRequestFailureException;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogPackageManagementServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance.NsStateEnum;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+public class CreateNsTask extends AbstractNetworkServiceTask {
+ private static final String NETWORK_SERVICE_NAME = "NetworkService";
+ private static final String NETWORK_SERVICE_ROLE = "NetworkService";
+ private static final String DOES_NS_PACKAGE_EXISTS_PARAM_NAME = "doesNsPackageExists";
+ private static final String DOES_NS_INSTANCE_EXISTS_PARAM_NAME = "doesNsInstanceExists";
+ private static final Logger logger = LoggerFactory.getLogger(CreateNsTask.class);
+ private final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider;
+ private final AaiServiceProvider aaiServiceProvider;
+
+ @Autowired
+ public CreateNsTask(final DatabaseServiceProvider databaseServiceProvider,
+ final AaiServiceProvider aaiServiceProvider,
+ final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider) {
+ super(databaseServiceProvider);
+ this.aaiServiceProvider = aaiServiceProvider;
+ this.etsiCatalogPackageManagementServiceProvider = etsiCatalogPackageManagementServiceProvider;
+ }
+
+ public void setJobStatusToStarted(final DelegateExecution execution) {
+ setJobStatus(execution, JobStatusEnum.STARTED, "Create NS workflow process started");
+ }
+
+ public void setJobStatusToFinished(final DelegateExecution execution) {
+ setJobStatus(execution, JobStatusEnum.FINISHED, "Create NS workflow process finished");
+ }
+
+ public void setJobStatusToError(final DelegateExecution execution) {
+ setJobStatusToError(execution, "Create NS workflow process failed");
+ }
+
+ public void getNsPackage(final DelegateExecution execution) {
+ logger.info("Retrieving NS package from ETSI Catalog Manager ...");
+ setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Retrieving NS package from ETSI Catalog Manager");
+
+ final CreateNsRequest createNsRequest = (CreateNsRequest) execution.getVariable(CREATE_NS_REQUEST_PARAM_NAME);
+
+ try {
+ final Optional<NsdInfo> optional =
+ etsiCatalogPackageManagementServiceProvider.getNSPackageModel(createNsRequest.getNsdId());
+
+ if (optional.isPresent()) {
+ final NsdInfo packageModel = optional.get();
+ logger.info("NS Package exists {}", packageModel);
+ execution.setVariable(NS_PACKAGE_MODEL_PARAM_NAME, packageModel);
+ execution.setVariable(DOES_NS_PACKAGE_EXISTS_PARAM_NAME, true);
+ } else {
+ final String message = "Unable to find NS package using NsdId: " + createNsRequest.getNsdId();
+ logger.error(message);
+ execution.setVariable(DOES_NS_PACKAGE_EXISTS_PARAM_NAME, false);
+ execution.setVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME,
+ new InlineResponse400().detail(message));
+ }
+
+ } catch (final EtsiCatalogManagerRequestFailureException failureException) {
+ final String message =
+ "Unexpected exception occured while getting ns package using nsdId: " + createNsRequest.getNsdId();
+ logger.error(message, failureException);
+
+ execution.setVariable(DOES_NS_PACKAGE_EXISTS_PARAM_NAME, false);
+
+ execution.setVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME,
+ new InlineResponse400().title(message).detail(message));
+ }
+
+ }
+
+ public void doesNsInstanceExistsInDb(final DelegateExecution execution) {
+ logger.info("Executing doesNsInstanceExistsInDb ...");
+
+ setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Checking if NS package exists in database");
+
+ final CreateNsRequest createNsRequest =
+ (CreateNsRequest) execution.getVariables().get(CREATE_NS_REQUEST_PARAM_NAME);
+
+ final boolean exists = databaseServiceProvider.isNsInstExists(createNsRequest.getNsName());
+ logger.info("Ns Instance entry {} exists in database", exists ? "does" : "doesn't");
+ execution.setVariable(DOES_NS_INSTANCE_EXISTS_PARAM_NAME, exists);
+
+ if (exists) {
+ final Optional<NfvoNsInst> optional =
+ databaseServiceProvider.getNfvoNsInstByName(createNsRequest.getNsName());
+ final NfvoNsInst nfvoNsInst = optional.get();
+ execution.setVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, new InlineResponse400()
+ .detail("Ns Instance already exists in database : " + nfvoNsInst.toString()));
+ }
+
+ logger.info("Finished executing doesNsInstanceExistsInDb ...");
+
+ }
+
+ public void createNsInstanceInDb(final DelegateExecution execution) {
+ logger.info("Executing createNsInstanceInDb ...");
+
+ setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Checking if NS package exists");
+
+ final CreateNsRequest createNsRequest = (CreateNsRequest) execution.getVariable(CREATE_NS_REQUEST_PARAM_NAME);
+ final NsdInfo packageMode = (NsdInfo) execution.getVariable(NS_PACKAGE_MODEL_PARAM_NAME);
+
+ final String globalCustomerId = (String) execution.getVariable(GLOBAL_CUSTOMER_ID_PARAM_NAME);
+ final String serviceType = (String) execution.getVariable(SERVICE_TYPE_PARAM_NAME);
+
+ final String nsInstId = UUID.randomUUID().toString();
+ execution.setVariable(NS_INSTANCE_ID_PARAM_NAME, nsInstId);
+
+ databaseServiceProvider.saveNfvoNsInst(new NfvoNsInst().nsInstId(nsInstId).name(createNsRequest.getNsName())
+ .nsPackageId(packageMode.getId()).nsdId(packageMode.getNsdId())
+ .nsdInvariantId(packageMode.getNsdInvariantId()).description(createNsRequest.getNsDescription())
+ .status(State.NOT_INSTANTIATED).statusUpdatedTime(LocalDateTime.now())
+ .globalCustomerId(globalCustomerId).serviceType(serviceType));
+ logger.info("Finished executing createNsInstanceInDb ...");
+
+ }
+
+
+ public void createNsInstanceInAai(final DelegateExecution execution) {
+ logger.info("Executing createNsInstanceInAai ...");
+ try {
+ setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Creating NS Instance in AAI");
+
+ final CreateNsRequest createNsRequest =
+ (CreateNsRequest) execution.getVariable(CREATE_NS_REQUEST_PARAM_NAME);
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+
+ final String globalCustomerId = (String) execution.getVariable(GLOBAL_CUSTOMER_ID_PARAM_NAME);
+ final String serviceType = (String) execution.getVariable(SERVICE_TYPE_PARAM_NAME);
+
+ final ServiceInstance aaiServiceInstance = new ServiceInstance();
+ aaiServiceInstance.setServiceInstanceId(nsInstId);
+ aaiServiceInstance.setServiceInstanceName(createNsRequest.getNsName());
+ aaiServiceInstance.setServiceType(NETWORK_SERVICE_NAME);
+ aaiServiceInstance.setServiceRole(NETWORK_SERVICE_ROLE);
+
+ aaiServiceProvider.createServiceInstance(globalCustomerId, serviceType, aaiServiceInstance);
+ } catch (final Exception exception) {
+ final String message = "Unable to Create Service Instance in AAI";
+ logger.error(message, exception);
+ abortOperation(execution, message, new InlineResponse400().detail(message));
+ }
+ logger.info("Finished executing createNsInstanceInAai ...");
+
+ }
+
+ public void setCreateNsResponse(final DelegateExecution execution) {
+ logger.info("Executing setCreateNsResponse ...");
+ final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+ final Optional<NfvoNsInst> optional = databaseServiceProvider.getNfvoNsInst(nsInstId);
+
+ if (optional.isPresent()) {
+ final NfvoNsInst nfvoNsInst = optional.get();
+ final NsInstancesNsInstance response = new NsInstancesNsInstance().id(nfvoNsInst.getNsInstId())
+ .nsInstanceName(nfvoNsInst.getName()).nsdId(nfvoNsInst.getNsdId())
+ .nsdInfoId(nfvoNsInst.getNsPackageId()).nsInstanceDescription(nfvoNsInst.getDescription())
+ .nsState(NsStateEnum.fromValue(nfvoNsInst.getStatus().toString()));
+ logger.info("Saving CreateNsResponse: {} in Execution ...", response);
+ execution.setVariable(CREATE_NS_RESPONSE_PARAM_NAME, response);
+ } else {
+ final String message = "Unable to find NS Instance in datababse using id: " + nsInstId;
+ logger.error(message);
+ abortOperation(execution, message);
+ }
+
+ logger.info("Finished executing setCreateNsResponse ...");
+
+ }
+
+}
diff --git a/so-etsi-nfvo/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/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorInstantiateSol003AdapterNodeTask.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/MonitorInstantiateSol003AdapterNodeTask.java
new file mode 100644
index 0000000000..51fa6b9381
--- /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/MonitorInstantiateSol003AdapterNodeTask.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+public class MonitorInstantiateSol003AdapterNodeTask extends MonitorSol003AdapterNodeTask {
+ public static final String CREATE_VNF_NODE_STATUS = "createVnfNodeStatus";
+ public static final String VNF_CREATED = "Created";
+
+ @Autowired
+ public MonitorInstantiateSol003AdapterNodeTask(final DatabaseServiceProvider databaseServiceProvider,
+ final AaiServiceProvider aaiServiceProvider) {
+ super(databaseServiceProvider, aaiServiceProvider);
+ }
+
+ @Override
+ public String getNodeStatusVariableName() {
+ return CREATE_VNF_NODE_STATUS;
+ }
+
+ @Override
+ public boolean isOrchestrationStatusValid(final String orchestrationStatus) {
+ return VNF_CREATED.equalsIgnoreCase(orchestrationStatus);
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterCreateJobTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterCreateJobTask.java
new file mode 100644
index 0000000000..3c91598dfb
--- /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/MonitorSol003AdapterCreateJobTask.java
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_VNF_RESPONSE_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+public class MonitorSol003AdapterCreateJobTask extends MonitorSol003AdapterJobTask {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MonitorSol003AdapterCreateJobTask.class);
+
+ @Autowired
+ public MonitorSol003AdapterCreateJobTask(final Sol003AdapterServiceProvider sol003AdapterServiceProvider,
+ final DatabaseServiceProvider databaseServiceProvider) {
+ super(sol003AdapterServiceProvider, databaseServiceProvider);
+ }
+
+ public void getCurrentOperationStatus(final DelegateExecution execution) {
+ try {
+ LOGGER.debug("Executing getCurrentOperationStatus ...");
+ final CreateVnfResponse vnfInstantiateResponse =
+ (CreateVnfResponse) execution.getVariable(CREATE_VNF_RESPONSE_PARAM_NAME);
+ execution.setVariable(OPERATION_STATUS_PARAM_NAME,
+ getOperationStatus(execution, vnfInstantiateResponse.getJobId()));
+ LOGGER.debug("Finished executing getCurrentOperationStatus ...");
+ } catch (final Exception exception) {
+ final String message = "Unable to invoke get current Operation status";
+ LOGGER.error(message, exception);
+ abortOperation(execution, message);
+
+ }
+ }
+
+ /**
+ * Log and throw exception on timeout for job status
+ *
+ * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl}
+ */
+ public void timeOutLogFailue(final DelegateExecution execution) {
+ final String message = "Instantiation operation time out";
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+
+ /**
+ * Check the final status of instantiation throw exception if not completed successfully
+ *
+ * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl}
+ */
+ public void checkIfOperationWasSuccessful(final DelegateExecution execution) {
+ LOGGER.debug("Executing checkIfOperationWasSuccessful ...");
+ final OperationStateEnum operationStatus =
+ (OperationStateEnum) execution.getVariable(OPERATION_STATUS_PARAM_NAME);
+ final CreateVnfResponse vnfInstantiateResponse =
+ (CreateVnfResponse) execution.getVariable(CREATE_VNF_RESPONSE_PARAM_NAME);
+
+ if (operationStatus == null) {
+ final String message = "Unable to instantiate jobId: "
+ + (vnfInstantiateResponse != null ? vnfInstantiateResponse.getJobId() : "null")
+ + "Unable to retrieve OperationStatus";
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+ if (operationStatus != OperationStateEnum.COMPLETED) {
+ final String message = "Unable to instantiate jobId: "
+ + (vnfInstantiateResponse != null ? vnfInstantiateResponse.getJobId() : "null")
+ + " OperationStatus: " + operationStatus;
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+
+ LOGGER.debug("Successfully completed instatiation of job {}", vnfInstantiateResponse);
+ }
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterJobTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterJobTask.java
new file mode 100644
index 0000000000..bac79dfa3e
--- /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/MonitorSol003AdapterJobTask.java
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME;
+import java.util.Optional;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStatusRetrievalStatusEnum;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+public class MonitorSol003AdapterJobTask extends AbstractNetworkServiceTask {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MonitorSol003AdapterJobTask.class);
+ public static final ImmutableSet<OperationStateEnum> OPERATION_FINISHED_STATES =
+ ImmutableSet.of(OperationStateEnum.COMPLETED, OperationStateEnum.FAILED, OperationStateEnum.ROLLED_BACK);
+ public static final ImmutableSet<OperationStatusRetrievalStatusEnum> OPERATION_RETRIEVAL_STATES = ImmutableSet
+ .of(OperationStatusRetrievalStatusEnum.STATUS_FOUND, OperationStatusRetrievalStatusEnum.WAITING_FOR_STATUS);
+ protected final Sol003AdapterServiceProvider sol003AdapterServiceProvider;
+
+ @Autowired
+ public MonitorSol003AdapterJobTask(final Sol003AdapterServiceProvider sol003AdapterServiceProvider,
+ final DatabaseServiceProvider databaseServiceProvider) {
+ super(databaseServiceProvider);
+ this.sol003AdapterServiceProvider = sol003AdapterServiceProvider;
+ }
+
+ public boolean hasOperationFinished(final DelegateExecution execution) {
+ LOGGER.debug("Executing hasOperationFinished ...");
+
+ final OperationStateEnum operationStatus =
+ (OperationStateEnum) execution.getVariable(OPERATION_STATUS_PARAM_NAME);
+ if (operationStatus != null) {
+ return OPERATION_FINISHED_STATES.contains(operationStatus);
+ }
+ LOGGER.debug("OperationStatus is not present yet... ");
+ LOGGER.debug("Finished executing hasOperationFinished ...");
+ return false;
+ }
+
+ protected OperationStateEnum getOperationStatus(final DelegateExecution execution, final String jobId) {
+
+ final Optional<QueryJobResponse> instantiateOperationJobStatus =
+ sol003AdapterServiceProvider.getInstantiateOperationJobStatus(jobId);
+
+ if (instantiateOperationJobStatus.isPresent()) {
+ final QueryJobResponse queryJobResponse = instantiateOperationJobStatus.get();
+
+ if (!OPERATION_RETRIEVAL_STATES.contains(queryJobResponse.getOperationStatusRetrievalStatus())) {
+ final String message = "Received invalid operation retrieval state: "
+ + queryJobResponse.getOperationStatusRetrievalStatus();
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+ if (queryJobResponse.getOperationState() != null) {
+ final OperationStateEnum operationStatus = queryJobResponse.getOperationState();
+ LOGGER.debug("Operation {} with {} and operation retrieval status : {}", queryJobResponse.getId(),
+ operationStatus, queryJobResponse.getOperationStatusRetrievalStatus());
+ return queryJobResponse.getOperationState();
+ }
+
+ LOGGER.debug("Operation {} without operationStatus and operation retrieval status :{}",
+ queryJobResponse.getId(), queryJobResponse.getOperationStatusRetrievalStatus());
+ }
+ return null;
+ }
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterNodeTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterNodeTask.java
new file mode 100644
index 0000000000..e27e0c1579
--- /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/MonitorSol003AdapterNodeTask.java
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NF_INST_ID_PARAM_NAME;
+import java.util.Optional;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public abstract class MonitorSol003AdapterNodeTask extends AbstractNetworkServiceTask {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MonitorSol003AdapterNodeTask.class);
+ private final AaiServiceProvider aaiServiceProvider;
+
+ public MonitorSol003AdapterNodeTask(final DatabaseServiceProvider databaseServiceProvider,
+ final AaiServiceProvider aaiServiceProvider) {
+ super(databaseServiceProvider);
+ this.aaiServiceProvider = aaiServiceProvider;
+ }
+
+ /**
+ * Check the final status of vnf in A&AI
+ *
+ * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl}
+ */
+ public void getNodeStatus(final DelegateExecution execution) {
+ try {
+ LOGGER.debug("Executing getNodeStatus ...");
+ final String vnfId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME);
+
+ LOGGER.debug("Query A&AI for generic VNF using vnfID: {}", vnfId);
+ final Optional<GenericVnf> aaiGenericVnfOptional = aaiServiceProvider.getGenericVnf(vnfId);
+
+ if (!aaiGenericVnfOptional.isPresent()) {
+ abortOperation(execution, "Unable to invoke Sol003 adapter for create and instantiate vnfId" + vnfId);
+ }
+ final GenericVnf genericVnf = aaiGenericVnfOptional.get();
+ final String orchestrationStatus = genericVnf.getOrchestrationStatus();
+ LOGGER.debug("Found generic vnf with orchestration status : {}", orchestrationStatus);
+
+ execution.setVariable(getNodeStatusVariableName(), isOrchestrationStatusValid(orchestrationStatus));
+
+ } catch (final Exception exception) {
+ LOGGER.error("Unable to get vnf from AAI", exception);
+ abortOperation(execution, "Unable to get vnf from AAI");
+ }
+ }
+
+ /**
+ * Get variable to store in execution context
+ *
+ * @return the variable name
+ */
+ public abstract String getNodeStatusVariableName();
+
+ /**
+ * @param orchestrationStatus the orchestration status from A&AI
+ * @return true if valid
+ */
+ public abstract boolean isOrchestrationStatusValid(final String orchestrationStatus);
+
+ public void timeOutLogFailue(final DelegateExecution execution) {
+ final String message = "Node operation time out";
+ LOGGER.error(message);
+ abortOperation(execution, message);
+ }
+}
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/utils/LocalDateTimeTypeAdapter.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/utils/LocalDateTimeTypeAdapter.java
new file mode 100644
index 0000000000..34959ee0f0
--- /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/utils/LocalDateTimeTypeAdapter.java
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.utils;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class LocalDateTimeTypeAdapter extends TypeAdapter<LocalDateTime> {
+
+ private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+ @Override
+ public void write(final JsonWriter out, final LocalDateTime localDateTime) throws IOException {
+ if (localDateTime == null) {
+ out.nullValue();
+ } else {
+ out.value(FORMATTER.format(localDateTime));
+ }
+ }
+
+ @Override
+ public LocalDateTime read(final JsonReader in) throws IOException {
+ switch (in.peek()) {
+ case NULL:
+ in.nextNull();
+ return null;
+ default:
+ final String dateTime = in.nextString();
+ return LocalDateTime.parse(dateTime, FORMATTER);
+ }
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn
new file mode 100644
index 0000000000..025faa4128
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1uf6nd9" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.0.0">
+ <bpmn:process id="CreateInstantiateVnf" name="CreateInstantiateVnf" isExecutable="true">
+ <bpmn:startEvent id="StartEvent_1">
+ <bpmn:outgoing>Flow_02bjz2v</bpmn:outgoing>
+ </bpmn:startEvent>
+ <bpmn:serviceTask id="Activity_19rmtjr" name="Create NF Instance (VNF) record in DB" camunda:expression="${CreateInstantiateVnfTask.createNfInstanceInDb(execution)}">
+ <bpmn:incoming>Flow_123uagz</bpmn:incoming>
+ <bpmn:outgoing>Flow_03p6ifi</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_02bjz2v" sourceRef="StartEvent_1" targetRef="Activity_1cluqgp" />
+ <bpmn:endEvent id="Event_14qdixj">
+ <bpmn:incoming>Flow_0srinh7</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:sequenceFlow id="Flow_03p6ifi" sourceRef="Activity_19rmtjr" targetRef="Activity_0rto3n3" />
+ <bpmn:serviceTask id="Activity_0rto3n3" name="Create Generic VNF and Connect to Service Instance in AAI" camunda:expression="${CreateInstantiateVnfTask.createGenericVnfInAai(execution)}">
+ <bpmn:incoming>Flow_03p6ifi</bpmn:incoming>
+ <bpmn:outgoing>Flow_1c3kc4e</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_1c3kc4e" sourceRef="Activity_0rto3n3" targetRef="ServiceTask_0iry5yw" />
+ <bpmn:serviceTask id="Activity_1cluqgp" name="Check If NF Instance (VNF) exists in DB" camunda:expression="${CreateInstantiateVnfTask.checkIfNfInstanceExistsInDb(execution)}">
+ <bpmn:incoming>Flow_02bjz2v</bpmn:incoming>
+ <bpmn:outgoing>Flow_123uagz</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_123uagz" sourceRef="Activity_1cluqgp" targetRef="Activity_19rmtjr" />
+ <bpmn:serviceTask id="ServiceTask_0iry5yw" name="&#10;Invoke VNFM Adaptor&#10;" camunda:asyncAfter="true" camunda:expression="${CreateInstantiateVnfTask.invokeCreateInstantiationRequest(execution)}">
+ <bpmn:incoming>Flow_1c3kc4e</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_0xzptc2</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:callActivity id="CallActivity_1yilxx3" name="Monitor Sol003 adapter Instantiation Job" calledElement="MonitorSol003AdapterCreateJob">
+ <bpmn:extensionElements>
+ <camunda:in source="createVnfResponse" target="createVnfResponse" />
+ <camunda:in source="jobId" target="jobId" />
+ </bpmn:extensionElements>
+ <bpmn:incoming>SequenceFlow_0xzptc2</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_053tvct</bpmn:outgoing>
+ </bpmn:callActivity>
+ <bpmn:callActivity id="CallActivity_0p84lpt" name="Monitor Sol003 adapter Create Node Status" calledElement="MonitorSol003AdapterCreateNodeStatus">
+ <bpmn:extensionElements>
+ <camunda:in source="NF_INST_ID" target="NF_INST_ID" />
+ <camunda:in source="createVnfResponse" target="createVnfResponse" />
+ </bpmn:extensionElements>
+ <bpmn:incoming>SequenceFlow_053tvct</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_0h7yluk</bpmn:outgoing>
+ </bpmn:callActivity>
+ <bpmn:sequenceFlow id="SequenceFlow_0xzptc2" sourceRef="ServiceTask_0iry5yw" targetRef="CallActivity_1yilxx3" />
+ <bpmn:sequenceFlow id="SequenceFlow_053tvct" sourceRef="CallActivity_1yilxx3" targetRef="CallActivity_0p84lpt" />
+ <bpmn:sequenceFlow id="SequenceFlow_0h7yluk" sourceRef="CallActivity_0p84lpt" targetRef="Activity_0g3dip7" />
+ <bpmn:serviceTask id="Activity_0g3dip7" name="Update NF Instance (VNF) Status to INSTANTIATED" camunda:expression="${CreateInstantiateVnfTask.updateNfInstanceStatusToInstantiated(execution)}">
+ <bpmn:incoming>SequenceFlow_0h7yluk</bpmn:incoming>
+ <bpmn:outgoing>Flow_0srinh7</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_0srinh7" sourceRef="Activity_0g3dip7" targetRef="Event_14qdixj" />
+ <bpmn:subProcess id="Activity_0qtgdm9" name="Error Handling" triggeredByEvent="true">
+ <bpmn:startEvent id="Event_08zcwc2" name="error">
+ <bpmn:outgoing>Flow_06q1m6i</bpmn:outgoing>
+ <bpmn:errorEventDefinition id="ErrorEventDefinition_1ppvn77" />
+ </bpmn:startEvent>
+ <bpmn:endEvent id="Event_1wkm29u" name="end">
+ <bpmn:incoming>Flow_0anjylz</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:serviceTask id="Activity_0ltxcii" name="Update NF Instance (VNF) Status to FAILED" camunda:asyncBefore="true" camunda:expression="${CreateInstantiateVnfTask.updateNfInstanceStatusToFailed(execution)}">
+ <bpmn:incoming>Flow_06q1m6i</bpmn:incoming>
+ <bpmn:outgoing>Flow_0anjylz</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_06q1m6i" sourceRef="Event_08zcwc2" targetRef="Activity_0ltxcii" />
+ <bpmn:sequenceFlow id="Flow_0anjylz" sourceRef="Activity_0ltxcii" targetRef="Event_1wkm29u" />
+ </bpmn:subProcess>
+ </bpmn:process>
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="CreateInstantiateVnf">
+ <bpmndi:BPMNEdge id="SequenceFlow_0h7yluk_di" bpmnElement="SequenceFlow_0h7yluk">
+ <di:waypoint x="1030" y="117" />
+ <di:waypoint x="1080" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_053tvct_di" bpmnElement="SequenceFlow_053tvct">
+ <di:waypoint x="880" y="117" />
+ <di:waypoint x="930" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_0xzptc2_di" bpmnElement="SequenceFlow_0xzptc2">
+ <di:waypoint x="740" y="117" />
+ <di:waypoint x="780" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_123uagz_di" bpmnElement="Flow_123uagz">
+ <di:waypoint x="350" y="117" />
+ <di:waypoint x="380" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1c3kc4e_di" bpmnElement="Flow_1c3kc4e">
+ <di:waypoint x="610" y="117" />
+ <di:waypoint x="640" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_03p6ifi_di" bpmnElement="Flow_03p6ifi">
+ <di:waypoint x="480" y="117" />
+ <di:waypoint x="510" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_02bjz2v_di" bpmnElement="Flow_02bjz2v">
+ <di:waypoint x="215" y="117" />
+ <di:waypoint x="250" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0srinh7_di" bpmnElement="Flow_0srinh7">
+ <di:waypoint x="1180" y="117" />
+ <di:waypoint x="1232" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+ <dc:Bounds x="179" y="99" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_19rmtjr_di" bpmnElement="Activity_19rmtjr">
+ <dc:Bounds x="380" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0rto3n3_di" bpmnElement="Activity_0rto3n3">
+ <dc:Bounds x="510" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1cluqgp_di" bpmnElement="Activity_1cluqgp">
+ <dc:Bounds x="250" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="ServiceTask_0iry5yw_di" bpmnElement="ServiceTask_0iry5yw">
+ <dc:Bounds x="640" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="CallActivity_1yilxx3_di" bpmnElement="CallActivity_1yilxx3">
+ <dc:Bounds x="780" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="CallActivity_0p84lpt_di" bpmnElement="CallActivity_0p84lpt">
+ <dc:Bounds x="930" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_14qdixj_di" bpmnElement="Event_14qdixj">
+ <dc:Bounds x="1232" y="99" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0g3dip7_di" bpmnElement="Activity_0g3dip7">
+ <dc:Bounds x="1080" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0qtgdm9_di" bpmnElement="Activity_0qtgdm9" isExpanded="true">
+ <dc:Bounds x="430" y="270" width="438" height="130" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="Flow_06q1m6i_di" bpmnElement="Flow_06q1m6i">
+ <di:waypoint x="488" y="333" />
+ <di:waypoint x="580" y="333" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0anjylz_di" bpmnElement="Flow_0anjylz">
+ <di:waypoint x="680" y="333" />
+ <di:waypoint x="812" y="333" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="Event_08zcwc2_di" bpmnElement="Event_08zcwc2">
+ <dc:Bounds x="452" y="315" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="458" y="358" width="24" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_1wkm29u_di" bpmnElement="Event_1wkm29u">
+ <dc:Bounds x="812" y="315" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="822" y="357" width="19" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0ltxcii_di" bpmnElement="Activity_0ltxcii">
+ <dc:Bounds x="580" y="293" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</bpmn:definitions>
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateNs.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateNs.bpmn
new file mode 100644
index 0000000000..815b76c907
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateNs.bpmn
@@ -0,0 +1,266 @@
+<?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_1l4zor5" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.0.0">
+ <bpmn:process id="CreateNs" name="&#10;CreateNs" isExecutable="true">
+ <bpmn:startEvent id="StartEvent_1" name="Start Process">
+ <bpmn:outgoing>Flow_1tqn5q5</bpmn:outgoing>
+ </bpmn:startEvent>
+ <bpmn:endEvent id="EndEvent_1" name="End Process">
+ <bpmn:incoming>Flow_0t87ov3</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:sequenceFlow id="Flow_1tqn5q5" sourceRef="StartEvent_1" targetRef="Activity_15ksfz6" />
+ <bpmn:serviceTask id="Activity_15ksfz6" name="Set Job Status to STARTED" camunda:asyncBefore="true" camunda:expression="${CreateNsTask.setJobStatusToStarted(execution)}">
+ <bpmn:incoming>Flow_1tqn5q5</bpmn:incoming>
+ <bpmn:outgoing>Flow_0y07mxe</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_0y07mxe" sourceRef="Activity_15ksfz6" targetRef="Activity_12yonzp" />
+ <bpmn:serviceTask id="Activity_1r4l8w8" name="Set Job Status to FINISHED" camunda:expression="${CreateNsTask.setJobStatusToFinished(execution)}">
+ <bpmn:incoming>Flow_1rtsvpm</bpmn:incoming>
+ <bpmn:outgoing>Flow_0t87ov3</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_0t87ov3" sourceRef="Activity_1r4l8w8" targetRef="EndEvent_1" />
+ <bpmn:exclusiveGateway id="Gateway_0fuwzjj" name="Does Ns Package exists?">
+ <bpmn:incoming>Flow_09582uw</bpmn:incoming>
+ <bpmn:outgoing>Flow_1f4vi10</bpmn:outgoing>
+ <bpmn:outgoing>Flow_0qabgp7</bpmn:outgoing>
+ </bpmn:exclusiveGateway>
+ <bpmn:serviceTask id="Activity_12yonzp" name="Get Ns Package from ETSI Catalog Manager" camunda:expression="${CreateNsTask.getNsPackage(execution)}">
+ <bpmn:incoming>Flow_0y07mxe</bpmn:incoming>
+ <bpmn:outgoing>Flow_09582uw</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_09582uw" sourceRef="Activity_12yonzp" targetRef="Gateway_0fuwzjj" />
+ <bpmn:subProcess id="Activity_06ko4e2" name="Error Handling" triggeredByEvent="true">
+ <bpmn:startEvent id="Event_1ibvrn2" name="error">
+ <bpmn:outgoing>Flow_0554tjv</bpmn:outgoing>
+ <bpmn:errorEventDefinition id="ErrorEventDefinition_0lc46mh" />
+ </bpmn:startEvent>
+ <bpmn:endEvent id="Event_02f7sr1" name="end">
+ <bpmn:incoming>Flow_04xvpee</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:sequenceFlow id="Flow_0554tjv" sourceRef="Event_1ibvrn2" targetRef="Activity_1sj0nvr" />
+ <bpmn:serviceTask id="Activity_1sj0nvr" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${CreateNsTask.setJobStatusToError(execution)}">
+ <bpmn:incoming>Flow_0554tjv</bpmn:incoming>
+ <bpmn:outgoing>Flow_04xvpee</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_04xvpee" sourceRef="Activity_1sj0nvr" targetRef="Event_02f7sr1" />
+ </bpmn:subProcess>
+ <bpmn:subProcess id="Activity_1dx9fz6" name="Java Exception Handling" triggeredByEvent="true">
+ <bpmn:startEvent id="Event_0zne7ch" name="error">
+ <bpmn:outgoing>Flow_0j1otrx</bpmn:outgoing>
+ <bpmn:errorEventDefinition id="ErrorEventDefinition_1p3h4ta" errorRef="Error_0s855yd" camunda:errorCodeVariable="BPMN_javaExpCode" camunda:errorMessageVariable="BPMN_javaExpMsg" />
+ </bpmn:startEvent>
+ <bpmn:endEvent id="Event_0bcyh7u">
+ <bpmn:incoming>Flow_0oqv7vl</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:sequenceFlow id="Flow_0j1otrx" sourceRef="Event_0zne7ch" targetRef="Activity_15uwy90" />
+ <bpmn:serviceTask id="Activity_15uwy90" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${CreateNsTask.setJobStatusToError(execution)}">
+ <bpmn:incoming>Flow_0j1otrx</bpmn:incoming>
+ <bpmn:outgoing>Flow_0oqv7vl</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_0oqv7vl" sourceRef="Activity_15uwy90" targetRef="Event_0bcyh7u" />
+ </bpmn:subProcess>
+ <bpmn:sequenceFlow id="Flow_1f4vi10" name="No" sourceRef="Gateway_0fuwzjj" targetRef="Event_016q8gu">
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{not doesNsPackageExists}</bpmn:conditionExpression>
+ </bpmn:sequenceFlow>
+ <bpmn:endEvent id="Event_016q8gu">
+ <bpmn:incoming>Flow_1f4vi10</bpmn:incoming>
+ <bpmn:incoming>Flow_1yql1cm</bpmn:incoming>
+ <bpmn:errorEventDefinition id="ErrorEventDefinition_1ugx52k" errorRef="Error_0rqvnym" />
+ </bpmn:endEvent>
+ <bpmn:sequenceFlow id="Flow_0qabgp7" name="Yes" sourceRef="Gateway_0fuwzjj" targetRef="Activity_0vlb2nk">
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{doesNsPackageExists}</bpmn:conditionExpression>
+ </bpmn:sequenceFlow>
+ <bpmn:serviceTask id="Activity_0vlb2nk" name="Check NS Instance exists In DB " camunda:expression="${CreateNsTask.doesNsInstanceExistsInDb(execution)}">
+ <bpmn:incoming>Flow_0qabgp7</bpmn:incoming>
+ <bpmn:outgoing>Flow_1exrj2b</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_1exrj2b" sourceRef="Activity_0vlb2nk" targetRef="Gateway_0d7n517" />
+ <bpmn:exclusiveGateway id="Gateway_0d7n517">
+ <bpmn:incoming>Flow_1exrj2b</bpmn:incoming>
+ <bpmn:outgoing>Flow_1rkg44s</bpmn:outgoing>
+ <bpmn:outgoing>Flow_1yql1cm</bpmn:outgoing>
+ </bpmn:exclusiveGateway>
+ <bpmn:sequenceFlow id="Flow_1rkg44s" name="No" sourceRef="Gateway_0d7n517" targetRef="Activity_09tqz8x">
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{not doesNsInstanceExists}</bpmn:conditionExpression>
+ </bpmn:sequenceFlow>
+ <bpmn:sequenceFlow id="Flow_1yql1cm" name="Yes" sourceRef="Gateway_0d7n517" targetRef="Event_016q8gu">
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{doesNsInstanceExists}</bpmn:conditionExpression>
+ </bpmn:sequenceFlow>
+ <bpmn:serviceTask id="Activity_09tqz8x" name="Create NS Instance record in DB" camunda:expression="${CreateNsTask.createNsInstanceInDb(execution)}">
+ <bpmn:incoming>Flow_1rkg44s</bpmn:incoming>
+ <bpmn:outgoing>Flow_1jvfwd2</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_1jvfwd2" sourceRef="Activity_09tqz8x" targetRef="Activity_1akc79d" />
+ <bpmn:serviceTask id="Activity_1akc79d" name="Create NS Instance in AAI" camunda:expression="${CreateNsTask.createNsInstanceInAai(execution)}">
+ <bpmn:incoming>Flow_1jvfwd2</bpmn:incoming>
+ <bpmn:outgoing>Flow_0e5hvno</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_0e5hvno" sourceRef="Activity_1akc79d" targetRef="Activity_03ht66t" />
+ <bpmn:serviceTask id="Activity_03ht66t" name="Set Create NS Response" camunda:expression="${CreateNsTask.setCreateNsResponse(execution)}">
+ <bpmn:incoming>Flow_0e5hvno</bpmn:incoming>
+ <bpmn:outgoing>Flow_1rtsvpm</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="Flow_1rtsvpm" sourceRef="Activity_03ht66t" targetRef="Activity_1r4l8w8" />
+ </bpmn:process>
+ <bpmn:error id="Error_0s855yd" name="java.lang.Exception" errorCode="java.lang.Exception" />
+ <bpmn:error id="Error_0rqvnym" name="CreateNsProcessingException" errorCode="CREATE_NS_PROCESSING_EXCEPTION" />
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="CreateNs">
+ <bpmndi:BPMNEdge id="Flow_1rtsvpm_di" bpmnElement="Flow_1rtsvpm">
+ <di:waypoint x="1160" y="157" />
+ <di:waypoint x="1160" y="230" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0e5hvno_di" bpmnElement="Flow_0e5hvno">
+ <di:waypoint x="1070" y="117" />
+ <di:waypoint x="1110" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1jvfwd2_di" bpmnElement="Flow_1jvfwd2">
+ <di:waypoint x="930" y="117" />
+ <di:waypoint x="970" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1yql1cm_di" bpmnElement="Flow_1yql1cm">
+ <di:waypoint x="760" y="142" />
+ <di:waypoint x="760" y="230" />
+ <di:waypoint x="668" y="230" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="766" y="183" width="19" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1rkg44s_di" bpmnElement="Flow_1rkg44s">
+ <di:waypoint x="785" y="117" />
+ <di:waypoint x="830" y="117" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="799" y="99" width="14" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1exrj2b_di" bpmnElement="Flow_1exrj2b">
+ <di:waypoint x="700" y="117" />
+ <di:waypoint x="735" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0qabgp7_di" bpmnElement="Flow_0qabgp7">
+ <di:waypoint x="565" y="117" />
+ <di:waypoint x="600" y="117" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="579" y="99" width="19" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1f4vi10_di" bpmnElement="Flow_1f4vi10">
+ <di:waypoint x="540" y="142" />
+ <di:waypoint x="540" y="230" />
+ <di:waypoint x="632" y="230" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="548" y="183" width="14" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_09582uw_di" bpmnElement="Flow_09582uw">
+ <di:waypoint x="480" y="117" />
+ <di:waypoint x="515" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0t87ov3_di" bpmnElement="Flow_0t87ov3">
+ <di:waypoint x="1160" y="310" />
+ <di:waypoint x="1160" y="357" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0y07mxe_di" bpmnElement="Flow_0y07mxe">
+ <di:waypoint x="350" y="117" />
+ <di:waypoint x="380" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_1tqn5q5_di" bpmnElement="Flow_1tqn5q5">
+ <di:waypoint x="208" y="117" />
+ <di:waypoint x="250" y="117" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+ <dc:Bounds x="172" y="99" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="158" y="142" width="67" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_0db1w1a_di" bpmnElement="EndEvent_1">
+ <dc:Bounds x="1142" y="357" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="1129" y="400" width="63" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_15ksfz6_di" bpmnElement="Activity_15ksfz6">
+ <dc:Bounds x="250" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1r4l8w8_di" bpmnElement="Activity_1r4l8w8">
+ <dc:Bounds x="1110" y="230" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Gateway_0fuwzjj_di" bpmnElement="Gateway_0fuwzjj" isMarkerVisible="true">
+ <dc:Bounds x="515" y="92" width="50" height="50" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="498" y="62" width="88" height="27" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_12yonzp_di" bpmnElement="Activity_12yonzp">
+ <dc:Bounds x="380" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_06ko4e2_di" bpmnElement="Activity_06ko4e2" isExpanded="true">
+ <dc:Bounds x="431" y="310" width="438" height="130" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="Flow_04xvpee_di" bpmnElement="Flow_04xvpee">
+ <di:waypoint x="681" y="373" />
+ <di:waypoint x="813" y="373" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0554tjv_di" bpmnElement="Flow_0554tjv">
+ <di:waypoint x="489" y="373" />
+ <di:waypoint x="581" y="373" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="Event_1ibvrn2_di" bpmnElement="Event_1ibvrn2">
+ <dc:Bounds x="453" y="355" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="459" y="398" width="24" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_02f7sr1_di" bpmnElement="Event_02f7sr1">
+ <dc:Bounds x="813" y="355" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="823" y="397" width="19" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1sj0nvr_di" bpmnElement="Activity_1sj0nvr">
+ <dc:Bounds x="581" y="333" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1dx9fz6_di" bpmnElement="Activity_1dx9fz6" isExpanded="true">
+ <dc:Bounds x="431" y="470" width="438" height="130" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="Flow_0oqv7vl_di" bpmnElement="Flow_0oqv7vl">
+ <di:waypoint x="680" y="533" />
+ <di:waypoint x="772" y="533" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="Flow_0j1otrx_di" bpmnElement="Flow_0j1otrx">
+ <di:waypoint x="522" y="533" />
+ <di:waypoint x="580" y="533" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="Event_0zne7ch_di" bpmnElement="Event_0zne7ch">
+ <dc:Bounds x="486" y="515" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="493" y="558" width="24" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_0bcyh7u_di" bpmnElement="Event_0bcyh7u">
+ <dc:Bounds x="772" y="515" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_15uwy90_di" bpmnElement="Activity_15uwy90">
+ <dc:Bounds x="580" y="493" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Event_0spfqz1_di" bpmnElement="Event_016q8gu">
+ <dc:Bounds x="632" y="212" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_0vlb2nk_di" bpmnElement="Activity_0vlb2nk">
+ <dc:Bounds x="600" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Gateway_0d7n517_di" bpmnElement="Gateway_0d7n517" isMarkerVisible="true">
+ <dc:Bounds x="735" y="92" width="50" height="50" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_09tqz8x_di" bpmnElement="Activity_09tqz8x">
+ <dc:Bounds x="830" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_1akc79d_di" bpmnElement="Activity_1akc79d">
+ <dc:Bounds x="970" y="77" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Activity_03ht66t_di" bpmnElement="Activity_03ht66t">
+ <dc:Bounds x="1110" y="77" 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/main/resources/META-INF/services/org.onap.so.client.RestProperties b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/META-INF/services/org.onap.so.client.RestProperties
new file mode 100644
index 0000000000..9d9ba7371a
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/META-INF/services/org.onap.so.client.RestProperties
@@ -0,0 +1 @@
+org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiPropertiesImpl \ 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/resources/MonitorSol003AdapterCreateJob.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterCreateJob.bpmn
new file mode 100644
index 0000000000..a9204ec442
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterCreateJob.bpmn
@@ -0,0 +1,160 @@
+<?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:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_12gnsyw" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.4.1">
+ <bpmn:process id="MonitorSol003AdapterCreateJob" name="MonitorSol003AdapterCreateJob" isExecutable="true">
+ <bpmn:startEvent id="StartEvent_1">
+ <bpmn:outgoing>SequenceFlow_1x3tbl0</bpmn:outgoing>
+ </bpmn:startEvent>
+ <bpmn:endEvent id="EndEvent_0rf1gde">
+ <bpmn:incoming>SequenceFlow_1543qy7</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:subProcess id="SubProcess_19j0v63">
+ <bpmn:incoming>SequenceFlow_1x3tbl0</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_1v4yr3f</bpmn:outgoing>
+ <bpmn:startEvent id="StartEvent_01r97z2">
+ <bpmn:outgoing>SequenceFlow_0s1plu9</bpmn:outgoing>
+ </bpmn:startEvent>
+ <bpmn:exclusiveGateway id="ExclusiveGateway_1hkl6yy" default="SequenceFlow_1vmxw9g">
+ <bpmn:incoming>SequenceFlow_153a3kp</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_1vmxw9g</bpmn:outgoing>
+ <bpmn:outgoing>SequenceFlow_0is7myf</bpmn:outgoing>
+ </bpmn:exclusiveGateway>
+ <bpmn:intermediateCatchEvent id="IntermediateCatchEvent_1besn3n" name="Wait between checks" camunda:asyncAfter="true">
+ <bpmn:incoming>SequenceFlow_1vmxw9g</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_0etw572</bpmn:outgoing>
+ <bpmn:timerEventDefinition id="TimerEventDefinition_0qgh11t">
+ <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT15S</bpmn:timeDuration>
+ </bpmn:timerEventDefinition>
+ </bpmn:intermediateCatchEvent>
+ <bpmn:endEvent id="EndEvent_1ohsce9">
+ <bpmn:incoming>SequenceFlow_0is7myf</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:sequenceFlow id="SequenceFlow_0s1plu9" sourceRef="StartEvent_01r97z2" targetRef="ServiceTask_17jlnng" />
+ <bpmn:sequenceFlow id="SequenceFlow_0etw572" sourceRef="IntermediateCatchEvent_1besn3n" targetRef="ServiceTask_17jlnng" />
+ <bpmn:serviceTask id="ServiceTask_17jlnng" name="&#10;Get Current Operation Status&#10;" camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterCreateJobTask.getCurrentOperationStatus(execution)}">
+ <bpmn:incoming>SequenceFlow_0etw572</bpmn:incoming>
+ <bpmn:incoming>SequenceFlow_0s1plu9</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_153a3kp</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="SequenceFlow_1vmxw9g" sourceRef="ExclusiveGateway_1hkl6yy" targetRef="IntermediateCatchEvent_1besn3n" />
+ <bpmn:sequenceFlow id="SequenceFlow_0is7myf" sourceRef="ExclusiveGateway_1hkl6yy" targetRef="EndEvent_1ohsce9">
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${MonitorSol003AdapterCreateJobTask.hasOperationFinished(execution)}</bpmn:conditionExpression>
+ </bpmn:sequenceFlow>
+ <bpmn:sequenceFlow id="SequenceFlow_153a3kp" sourceRef="ServiceTask_17jlnng" targetRef="ExclusiveGateway_1hkl6yy" />
+ </bpmn:subProcess>
+ <bpmn:endEvent id="EndEvent_1w3t3t0" name="Timeout Exception">
+ <bpmn:incoming>SequenceFlow_0bcgtzj</bpmn:incoming>
+ <bpmn:terminateEventDefinition id="TerminateEventDefinition_0fjecl3" />
+ </bpmn:endEvent>
+ <bpmn:boundaryEvent id="BoundaryEvent_0xiabzp" name="Overall Wait" attachedToRef="SubProcess_19j0v63">
+ <bpmn:outgoing>SequenceFlow_1i1o9sh</bpmn:outgoing>
+ <bpmn:timerEventDefinition id="TimerEventDefinition_10kqw61">
+ <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT3H</bpmn:timeDuration>
+ </bpmn:timerEventDefinition>
+ </bpmn:boundaryEvent>
+ <bpmn:sequenceFlow id="SequenceFlow_1v4yr3f" sourceRef="SubProcess_19j0v63" targetRef="ServiceTask_1gms128" />
+ <bpmn:sequenceFlow id="SequenceFlow_1i1o9sh" sourceRef="BoundaryEvent_0xiabzp" targetRef="ServiceTask_1s87b92" />
+ <bpmn:sequenceFlow id="SequenceFlow_1x3tbl0" sourceRef="StartEvent_1" targetRef="SubProcess_19j0v63" />
+ <bpmn:serviceTask id="ServiceTask_1s87b92" name="&#10;Time Out Log Failure&#10;" camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterCreateJobTask.timeOutLogFailue(execution)}">
+ <bpmn:incoming>SequenceFlow_1i1o9sh</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_0bcgtzj</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="SequenceFlow_0bcgtzj" sourceRef="ServiceTask_1s87b92" targetRef="EndEvent_1w3t3t0" />
+ <bpmn:serviceTask id="ServiceTask_1gms128" name="&#10;Check if operation was successful&#10;" camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterCreateJobTask.checkIfOperationWasSuccessful(execution)}">
+ <bpmn:incoming>SequenceFlow_1v4yr3f</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_1543qy7</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="SequenceFlow_1543qy7" sourceRef="ServiceTask_1gms128" targetRef="EndEvent_0rf1gde" />
+ </bpmn:process>
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="MonitorSol003AdapterCreateJob">
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+ <dc:Bounds x="161" y="330" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="EndEvent_0rf1gde_di" bpmnElement="EndEvent_0rf1gde">
+ <dc:Bounds x="1102" y="100" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="SubProcess_19j0v63_di" bpmnElement="SubProcess_19j0v63" isExpanded="true">
+ <dc:Bounds x="301" y="248" width="523" height="200" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="EndEvent_1w3t3t0_di" bpmnElement="EndEvent_1w3t3t0">
+ <dc:Bounds x="1102" y="322" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="1095" y="282" width="49" height="27" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="BoundaryEvent_0xiabzp_di" bpmnElement="BoundaryEvent_0xiabzp">
+ <dc:Bounds x="806" y="322" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="794" y="361" width="61" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_1v4yr3f_di" bpmnElement="SequenceFlow_1v4yr3f">
+ <di:waypoint x="563" y="248" />
+ <di:waypoint x="563" y="118" />
+ <di:waypoint x="923" y="118" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_1i1o9sh_di" bpmnElement="SequenceFlow_1i1o9sh">
+ <di:waypoint x="842" y="340" />
+ <di:waypoint x="923" y="340" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="StartEvent_01r97z2_di" bpmnElement="StartEvent_01r97z2">
+ <dc:Bounds x="330" y="306" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="ExclusiveGateway_1hkl6yy_di" bpmnElement="ExclusiveGateway_1hkl6yy" isMarkerVisible="true">
+ <dc:Bounds x="609" y="299" width="50" height="50" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="IntermediateCatchEvent_1besn3n_di" bpmnElement="IntermediateCatchEvent_1besn3n">
+ <dc:Bounds x="550" y="378" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="537" y="421" width="66" height="27" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="EndEvent_1ohsce9_di" bpmnElement="EndEvent_1ohsce9">
+ <dc:Bounds x="722" y="306" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_1x3tbl0_di" bpmnElement="SequenceFlow_1x3tbl0">
+ <di:waypoint x="197" y="348" />
+ <di:waypoint x="301" y="348" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="ServiceTask_17jlnng_di" bpmnElement="ServiceTask_17jlnng">
+ <dc:Bounds x="425" y="284" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_0s1plu9_di" bpmnElement="SequenceFlow_0s1plu9">
+ <di:waypoint x="366" y="324" />
+ <di:waypoint x="425" y="324" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_0etw572_di" bpmnElement="SequenceFlow_0etw572">
+ <di:waypoint x="550" y="396" />
+ <di:waypoint x="486" y="396" />
+ <di:waypoint x="486" y="367" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_1vmxw9g_di" bpmnElement="SequenceFlow_1vmxw9g">
+ <di:waypoint x="634" y="349" />
+ <di:waypoint x="634" y="396" />
+ <di:waypoint x="586" y="396" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_0is7myf_di" bpmnElement="SequenceFlow_0is7myf">
+ <di:waypoint x="659" y="324" />
+ <di:waypoint x="722" y="324" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_153a3kp_di" bpmnElement="SequenceFlow_153a3kp">
+ <di:waypoint x="525" y="324" />
+ <di:waypoint x="609" y="324" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="ServiceTask_1s87b92_di" bpmnElement="ServiceTask_1s87b92">
+ <dc:Bounds x="923" y="300" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_0bcgtzj_di" bpmnElement="SequenceFlow_0bcgtzj">
+ <di:waypoint x="1023" y="340" />
+ <di:waypoint x="1102" y="340" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="ServiceTask_1gms128_di" bpmnElement="ServiceTask_1gms128">
+ <dc:Bounds x="923" y="78" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_1543qy7_di" bpmnElement="SequenceFlow_1543qy7">
+ <di:waypoint x="1023" y="118" />
+ <di:waypoint x="1102" y="118" />
+ </bpmndi:BPMNEdge>
+ </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/MonitorSol003AdapterCreateNodeStatus.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterCreateNodeStatus.bpmn
new file mode 100644
index 0000000000..c0de5e0352
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterCreateNodeStatus.bpmn
@@ -0,0 +1,138 @@
+<?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:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1ko0frn" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.4.1">
+ <bpmn:process id="MonitorSol003AdapterCreateNodeStatus" name="MonitorSol003AdapterCreateNodeStatus" isExecutable="true">
+ <bpmn:startEvent id="StartEvent_0k0qfjb">
+ <bpmn:outgoing>SequenceFlow_1miob62</bpmn:outgoing>
+ </bpmn:startEvent>
+ <bpmn:subProcess id="SubProcess_10wotbc">
+ <bpmn:incoming>SequenceFlow_1miob62</bpmn:incoming>
+ <bpmn:startEvent id="StartEvent_0r9qf43">
+ <bpmn:outgoing>SequenceFlow_1moaz0q</bpmn:outgoing>
+ </bpmn:startEvent>
+ <bpmn:exclusiveGateway id="ExclusiveGateway_00xtlfj" default="SequenceFlow_1luu31f">
+ <bpmn:incoming>SequenceFlow_0qvy3sn</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_1rxbeqi</bpmn:outgoing>
+ <bpmn:outgoing>SequenceFlow_1luu31f</bpmn:outgoing>
+ </bpmn:exclusiveGateway>
+ <bpmn:intermediateCatchEvent id="IntermediateCatchEvent_0xuznv9" name="Wait between checks" camunda:asyncAfter="true">
+ <bpmn:incoming>SequenceFlow_1luu31f</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_09t51ao</bpmn:outgoing>
+ <bpmn:timerEventDefinition id="TimerEventDefinition_0vrbrge">
+ <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT15S</bpmn:timeDuration>
+ </bpmn:timerEventDefinition>
+ </bpmn:intermediateCatchEvent>
+ <bpmn:endEvent id="EndEvent_0tei3i9">
+ <bpmn:incoming>SequenceFlow_1rxbeqi</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:serviceTask id="ServiceTask_0y71su8" name="&#10;Get node status &#10;" camunda:asyncAfter="true" camunda:expression="${MonitorInstantiateSol003AdapterNodeTask.getNodeStatus(execution)}">
+ <bpmn:incoming>SequenceFlow_1moaz0q</bpmn:incoming>
+ <bpmn:incoming>SequenceFlow_09t51ao</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_0qvy3sn</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:sequenceFlow id="SequenceFlow_1rxbeqi" name="&#10;&#10;create vnf success&#10;&#10;" sourceRef="ExclusiveGateway_00xtlfj" targetRef="EndEvent_0tei3i9">
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${execution.getVariable("createVnfNodeStatus")}</bpmn:conditionExpression>
+ </bpmn:sequenceFlow>
+ <bpmn:sequenceFlow id="SequenceFlow_1luu31f" sourceRef="ExclusiveGateway_00xtlfj" targetRef="IntermediateCatchEvent_0xuznv9" />
+ <bpmn:sequenceFlow id="SequenceFlow_1moaz0q" sourceRef="StartEvent_0r9qf43" targetRef="ServiceTask_0y71su8" />
+ <bpmn:sequenceFlow id="SequenceFlow_0qvy3sn" sourceRef="ServiceTask_0y71su8" targetRef="ExclusiveGateway_00xtlfj" />
+ <bpmn:sequenceFlow id="SequenceFlow_09t51ao" sourceRef="IntermediateCatchEvent_0xuznv9" targetRef="ServiceTask_0y71su8" />
+ </bpmn:subProcess>
+ <bpmn:endEvent id="EndEvent_1b83rci" name="Timeout Exception">
+ <bpmn:incoming>SequenceFlow_0uiqnl8</bpmn:incoming>
+ <bpmn:terminateEventDefinition id="TerminateEventDefinition_12rjfva" />
+ </bpmn:endEvent>
+ <bpmn:serviceTask id="ServiceTask_12qp0ty" name="&#10;Time Out Log Failure&#10;" camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterNodeTask.timeOutLogFailue(execution)}">
+ <bpmn:incoming>SequenceFlow_0qcc5x4</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_0uiqnl8</bpmn:outgoing>
+ </bpmn:serviceTask>
+ <bpmn:boundaryEvent id="BoundaryEvent_1f5o5i9" name="Overall Wait" attachedToRef="SubProcess_10wotbc">
+ <bpmn:outgoing>SequenceFlow_0qcc5x4</bpmn:outgoing>
+ <bpmn:timerEventDefinition id="TimerEventDefinition_1t3ya63">
+ <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT3H</bpmn:timeDuration>
+ </bpmn:timerEventDefinition>
+ </bpmn:boundaryEvent>
+ <bpmn:sequenceFlow id="SequenceFlow_1miob62" sourceRef="StartEvent_0k0qfjb" targetRef="SubProcess_10wotbc" />
+ <bpmn:sequenceFlow id="SequenceFlow_0uiqnl8" sourceRef="ServiceTask_12qp0ty" targetRef="EndEvent_1b83rci" />
+ <bpmn:sequenceFlow id="SequenceFlow_0qcc5x4" sourceRef="BoundaryEvent_1f5o5i9" targetRef="ServiceTask_12qp0ty" />
+ </bpmn:process>
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="MonitorSol003AdapterCreateNodeStatus">
+ <bpmndi:BPMNShape id="StartEvent_0k0qfjb_di" bpmnElement="StartEvent_0k0qfjb">
+ <dc:Bounds x="155" y="159" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="SubProcess_10wotbc_di" bpmnElement="SubProcess_10wotbc" isExpanded="true">
+ <dc:Bounds x="293" y="77" width="523" height="200" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="EndEvent_1b83rci_di" bpmnElement="EndEvent_1b83rci">
+ <dc:Bounds x="1096" y="151" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="1089" y="111" width="49" height="27" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="ServiceTask_12qp0ty_di" bpmnElement="ServiceTask_12qp0ty">
+ <dc:Bounds x="917" y="129" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="BoundaryEvent_1f5o5i9_di" bpmnElement="BoundaryEvent_1f5o5i9">
+ <dc:Bounds x="800" y="151" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="788" y="190" width="61" height="14" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_1miob62_di" bpmnElement="SequenceFlow_1miob62">
+ <di:waypoint x="191" y="177" />
+ <di:waypoint x="293" y="177" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_0uiqnl8_di" bpmnElement="SequenceFlow_0uiqnl8">
+ <di:waypoint x="1017" y="169" />
+ <di:waypoint x="1096" y="169" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_0qcc5x4_di" bpmnElement="SequenceFlow_0qcc5x4">
+ <di:waypoint x="836" y="169" />
+ <di:waypoint x="917" y="169" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="StartEvent_0r9qf43_di" bpmnElement="StartEvent_0r9qf43">
+ <dc:Bounds x="324" y="135" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="ExclusiveGateway_00xtlfj_di" bpmnElement="ExclusiveGateway_00xtlfj" isMarkerVisible="true">
+ <dc:Bounds x="603" y="128" width="50" height="50" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="IntermediateCatchEvent_0xuznv9_di" bpmnElement="IntermediateCatchEvent_0xuznv9">
+ <dc:Bounds x="544" y="207" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="532" y="250" width="66" height="27" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="EndEvent_0tei3i9_di" bpmnElement="EndEvent_0tei3i9">
+ <dc:Bounds x="716" y="135" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="ServiceTask_0y71su8_di" bpmnElement="ServiceTask_0y71su8">
+ <dc:Bounds x="412" y="113" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_1rxbeqi_di" bpmnElement="SequenceFlow_1rxbeqi">
+ <di:waypoint x="653" y="153" />
+ <di:waypoint x="716" y="153" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="660" y="135" width="50" height="80" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_1luu31f_di" bpmnElement="SequenceFlow_1luu31f">
+ <di:waypoint x="628" y="178" />
+ <di:waypoint x="628" y="225" />
+ <di:waypoint x="580" y="225" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_1moaz0q_di" bpmnElement="SequenceFlow_1moaz0q">
+ <di:waypoint x="360" y="153" />
+ <di:waypoint x="412" y="153" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_0qvy3sn_di" bpmnElement="SequenceFlow_0qvy3sn">
+ <di:waypoint x="512" y="153" />
+ <di:waypoint x="603" y="153" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="SequenceFlow_09t51ao_di" bpmnElement="SequenceFlow_09t51ao">
+ <di:waypoint x="544" y="225" />
+ <di:waypoint x="451" y="225" />
+ <di:waypoint x="452" y="193" />
+ </bpmndi:BPMNEdge>
+ </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/lcm/bpmn/flows/BaseTest.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/lcm/bpmn/flows/BaseTest.java
new file mode 100644
index 0000000000..86f2879966
--- /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/lcm/bpmn/flows/BaseTest.java
@@ -0,0 +1,150 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows;
+
+import static org.camunda.bpm.engine.history.HistoricProcessInstance.STATE_ACTIVE;
+import static org.slf4j.LoggerFactory.getLogger;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import org.camunda.bpm.engine.HistoryService;
+import org.camunda.bpm.engine.RuntimeService;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
+import org.camunda.bpm.engine.history.HistoricVariableInstance;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+import org.junit.runner.RunWith;
+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.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+import com.github.tomakehurst.wiremock.WireMockServer;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ActiveProfiles("test")
+@ContextConfiguration
+@AutoConfigureWireMock(port = 0)
+public abstract class BaseTest {
+ protected static final String ETSI_CATALOG_URL = "http://modeling-etsicatalog.onap:8806/api";
+ protected static final String SOL003_ADAPTER_ENDPOINT_URL = "https://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1";
+ protected static final String GLOBAL_CUSTOMER_ID = UUID.randomUUID().toString();
+ protected static final String NSD_INVARIANT_ID = UUID.randomUUID().toString();
+ protected static final String SERVICE_TYPE = "NetworkService";
+ protected 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}";
+ protected static final String RANDOM_JOB_ID = UUID.randomUUID().toString();
+
+ protected static final Logger logger = getLogger(BaseTest.class);
+
+ private static final long TIME_OUT_IN_SECONDS = 60;
+ private static final int SLEEP_TIME_IN_SECONDS = 5;
+
+ @Autowired
+ private HistoryService historyService;
+
+ @Autowired
+ private RuntimeService runtimeService;
+
+ @Autowired
+ protected DatabaseServiceProvider databaseServiceProvider;
+
+ @Autowired
+ protected WireMockServer wireMockServer;
+
+ public NfvoJob createNewNfvoJob(final String jobAction, final String nsdId, final String nsName) {
+ final NfvoJob newJob = new NfvoJob().startTime(LocalDateTime.now()).jobType("NS").jobAction(JobAction.CREATE)
+ .status(JobStatusEnum.STARTING).resourceId(nsdId).resourceName(nsName);
+ databaseServiceProvider.addJob(newJob);
+ return newJob;
+ }
+
+ public Optional<NfvoJob> getNfvoJob(final String jobId) {
+ return databaseServiceProvider.getJob(jobId);
+ }
+
+ public Optional<NfvoJob> getJobByResourceId(final String resourceId) {
+ return databaseServiceProvider.getJobByResourceId(resourceId);
+ }
+
+ public ProcessInstance executeWorkflow(final String processDefinitionKey, final String businessKey,
+ final Map<String, Object> variables) {
+ return runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);
+ }
+
+ public HistoricProcessInstance getHistoricProcessInstance(final String processInstanceId) {
+ return historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
+ }
+
+ public HistoricVariableInstance getVariable(final String processInstanceId, final String name) {
+ return historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId)
+ .variableName(name).singleResult();
+ }
+
+ public List<HistoricVariableInstance> getVariables(final String processInstanceId) {
+ return historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).list();
+ }
+
+ public boolean waitForProcessInstanceToFinish(final String processInstanceId) throws InterruptedException {
+ final long startTimeInMillis = System.currentTimeMillis();
+ final long timeOutTime = startTimeInMillis + TimeUnit.SECONDS.toMillis(TIME_OUT_IN_SECONDS);
+ while (timeOutTime > System.currentTimeMillis()) {
+
+ if (isProcessEndedByProcessInstanceId(processInstanceId)) {
+ logger.info("processInstanceId: {} is finished", processInstanceId);
+ return true;
+ }
+ logger.info("processInstanceId: {} is still running", processInstanceId);
+ logger.info("Process instance {} not finished yet, will try again in {} seconds", processInstanceId,
+ SLEEP_TIME_IN_SECONDS);
+ TimeUnit.SECONDS.sleep(SLEEP_TIME_IN_SECONDS);
+ }
+ logger.warn("Timeout {} process didn't finished ", processInstanceId);
+ return false;
+ }
+
+
+ public boolean isProcessEndedByProcessInstanceId(final String processInstanceId) {
+ return !isProcessInstanceActive(processInstanceId) && isProcessInstanceEnded(processInstanceId);
+ }
+
+ private boolean isProcessInstanceActive(final String processInstanceId) {
+ final HistoricProcessInstance processInstance = getHistoricProcessInstance(processInstanceId);
+ return processInstance != null && STATE_ACTIVE.equalsIgnoreCase(processInstance.getState());
+ }
+
+ private boolean isProcessInstanceEnded(final String processInstanceId) {
+ return runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult() == null;
+ }
+
+}
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/lcm/bpmn/flows/DefaultToShortClassNameBeanNameGenerator.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/lcm/bpmn/flows/DefaultToShortClassNameBeanNameGenerator.java
new file mode 100644
index 0000000000..f91cf9d0c3
--- /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/lcm/bpmn/flows/DefaultToShortClassNameBeanNameGenerator.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.AnnotationBeanNameGenerator;
+import org.springframework.util.ClassUtils;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class DefaultToShortClassNameBeanNameGenerator extends AnnotationBeanNameGenerator {
+
+ @Override
+ protected String buildDefaultBeanName(final BeanDefinition definition) {
+ return ClassUtils.getShortName(definition.getBeanClassName());
+ }
+}
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/lcm/bpmn/flows/TestApplication.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/lcm/bpmn/flows/TestApplication.java
new file mode 100644
index 0000000000..18d601930c
--- /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/lcm/bpmn/flows/TestApplication.java
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.context.annotation.ComponentScan.Filter;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@SpringBootApplication(scanBasePackages = {"org.onap.so"})
+@EnableAutoConfiguration(exclude = {JacksonAutoConfiguration.class})
+@ComponentScan(basePackages = {"org.onap"}, nameGenerator = DefaultToShortClassNameBeanNameGenerator.class,
+ excludeFilters = {@Filter(type = FilterType.ANNOTATION, classes = SpringBootApplication.class)})
+public class TestApplication {
+
+ public static void main(final String[] args) {
+ new SpringApplication(TestApplication.class).run(args);
+ }
+
+}
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/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParserTest.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/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParserTest.java
new file mode 100644
index 0000000000..2bebf1c30a
--- /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/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParserTest.java
@@ -0,0 +1,87 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Map;
+import java.util.Optional;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.TestApplication;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ActiveProfiles("test")
+public class NetworkServiceDescriptorParserTest {
+
+ private static final String VALID_ETSI_NSD_FILE = "src/test/resources/ns.csar";
+ private static final String INVALID_ETSI_NSD_FILE = "src/test/resources/invalid_ns.csar";
+
+ @Autowired
+ private NetworkServiceDescriptorParser objUnderTest;
+
+ @Test
+ public void testValidEtsiNsd_ableToParseIt() throws IOException {
+ final byte[] zipBytes = Files.readAllBytes(Paths.get(getAbsolutePath(VALID_ETSI_NSD_FILE)));
+ final Optional<NetworkServiceDescriptor> optional = objUnderTest.parse(zipBytes);
+ assertTrue(optional.isPresent());
+ final NetworkServiceDescriptor actualNsd = optional.get();
+ assertEquals(NetworkServiceDescriptorParser.NS_NODE_TYPE, actualNsd.getType());
+ assertFalse(actualNsd.getProperties().isEmpty());
+
+ final Map<String, Object> actualNsdProperties = actualNsd.getProperties();
+ assertEquals(5, actualNsdProperties.size());
+ assertEquals("ffdddc5d-a44b-45ae-8fc3-e6551cce350f", actualNsdProperties.get("descriptor_id"));
+ assertEquals(5, actualNsd.getVnfs().size());
+
+ }
+
+ @Test
+ public void testEmptyEtsiNsd_returnEmptyOptional() throws IOException {
+ assertFalse(objUnderTest.parse(new byte[] {}).isPresent());
+ }
+
+ @Test
+ public void testInvalidEtsiNsd_returnEmptyOptional() throws IOException {
+ final byte[] zipBytes = Files.readAllBytes(Paths.get(getAbsolutePath(INVALID_ETSI_NSD_FILE)));
+ assertFalse(objUnderTest.parse(zipBytes).isPresent());
+ }
+
+ private String getAbsolutePath(final String path) {
+ final File file = new File(path);
+ return file.getAbsolutePath();
+ }
+
+}
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/CreateNsTaskTest.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/CreateNsTaskTest.java
new file mode 100644
index 0000000000..05213a344f
--- /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/CreateNsTaskTest.java
@@ -0,0 +1,387 @@
+/*-
+ * ============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.put;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_REST_TEMPLATE_BEAN;
+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.withStatus;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
+import org.camunda.bpm.engine.history.HistoricVariableInstance;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.BaseTest;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants;
+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.bpmn.flows.service.JobExecutorService;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.WorkflowQueryService;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance.NsStateEnum;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+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.github.tomakehurst.wiremock.client.WireMock;
+import com.google.gson.Gson;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class CreateNsTaskTest extends BaseTest {
+ private static final String NSD_ID = UUID.randomUUID().toString();
+ private static final String NS_NAME = "CreateNetworkService-" + NSD_ID;
+ private static final String CREATE_NS_WORKFLOW_NAME = "CreateNs";
+
+ @Autowired
+ @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN)
+ private RestTemplate restTemplate;
+
+ @Autowired
+ private GsonProvider gsonProvider;
+
+ @Autowired
+ private JobExecutorService objUnderTest;
+
+ @Autowired
+ private WorkflowQueryService workflowQueryService;
+
+ private MockRestServiceServer mockRestServiceServer;
+
+ private Gson gson;
+
+ @Before
+ public void before() {
+ wireMockServer.resetAll();
+ final MockRestServiceServer.MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(restTemplate);
+ builder.ignoreExpectOrder(true);
+ mockRestServiceServer = builder.build();
+ gson = gsonProvider.getGson();
+ restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson));
+ }
+
+ @After
+ public void after() {
+ wireMockServer.resetAll();
+ mockRestServiceServer.reset();
+ }
+
+ @Test
+ public void testCreateNsWorkflow_SuccessfullCase() throws InterruptedException {
+ final CreateNsRequest createNsRequest = getCreateNsRequest();
+
+ mockEtsiCatalogEndpoints();
+ mockAAIEndpoints(createNsRequest);
+
+ final NsInstancesNsInstance nsResponse =
+ objUnderTest.runCreateNsJob(createNsRequest, GLOBAL_CUSTOMER_ID, SERVICE_TYPE);
+ assertNotNull(nsResponse);
+ assertNotNull(nsResponse.getId());
+
+ final Optional<NfvoJob> optional = getJobByResourceId(createNsRequest.getNsdId());
+ assertTrue(optional.isPresent());
+ final NfvoJob nfvoJob = optional.get();
+
+ assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId()));
+
+ mockRestServiceServer.verify();
+ final HistoricProcessInstance historicProcessInstance =
+ getHistoricProcessInstance(nfvoJob.getProcessInstanceId());
+ assertNotNull(historicProcessInstance);
+
+ assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+ assertTrue(databaseServiceProvider.isNsInstExists(createNsRequest.getNsName()));
+
+ final NfvoJob actualJob = optional.get();
+ assertEquals(JobStatusEnum.FINISHED, actualJob.getStatus());
+
+ assertEquals(NS_NAME, nsResponse.getNsInstanceName());
+ assertEquals(NsStateEnum.NOT_INSTANTIATED, nsResponse.getNsState());
+
+ final HistoricVariableInstance doesNsPackageExistsVar =
+ getVariable(nfvoJob.getProcessInstanceId(), "doesNsPackageExists");
+ assertNotNull(doesNsPackageExistsVar);
+ assertTrue((boolean) doesNsPackageExistsVar.getValue());
+
+ final HistoricVariableInstance doesNsInstanceExistsVar =
+ getVariable(nfvoJob.getProcessInstanceId(), "doesNsInstanceExists");
+ assertNotNull(doesNsInstanceExistsVar);
+ assertFalse((boolean) doesNsInstanceExistsVar.getValue());
+
+ }
+
+ @Test
+ public void testCreateNsWorkflow_FailsToGetNsPackage() throws InterruptedException {
+ final String nsdId = UUID.randomUUID().toString();
+ final String nsdName = NS_NAME + "-" + System.currentTimeMillis();
+ final CreateNsRequest createNsRequest = getCreateNsRequest(nsdId, nsdName);
+
+ mockRestServiceServer.expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId))
+ .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.NOT_FOUND));
+
+ try {
+ objUnderTest.runCreateNsJob(createNsRequest, GLOBAL_CUSTOMER_ID, SERVICE_TYPE);
+ fail("runCreateNsJob should throw exception");
+ } catch (final Exception exception) {
+ assertEquals(NsRequestProcessingException.class, exception.getClass());
+ }
+
+ final Optional<NfvoJob> optional = getJobByResourceId(createNsRequest.getNsdId());
+ assertTrue(optional.isPresent());
+ final NfvoJob nfvoJob = optional.get();
+ assertEquals(JobStatusEnum.ERROR, nfvoJob.getStatus());
+
+ assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId()));
+
+ mockRestServiceServer.verify();
+ final HistoricProcessInstance historicProcessInstance =
+ getHistoricProcessInstance(nfvoJob.getProcessInstanceId());
+ assertNotNull(historicProcessInstance);
+
+ assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+
+
+ final HistoricVariableInstance nsResponseVariable =
+ getVariable(nfvoJob.getProcessInstanceId(), CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME);
+ assertNull(nsResponseVariable);
+
+ final Optional<InlineResponse400> problemDetailsOptional =
+ workflowQueryService.getProblemDetails(nfvoJob.getProcessInstanceId());
+ assertTrue(problemDetailsOptional.isPresent());
+
+ final InlineResponse400 problemDetails = problemDetailsOptional.get();
+ assertNotNull(problemDetails);
+ assertNotNull(problemDetails.getDetail());
+
+ final HistoricVariableInstance doesNsPackageExistsVar =
+ getVariable(nfvoJob.getProcessInstanceId(), "doesNsPackageExists");
+ assertNotNull(doesNsPackageExistsVar);
+ assertFalse((boolean) doesNsPackageExistsVar.getValue());
+ assertEquals("Unexpected exception occured while getting ns package using nsdId: " + nsdId,
+ problemDetails.getDetail());
+ }
+
+ @Test
+ public void testCreateNsWorkflow_FailsToFindJobUsingJobId() throws InterruptedException {
+ final String nsdId = UUID.randomUUID().toString();
+ final String nsdName = NS_NAME + "-" + System.currentTimeMillis();
+ final CreateNsRequest createNsRequest = getCreateNsRequest(nsdId, nsdName);
+
+ final String randomJobId = UUID.randomUUID().toString();
+ final ProcessInstance processInstance =
+ executeWorkflow(CREATE_NS_WORKFLOW_NAME, randomJobId, getVariables(randomJobId, createNsRequest));
+ assertTrue(waitForProcessInstanceToFinish(processInstance.getProcessInstanceId()));
+
+ mockRestServiceServer.verify();
+ final HistoricProcessInstance historicProcessInstance =
+ getHistoricProcessInstance(processInstance.getProcessInstanceId());
+ assertNotNull(historicProcessInstance);
+
+ assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+
+ final HistoricVariableInstance nsResponseVariable = getVariable(processInstance.getProcessInstanceId(),
+ CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME);
+
+ assertNull(nsResponseVariable);
+
+ final HistoricVariableInstance workflowExceptionVariable = getVariable(processInstance.getProcessInstanceId(),
+ CamundaVariableNameConstants.CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME);
+
+ final InlineResponse400 problemDetails = (InlineResponse400) workflowExceptionVariable.getValue();
+ assertNotNull(problemDetails);
+ assertNotNull(problemDetails.getDetail());
+ assertEquals("Unable to find job using job id: " + randomJobId, problemDetails.getDetail());
+
+ }
+
+ @Test
+ public void testCreateNsWorkflow_NsInstanceExistsInDb() throws InterruptedException {
+ final String nsdId = UUID.randomUUID().toString();
+ final String nsdName = NS_NAME + "-" + System.currentTimeMillis();
+ final CreateNsRequest createNsRequest = getCreateNsRequest(nsdId, nsdName);
+
+ databaseServiceProvider.saveNfvoNsInst(new NfvoNsInst().nsInstId(nsdId).name(createNsRequest.getNsName())
+ .nsPackageId(UUID.randomUUID().toString()).nsdId(nsdId).nsdInvariantId(nsdId)
+ .description(createNsRequest.getNsDescription()).status(State.INSTANTIATED)
+ .statusUpdatedTime(LocalDateTime.now()).globalCustomerId(GLOBAL_CUSTOMER_ID).serviceType(SERVICE_TYPE));
+
+ mockEtsiCatalogEndpoints(nsdId);
+
+ try {
+ objUnderTest.runCreateNsJob(createNsRequest, GLOBAL_CUSTOMER_ID, SERVICE_TYPE);
+ fail("runCreateNsJob should throw exception");
+ } catch (final Exception exception) {
+ assertEquals(NsRequestProcessingException.class, exception.getClass());
+ }
+
+ final Optional<NfvoJob> optional = getJobByResourceId(createNsRequest.getNsdId());
+ assertTrue(optional.isPresent());
+ final NfvoJob nfvoJob = optional.get();
+ assertEquals(JobStatusEnum.ERROR, nfvoJob.getStatus());
+
+ assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId()));
+
+ mockRestServiceServer.verify();
+ final HistoricProcessInstance historicProcessInstance =
+ getHistoricProcessInstance(nfvoJob.getProcessInstanceId());
+ assertNotNull(historicProcessInstance);
+
+ assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+ assertTrue(databaseServiceProvider.isNsInstExists(createNsRequest.getNsName()));
+
+ final HistoricVariableInstance historicVariableInstance =
+ getVariable(nfvoJob.getProcessInstanceId(), CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME);
+
+ assertNull(historicVariableInstance);
+
+ final Optional<InlineResponse400> problemDetailsOptional =
+ workflowQueryService.getProblemDetails(nfvoJob.getProcessInstanceId());
+
+ final InlineResponse400 problemDetails = problemDetailsOptional.get();
+ assertNotNull(problemDetails);
+ assertNotNull(problemDetails.getDetail());
+ assertTrue(problemDetails.getDetail().startsWith("Ns Instance already exists in database"));
+
+ final HistoricVariableInstance doesNsInstanceExistsVar =
+ getVariable(nfvoJob.getProcessInstanceId(), "doesNsInstanceExists");
+ assertNotNull(doesNsInstanceExistsVar);
+ assertTrue((boolean) doesNsInstanceExistsVar.getValue());
+
+ }
+
+ @Test
+ public void testCreateNsWorkflow_FailToCreateResouceInAai() throws InterruptedException {
+ final String nsdId = UUID.randomUUID().toString();
+ final String nsdName = NS_NAME + "-" + System.currentTimeMillis();
+ final CreateNsRequest createNsRequest = getCreateNsRequest(nsdId, nsdName);
+
+ mockEtsiCatalogEndpoints(nsdId);
+
+ final String modelEndpoint = getAiaServiceInstancelEndPoint(createNsRequest);
+ wireMockServer.stubFor(put(urlMatching(modelEndpoint)).willReturn(WireMock.serverError()));
+ wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(WireMock.serverError()));
+
+ try {
+ objUnderTest.runCreateNsJob(createNsRequest, GLOBAL_CUSTOMER_ID, SERVICE_TYPE);
+ fail("runCreateNsJob should throw exception");
+ } catch (final Exception exception) {
+ assertEquals(NsRequestProcessingException.class, exception.getClass());
+ }
+ final Optional<NfvoJob> optional = getJobByResourceId(createNsRequest.getNsdId());
+ assertTrue(optional.isPresent());
+ final NfvoJob nfvoJob = optional.get();
+ assertEquals(JobStatusEnum.ERROR, nfvoJob.getStatus());
+
+ mockRestServiceServer.verify();
+ final HistoricProcessInstance historicProcessInstance =
+ getHistoricProcessInstance(nfvoJob.getProcessInstanceId());
+ assertNotNull(historicProcessInstance);
+
+ assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+ assertTrue(databaseServiceProvider.isNsInstExists(createNsRequest.getNsName()));
+
+ final Optional<InlineResponse400> problemDetailsOptional =
+ workflowQueryService.getProblemDetails(nfvoJob.getProcessInstanceId());
+
+ final InlineResponse400 problemDetails = problemDetailsOptional.get();
+ assertNotNull(problemDetails);
+ assertEquals("Unable to Create Service Instance in AAI", problemDetails.getDetail());
+
+ }
+
+ private void mockAAIEndpoints(final CreateNsRequest createNsRequest) {
+ final String modelEndpoint = getAiaServiceInstancelEndPoint(createNsRequest);
+
+ wireMockServer.stubFor(put(urlMatching(modelEndpoint)).willReturn(ok()));
+ wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(notFound()));
+ }
+
+ private String getAiaServiceInstancelEndPoint(final CreateNsRequest createNsRequest) {
+ return "/aai/v[0-9]+/business/customers/customer/" + GLOBAL_CUSTOMER_ID
+ + "/service-subscriptions/service-subscription/" + SERVICE_TYPE
+ + "/service-instances/service-instance/.*";
+ }
+
+ private void mockEtsiCatalogEndpoints(final String nsdId) {
+ mockRestServiceServer.expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withSuccess(gson.toJson(getNSPackageModel(NSD_ID)), MediaType.APPLICATION_JSON));
+ }
+
+ private void mockEtsiCatalogEndpoints() {
+ mockEtsiCatalogEndpoints(NSD_ID);;
+ }
+
+ private NsdInfo getNSPackageModel(final String nsdId) {
+ return new NsdInfo().id(nsdId).nsdId(nsdId).nsdInvariantId(NSD_INVARIANT_ID).nsdName("vcpe").nsdDesigner("ONAP")
+ .vnfPkgIds(Arrays.asList(GLOBAL_CUSTOMER_ID));
+ }
+
+ private CreateNsRequest getCreateNsRequest() {
+ return getCreateNsRequest(NSD_ID, NS_NAME);
+ }
+
+ private CreateNsRequest getCreateNsRequest(final String nsdId, final String nsName) {
+ return new CreateNsRequest().nsdId(nsdId).nsName(nsName);
+ }
+
+ private Map<String, Object> getVariables(final String jobId, final CreateNsRequest createNsRequest) {
+ final Map<String, Object> variables = new HashMap<>();
+ variables.put(CamundaVariableNameConstants.JOB_ID_PARAM_NAME, jobId);
+ variables.put(CamundaVariableNameConstants.CREATE_NS_REQUEST_PARAM_NAME, createNsRequest);
+ variables.put(CamundaVariableNameConstants.GLOBAL_CUSTOMER_ID_PARAM_NAME, GLOBAL_CUSTOMER_ID);
+ variables.put(CamundaVariableNameConstants.SERVICE_TYPE_PARAM_NAME, SERVICE_TYPE);
+
+ return variables;
+ }
+
+}
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..00e9433eac
--- /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,327 @@
+/*-
+ * ============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.aaiclient.client.aai.AAIVersion.V19;
+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.aaiclient.client.aai.entities.Results;
+import org.onap.aaiclient.client.graphinventory.entities.Resource;
+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.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+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) throws JsonProcessingException {
+ final String modelEndpoint = "/aai/" + V19 + "/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\"}")));
+
+ wireMockServer.stubFor(get(urlMatching("/aai/" + V19 + "/nodes/service-instances/service-instance/.*"))
+ .willReturn(okJson(getResourceResultsResponseAsJson(nsdId))));
+
+ wireMockServer.stubFor(
+ put(urlMatching("/aai/" + V19 + "/cloud-infrastructure/cloud-regions/cloud-region/" + CLOUD_OWNER + "/"
+ + CLOUD_REGION + "/tenants/tenant/" + TENANT_ID + "/relationship-list/relationship"))
+ .willReturn(ok()));
+
+ }
+
+ private String getResourceResultsResponseAsJson(final String nsdId) throws JsonProcessingException {
+ final Resource resource = new Resource();
+ resource.setResourceType("service-instance");
+ resource.setResourceLink("/aai/" + V19 + "/business/customers/customer/" + GLOBAL_CUSTOMER_ID
+ + "/service-subscriptions/service-subscription/NetworkService/service-instances/service-instance/"
+ + nsdId);
+ final Results<Resource> results = new Results<>();
+ results.getResult().add(resource);
+ return new ObjectMapper().writeValueAsString(results);
+ }
+
+}
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/MonitorInstantiateSol003AdapterNodeTaskTest.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/MonitorInstantiateSol003AdapterNodeTaskTest.java
new file mode 100644
index 0000000000..ea720cd73b
--- /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/MonitorInstantiateSol003AdapterNodeTaskTest.java
@@ -0,0 +1,93 @@
+/*-
+ * ============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.ok;
+import static com.github.tomakehurst.wiremock.client.WireMock.okJson;
+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 java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
+import org.camunda.bpm.engine.history.HistoricVariableInstance;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.BaseTest;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks.MonitorInstantiateSol003AdapterNodeTask;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class MonitorInstantiateSol003AdapterNodeTaskTest extends BaseTest {
+
+ private static final String RANDOWM_GENERIC_VNF_ID = UUID.randomUUID().toString();
+ private static final String MONITOR_SOL003_ADAPTER_CREATE_NODE_STATUS_WORKFLOW =
+ "MonitorSol003AdapterCreateNodeStatus";
+
+ @Before
+ public void before() {
+ wireMockServer.resetAll();
+ }
+
+ @Test
+ public void testMonitorSol003AdapterCreateNodeStatus_SuccessfullCase() throws InterruptedException {
+
+ final String modelEndpoint = "/aai/v[0-9]+/network/generic-vnfs/generic-vnf/" + UUID_REGEX;
+
+ wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(ok())
+ .willReturn(okJson("{\"orchestration-status\": \"Created\"}")));
+
+
+ final ProcessInstance processInstance = executeWorkflow(MONITOR_SOL003_ADAPTER_CREATE_NODE_STATUS_WORKFLOW,
+ RANDOM_JOB_ID, getVariables(RANDOM_JOB_ID, RANDOWM_GENERIC_VNF_ID));
+
+ assertTrue(waitForProcessInstanceToFinish(processInstance.getProcessInstanceId()));
+
+ final HistoricProcessInstance historicProcessInstance =
+ getHistoricProcessInstance(processInstance.getProcessInstanceId());
+ assertNotNull(historicProcessInstance);
+
+ assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+
+ final HistoricVariableInstance nsResponseVariable = getVariable(processInstance.getProcessInstanceId(),
+ MonitorInstantiateSol003AdapterNodeTask.CREATE_VNF_NODE_STATUS);
+
+ assertNotNull(nsResponseVariable);
+ assertTrue((boolean) nsResponseVariable.getValue());
+
+ }
+
+ private Map<String, Object> getVariables(final String jobId, final String vnfId) {
+ final Map<String, Object> variables = new HashMap<>();
+ variables.put(CamundaVariableNameConstants.JOB_ID_PARAM_NAME, jobId);
+ variables.put(CamundaVariableNameConstants.NF_INST_ID_PARAM_NAME, vnfId);
+
+ return variables;
+ }
+
+
+}
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/MonitorSol003AdapterCreateJobTaskTest.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/MonitorSol003AdapterCreateJobTaskTest.java
new file mode 100644
index 0000000000..ff5c2a9105
--- /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/MonitorSol003AdapterCreateJobTaskTest.java
@@ -0,0 +1,156 @@
+/*-
+ * ============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 org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum.COMPLETED;
+import static org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStatusRetrievalStatusEnum.STATUS_FOUND;
+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.match.MockRestRequestMatchers.method;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
+import java.util.HashMap;
+import java.util.Map;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
+import org.camunda.bpm.engine.history.HistoricVariableInstance;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+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.QueryJobResponse;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.BaseTest;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+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 Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class MonitorSol003AdapterCreateJobTaskTest extends BaseTest {
+
+ private static final String MONITOR_SOL003_ADAPTER_CREATE_JOB_WORKFLOW = "MonitorSol003AdapterCreateJob";
+
+ @Autowired
+ @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN)
+ private RestTemplate restTemplate;
+
+ @Autowired
+ private GsonProvider gsonProvider;
+
+ private MockRestServiceServer mockRestServiceServer;
+ private Gson gson;
+
+ @Before
+ public void before() {
+ wireMockServer.resetAll();
+ final MockRestServiceServer.MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(restTemplate);
+ builder.ignoreExpectOrder(true);
+ mockRestServiceServer = builder.build();
+
+ gson = gsonProvider.getGson();
+ restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson));
+ }
+
+
+ @Test
+ public void testMonitorSol003AdapterCreateJobTaskWorkflow_SuccessfullCase() throws InterruptedException {
+
+ mockRestServiceServer.expect(requestTo(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/" + RANDOM_JOB_ID))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withSuccess(gson.toJson(getQueryJobResponse()), MediaType.APPLICATION_JSON));
+
+ final ProcessInstance processInstance = executeWorkflow(MONITOR_SOL003_ADAPTER_CREATE_JOB_WORKFLOW,
+ RANDOM_JOB_ID, getVariables(RANDOM_JOB_ID, new CreateVnfResponse().jobId(RANDOM_JOB_ID)));
+
+ assertTrue(waitForProcessInstanceToFinish(processInstance.getProcessInstanceId()));
+
+ final HistoricProcessInstance historicProcessInstance =
+ getHistoricProcessInstance(processInstance.getProcessInstanceId());
+ assertNotNull(historicProcessInstance);
+
+ assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+
+ final HistoricVariableInstance nsResponseVariable = getVariable(processInstance.getProcessInstanceId(),
+ CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME);
+
+ assertNotNull(nsResponseVariable);
+ assertEquals(COMPLETED, nsResponseVariable.getValue());
+
+ }
+
+ @Test
+ public void testMonitorSol003AdapterCreateJobTaskWorkflow_FailurelCase() throws InterruptedException {
+
+ mockRestServiceServer.expect(requestTo(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/" + RANDOM_JOB_ID))
+ .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.NOT_FOUND));
+
+ final ProcessInstance processInstance = executeWorkflow(MONITOR_SOL003_ADAPTER_CREATE_JOB_WORKFLOW,
+ RANDOM_JOB_ID, getVariables(RANDOM_JOB_ID, new CreateVnfResponse().jobId(RANDOM_JOB_ID)));
+
+ assertTrue(waitForProcessInstanceToFinish(processInstance.getProcessInstanceId()));
+
+ final HistoricProcessInstance historicProcessInstance =
+ getHistoricProcessInstance(processInstance.getProcessInstanceId());
+ assertNotNull(historicProcessInstance);
+
+ assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+
+ final HistoricVariableInstance nsResponseVariable = getVariable(processInstance.getProcessInstanceId(),
+ CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME);
+
+ assertNull(nsResponseVariable);
+
+ final HistoricVariableInstance workflowExceptionVariable = getVariable(processInstance.getProcessInstanceId(),
+ CamundaVariableNameConstants.CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME);
+
+ final InlineResponse400 problemDetails = (InlineResponse400) workflowExceptionVariable.getValue();
+ assertNotNull(problemDetails);
+ assertNotNull(problemDetails.getDetail());
+ }
+
+
+ private QueryJobResponse getQueryJobResponse() {
+ return new QueryJobResponse().id(RANDOM_JOB_ID).operationState(COMPLETED)
+ .operationStatusRetrievalStatus(STATUS_FOUND);
+ }
+
+ private Map<String, Object> getVariables(final String jobId, final CreateVnfResponse createVnfResponse) {
+ final Map<String, Object> variables = new HashMap<>();
+ variables.put(CamundaVariableNameConstants.JOB_ID_PARAM_NAME, jobId);
+ variables.put(CamundaVariableNameConstants.CREATE_VNF_RESPONSE_PARAM_NAME, createVnfResponse);
+
+ return variables;
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml
new file mode 100644
index 0000000000..1fabfbaac9
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml
@@ -0,0 +1,49 @@
+# Copyright © 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.
+spring:
+ main:
+ allow-bean-definition-overriding: true
+ datasource:
+ hikari:
+ camunda:
+ jdbcUrl: jdbc:h2:mem:example-simple;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
+ driver-class-name: org.h2.Driver
+ pool-name: ns-lcm-bpmn-pool
+ registerMbeans: true
+ nfvo:
+ jdbcUrl: jdbc:h2:mem:nfvo;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS nfvo;
+ driver-class-name: org.h2.Driver
+ pool-name: ns-lcm-bpmn-pool
+ registerMbeans: true
+ jpa:
+ generate-ddl: true
+ hibernate:
+ ddl-auto: create
+hibernate:
+ dialect: org.hibernate.dialect.H2Dialect
+ hbm2ddl:
+ auto: create
+aai:
+ version: v19
+ endpoint: http://localhost:${wiremock.server.port}
+etsi-catalog-manager:
+ base:
+ endpoint: http://modeling-etsicatalog.onap:8806/api
+so-etsi-ns-lcm-workflow-engine:
+ requesttimeout:
+ timeoutInSeconds: 60
+
+logging:
+ level:
+ org.reflections.Reflections: ERROR \ 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/test/resources/invalid_ns.csar b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/invalid_ns.csar
new file mode 100644
index 0000000000..63bad965b7
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/invalid_ns.csar
Binary files differ
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csar b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csar
new file mode 100644
index 0000000000..eb19c762ae
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csar
Binary files differ
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/pom.xml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/pom.xml
index 8e1fba43f0..e0439073bb 100644
--- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/pom.xml
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/pom.xml
@@ -8,4 +8,28 @@
</parent>
<artifactId>so-etsi-nfvo-ns-lcm-database-service</artifactId>
<name>SO ETSI NFVO NS LCM Database Service</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-data-jpa</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mariadb.jdbc</groupId>
+ <artifactId>mariadb-java-client</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.flywaydb</groupId>
+ <artifactId>flyway-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <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-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobAction.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobAction.java
new file mode 100644
index 0000000000..8a22689f8a
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobAction.java
@@ -0,0 +1,29 @@
+/*-
+ * ============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.database.beans;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public enum JobAction {
+ CREATE, INSTANTIATE, TERMINATE, DELETE;
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobStatusEnum.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobStatusEnum.java
new file mode 100644
index 0000000000..c67a3cc692
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobStatusEnum.java
@@ -0,0 +1,29 @@
+/*-
+ * ============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.database.beans;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public enum JobStatusEnum {
+ STARTING, STARTED, IN_PROGRESS, ERROR, FINISHED, FINISHED_WITH_ERROR;
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJob.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJob.java
new file mode 100644
index 0000000000..9453caac9e
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJob.java
@@ -0,0 +1,274 @@
+/*-
+ * ============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.database.beans;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils;
+
+
+@Entity
+@Table(name = "JOB")
+public class NfvoJob {
+
+ @Id
+ @Column(name = "JOB_ID")
+ private String jobId;
+
+ @Column(name = "JOB_TYPE")
+ private String jobType;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "JOB_ACTION")
+ private JobAction jobAction;
+
+ @Column(name = "RESOURCE_ID")
+ private String resourceId;
+
+ @Column(name = "RESOURCE_NAME")
+ private String resourceName;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "STATUS")
+ private JobStatusEnum status;
+
+ @Column(name = "START_TIME")
+ private LocalDateTime startTime;
+
+ @Column(name = "END_TIME")
+ private LocalDateTime endTime;
+
+ @Column(name = "PROGRESS")
+ private int progress;
+
+ @Column(name = "PROCESS_INSTANCE_ID")
+ private String processInstanceId;
+
+ @OneToMany(mappedBy = "nfvoJob", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+ private List<NfvoJobStatus> nfvoJobStatuses = new ArrayList<>();
+
+ public NfvoJob() {
+ this.jobId = UUID.randomUUID().toString();
+ }
+
+ public void setJobId(final String jobId) {
+ this.jobId = jobId;
+ }
+
+ public String getJobId() {
+ return jobId;
+ }
+
+ public NfvoJob jobId(final String jobId) {
+ this.jobId = jobId;
+ return this;
+ }
+
+ public String getJobType() {
+ return jobType;
+ }
+
+ public void setJobType(final String jobType) {
+ this.jobType = jobType;
+ }
+
+ public NfvoJob jobType(final String jobType) {
+ this.jobType = jobType;
+ return this;
+ }
+
+ public JobAction getJobAction() {
+ return jobAction;
+ }
+
+ public void setJobAction(final JobAction jobAction) {
+ this.jobAction = jobAction;
+ }
+
+ public NfvoJob jobAction(final JobAction jobAction) {
+ this.jobAction = jobAction;
+ return this;
+ }
+
+ public String getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(final String resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public NfvoJob resourceId(final String resourceId) {
+ this.resourceId = resourceId;
+ return this;
+ }
+
+ public JobStatusEnum getStatus() {
+ return status;
+ }
+
+ public void setStatus(final JobStatusEnum status) {
+ this.status = status;
+ }
+
+ public NfvoJob status(final JobStatusEnum status) {
+ this.status = status;
+ return this;
+ }
+
+ public LocalDateTime getStartTime() {
+ return startTime;
+ }
+
+ public void setStartTime(final LocalDateTime startTime) {
+ this.startTime = startTime;
+ }
+
+ public NfvoJob startTime(final LocalDateTime startTime) {
+ this.startTime = startTime;
+ return this;
+ }
+
+ public LocalDateTime getEndTime() {
+ return endTime;
+ }
+
+ public void setEndTime(final LocalDateTime endTime) {
+ this.endTime = endTime;
+ }
+
+ public NfvoJob endTime(final LocalDateTime endTime) {
+ this.endTime = endTime;
+ return this;
+ }
+
+ public int getProgress() {
+ return progress;
+ }
+
+ public void setProgress(final int progress) {
+ this.progress = progress;
+ }
+
+ public NfvoJob progress(final int progress) {
+ this.progress = progress;
+ return this;
+ }
+
+ public String getProcessInstanceId() {
+ return processInstanceId;
+ }
+
+ public void setProcessInstanceId(final String processInstanceId) {
+ this.processInstanceId = processInstanceId;
+ }
+
+ public NfvoJob processInstanceId(final String processInstanceId) {
+ this.processInstanceId = processInstanceId;
+ return this;
+ }
+
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ public void setResourceName(final String resourceName) {
+ this.resourceName = resourceName;
+ }
+
+ public NfvoJob resourceName(final String resourceName) {
+ this.resourceName = resourceName;
+ return this;
+ }
+
+ public List<NfvoJobStatus> getNfvoJobStatuses() {
+ return nfvoJobStatuses;
+ }
+
+ public void setJobStatuses(final List<NfvoJobStatus> nfvoJobStatuses) {
+ this.nfvoJobStatuses = nfvoJobStatuses;
+ }
+
+ public NfvoJob nfvoJobStatuses(final List<NfvoJobStatus> nfvoJobStatuses) {
+ this.nfvoJobStatuses = nfvoJobStatuses;
+ return this;
+ }
+
+ public NfvoJob nfvoJobStatus(final NfvoJobStatus nfvoJobStatus) {
+ nfvoJobStatus.setNfvoJob(this);
+ this.nfvoJobStatuses.add(nfvoJobStatus);
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(jobId, processInstanceId, jobType, jobAction, startTime, endTime, status, progress,
+ resourceId, resourceName, nfvoJobStatuses);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof NfvoJob) {
+ final NfvoJob other = (NfvoJob) obj;
+ return Objects.equals(jobId, other.jobId) && Objects.equals(processInstanceId, other.processInstanceId)
+ && Objects.equals(jobType, other.jobType) && Objects.equals(jobAction, other.jobAction)
+ && Objects.equals(progress, other.progress) && Objects.equals(status, other.status)
+ && Objects.equals(startTime, other.startTime) && Objects.equals(endTime, other.endTime)
+ && Objects.equals(status, other.status) && Objects.equals(resourceId, other.resourceId)
+ && Objects.equals(resourceName, other.resourceName)
+ && Utils.isEquals(nfvoJobStatuses, other.nfvoJobStatuses);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class NfvoJob {\n");
+ sb.append(" jobId: ").append(toIndentedString(jobId)).append("\n");
+ sb.append(" processInstanceId: ").append(toIndentedString(processInstanceId)).append("\n");
+ sb.append(" jobType: ").append(toIndentedString(jobType)).append("\n");
+ sb.append(" jobAction: ").append(toIndentedString(jobAction)).append("\n");
+ sb.append(" progress: ").append(toIndentedString(progress)).append("\n");
+ sb.append(" status: ").append(toIndentedString(status)).append("\n");
+ sb.append(" startTime: ").append(toIndentedString(startTime)).append("\n");
+ sb.append(" endTime: ").append(toIndentedString(endTime)).append("\n");
+ sb.append(" resId: ").append(toIndentedString(resourceId)).append("\n");
+ sb.append(" resName: ").append(toIndentedString(resourceName)).append("\n");
+ sb.append(" nfvoJobStatuses: ").append(toIndentedString(nfvoJobStatuses)).append("\n");
+
+ sb.append("}");
+ return sb.toString();
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJobStatus.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJobStatus.java
new file mode 100644
index 0000000000..89e07701ed
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJobStatus.java
@@ -0,0 +1,147 @@
+/*-
+ * ============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.database.beans;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.time.LocalDateTime;
+import java.util.Objects;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "JOB_STATUS")
+public class NfvoJobStatus {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "ID")
+ private int id;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "STATUS")
+ private JobStatusEnum status;
+
+ @Column(name = "DESCRIPTION", columnDefinition = "LONGTEXT")
+ private String description;
+
+ @Column(name = "UPDATED_TIME")
+ private LocalDateTime updatedTime;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "JOB_ID")
+ private NfvoJob nfvoJob;
+
+ public int getId() {
+ return id;
+ }
+
+ public JobStatusEnum getStatus() {
+ return status;
+ }
+
+ public void setStatus(final JobStatusEnum status) {
+ this.status = status;
+ }
+
+ public NfvoJobStatus status(final JobStatusEnum status) {
+ this.status = status;
+ return this;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(final String description) {
+ this.description = description;
+ }
+
+ public NfvoJobStatus description(final String description) {
+ this.description = description;
+ return this;
+ }
+
+ public LocalDateTime getUpdatedTime() {
+ return updatedTime;
+ }
+
+ public void setUpdatedTime(final LocalDateTime updatedTime) {
+ this.updatedTime = updatedTime;
+ }
+
+ public NfvoJobStatus updatedTime(final LocalDateTime addTime) {
+ this.updatedTime = addTime;
+ return this;
+ }
+
+ public NfvoJob getNfvoJob() {
+ return nfvoJob;
+ }
+
+ public void setNfvoJob(final NfvoJob nfvoJob) {
+ this.nfvoJob = nfvoJob;
+ }
+
+ public NfvoJobStatus nfvoJob(final NfvoJob nfvoJob) {
+ this.nfvoJob = nfvoJob;
+ return this;
+ }
+
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, status, updatedTime, description, nfvoJob.getJobId());
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+
+ if (obj instanceof NfvoJobStatus) {
+ final NfvoJobStatus other = (NfvoJobStatus) obj;
+ return Objects.equals(id, other.id) && Objects.equals(status, other.status)
+ && Objects.equals(updatedTime, other.updatedTime) && Objects.equals(description, other.description)
+ && Objects.equals(nfvoJob.getJobId(), other.nfvoJob.getJobId());
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class NfvoJobStatus {\n");
+ sb.append(" Id: ").append(toIndentedString(id)).append("\n");
+ sb.append(" status: ").append(toIndentedString(status)).append("\n");
+ sb.append(" descp: ").append(toIndentedString(description)).append("\n");
+ sb.append(" updatedTime: ").append(toIndentedString(updatedTime)).append("\n");
+ sb.append(" jobId: ").append(nfvoJob != null ? toIndentedString(nfvoJob.getJobId()) : "").append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNfInst.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNfInst.java
new file mode 100644
index 0000000000..e901e10596
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNfInst.java
@@ -0,0 +1,213 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.database.beans;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.time.LocalDateTime;
+import java.util.Objects;
+import java.util.UUID;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+/**
+ * @author mukeshsharma (mukeshsharma@est.tech)
+ */
+@Entity
+@Table(name = "NF_INST")
+public class NfvoNfInst {
+
+ @Id
+ @Column(name = "NF_INST_ID")
+ private String nfInstId;
+
+ @Column(name = "NAME")
+ private String name;
+
+ @Column(name = "VNFD_ID")
+ private String vnfdId;
+
+ @Column(name = "PACKAGE_ID")
+ private String packageId;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "NS_INST_ID")
+ private NfvoNsInst nsInst;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "STATUS")
+ private State status;
+
+ @Column(name = "CREATE_TIME")
+ private LocalDateTime createTime;
+
+ @Column(name = "LAST_UPDATE_TIME")
+ private LocalDateTime lastUpdateTime;
+
+ public NfvoNfInst() {
+ this.nfInstId = UUID.randomUUID().toString();
+ }
+
+ public String getNfInstId() {
+ return nfInstId;
+ }
+
+ public void setNfInstId(final String nfInstId) {
+ this.nfInstId = nfInstId;
+ }
+
+ public NfvoNfInst nfInstId(final String nfInstId) {
+ this.nfInstId = nfInstId;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public NfvoNfInst name(final String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String getVnfdId() {
+ return vnfdId;
+ }
+
+ public void setVnfdId(final String vnfdId) {
+ this.vnfdId = vnfdId;
+ }
+
+ public NfvoNfInst vnfdId(final String vnfdId) {
+ this.vnfdId = vnfdId;
+ return this;
+ }
+
+ public String getPackageId() {
+ return packageId;
+ }
+
+ public void setPackageId(final String packageId) {
+ this.packageId = packageId;
+ }
+
+ public NfvoNfInst packageId(final String packageId) {
+ this.packageId = packageId;
+ return this;
+ }
+
+ public NfvoNsInst getNsInst() {
+ return nsInst;
+ }
+
+ public void setNsInst(final NfvoNsInst nsInst) {
+ this.nsInst = nsInst;
+ }
+
+ public NfvoNfInst nfvoNsInst(final NfvoNsInst nfvoNsInst) {
+ this.nsInst = nfvoNsInst;
+ return this;
+ }
+
+ public State getStatus() {
+ return status;
+ }
+
+ public void setStatus(final State status) {
+ this.status = status;
+ }
+
+ public NfvoNfInst status(final State status) {
+ this.status = status;
+ return this;
+ }
+
+ public LocalDateTime getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(final LocalDateTime createTime) {
+ this.createTime = createTime;
+ }
+
+ public NfvoNfInst createTime(final LocalDateTime createTime) {
+ this.createTime = createTime;
+ return this;
+ }
+
+ public LocalDateTime getLastUpdateTime() {
+ return lastUpdateTime;
+ }
+
+ public void setLastUpdateTime(final LocalDateTime lastUpdateTime) {
+ this.lastUpdateTime = lastUpdateTime;
+ }
+
+ public NfvoNfInst lastUpdateTime(final LocalDateTime lastUpdateTime) {
+ this.lastUpdateTime = lastUpdateTime;
+ return this;
+ }
+
+ @Override
+ public boolean equals(final Object object) {
+ if (this == object)
+ return true;
+ if (object == null || getClass() != object.getClass())
+ return false;
+ final NfvoNfInst that = (NfvoNfInst) object;
+ return Objects.equals(nfInstId, that.nfInstId) && Objects.equals(name, that.name)
+ && Objects.equals(vnfdId, that.vnfdId) && Objects.equals(packageId, that.packageId)
+ && Objects.equals(nsInst, that.nsInst) && Objects.equals(status, that.status)
+ && Objects.equals(createTime, that.createTime) && Objects.equals(lastUpdateTime, that.lastUpdateTime);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(nfInstId, name, vnfdId, packageId, nsInst, status, createTime, lastUpdateTime);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class NfvoNfInst {\n");
+ sb.append(" nfInstId: ").append(toIndentedString(nfInstId)).append("\n");
+ sb.append(" name: ").append(toIndentedString(name)).append("\n");
+ sb.append(" vnfdId: ").append(toIndentedString(vnfdId)).append("\n");
+ sb.append(" packageId: ").append(toIndentedString(packageId)).append("\n");
+ sb.append(" nsInst: ").append(nsInst != null ? toIndentedString(nsInst.getNsInstId()) : null).append("\n");
+ sb.append(" status: ").append(toIndentedString(status)).append("\n");
+ sb.append(" createTime: ").append(toIndentedString(createTime)).append("\n");
+ sb.append(" lastUpdateTime: ").append(toIndentedString(lastUpdateTime)).append("\n");
+
+ sb.append("}");
+ return sb.toString();
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNsInst.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNsInst.java
new file mode 100644
index 0000000000..dd8448fe56
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNsInst.java
@@ -0,0 +1,289 @@
+/*-
+ * ============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.database.beans;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Entity
+@Table(name = "NS_INST")
+public class NfvoNsInst {
+
+ @Id
+ @Column(name = "NS_INST_ID")
+ private String nsInstId;
+
+ @Column(name = "NAME")
+ private String name;
+
+ @Column(name = "NS_PACKAGE_ID")
+ private String nsPackageId;
+
+ @Column(name = "NSD_ID")
+ private String nsdId;
+
+ @Column(name = "NSD_INVARIANT_ID")
+ private String nsdInvariantId;
+
+ @Column(name = "DESCRIPTION", columnDefinition = "LONGTEXT")
+ private String description;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "STATUS")
+ private State status;
+
+ @Column(name = "STATUS_UPDATED_TIME")
+ private LocalDateTime statusUpdatedTime;
+
+ @Column(name = "GLOBAL_CUSTOMER_ID")
+ private String globalCustomerId;
+
+ @Column(name = "SERVICE_TYPE")
+ private String serviceType;
+
+ @OneToMany(mappedBy = "nsInst", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
+ private List<NfvoNfInst> nfvoNfInsts = new ArrayList<>();
+
+ @OneToMany(mappedBy = "nfvoNsInst", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
+ private List<NsLcmOpOcc> nsLcmOpOccs = new ArrayList<>();
+
+ public NfvoNsInst() {
+ this.nsInstId = UUID.randomUUID().toString();
+ }
+
+ public String getNsInstId() {
+ return nsInstId;
+ }
+
+ public void setNsInstId(final String nsInstId) {
+ this.nsInstId = nsInstId;
+ }
+
+ public NfvoNsInst nsInstId(final String nsInstId) {
+ this.nsInstId = nsInstId;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public NfvoNsInst name(final String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String getNsPackageId() {
+ return nsPackageId;
+ }
+
+ public void setNsPackageId(final String nsPackageId) {
+ this.nsPackageId = nsPackageId;
+ }
+
+ public NfvoNsInst nsPackageId(final String nsPackageId) {
+ this.nsPackageId = nsPackageId;
+ return this;
+ }
+
+ public String getNsdId() {
+ return nsdId;
+ }
+
+ public void setNsdId(final String nsdId) {
+ this.nsdId = nsdId;
+ }
+
+ public NfvoNsInst nsdId(final String nsdId) {
+ this.nsdId = nsdId;
+ return this;
+ }
+
+ public String getNsdInvariantId() {
+ return nsdInvariantId;
+ }
+
+ public void setNsdInvariantId(final String nsdInvariantId) {
+ this.nsdInvariantId = nsdInvariantId;
+ }
+
+ public NfvoNsInst nsdInvariantId(final String nsdInvariantId) {
+ this.nsdInvariantId = nsdInvariantId;
+ return this;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(final String description) {
+ this.description = description;
+ }
+
+ public NfvoNsInst description(final String description) {
+ this.description = description;
+ return this;
+ }
+
+ public State getStatus() {
+ return status;
+ }
+
+ public void setStatus(final State status) {
+ this.status = status;
+ }
+
+ public NfvoNsInst status(final State status) {
+ this.status = status;
+ return this;
+ }
+
+ public LocalDateTime getStatusUpdatedTime() {
+ return statusUpdatedTime;
+ }
+
+ public void setStatusUpdatedTime(final LocalDateTime statusUpdatedTime) {
+ this.statusUpdatedTime = statusUpdatedTime;
+ }
+
+ public NfvoNsInst statusUpdatedTime(final LocalDateTime statusUpdatedTime) {
+ this.statusUpdatedTime = statusUpdatedTime;
+ return this;
+ }
+
+ public String getGlobalCustomerId() {
+ return globalCustomerId;
+ }
+
+ public void setGlobalCustomerId(final String globalCustomerId) {
+ this.globalCustomerId = globalCustomerId;
+ }
+
+ public NfvoNsInst globalCustomerId(final String globalCustomerId) {
+ this.globalCustomerId = globalCustomerId;
+ return this;
+ }
+
+ public String getServiceType() {
+ return serviceType;
+ }
+
+ public void setServiceType(final String serviceType) {
+ this.serviceType = serviceType;
+ }
+
+ public NfvoNsInst serviceType(final String serviceType) {
+ this.serviceType = serviceType;
+ return this;
+ }
+
+ public List<NfvoNfInst> getNfvoNfInsts() {
+ return nfvoNfInsts;
+ }
+
+ public void setNfvoNfInsts(final List<NfvoNfInst> nfvoNfInsts) {
+ this.nfvoNfInsts = nfvoNfInsts;
+ }
+
+ public NfvoNsInst nfvoNfInsts(final NfvoNfInst nfvoNfInsts) {
+ nfvoNfInsts.nfvoNsInst(this);
+ this.nfvoNfInsts.add(nfvoNfInsts);
+ return this;
+ }
+
+ public List<NsLcmOpOcc> getNsLcmOpOccs() {
+ return nsLcmOpOccs;
+ }
+
+ public void setNsLcmOpOccs(final List<NsLcmOpOcc> nsLcmOpOccs) {
+ this.nsLcmOpOccs = nsLcmOpOccs;
+ }
+
+ public NfvoNsInst nsLcmOpOccs(final NsLcmOpOcc nsLcmOpOcc) {
+ nsLcmOpOcc.nfvoNsInst(this);
+ this.nsLcmOpOccs.add(nsLcmOpOcc);
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(nsInstId, name, nsPackageId, nsdId, nsdInvariantId, description, status, statusUpdatedTime,
+ globalCustomerId, serviceType, nfvoNfInsts, nsLcmOpOccs);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof NfvoNsInst) {
+ final NfvoNsInst other = (NfvoNsInst) obj;
+ return Objects.equals(nsInstId, other.nsInstId) && Objects.equals(name, other.name)
+ && Objects.equals(nsPackageId, other.nsPackageId) && Objects.equals(nsdId, other.nsdId)
+ && Objects.equals(nsdInvariantId, other.nsdInvariantId)
+ && Objects.equals(description, other.description) && Objects.equals(status, other.status)
+ && Objects.equals(statusUpdatedTime, other.statusUpdatedTime)
+ && Objects.equals(globalCustomerId, other.globalCustomerId)
+ && Objects.equals(serviceType, other.serviceType) && Objects.equals(nfvoNfInsts, other.nfvoNfInsts)
+ && Objects.equals(nsLcmOpOccs, other.nsLcmOpOccs);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class NfvoNsInst {\n");
+ sb.append(" nsInstId: ").append(toIndentedString(nsInstId)).append("\n");
+ sb.append(" name: ").append(toIndentedString(name)).append("\n");
+ sb.append(" nsPackageId: ").append(toIndentedString(nsPackageId)).append("\n");
+ sb.append(" nsdId: ").append(toIndentedString(nsdId)).append("\n");
+ sb.append(" nsdInvariantId: ").append(toIndentedString(nsdInvariantId)).append("\n");
+ sb.append(" description: ").append(toIndentedString(description)).append("\n");
+ sb.append(" status: ").append(toIndentedString(status)).append("\n");
+ sb.append(" statusUpdatedTime: ").append(toIndentedString(statusUpdatedTime)).append("\n");
+ sb.append(" globalCustomerId: ").append(toIndentedString(globalCustomerId)).append("\n");
+ sb.append(" serviceType: ").append(toIndentedString(serviceType)).append("\n");
+ sb.append(" nfvoNfInsts: ").append(toIndentedString(nfvoNfInsts)).append("\n");
+ sb.append(" nsLcmOpOccs: ").append(toIndentedString(nsLcmOpOccs)).append("\n");
+
+ sb.append("}");
+ return sb.toString();
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpOcc.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpOcc.java
new file mode 100644
index 0000000000..cb8f92070a
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpOcc.java
@@ -0,0 +1,233 @@
+/*-
+ * ============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.database.beans;
+
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString;
+import java.time.LocalDateTime;
+import java.util.Objects;
+import java.util.UUID;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+/**
+ * @author mukeshsharma(mukeshsharma@est.tech)
+ */
+@Entity
+@Table(name = "NS_LCM_OP_OCCS")
+public class NsLcmOpOcc {
+
+ @Id
+ @Column(name = "ID")
+ private String id;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "OPERATION_STATE")
+ private OperationStateEnum operationState;
+
+ @Column(name = "STATE_ENTERED_TIME")
+ private LocalDateTime stateEnteredTime;
+
+ @Column(name = "START_TIME")
+ private LocalDateTime startTime;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "NS_INST_ID")
+ private NfvoNsInst nfvoNsInst;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "OPERATION")
+ private NsLcmOpType operation;
+
+ @Column(name = "IS_AUTO_INNOVATION")
+ private boolean isAutoInnovation;
+
+ @Column(name = "OPERATION_PARAMS", columnDefinition = "LONGTEXT")
+ private String operationParams;
+
+ @Column(name = "IS_CANCEL_PENDING")
+ private boolean isCancelPending;
+
+ public NsLcmOpOcc() {
+ this.id = UUID.randomUUID().toString();
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(final String id) {
+ this.id = id;
+ }
+
+ public NsLcmOpOcc id(final String id) {
+ this.id = id;
+ return this;
+ }
+
+ public OperationStateEnum getOperationState() {
+ return operationState;
+ }
+
+ public void setOperationState(final OperationStateEnum operationState) {
+ this.operationState = operationState;
+ }
+
+ public NsLcmOpOcc operationState(final OperationStateEnum operationState) {
+ this.operationState = operationState;
+ return this;
+ }
+
+ public LocalDateTime getStateEnteredTime() {
+ return stateEnteredTime;
+ }
+
+ public void setStateEnteredTime(final LocalDateTime stateEnteredTime) {
+ this.stateEnteredTime = stateEnteredTime;
+ }
+
+ public NsLcmOpOcc stateEnteredTime(final LocalDateTime stateEnteredTime) {
+ this.stateEnteredTime = stateEnteredTime;
+ return this;
+ }
+
+ public LocalDateTime getStartTime() {
+ return startTime;
+ }
+
+ public void setStartTime(final LocalDateTime startTime) {
+ this.startTime = startTime;
+ }
+
+ public NsLcmOpOcc startTime(final LocalDateTime startTime) {
+ this.startTime = startTime;
+ return this;
+ }
+
+ public NfvoNsInst getNfvoNsInst() {
+ return nfvoNsInst;
+ }
+
+ public void setNfvoNsInst(final NfvoNsInst nfvoNsInst) {
+ this.nfvoNsInst = nfvoNsInst;
+ }
+
+ public NsLcmOpOcc nfvoNsInst(final NfvoNsInst nfvoNsInst) {
+ this.nfvoNsInst = nfvoNsInst;
+ return this;
+ }
+
+ public NsLcmOpType getOperation() {
+ return operation;
+ }
+
+ public void setOperation(final NsLcmOpType operation) {
+ this.operation = operation;
+ }
+
+ public NsLcmOpOcc operation(final NsLcmOpType operation) {
+ this.operation = operation;
+ return this;
+ }
+
+ public boolean getIsAutoInnovation() {
+ return isAutoInnovation;
+ }
+
+ public void setIsAutoInnovation(final boolean isAutoInnovation) {
+ this.isAutoInnovation = isAutoInnovation;
+ }
+
+ public NsLcmOpOcc isAutoInnovation(final boolean isAutoInnovation) {
+ this.isAutoInnovation = isAutoInnovation;
+ return this;
+ }
+
+ public String getOperationParams() {
+ return operationParams;
+ }
+
+ public void setOperationParams(final String operationParams) {
+ this.operationParams = operationParams;
+ }
+
+ public NsLcmOpOcc operationParams(final String operationParams) {
+ this.operationParams = operationParams;
+ return this;
+ }
+
+ public boolean getIsCancelPending() {
+ return isCancelPending;
+ }
+
+ public void setIsCancelPending(final boolean isCancelPending) {
+ this.isCancelPending = isCancelPending;
+ }
+
+ public NsLcmOpOcc isCancelPending(final boolean isCancelPending) {
+ this.isCancelPending = isCancelPending;
+ return this;
+ }
+
+ @Override
+ public boolean equals(final Object object) {
+ if (this == object)
+ return true;
+ if (object == null || getClass() != object.getClass())
+ return false;
+ final NsLcmOpOcc that = (NsLcmOpOcc) object;
+ return Objects.equals(id, that.id) && Objects.equals(operationState, that.operationState)
+ && Objects.equals(stateEnteredTime, that.stateEnteredTime) && Objects.equals(startTime, that.startTime)
+ && Objects.equals(nfvoNsInst, that.nfvoNsInst) && Objects.equals(operation, that.operation)
+ && Objects.equals(isAutoInnovation, that.isAutoInnovation)
+ && Objects.equals(operationParams, that.operationParams)
+ && Objects.equals(isCancelPending, that.isCancelPending);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, operationState, stateEnteredTime, startTime, nfvoNsInst, operation, isAutoInnovation,
+ operationParams, isCancelPending);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("class NfvoNsInst {\n");
+ sb.append(" id: ").append(toIndentedString(id)).append("\n");
+ sb.append(" operationState: ").append(toIndentedString(operationState)).append("\n");
+ sb.append(" stateEnteredTime: ").append(toIndentedString(stateEnteredTime)).append("\n");
+ sb.append(" startTime: ").append(toIndentedString(startTime)).append("\n");
+ sb.append(" nfvoNsInst: ").append(nfvoNsInst != null ? toIndentedString(nfvoNsInst.getNsInstId()) : null)
+ .append("\n");
+ sb.append(" operation: ").append(toIndentedString(operation)).append("\n");
+ sb.append(" isAutoInnovation: ").append(toIndentedString(isAutoInnovation)).append("\n");
+ sb.append(" operationParams: ").append(toIndentedString(operationParams)).append("\n");
+ sb.append(" isCancelPending: ").append(toIndentedString(isCancelPending)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpType.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpType.java
new file mode 100644
index 0000000000..351f9611c5
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpType.java
@@ -0,0 +1,28 @@
+/*-
+ * ============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.database.beans;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public enum NsLcmOpType {
+ INSTANTIATE, TERMINATE, SCALE, UPDATE, HEAL;
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/OperationStateEnum.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/OperationStateEnum.java
new file mode 100644
index 0000000000..236652e027
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/OperationStateEnum.java
@@ -0,0 +1,29 @@
+/*-
+ * ============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.database.beans;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public enum OperationStateEnum {
+ PROCESSING, COMPLETED, PARTIALLY_COMPLETED, FAILED_TEMP, FAILED, ROLLING_BACK, ROLLED_BACK;
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/State.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/State.java
new file mode 100644
index 0000000000..390c7fd776
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/State.java
@@ -0,0 +1,29 @@
+/*-
+ * ============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.database.beans;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public enum State {
+ NOT_INSTANTIATED, INSTANTIATING, INSTANTIATED, FAILED;
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/Utils.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/Utils.java
new file mode 100644
index 0000000000..c55ef5728e
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/Utils.java
@@ -0,0 +1,58 @@
+/*-
+ * ============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.database.beans.utils;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class Utils {
+
+ private Utils() {}
+
+ public static final String toIndentedString(final Object object) {
+ return object == null ? "null" : object.toString().replace("\n", "\n ");
+ }
+
+
+ public static boolean isEquals(final List<?> first, List<?> second) {
+ if (first == null) {
+ return second == null;
+ }
+ if (first.isEmpty()) {
+ return second.isEmpty();
+ }
+ if (first.size() == second.size()) {
+ for (int index = 0; index < first.size(); index++) {
+ if (!Objects.equals(first.get(index), second.get(index))) {
+ return false;
+ }
+ }
+ return true;
+
+ }
+ return false;
+ }
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/config/NfvoDatabaseConfiguration.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/config/NfvoDatabaseConfiguration.java
new file mode 100644
index 0000000000..8f146e5378
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/config/NfvoDatabaseConfiguration.java
@@ -0,0 +1,87 @@
+/*-
+ * ============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.database.config;
+
+import javax.persistence.EntityManagerFactory;
+import javax.sql.DataSource;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.jmx.export.MBeanExporter;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Configuration
+@EnableTransactionManagement
+@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory",
+ basePackages = {"org.onap.so.etsi.nfvo.ns.lcm.database.repository"})
+public class NfvoDatabaseConfiguration {
+
+ private static final String PERSISTENCE_UNIT = "nfvo";
+ private static final String NFVO_DATA_SOURCE_QUALIFIER = "nfvoDataSource";
+
+ @Autowired(required = false)
+ private MBeanExporter mBeanExporter;
+
+ @Bean
+ @ConfigurationProperties(prefix = "spring.datasource.hikari.nfvo")
+ public HikariConfig nfvoDbConfig() {
+ return new HikariConfig();
+ }
+
+ @Bean(name = NFVO_DATA_SOURCE_QUALIFIER)
+ public DataSource dataSource() {
+ if (mBeanExporter != null) {
+ mBeanExporter.addExcludedBean(NFVO_DATA_SOURCE_QUALIFIER);
+ }
+ final HikariConfig hikariConfig = this.nfvoDbConfig();
+ return new HikariDataSource(hikariConfig);
+ }
+
+ @Primary
+ @Bean(name = "entityManagerFactory")
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory(final EntityManagerFactoryBuilder builder,
+ @Qualifier(NFVO_DATA_SOURCE_QUALIFIER) final DataSource dataSource) {
+ return builder.dataSource(dataSource).packages(NfvoJob.class.getPackage().getName())
+ .persistenceUnit(PERSISTENCE_UNIT).build();
+ }
+
+ @Primary
+ @Bean(name = "transactionManager")
+ public PlatformTransactionManager transactionManager(
+ @Qualifier("entityManagerFactory") final EntityManagerFactory entityManagerFactory) {
+ return new JpaTransactionManager(entityManagerFactory);
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NSLcmOpOccRepository.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NSLcmOpOccRepository.java
new file mode 100644
index 0000000000..696c7be5dd
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NSLcmOpOccRepository.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.database.repository;
+
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc;
+import org.springframework.data.repository.CrudRepository;
+import java.util.Optional;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ * @author mukeshsharma(mukeshsharma@est.tech)
+ */
+public interface NSLcmOpOccRepository extends CrudRepository<NsLcmOpOcc, String> {
+
+ Optional<NsLcmOpOcc> findById(final String id);
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobRepository.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobRepository.java
new file mode 100644
index 0000000000..844f60827e
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobRepository.java
@@ -0,0 +1,35 @@
+/*-
+ * ============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.database.repository;
+
+import java.util.Optional;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
+import org.springframework.data.repository.CrudRepository;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface NfvoJobRepository extends CrudRepository<NfvoJob, String> {
+
+ Optional<NfvoJob> findByResourceId(final String resourceId);
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobStatusRepository.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobStatusRepository.java
new file mode 100644
index 0000000000..c3fe469ff6
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobStatusRepository.java
@@ -0,0 +1,30 @@
+/*-
+ * ============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.database.repository;
+
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJobStatus;
+import org.springframework.data.repository.CrudRepository;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface NfvoJobStatusRepository extends CrudRepository<NfvoJobStatus, Integer> {
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNfInstRepository.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNfInstRepository.java
new file mode 100644
index 0000000000..de14d43de4
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNfInstRepository.java
@@ -0,0 +1,38 @@
+/*-
+ * ============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.database.repository;
+
+import java.util.List;
+import java.util.Optional;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst;
+import org.springframework.data.repository.CrudRepository;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ * @author mukeshsharma(mukeshsharma@est.tech)
+ */
+public interface NfvoNfInstRepository extends CrudRepository<NfvoNfInst, String> {
+
+ Optional<NfvoNfInst> findByNfInstId(final String nfInstId);
+
+ List<NfvoNfInst> findByNsInstNsInstId(final String nsInstId);
+
+ List<NfvoNfInst> findByNsInstNsInstIdAndName(final String nsInstId, final String name);
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNsInstRepository.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNsInstRepository.java
new file mode 100644
index 0000000000..beeeacf8cf
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNsInstRepository.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.database.repository;
+
+import java.util.Optional;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
+import org.springframework.data.repository.CrudRepository;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface NfvoNsInstRepository extends CrudRepository<NfvoNsInst, String> {
+
+ Optional<NfvoNsInst> findByName(final String name);
+
+ Optional<NfvoNsInst> findByNsInstId(final String nsInstId);
+
+ boolean existsNfvoNsInstByName(final String name);
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/service/DatabaseServiceProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/service/DatabaseServiceProvider.java
new file mode 100644
index 0000000000..368242515b
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/service/DatabaseServiceProvider.java
@@ -0,0 +1,141 @@
+/*-
+ * ============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.database.service;
+
+import java.util.List;
+import java.util.Optional;
+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.repository.NSLcmOpOccRepository;
+import org.onap.so.etsi.nfvo.ns.lcm.database.repository.NfvoJobRepository;
+import org.onap.so.etsi.nfvo.ns.lcm.database.repository.NfvoNfInstRepository;
+import org.onap.so.etsi.nfvo.ns.lcm.database.repository.NfvoNsInstRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+
+@Service
+public class DatabaseServiceProvider {
+ private static final Logger logger = LoggerFactory.getLogger(DatabaseServiceProvider.class);
+
+ private final NfvoJobRepository nfvoJobRepository;
+
+ private final NfvoNsInstRepository nfvoNsInstRepository;
+
+ private final NfvoNfInstRepository nfvoNfInstRepository;
+
+ private final NSLcmOpOccRepository nsLcmOpOccRepository;
+
+ @Autowired
+ public DatabaseServiceProvider(final NfvoJobRepository nfvoJobRepository,
+ final NfvoNsInstRepository nfvoNsInstRepository, final NfvoNfInstRepository nfvoNfInstRepository,
+ final NSLcmOpOccRepository nsLcmOpOccRepository) {
+ this.nfvoJobRepository = nfvoJobRepository;
+ this.nfvoNsInstRepository = nfvoNsInstRepository;
+ this.nfvoNfInstRepository = nfvoNfInstRepository;
+ this.nsLcmOpOccRepository = nsLcmOpOccRepository;
+ }
+
+ public boolean addJob(final NfvoJob job) {
+ logger.info("Adding NfvoJob: {} to database", job);
+ return nfvoJobRepository.save(job) != null;
+ }
+
+ public Optional<NfvoJob> getJob(final String jobId) {
+ logger.info("Querying database for NfvoJob using jobId: {}", jobId);
+ return nfvoJobRepository.findById(jobId);
+ }
+
+ public Optional<NfvoJob> getJobByResourceId(final String resourceId) {
+ logger.info("Querying database for NfvoJob using resourceId: {}", resourceId);
+ return nfvoJobRepository.findByResourceId(resourceId);
+ }
+
+ public boolean isNsInstExists(final String name) {
+ logger.info("Checking if NfvoNsInst entry exists in database using name: {}", name);
+ return nfvoNsInstRepository.existsNfvoNsInstByName(name);
+ }
+
+ public boolean isNsInstExists(final String nsInstId, final String nfName) {
+ logger.info("Checking if NfvoNfInst entry exists in database using nsInstId: {} and nfName: {}", nsInstId,
+ nfName);
+ return nfvoNfInstRepository.findByNsInstNsInstIdAndName(nsInstId, nfName).isEmpty();
+ }
+
+ public boolean saveNfvoNsInst(final NfvoNsInst nfvoNsInst) {
+ logger.info("Saving NfvoNsInst: {} to database", nfvoNsInst);
+ return nfvoNsInstRepository.save(nfvoNsInst) != null;
+ }
+
+ public Optional<NfvoNsInst> getNfvoNsInst(final String nsInstId) {
+ logger.info("Querying database for NfvoNsInst using nsInstId: {}", nsInstId);
+ return nfvoNsInstRepository.findById(nsInstId);
+ }
+
+ public Optional<NfvoNsInst> getNfvoNsInstByName(final String name) {
+ logger.info("Querying database for NfvoNsInst using name: {}", name);
+ return nfvoNsInstRepository.findByName(name);
+ }
+
+ public boolean saveNfvoNfInst(final NfvoNfInst nfvoNfInst) {
+ logger.info("Saving NfvoNfInst: {} to database", nfvoNfInst);
+ return nfvoNfInstRepository.save(nfvoNfInst) != null;
+ }
+
+ public Optional<NfvoNfInst> getNfvoNfInstByNfInstId(final String nfInstId) {
+ logger.info("Querying database for NfvoNfInst using nfInstId: {}", nfInstId);
+ return nfvoNfInstRepository.findByNfInstId(nfInstId);
+ }
+
+ public List<NfvoNfInst> getNfvoNfInstByNsInstId(final String nsInstId) {
+ logger.info("Querying database for NfvoNfInst using nsInstId: {}", nsInstId);
+ return nfvoNfInstRepository.findByNsInstNsInstId(nsInstId);
+ }
+
+ public List<NfvoNfInst> getNfvoNfInstByNsInstIdAndNfName(final String nsInstId, final String name) {
+ logger.info("Querying database for NfvoNfInst using nsInstId: {} and name : {} ", nsInstId, name);
+ return nfvoNfInstRepository.findByNsInstNsInstIdAndName(nsInstId, name);
+ }
+
+ public Optional<NfvoNfInst> getNfvoNfInst(final String nfInstId) {
+ logger.info("Querying database for NfvoNfInst using nfInstId: {}", nfInstId);
+ return nfvoNfInstRepository.findByNfInstId(nfInstId);
+ }
+
+ public boolean addNSLcmOpOcc(final NsLcmOpOcc nsLcmOpOcc) {
+ logger.info("Adding NSLcmOpOcc: {} to database", nsLcmOpOcc);
+ return nsLcmOpOccRepository.save(nsLcmOpOcc) != null;
+ }
+
+ public Optional<NsLcmOpOcc> getNsLcmOpOcc(final String id) {
+ logger.info("Querying database for NsLcmOpOcc using id: {}", id);
+ return nsLcmOpOccRepository.findById(id);
+ }
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/resources/db/migration/V1_1__create_nfvo_tables.sql b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/resources/db/migration/V1_1__create_nfvo_tables.sql
new file mode 100644
index 0000000000..f41a8206e0
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/resources/db/migration/V1_1__create_nfvo_tables.sql
@@ -0,0 +1,74 @@
+use nfvo;
+
+CREATE TABLE IF NOT EXISTS `JOB` (
+ `JOB_ID` varchar(255) NOT NULL,
+ `JOB_TYPE` varchar(255) NOT NULL,
+ `JOB_ACTION` varchar(255) NOT NULL,
+ `RESOURCE_ID` varchar(255) NOT NULL,
+ `RESOURCE_NAME` varchar(255) DEFAULT NULL,
+ `STATUS` varchar(255) NOT NULL,
+ `START_TIME` DATETIME DEFAULT NULL,
+ `END_TIME` DATETIME DEFAULT NULL,
+ `PROGRESS` int(11) DEFAULT NULL,
+ `PROCESS_INSTANCE_ID` varchar(255) DEFAULT NULL,
+ PRIMARY KEY (`JOB_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+
+CREATE TABLE IF NOT EXISTS `JOB_STATUS` (
+ `ID` INT NOT NULL AUTO_INCREMENT,
+ `UPDATED_TIME` DATETIME NOT NULL,
+ `DESCRIPTION` longtext DEFAULT NULL,
+ `STATUS` varchar(255) NOT NULL,
+ `JOB_ID` varchar(255) NOT NULL,
+ PRIMARY KEY (`ID`),
+ FOREIGN KEY (JOB_ID)
+ REFERENCES JOB(JOB_ID)
+ ON UPDATE CASCADE ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `NS_INST` (
+ `NS_INST_ID` varchar(255) NOT NULL,
+ `NAME` varchar(255) NOT NULL,
+ `NS_PACKAGE_ID` varchar(255) DEFAULT NULL,
+ `NSD_ID` varchar(255) NOT NULL,
+ `NSD_INVARIANT_ID` varchar(255) NOT NULL,
+ `DESCRIPTION` longtext DEFAULT NULL,
+ `STATUS` varchar(255) NOT NULL,
+ `STATUS_UPDATED_TIME` DATETIME NOT NULL,
+ `GLOBAL_CUSTOMER_ID` varchar(255) DEFAULT NULL,
+ `SERVICE_TYPE` varchar(255) DEFAULT NULL,
+ PRIMARY KEY (`NS_INST_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `NF_INST` (
+ `NF_INST_ID` varchar(255) NOT NULL,
+ `NAME` varchar(255) DEFAULT NULL,
+ `VNFD_ID` varchar(255) DEFAULT NULL,
+ `PACKAGE_ID` varchar(255) DEFAULT NULL,
+ `NS_INST_ID` varchar(255) NOT NULL,
+ `STATUS` varchar(255) NOT NULL,
+ `CREATE_TIME` DATETIME DEFAULT NULL,
+ `LAST_UPDATE_TIME` DATETIME DEFAULT NULL,
+ PRIMARY KEY (`NF_INST_ID`),
+ FOREIGN KEY (NS_INST_ID)
+ REFERENCES NS_INST(NS_INST_ID)
+ ON UPDATE CASCADE ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `NS_LCM_OP_OCCS` (
+ `ID` varchar(255) NOT NULL,
+ `OPERATION_STATE` varchar(255) NOT NULL,
+ `STATE_ENTERED_TIME` DATETIME DEFAULT NULL,
+ `START_TIME` DATETIME DEFAULT NULL,
+ `NS_INST_ID` varchar(255) NOT NULL,
+ `OPERATION` varchar(255) NOT NULL,
+ `IS_AUTO_INNOVATION` varchar(255) NOT NULL,
+ `OPERATION_PARAMS` longtext NOT NULL,
+ `IS_CANCEL_PENDING` varchar(255) NOT NULL,
+ PRIMARY KEY (`ID`),
+ FOREIGN KEY (NS_INST_ID)
+ REFERENCES NS_INST(NS_INST_ID)
+ ON UPDATE CASCADE ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/DatabaseServiceProviderTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/DatabaseServiceProviderTest.java
new file mode 100644
index 0000000000..42579fd5e8
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/DatabaseServiceProviderTest.java
@@ -0,0 +1,176 @@
+/*-
+ * ============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.database;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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.NfvoJobStatus;
+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.NsLcmOpType;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ActiveProfiles("test")
+public class DatabaseServiceProviderTest {
+
+ private static final String RANDOM_ID = UUID.randomUUID().toString();
+ private static final String DUMMY_NAME = "NAME";
+ private static final LocalDateTime CURRENT_DATE_TIME = LocalDateTime.now();
+ @Autowired
+ private DatabaseServiceProvider databaseServiceProvider;
+
+ @Test
+ public void testAddJob_StoredInDatabase() {
+ final NfvoJob expected = new NfvoJob().jobType("TYPE").jobAction(JobAction.CREATE).resourceId(RANDOM_ID)
+ .resourceName(DUMMY_NAME).startTime(CURRENT_DATE_TIME).status(JobStatusEnum.STARTED);
+ databaseServiceProvider.addJob(expected);
+
+ final Optional<NfvoJob> actual = databaseServiceProvider.getJob(expected.getJobId());
+ assertEquals(expected, actual.get());
+ }
+
+ @Test
+ public void testAddJobWithJobStatus_StoredInDatabase() {
+ final NfvoJob job = new NfvoJob().jobType("TYPE").jobAction(JobAction.CREATE).resourceId(RANDOM_ID)
+ .resourceName(DUMMY_NAME).startTime(CURRENT_DATE_TIME).status(JobStatusEnum.STARTED);
+ databaseServiceProvider.addJob(job);
+
+ final NfvoJobStatus jobStatus = new NfvoJobStatus().status(JobStatusEnum.STARTED)
+ .description("Create NS workflow process started").updatedTime(CURRENT_DATE_TIME);
+ databaseServiceProvider.addJob(job.nfvoJobStatus(jobStatus));
+
+ final Optional<NfvoJob> actual = databaseServiceProvider.getJob(job.getJobId());
+ final NfvoJob actualNfvoJob = actual.get();
+
+ assertEquals(job.getJobId(), actualNfvoJob.getJobId());
+ assertFalse(actualNfvoJob.getNfvoJobStatuses().isEmpty());
+ assertEquals(job.getJobId(), actualNfvoJob.getNfvoJobStatuses().get(0).getNfvoJob().getJobId());
+
+ }
+
+ @Test
+ public void testAddNsInst_StoredInDatabase_ableTofindByQuery() {
+
+ final NfvoNsInst nsInst = new NfvoNsInst().name(DUMMY_NAME).nsdId(RANDOM_ID).status(State.NOT_INSTANTIATED)
+ .nsdInvariantId(RANDOM_ID).statusUpdatedTime(CURRENT_DATE_TIME);
+
+ databaseServiceProvider.saveNfvoNsInst(nsInst);
+
+ Optional<NfvoNsInst> actual = databaseServiceProvider.getNfvoNsInst(nsInst.getNsInstId());
+ NfvoNsInst actualNfvoNsInst = actual.get();
+ assertEquals(nsInst.getNsInstId(), actualNfvoNsInst.getNsInstId());
+ assertEquals(RANDOM_ID, actualNfvoNsInst.getNsdId());
+ assertEquals(State.NOT_INSTANTIATED, actualNfvoNsInst.getStatus());
+ assertEquals(RANDOM_ID, actualNfvoNsInst.getNsdInvariantId());
+ assertEquals(CURRENT_DATE_TIME, actualNfvoNsInst.getStatusUpdatedTime());
+
+ actual = databaseServiceProvider.getNfvoNsInstByName(DUMMY_NAME);
+ actualNfvoNsInst = actual.get();
+
+ assertEquals(nsInst.getNsInstId(), actualNfvoNsInst.getNsInstId());
+ assertEquals(RANDOM_ID, actualNfvoNsInst.getNsdId());
+ assertEquals(State.NOT_INSTANTIATED, actualNfvoNsInst.getStatus());
+ assertEquals(RANDOM_ID, actualNfvoNsInst.getNsdInvariantId());
+ assertEquals(CURRENT_DATE_TIME, actualNfvoNsInst.getStatusUpdatedTime());
+
+
+ assertTrue(databaseServiceProvider.isNsInstExists(DUMMY_NAME));
+ }
+
+ @Test
+ public void testAddNfInst_StoredInDatabase_ableTofindByQuery() {
+
+ final NfvoNsInst nsInst = new NfvoNsInst().name(DUMMY_NAME).nsdId(RANDOM_ID).status(State.NOT_INSTANTIATED)
+ .nsdInvariantId(RANDOM_ID).statusUpdatedTime(CURRENT_DATE_TIME);
+
+ databaseServiceProvider.saveNfvoNsInst(nsInst);
+
+ final NfvoNfInst nfInst = new NfvoNfInst().nfvoNsInst(nsInst).name(DUMMY_NAME).vnfdId(RANDOM_ID)
+ .status(State.NOT_INSTANTIATED).createTime(CURRENT_DATE_TIME).lastUpdateTime(CURRENT_DATE_TIME);
+ databaseServiceProvider.saveNfvoNfInst(nfInst);
+
+ final Optional<NfvoNfInst> actual = databaseServiceProvider.getNfvoNfInstByNfInstId(nfInst.getNfInstId());
+ final NfvoNfInst actualNfvoNfInst = actual.get();
+ assertEquals(nsInst.getNsInstId(), actualNfvoNfInst.getNsInst().getNsInstId());
+ assertEquals(nfInst.getNfInstId(), actualNfvoNfInst.getNfInstId());
+ assertEquals(nfInst.getName(), actualNfvoNfInst.getName());
+ assertEquals(nfInst.getVnfdId(), actualNfvoNfInst.getVnfdId());
+ assertEquals(nfInst.getStatus(), actualNfvoNfInst.getStatus());
+ assertEquals(nfInst.getCreateTime(), actualNfvoNfInst.getCreateTime());
+ assertEquals(nfInst.getLastUpdateTime(), actualNfvoNfInst.getLastUpdateTime());
+
+
+ List<NfvoNfInst> nfvoNfInstList = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInst.getNsInstId());
+ assertFalse(nfvoNfInstList.isEmpty());
+ assertEquals(nsInst.getNsInstId(), nfvoNfInstList.get(0).getNsInst().getNsInstId());
+
+ nfvoNfInstList = databaseServiceProvider.getNfvoNfInstByNsInstIdAndNfName(nsInst.getNsInstId(), DUMMY_NAME);
+
+ assertFalse(nfvoNfInstList.isEmpty());
+ assertEquals(nsInst.getNsInstId(), nfvoNfInstList.get(0).getNsInst().getNsInstId());
+ assertEquals(DUMMY_NAME, nfvoNfInstList.get(0).getName());
+ }
+
+ @Test
+ public void testAddNsLcmOpOcc_StoredInDatabase_ableTofindByQuery() {
+
+ final NfvoNsInst nsInst = new NfvoNsInst().name(DUMMY_NAME).nsdId(RANDOM_ID).status(State.NOT_INSTANTIATED)
+ .nsdInvariantId(RANDOM_ID).statusUpdatedTime(CURRENT_DATE_TIME);
+
+ databaseServiceProvider.saveNfvoNsInst(nsInst);
+
+ final NsLcmOpOcc nsLcmOpOcc = new NsLcmOpOcc().nfvoNsInst(nsInst).operationState(OperationStateEnum.PROCESSING)
+ .isCancelPending(false).isAutoInnovation(false).operation(NsLcmOpType.INSTANTIATE)
+ .startTime(CURRENT_DATE_TIME).stateEnteredTime(CURRENT_DATE_TIME).operationParams("");
+
+
+ databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc);
+
+ final Optional<NsLcmOpOcc> actual = databaseServiceProvider.getNsLcmOpOcc(nsLcmOpOcc.getId());
+ final NsLcmOpOcc actualLcmOpOcc = actual.get();
+ assertEquals(nsLcmOpOcc.getId(), actualLcmOpOcc.getId());
+
+ assertEquals(nsInst.getNsInstId(), actualLcmOpOcc.getNfvoNsInst().getNsInstId());
+
+ }
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/TestApplication.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/TestApplication.java
new file mode 100644
index 0000000000..921cae2343
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/TestApplication.java
@@ -0,0 +1,45 @@
+/*-
+ * ============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.database;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.context.annotation.ComponentScan.Filter;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@SpringBootApplication(scanBasePackages = {"org.onap.so"})
+@EnableAutoConfiguration(exclude = {JacksonAutoConfiguration.class})
+@ComponentScan(basePackages = {"org.onap"},
+ excludeFilters = {@Filter(type = FilterType.ANNOTATION, classes = SpringBootApplication.class)})
+public class TestApplication {
+
+ public static void main(final String[] args) {
+ new SpringApplication(TestApplication.class).run(args);
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/UtilsTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/UtilsTest.java
new file mode 100644
index 0000000000..632bda937c
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/UtilsTest.java
@@ -0,0 +1,65 @@
+/*-
+ * ============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.database.beans.utils;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import java.util.Arrays;
+import java.util.Collections;
+import org.junit.Test;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class UtilsTest {
+
+ @Test
+ public void testTwoEmptyLists_equal() {
+ assertTrue(Utils.isEquals(Collections.emptyList(), Collections.emptyList()));
+ }
+
+ @Test
+ public void testEmptyListAndNonEmpty_notEqual() {
+ assertFalse(Utils.isEquals(Collections.emptyList(), Arrays.asList("A")));
+ }
+
+ @Test
+ public void testTwoNullLists_equal() {
+ assertTrue(Utils.isEquals(null, null));
+ }
+
+ @Test
+ public void testNullListAndEmptyList_notEqual() {
+ assertFalse(Utils.isEquals(null, Collections.emptyList()));
+ }
+
+ @Test
+ public void testTwoNotEmptyListsContainSameObjects_equal() {
+ assertTrue(Utils.isEquals(Arrays.asList("A"), Arrays.asList("A")));
+ }
+
+ @Test
+ public void testTwoNotEmptyListsContainsDifferentObjects_equal() {
+ assertFalse(Utils.isEquals(Arrays.asList("A"), Arrays.asList(1)));
+ }
+
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/resources/application.yaml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/resources/application.yaml
new file mode 100644
index 0000000000..adc36aca1d
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/resources/application.yaml
@@ -0,0 +1,31 @@
+# Copyright © 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.
+spring:
+ main:
+ web-application-type: none
+ datasource:
+ hikari:
+ nfvo:
+ jdbcUrl: jdbc:h2:mem:nfvo;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS nfvo;
+ driver-class-name: org.h2.Driver
+ pool-name: ns-lcm-bpmn-pool
+ registerMbeans: true
+ jpa:
+ generate-ddl: true
+ hibernate:
+ ddl-auto: create
+hibernate:
+ dialect: org.hibernate.dialect.H2Dialect
+ hbm2ddl:
+ auto: create \ No newline at end of file
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/pom.xml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/pom.xml
index 2c3c394d01..6605602f53 100644
--- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/pom.xml
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/pom.xml
@@ -16,6 +16,11 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.onap.so.etsi.nfvo</groupId>
+ <artifactId>so-etsi-nfvo-ns-lcm-bpmn-flows</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
@@ -50,9 +55,24 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.onap.so.etsi.nfvo</groupId>
+ <artifactId>so-etsi-nfvo-ns-lcm-bpmn-flows</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <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-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/Constants.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/Constants.java
index 97ad1743bc..d330df3bae 100644
--- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/Constants.java
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/Constants.java
@@ -1,19 +1,19 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix. All rights reserved.
+ * 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=========================================================
*/
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/EtsiSoNsLcmManagerUrlProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/EtsiSoNsLcmManagerUrlProvider.java
new file mode 100644
index 0000000000..da1649de57
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/EtsiSoNsLcmManagerUrlProvider.java
@@ -0,0 +1,53 @@
+/*-
+ * ============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;
+
+import java.net.URI;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Configuration
+public class EtsiSoNsLcmManagerUrlProvider {
+
+ private final String etsiNsLcmManagerEndpoint;
+
+ @Autowired
+ public EtsiSoNsLcmManagerUrlProvider(
+ @Value("${so-etsi-nfvo-ns-lcm.endpoint:http://so-etsi-nfvo-ns-lcm.onap:9095}") final String etsiNsLcmManagerEndpoint) {
+ this.etsiNsLcmManagerEndpoint = etsiNsLcmManagerEndpoint;
+ }
+
+ public URI getCreatedNsResourceUri(final String nsInstanceId) {
+ return URI.create(etsiNsLcmManagerEndpoint + Constants.NS_LIFE_CYCLE_MANAGEMENT_BASE_URL + "/ns_instances/"
+ + nsInstanceId);
+ }
+
+ public URI getInstantiatedOccUri(final String nsLcmOpOccId) {
+ return URI.create(etsiNsLcmManagerEndpoint + Constants.NS_LIFE_CYCLE_MANAGEMENT_BASE_URL + "/ns_lcm_op_occs/"
+ + nsLcmOpOccId);
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/GsonSerializerConfiguration.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/GsonSerializerConfiguration.java
new file mode 100644
index 0000000000..2e11adae01
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/GsonSerializerConfiguration.java
@@ -0,0 +1,42 @@
+/*-
+ * ============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;
+
+import java.time.LocalDateTime;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.utils.LocalDateTimeTypeAdapter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import com.google.gson.GsonBuilder;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Configuration
+public class GsonSerializerConfiguration {
+
+ @Bean
+ public GsonBuilder gsonBuilder() {
+ return new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter());
+ }
+
+}
+
+
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/lifecycle/NsLifeCycleManager.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/lifecycle/NsLifeCycleManager.java
new file mode 100644
index 0000000000..792ffdd00a
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/lifecycle/NsLifeCycleManager.java
@@ -0,0 +1,77 @@
+/*-
+ * ============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.lifecycle;
+
+import static org.slf4j.LoggerFactory.getLogger;
+import java.net.URI;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.onap.so.etsi.nfvo.ns.lcm.EtsiSoNsLcmManagerUrlProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.JobExecutorService;
+import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest;
+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;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class NsLifeCycleManager {
+ private static final Logger logger = getLogger(NsLifeCycleManager.class);
+
+ private final JobExecutorService jobExecutorService;
+
+ @Value("${etsi-so-ns-workflow-engine.requesttimeout.create.timeoutInSeconds:300}")
+ private int timeOutInSeconds;
+
+ private final EtsiSoNsLcmManagerUrlProvider etsiSoNsLcmManagerUrlProvider;
+
+ @Autowired
+ public NsLifeCycleManager(final JobExecutorService jobExecutorService,
+ final EtsiSoNsLcmManagerUrlProvider etsiSoNsLcmManagerUrlProvider) {
+ this.jobExecutorService = jobExecutorService;
+ this.etsiSoNsLcmManagerUrlProvider = etsiSoNsLcmManagerUrlProvider;
+ }
+
+ public ImmutablePair<URI, NsInstancesNsInstance> createNs(final CreateNsRequest createNsRequest,
+ final String globalCustomerId, final String serviceType) {
+ logger.info("Will execute Create Ns for CreateNsRequest: {}, globalCustomerId: {} and serviceType: {}",
+ createNsRequest, globalCustomerId, serviceType);
+ final NsInstancesNsInstance nsInstanceResponse =
+ jobExecutorService.runCreateNsJob(createNsRequest, globalCustomerId, serviceType);
+
+ return ImmutablePair.of(etsiSoNsLcmManagerUrlProvider.getCreatedNsResourceUri(nsInstanceResponse.getId()),
+ nsInstanceResponse);
+ }
+
+ public URI instantiateNs(final String nsInstanceId, final InstantiateNsRequest instantiateNsRequest) {
+ logger.info("Will execute Instantiate Ns for InstantiateNsRequest: {} and nsInstanceId: {}",
+ instantiateNsRequest, nsInstanceId);
+ final String nsLcmOpOccId = jobExecutorService.runInstantiateNsJob(nsInstanceId, instantiateNsRequest);
+
+ return etsiSoNsLcmManagerUrlProvider.getInstantiatedOccUri(nsLcmOpOccId);
+
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesController.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesController.java
index aed4f4b9dd..ec79ce6329 100644
--- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesController.java
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesController.java
@@ -1,19 +1,19 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix. All rights reserved.
+ * 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=========================================================
*/
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementController.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementController.java
index 4dd12589a0..87ec8420c6 100644
--- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementController.java
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementController.java
@@ -1,19 +1,19 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix. All rights reserved.
+ * 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=========================================================
*/
@@ -24,12 +24,17 @@ import static org.onap.so.etsi.nfvo.ns.lcm.Constants.HTTP_SERVICETYPE_HEADER_DEF
import static org.onap.so.etsi.nfvo.ns.lcm.Constants.HTTP_SERVICETYPE_HEADER_PARM_NAME;
import static org.onap.so.etsi.nfvo.ns.lcm.Constants.NS_LIFE_CYCLE_MANAGEMENT_BASE_URL;
import static org.slf4j.LoggerFactory.getLogger;
+import java.net.URI;
import javax.ws.rs.core.MediaType;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.onap.so.etsi.nfvo.ns.lcm.lifecycle.NsLifeCycleManager;
import org.onap.so.etsi.nfvo.ns.lcm.model.Body;
import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest;
import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance;
import org.onap.so.etsi.nfvo.ns.lcm.model.TerminateNsRequest;
import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
@@ -53,6 +58,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
public class NsLifecycleManagementController {
private static final Logger logger = getLogger(NsLifecycleManagementController.class);
+ private final NsLifeCycleManager nsLifeCycleManager;
+
+ @Autowired
+ public NsLifecycleManagementController(final NsLifeCycleManager nsLifeCycleManager) {
+ this.nsLifeCycleManager = nsLifeCycleManager;
+ }
/**
* The POST method creates new {@link Body new NS instance resource} request. See Section Number: 6.3.1 for more
@@ -74,7 +85,17 @@ public class NsLifecycleManagementController {
@RequestBody final CreateNsRequest createNsRequest) {
logger.info("Received Create NS Request: {}\n with globalCustomerId: {}\n serviceType: {}\n", createNsRequest,
globalCustomerId, serviceType);
- return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).body("Operation is not supported yet");
+
+ final ImmutablePair<URI, NsInstancesNsInstance> nsInstance =
+ nsLifeCycleManager.createNs(createNsRequest, globalCustomerId, serviceType);
+
+ final URI resourceUri = nsInstance.getLeft();
+ final NsInstancesNsInstance createdNsresponse = nsInstance.getRight();
+
+ logger.info("NS resource created successfully. Resource location: {}, response: {}", resourceUri,
+ createdNsresponse);
+
+ return ResponseEntity.created(resourceUri).body(createdNsresponse);
}
/**
@@ -104,7 +125,10 @@ public class NsLifecycleManagementController {
public ResponseEntity<?> instantiateNs(@PathVariable("nsInstanceId") final String nsInstanceId,
@RequestBody final InstantiateNsRequest instantiateNsRequest) {
logger.debug("Received instantiate NS request: {}\n with nsInstanceId: {}", instantiateNsRequest, nsInstanceId);
- return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).body("Operation is not supported yet");
+ final URI resourceUri = nsLifeCycleManager.instantiateNs(nsInstanceId, instantiateNsRequest);
+ logger.info("{} Ns Instantiation started successfully. Resource Operation Occurrence uri: {}", nsInstanceId,
+ resourceUri);
+ return ResponseEntity.accepted().location(resourceUri).build();
}
/**
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/exceptions/NsLcmControllerExceptionHandler.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/exceptions/NsLcmControllerExceptionHandler.java
new file mode 100644
index 0000000000..3db04fcfe8
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/exceptions/NsLcmControllerExceptionHandler.java
@@ -0,0 +1,58 @@
+/*-
+ * ============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.rest.exceptions;
+
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.NsRequestProcessingException;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
+import org.onap.so.etsi.nfvo.ns.lcm.rest.NsLifecycleManagementController;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@ControllerAdvice(assignableTypes = NsLifecycleManagementController.class)
+public class NsLcmControllerExceptionHandler {
+
+ @ExceptionHandler(NsRequestProcessingException.class)
+ public ResponseEntity<InlineResponse400> handleNsRequestProcessingException(
+ final NsRequestProcessingException nsRequestProcessingException) {
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(getInlineResponse400(nsRequestProcessingException));
+ }
+
+ @ExceptionHandler(Exception.class)
+ public ResponseEntity<InlineResponse400> handleNsRequestProcessingException(final Exception exception) {
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new InlineResponse400()
+ .status(HttpStatus.INTERNAL_SERVER_ERROR.value()).detail(exception.getMessage()));
+ }
+
+ private InlineResponse400 getInlineResponse400(final NsRequestProcessingException nsRequestProcessingException) {
+ if (nsRequestProcessingException.getProblemDetails() != null) {
+ return nsRequestProcessingException.getProblemDetails();
+ }
+ return new InlineResponse400().status(HttpStatus.INTERNAL_SERVER_ERROR.value())
+ .detail(nsRequestProcessingException.getMessage());
+ }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/TestApplication.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/TestApplication.java
index 6e5f6c0467..d6f4a83811 100644
--- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/TestApplication.java
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/TestApplication.java
@@ -1,19 +1,19 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Ericsson. All rights reserved.
+ * 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=========================================================
*/
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesControllerTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesControllerTest.java
index ae491b6f1e..9eace927d6 100644
--- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesControllerTest.java
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesControllerTest.java
@@ -1,19 +1,19 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Ericsson. All rights reserved.
+ * 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=========================================================
*/
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementControllerTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementControllerTest.java
index 6f25092050..81c4e8fd68 100644
--- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementControllerTest.java
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementControllerTest.java
@@ -1,19 +1,19 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Ericsson. All rights reserved.
+ * 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=========================================================
*/
@@ -24,18 +24,30 @@ package org.onap.so.etsi.nfvo.ns.lcm.rest;
*
*/
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+import java.net.URISyntaxException;
import java.time.LocalDateTime;
+import java.util.List;
import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.onap.so.etsi.nfvo.ns.lcm.Constants;
-import org.onap.so.etsi.nfvo.ns.lcm.JSON;
import org.onap.so.etsi.nfvo.ns.lcm.TestApplication;
+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.bpmn.flows.service.JobExecutorService;
import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest;
+import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest;
+import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance;
import org.onap.so.etsi.nfvo.ns.lcm.model.TerminateNsRequest;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.boot.web.server.LocalServerPort;
@@ -57,27 +69,107 @@ import com.google.gson.Gson;
@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
public class NsLifecycleManagementControllerTest {
+ private static final String EXPECTED_BASE_URL =
+ "http://so-etsi-nfvo-ns-lcm.onap:9095/so/so-etsi-nfvo-ns-lcm/v1/api/nslcm/v1";
+ private static final String RANDOM_NS_LCM_OP_OCC_ID = UUID.randomUUID().toString();
+ private static final String RANDOM_NS_INST_ID = UUID.randomUUID().toString();
+ private static final String SERVICE_TYPE = "NetworkService";
+ private static final String GLOBAL_CUSTOMER_ID = UUID.randomUUID().toString();
+ private static final String EXPECTED_CREATE_REQ_LOCATION_URL =
+ EXPECTED_BASE_URL + "/ns_instances/" + RANDOM_NS_INST_ID;
+ private static final String EXPECTED_INSTANTIATE_REQ_LOCATION_URL =
+ EXPECTED_BASE_URL + "/ns_lcm_op_occs/" + RANDOM_NS_LCM_OP_OCC_ID;
+
@LocalServerPort
private int port;
private TestRestTemplate testRestTemplate;
+ @Autowired
+ private GsonProvider gsonProvider;
+
+ @MockBean
+ private JobExecutorService mockedJobExecutorService;
+
@Before
public void setUp() {
- final Gson gson = JSON.createGson().create();
+ final Gson gson = gsonProvider.getGson();
testRestTemplate = new TestRestTemplate(
new RestTemplateBuilder().additionalMessageConverters(new GsonHttpMessageConverter(gson)));
}
@Test
- public void testCreateNs_ValidCreateNsRequest() {
+ public void testCreateNs_ValidCreateNsRequest() throws URISyntaxException {
+
+ final CreateNsRequest createNsRequest = getCreateNsRequest();
+
+ when(mockedJobExecutorService.runCreateNsJob(eq(createNsRequest), eq(GLOBAL_CUSTOMER_ID), eq(SERVICE_TYPE)))
+ .thenReturn(new NsInstancesNsInstance().id(RANDOM_NS_INST_ID));
+
final String baseUrl = getNsLcmBaseUrl() + "/ns_instances";
final HttpHeaders headers = new HttpHeaders();
- headers.add(Constants.HTTP_GLOBAL_CUSTOMER_ID_HTTP_HEADER_PARM_NAME, "GLOBAL_CUSTOMER_ID");
- final HttpEntity<?> request = new HttpEntity<>(getCreateNsRequest(), headers);
- final ResponseEntity<Void> responseEntity =
- testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, Void.class);
- assertEquals(HttpStatus.NOT_IMPLEMENTED, responseEntity.getStatusCode());
+ headers.add(Constants.HTTP_GLOBAL_CUSTOMER_ID_HTTP_HEADER_PARM_NAME, GLOBAL_CUSTOMER_ID);
+ final HttpEntity<?> request = new HttpEntity<>(createNsRequest, headers);
+ final ResponseEntity<NsInstancesNsInstance> responseEntity =
+ testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, NsInstancesNsInstance.class);
+ assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode());
+ assertTrue(responseEntity.hasBody());
+ assertNotNull(responseEntity.getBody());
+
+ final HttpHeaders httpHeaders = responseEntity.getHeaders();
+ assertTrue(httpHeaders.containsKey(HttpHeaders.LOCATION));
+ final List<String> actual = httpHeaders.get(HttpHeaders.LOCATION);
+ assertEquals(1, actual.size());
+ assertEquals(EXPECTED_CREATE_REQ_LOCATION_URL, actual.get(0));
+ }
+
+ @Test
+ public void testCreateNs_createNsRequest_nsRequestProcessingExceptionThrown_returnInlineResponse400()
+ throws URISyntaxException {
+
+ final CreateNsRequest createNsRequest = getCreateNsRequest();
+
+ final String message = "Unable to process request";
+ when(mockedJobExecutorService.runCreateNsJob(eq(createNsRequest), eq(GLOBAL_CUSTOMER_ID), eq(SERVICE_TYPE)))
+ .thenThrow(new NsRequestProcessingException(message, new InlineResponse400().detail(message)));
+
+ final String baseUrl = getNsLcmBaseUrl() + "/ns_instances";
+ final HttpHeaders headers = new HttpHeaders();
+ headers.add(Constants.HTTP_GLOBAL_CUSTOMER_ID_HTTP_HEADER_PARM_NAME, GLOBAL_CUSTOMER_ID);
+ final HttpEntity<?> request = new HttpEntity<>(createNsRequest, headers);
+ final ResponseEntity<InlineResponse400> responseEntity =
+ testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, InlineResponse400.class);
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode());
+ assertTrue(responseEntity.hasBody());
+ assertNotNull(responseEntity.getBody());
+
+ final InlineResponse400 body = responseEntity.getBody();
+ assertEquals(message, body.getDetail());
+
+ }
+
+ @Test
+ public void testCreateNs_createNsRequest_exceptionThrown_returnInlineResponse400() throws URISyntaxException {
+
+ final CreateNsRequest createNsRequest = getCreateNsRequest();
+
+ final String message = "Unable to process request";
+ when(mockedJobExecutorService.runCreateNsJob(eq(createNsRequest), eq(GLOBAL_CUSTOMER_ID), eq(SERVICE_TYPE)))
+ .thenThrow(new RuntimeException(message));
+
+ final String baseUrl = getNsLcmBaseUrl() + "/ns_instances";
+ final HttpHeaders headers = new HttpHeaders();
+ headers.add(Constants.HTTP_GLOBAL_CUSTOMER_ID_HTTP_HEADER_PARM_NAME, GLOBAL_CUSTOMER_ID);
+ final HttpEntity<?> request = new HttpEntity<>(createNsRequest, headers);
+ final ResponseEntity<InlineResponse400> responseEntity =
+ testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, InlineResponse400.class);
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode());
+ assertTrue(responseEntity.hasBody());
+ assertNotNull(responseEntity.getBody());
+
+ final InlineResponse400 body = responseEntity.getBody();
+ assertEquals(message, body.getDetail());
+
}
@Test
@@ -90,11 +182,39 @@ public class NsLifecycleManagementControllerTest {
@Test
public void testInstantiateNs_ValidInstantiateNsRequest() {
- final String baseUrl = getNsLcmBaseUrl() + "/ns_instances/" + UUID.randomUUID().toString() + "/instantiate";
- final HttpEntity<?> request = new HttpEntity<>(getInstantiateNsRequest());
+
+ final InstantiateNsRequest instantiateNsRequest = getInstantiateNsRequest();
+ when(mockedJobExecutorService.runInstantiateNsJob(eq(RANDOM_NS_INST_ID), eq(instantiateNsRequest)))
+ .thenReturn(RANDOM_NS_LCM_OP_OCC_ID);
+
+ final String baseUrl = getNsLcmBaseUrl() + "/ns_instances/" + RANDOM_NS_INST_ID + "/instantiate";
+ final HttpEntity<?> request = new HttpEntity<>(instantiateNsRequest);
final ResponseEntity<Void> responseEntity =
testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, Void.class);
- assertEquals(HttpStatus.NOT_IMPLEMENTED, responseEntity.getStatusCode());
+ assertEquals(HttpStatus.ACCEPTED, responseEntity.getStatusCode());
+
+ final HttpHeaders httpHeaders = responseEntity.getHeaders();
+ assertTrue(httpHeaders.containsKey(HttpHeaders.LOCATION));
+ final List<String> actual = httpHeaders.get(HttpHeaders.LOCATION);
+ assertEquals(1, actual.size());
+ assertEquals(EXPECTED_INSTANTIATE_REQ_LOCATION_URL, actual.get(0));
+ }
+
+ @Test
+ public void testInstantiateNs_instantiateNsRequest_nsRequestProcessingExceptionThrown_returnInlineResponse400() {
+ final String message = "Unable to process request";
+ final InstantiateNsRequest instantiateNsRequest = getInstantiateNsRequest();
+ when(mockedJobExecutorService.runInstantiateNsJob(eq(RANDOM_NS_INST_ID), eq(instantiateNsRequest)))
+ .thenThrow(new NsRequestProcessingException(message, new InlineResponse400().detail(message)));
+
+ final String baseUrl = getNsLcmBaseUrl() + "/ns_instances/" + RANDOM_NS_INST_ID + "/instantiate";
+ final HttpEntity<?> request = new HttpEntity<>(instantiateNsRequest);
+ final ResponseEntity<InlineResponse400> responseEntity =
+ testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, InlineResponse400.class);
+
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode());
+ assertTrue(responseEntity.hasBody());
+ assertNotNull(responseEntity.getBody());
}
@Test
@@ -116,7 +236,7 @@ public class NsLifecycleManagementControllerTest {
}
private CreateNsRequest getCreateNsRequest() {
- return new CreateNsRequest().nsdId(UUID.randomUUID().toString());
+ return new CreateNsRequest().nsdId(RANDOM_NS_INST_ID);
}
private String getNsLcmBaseUrl() {
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/resources/application.yaml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/resources/application.yaml
new file mode 100644
index 0000000000..44acda20a4
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/resources/application.yaml
@@ -0,0 +1,39 @@
+# Copyright © 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.
+spring:
+ main:
+ allow-bean-definition-overriding: true
+ flyway:
+ baseline-on-migrate: false
+ datasource:
+ hikari:
+ camunda:
+ jdbcUrl: jdbc:h2:mem:example-simple;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
+ driver-class-name: org.h2.Driver
+ pool-name: ns-lcm-bpmn-pool
+ registerMbeans: true
+ nfvo:
+ jdbcUrl: jdbc:h2:mem:NFVO;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS NFVO;
+ driver-class-name: org.h2.Driver
+ pool-name: ns-lcm-nfvo-pool
+ registerMbeans: true
+ jpa:
+ hibernate:
+ ddl-auto: none
+logging:
+ level:
+ org.reflections.Reflections: ERROR
+etsi-catalog-manager:
+ base:
+ endpoint: http://modeling-etsicatalog.onap:8806/api \ No newline at end of file