From 21a476895dc40402dced615cb0f1b112b1796355 Mon Sep 17 00:00:00 2001 From: "waqas.ikram" Date: Thu, 20 Aug 2020 09:59:05 +0100 Subject: [PATCH] Implementing Create NS Change-Id: Ib54e7476820fe716137e6d5e08e4d0deb9f104b9 Issue-ID: SO-3179 Signed-off-by: waqas.ikram --- so-etsi-nfvo/pom.xml | 1 + .../onap/so/etsi/nfvo/ns/lcm/app/Application.java | 8 +- .../lcm/app/AsyncThreadExecutorConfiguration.java | 8 +- .../DefaultToShortClassNameBeanNameGenerator.java | 9 +- .../src/main/resources/application.yaml | 43 ++- .../so-etsi-nfvo-ns-lcm-bpmn-flows/pom.xml | 77 ++++ .../lcm/bpmn/flows/CamundaCustomConfiguration.java | 49 +++ .../bpmn/flows/CamundaDatabaseConfiguration.java | 69 ++++ .../bpmn/flows/CamundaVariableNameConstants.java | 48 +++ .../so/etsi/nfvo/ns/lcm/bpmn/flows/Constants.java | 36 ++ .../etsi/nfvo/ns/lcm/bpmn/flows/GsonProvider.java | 44 +++ .../EtsiCatalogManagerRequestFailureException.java | 41 +++ .../exceptions/NsRequestProcessingException.java | 53 +++ .../flows/extclients/aai/AaiClientProvider.java | 34 ++ .../flows/extclients/aai/AaiPropertiesImpl.java | 76 ++++ .../flows/extclients/aai/AaiServiceProvider.java | 44 +++ .../extclients/aai/AaiServiceProviderImpl.java | 83 +++++ ...tsiCatalogPackageManagementServiceProvider.java | 36 ++ ...atalogPackageManagementServiceProviderImpl.java | 86 +++++ .../EtsiCatalogServiceProviderConfiguration.java | 188 ++++++++++ .../etsicatalog/EtsiCatalogUrlProvider.java | 51 +++ .../lcm/bpmn/flows/service/JobExecutorService.java | 182 ++++++++++ .../flows/service/WorkflowExecutorService.java | 59 ++++ .../bpmn/flows/service/WorkflowQueryService.java | 108 ++++++ .../flows/tasks/AbstractNetworkServiceTask.java | 117 +++++++ .../nfvo/ns/lcm/bpmn/flows/tasks/CreateNsTask.java | 221 ++++++++++++ .../bpmn/flows/utils/LocalDateTimeTypeAdapter.java | 58 +++ .../src/main/resources/CreateNs.bpmn | 266 ++++++++++++++ .../services/org.onap.so.client.RestProperties | 1 + .../so/etsi/nfvo/ns/lcm/bpmn/flows/BaseTest.java | 138 ++++++++ .../DefaultToShortClassNameBeanNameGenerator.java | 37 ++ .../nfvo/ns/lcm/bpmn/flows/TestApplication.java | 45 +++ .../ns/workflow/engine/tasks/CreateNsTaskTest.java | 387 +++++++++++++++++++++ .../src/test/resources/application.yaml | 48 +++ .../so-etsi-nfvo-ns-lcm-database-service/pom.xml | 10 + .../etsi/nfvo/ns/lcm/database/beans/JobAction.java | 1 + .../nfvo/ns/lcm/database/beans/NfvoJobStatus.java | 2 +- .../nfvo/ns/lcm/database/beans/NfvoNsInst.java | 2 +- .../database/config/NfvoDatabaseConfiguration.java | 9 +- .../lcm/database/repository/NfvoJobRepository.java | 35 ++ .../database/repository/NfvoNsInstRepository.java | 39 +++ .../database/service/DatabaseServiceProvider.java | 92 +++++ .../db/migration/V1_1__create_nfvo_tables.sql | 2 + .../lcm/database/DatabaseServiceProviderTest.java | 115 ++++++ .../etsi/nfvo/ns/lcm/database/TestApplication.java | 45 +++ .../ns/lcm/database/beans/utils/UtilsTest.java | 65 ++++ .../src/test/resources/application.yaml | 35 ++ .../so-etsi-nfvo-ns-lcm-service/pom.xml | 10 + .../org/onap/so/etsi/nfvo/ns/lcm/Constants.java | 8 +- .../nfvo/ns/lcm/EtsiSoNsLcmManagerUrlProvider.java | 53 +++ .../nfvo/ns/lcm/GsonSerializerConfiguration.java | 42 +++ .../nfvo/ns/lcm/lifecycle/NsLifeCycleManager.java | 67 ++++ .../rest/NsLcmOperationOccurrencesController.java | 8 +- .../lcm/rest/NsLifecycleManagementController.java | 31 +- .../NsLcmControllerExceptionHandler.java | 61 ++++ .../onap/so/etsi/nfvo/ns/lcm/TestApplication.java | 8 +- .../NsLcmOperationOccurrencesControllerTest.java | 8 +- .../rest/NsLifecycleManagementControllerTest.java | 113 +++++- .../src/test/resources/application.yaml | 17 +- 59 files changed, 3573 insertions(+), 56 deletions(-) create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateNs.bpmn create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/resources/application.yaml create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 diff --git a/so-etsi-nfvo/pom.xml b/so-etsi-nfvo/pom.xml index 8048f0c7d3..0b87b259c1 100644 --- a/so-etsi-nfvo/pom.xml +++ b/so-etsi-nfvo/pom.xml @@ -26,6 +26,7 @@ 2.7.5 1.13.0 2.3.0 + 0.11 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..563a15f2ae 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}/camundabpmn + username: ${DB_USERNAME} + password: ${DB_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 +etsi-so-ns-lcm-manager: + endpoint: http://so-etsi-nfvo-ns-lcm: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 e608465a8c..66c11f279f 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,11 +8,88 @@ so-etsi-nfvo-ns-lcm-bpmn-flows SO ETSI NFVO NS LCM BPMN Flows + + + + + org.jacoco + jacoco-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + DEBUG + + 2 + suites + false + 1 + + + + + + + org.onap.so.etsi.nfvo + so-etsi-nfvo-ns-lcm-api + ${project.version} + org.onap.so.etsi.nfvo so-etsi-nfvo-ns-lcm-database-service ${project.version} + + org.onap.so.adapters + etsi-sol003-pkgm-ext-clients + ${project.version} + + + org.onap.so + aai-client + ${project.version} + + + org.camunda.bpm.springboot + camunda-bpm-spring-boot-starter-rest + ${camunda.springboot.version} + + + org.camunda.bpmn + camunda-engine-rest-core + + + + + org.yaml + snakeyaml + + + com.shazam + shazamcrest + ${snakeyaml-version} + + + com.google.guava + guava + + + org.apache.commons + commons-lang3 + + + com.vaadin.external.google + android-json + + + + + com.h2database + h2 + test + \ 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..ed6da5430e --- /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,48 @@ +/*- + * ============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"; + + 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..46115a753b --- /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,36 @@ +/*- + * ============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 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 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..a373df43e7 --- /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,36 @@ +/*- + * ============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; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public interface EtsiCatalogPackageManagementServiceProvider { + + Optional getNSPackageModel(final String nsdId); + + Optional getVnfPkgInfo(final String 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/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..32f7cc1182 --- /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,86 @@ +/*- + * ============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.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; + + @Autowired + public EtsiCatalogPackageManagementServiceProviderImpl(final EtsiCatalogUrlProvider etsiCatalogUrlProvider, + @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider) { + this.etsiCatalogUrlProvider = etsiCatalogUrlProvider; + this.httpServiceProvider = httpServiceProvider; + } + + @Override + public Optional getNSPackageModel(final String nsdId) { + try { + final ResponseEntity 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 getVnfPkgInfo(final String vnfPkgId) { + try { + final ResponseEntity 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); + } + } + +} 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 socketFactoryRegistry = RegistryBuilder + .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 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> 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/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..692aff62cd --- /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,182 @@ +/*- + * ============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.JOB_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.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.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.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.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.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; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class JobExecutorService { + + private static final Logger logger = getLogger(JobExecutorService.class); + + private static final ImmutableSet 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; + + @Autowired + public JobExecutorService(final DatabaseServiceProvider databaseServiceProvider, + final WorkflowExecutorService workflowExecutorService, final WorkflowQueryService workflowQueryService) { + this.databaseServiceProvider = databaseServiceProvider; + this.workflowExecutorService = workflowExecutorService; + this.workflowQueryService = workflowQueryService; + } + + 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 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 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 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(); + } + + private ImmutablePair waitForJobToFinish(final String jobId, + final ImmutableSet 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 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.debug("Received job status response: \n ", nfvoJob); + if (jobFinishedStates.contains(nfvoJob.getStatus())) { + logger.info("Job finished \n {}", currentJobStatus); + return ImmutablePair.of(nfvoJob.getProcessInstanceId(), currentJobStatus); + } + + logger.debug("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 getVariables(final String jobId, final CreateNsRequest createNsRequest, + final String globalCustomerId, final String serviceType) { + final Map 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; + } + +} 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 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 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 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 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 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/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..19cac68f9b --- /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 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 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 optional = databaseServiceProvider.getNfvoNsInstByNsInstId(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/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 { + + 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/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 @@ + + + + + Flow_1tqn5q5 + + + Flow_0t87ov3 + + + + Flow_1tqn5q5 + Flow_0y07mxe + + + + Flow_1rtsvpm + Flow_0t87ov3 + + + + Flow_09582uw + Flow_1f4vi10 + Flow_0qabgp7 + + + Flow_0y07mxe + Flow_09582uw + + + + + Flow_0554tjv + + + + Flow_04xvpee + + + + Flow_0554tjv + Flow_04xvpee + + + + + + Flow_0j1otrx + + + + Flow_0oqv7vl + + + + Flow_0j1otrx + Flow_0oqv7vl + + + + + #{not doesNsPackageExists} + + + Flow_1f4vi10 + Flow_1yql1cm + + + + #{doesNsPackageExists} + + + Flow_0qabgp7 + Flow_1exrj2b + + + + Flow_1exrj2b + Flow_1rkg44s + Flow_1yql1cm + + + #{not doesNsInstanceExists} + + + #{doesNsInstanceExists} + + + Flow_1rkg44s + Flow_1jvfwd2 + + + + Flow_1jvfwd2 + Flow_0e5hvno + + + + Flow_0e5hvno + Flow_1rtsvpm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/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..16557e74d9 --- /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,138 @@ +/*- + * ============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 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 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 getNfvoJob(final String jobId) { + return databaseServiceProvider.getJob(jobId); + } + + public Optional getJobByResourceId(final String resourceId) { + return databaseServiceProvider.getJobByResourceId(resourceId); + } + + public ProcessInstance executeWorkflow(final String processDefinitionKey, final String businessKey, + final Map 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 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) { + final HistoricProcessInstance processInstance = getHistoricProcessInstance(processInstanceId); + return processInstance != null + && !HistoricProcessInstance.STATE_ACTIVE.equalsIgnoreCase(processInstance.getState()); + } + +} 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/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 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 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 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 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 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 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 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 getVariables(final String jobId, final CreateNsRequest createNsRequest) { + final Map 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/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..3faa62c51d --- /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,48 @@ +# 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;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: 10 +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-database-service/pom.xml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/pom.xml index b860ddeb5c..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 @@ -21,5 +21,15 @@ org.flywaydb flyway-core + + com.h2database + h2 + test + + + org.springframework.boot + spring-boot-starter-test + test + \ 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 index 50573b42f5..8a22689f8a 100644 --- 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 @@ -21,6 +21,7 @@ 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/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 index 9bd05924ad..89e07701ed 100644 --- 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 @@ -47,7 +47,7 @@ public class NfvoJobStatus { @Column(name = "STATUS") private JobStatusEnum status; - @Column(name = "DESCRIPTION") + @Column(name = "DESCRIPTION", columnDefinition = "LONGTEXT") private String description; @Column(name = "UPDATED_TIME") 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 index fdd053c49e..dd8448fe56 100644 --- 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 @@ -59,7 +59,7 @@ public class NfvoNsInst { @Column(name = "NSD_INVARIANT_ID") private String nsdInvariantId; - @Column(name = "DESCRIPTION") + @Column(name = "DESCRIPTION", columnDefinition = "LONGTEXT") private String description; @Enumerated(EnumType.STRING) 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 index 0438a4258c..8f146e5378 100644 --- 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 @@ -48,11 +48,12 @@ import com.zaxxer.hikari.HikariDataSource; 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; - private static final String NFVO_DATA_SOURCE_QUALIFIER = "nfvoDataSource"; - @Bean @ConfigurationProperties(prefix = "spring.datasource.hikari.nfvo") public HikariConfig nfvoDbConfig() { @@ -72,8 +73,8 @@ public class NfvoDatabaseConfiguration { @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("nfvo") - .build(); + return builder.dataSource(dataSource).packages(NfvoJob.class.getPackage().getName()) + .persistenceUnit(PERSISTENCE_UNIT).build(); } @Primary 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 { + + Optional 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/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 { + + Optional findByName(final String name); + + Optional 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..420d916014 --- /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,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.database.service; + +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.NfvoNsInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.repository.NfvoJobRepository; +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; + + @Autowired + public DatabaseServiceProvider(final NfvoJobRepository nfvoJobRepository, + final NfvoNsInstRepository nfvoNsInstRepository) { + this.nfvoJobRepository = nfvoJobRepository; + this.nfvoNsInstRepository = nfvoNsInstRepository; + } + + public boolean addJob(final NfvoJob job) { + logger.info("Adding NfvoJob: {} to database", job); + return nfvoJobRepository.save(job) != null; + } + + public Optional getJob(final String jobId) { + logger.info("Querying database for NfvoJob using jobId: {}", jobId); + return nfvoJobRepository.findById(jobId); + } + + public Optional 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 saveNfvoNsInst(final NfvoNsInst nfvoNsInst) { + logger.info("Saving NfvoNsInst: {} to database", nfvoNsInst); + return nfvoNsInstRepository.save(nfvoNsInst) != null; + } + + public Optional getNfvoNsInst(final String nsInstId) { + logger.info("Querying database for NfvoNsInst using nsInstId: {}", nsInstId); + return nfvoNsInstRepository.findById(nsInstId); + } + + public Optional getNfvoNsInstByName(final String name) { + logger.info("Querying database for NfvoNsInst using name: {}", name); + return nfvoNsInstRepository.findByName(name); + } + + public Optional getNfvoNsInstByNsInstId(final String nsInstId) { + logger.info("Querying database for NfvoNsInst using nsInstId: {}", nsInstId); + return nfvoNsInstRepository.findByNsInstId(nsInstId); + } + +} 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 index e4c959d6e3..f41a8206e0 100644 --- 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 @@ -14,6 +14,8 @@ CREATE TABLE IF NOT EXISTS `JOB` ( 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, 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..03488e9176 --- /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,115 @@ +/*- + * ============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.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.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.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 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 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 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)); + } + +} 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..8b7550d8ef --- /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,35 @@ +# 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 + +logging: + level: + org.flywaydb: DEBUG +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 d48acb62af..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 @@ -15,6 +15,11 @@ so-etsi-nfvo-ns-lcm-api ${project.version} + + org.onap.so.etsi.nfvo + so-etsi-nfvo-ns-lcm-bpmn-flows + ${project.version} + org.springframework.boot spring-boot-starter-web @@ -64,5 +69,10 @@ junit test + + com.h2database + h2 + test + \ 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..baf11193cf --- /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("${etsi-so-ns-lcm-manager.endpoint}") 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..f295731cb6 --- /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,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.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.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 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); + } + +} 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..fb0a2503a2 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 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); } /** 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..8d9fdbe339 --- /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,61 @@ +/*- + * ============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 handleNsRequestProcessingException( + final NsRequestProcessingException nsRequestProcessingException) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(getInlineResponse400(nsRequestProcessingException)); + } + + 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()); + + } + + @ExceptionHandler(Exception.class) + public ResponseEntity handleNsRequestProcessingException(final Exception exception) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new InlineResponse400() + .status(HttpStatus.INTERNAL_SERVER_ERROR.value()).detail(exception.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..4ff74eaaa1 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,102 @@ import com.google.gson.Gson; @SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("test") public class NsLifecycleManagementControllerTest { + 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_LOCATION_URL = "http://etsi-so-ns-lcm-manager-service:9095" + + "/so/so-etsi-nfvo-ns-lcm/v1/" + "api/nslcm/v1/ns_instances/" + RANDOM_NS_INST_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 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 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 actual = httpHeaders.get(HttpHeaders.LOCATION); + assertEquals(1, actual.size()); + assertEquals(EXPECTED_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 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 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 @@ -116,7 +203,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 index 255ed2f48f..6c8a7997af 100644 --- 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 @@ -18,11 +18,24 @@ spring: 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; + 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: hibernate: - ddl-auto: none \ No newline at end of file + ddl-auto: none +logging: + level: + org.reflections.Reflections: ERROR +etsi-catalog-manager: + base: + endpoint: http://modeling-etsicatalog.onap:8806/api +etsi-so-ns-lcm-manager: + endpoint: http://etsi-so-ns-lcm-manager-service:9095 \ No newline at end of file -- 2.16.6