diff options
Diffstat (limited to 'so-etsi-nfvo')
100 files changed, 9302 insertions, 86 deletions
diff --git a/so-etsi-nfvo/pom.xml b/so-etsi-nfvo/pom.xml index 8048f0c7d3..fa85460086 100644 --- a/so-etsi-nfvo/pom.xml +++ b/so-etsi-nfvo/pom.xml @@ -26,6 +26,8 @@ <okhttp-version>2.7.5</okhttp-version> <okio-version>1.13.0</okio-version> <jaxb-api>2.3.0</jaxb-api> + <snakeyaml-version>0.11</snakeyaml-version> + <hamcrest-version>2.2</hamcrest-version> </properties> <build> diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-api/src/main/resources/SOL005-NSLifecycleManagement-API.json b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-api/src/main/resources/SOL005-NSLifecycleManagement-API.json index 8257e6ba22..8a7eb9d006 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-api/src/main/resources/SOL005-NSLifecycleManagement-API.json +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-api/src/main/resources/SOL005-NSLifecycleManagement-API.json @@ -75,7 +75,8 @@ }, "retirementDate":{ "description":"Date-time stamp. Representation: String formatted according toas defined by the date-time production in IETF RFC 3339.\n", - "format":"date-time" + "format":"date-time", + "type":"string" } } } @@ -9667,7 +9668,8 @@ }, "startTime":{ "description":"Date-time stamp. Representation: String formatted according toas defined by the date-time production in IETF RFC 3339.\n", - "format":"date-time" + "format":"date-time", + "type":"string" }, "nsInstantiationLevelId":{ "description":"An identifier that is unique within a NS descriptor. Representation: string of variable length.\n", @@ -10745,7 +10747,8 @@ }, "scaleTime":{ "description":"Date-time stamp. Representation: String formatted according toas defined by the date-time production in IETF RFC 3339.\n", - "format":"date-time" + "format":"date-time", + "type":"string" } } }, @@ -13113,7 +13116,8 @@ }, "updateTime":{ "description":"Date-time stamp. Representation: String formatted according toas defined by the date-time production in IETF RFC 3339.\n", - "format":"date-time" + "format":"date-time", + "type":"string" } } }, @@ -15175,7 +15179,8 @@ }, "statusEnteredTime":{ "description":"Date-time stamp. Representation: String formatted according toas defined by the date-time production in IETF RFC 3339.\n", - "format":"date-time" + "format":"date-time", + "type":"string" }, "nsInstanceId":{ "description":"An identifier with the intention of being globally unique.\n", @@ -15194,7 +15199,8 @@ }, "startTime":{ "description":"Date-time stamp. Representation: String formatted according toas defined by the date-time production in IETF RFC 3339.\n", - "format":"date-time" + "format":"date-time", + "type":"string" }, "isAutomaticInvocation":{ "description":"Set to true if this NS LCM operation occurrence has been automatically triggered by the NFVO. This occurs in the case of auto-scaling, auto-healing and when a nested NS is modified as a result of an operation on its composite NS. Set to false otherwise.\n", @@ -15202,14 +15208,7 @@ }, "operationParams":{ "description":"Input parameters of the LCM operation. This attribute shall be formatted according to the request data type of the related LCM operation. The following mapping between lcmOperationType and the data type of this attribute shall apply: - INSTANTIATE: InstantiateNsRequest - SCALE: ScaleNsRequest - UPDATE: UpdateNsRequest - HEAL: HealNsRequest - TERMINATE: TerminateNsRequest This attribute shall be present if this data type is returned in a response to reading an individual resource, and may be present according to the chosen attribute selector parameter if this data type is returned in a response to a query of a container resource.\n", - "type":"string", - "enum":[ - "INSTANTIATE", - "SCALE", - "UPDATE", - "HEAL", - "TERMINATE" - ] + "type":"object" }, "isCancelPending":{ "description":"If the LCM operation occurrence is in \"PROCESSING\" or \"ROLLING_BACK\" state and the operation is being cancelled, this attribute shall be set to true. Otherwise, it shall be set to false.\n", @@ -16396,7 +16395,8 @@ }, "statusEnteredTime":{ "description":"Date-time stamp. Representation: String formatted according toas defined by the date-time production in IETF RFC 3339.\n", - "format":"date-time" + "format":"date-time", + "type":"string" }, "nsInstanceId":{ "description":"An identifier with the intention of being globally unique.\n", @@ -16415,7 +16415,8 @@ }, "startTime":{ "description":"Date-time stamp. Representation: String formatted according toas defined by the date-time production in IETF RFC 3339.\n", - "format":"date-time" + "format":"date-time", + "type":"string" }, "isAutomaticInvocation":{ "description":"Set to true if this NS LCM operation occurrence has been automatically triggered by the NFVO. This occurs in the case of auto-scaling, auto-healing and when a nested NS is modified as a result of an operation on its composite NS. Set to false otherwise.\n", @@ -16423,14 +16424,7 @@ }, "operationParams":{ "description":"Input parameters of the LCM operation. This attribute shall be formatted according to the request data type of the related LCM operation. The following mapping between lcmOperationType and the data type of this attribute shall apply: - INSTANTIATE: InstantiateNsRequest - SCALE: ScaleNsRequest - UPDATE: UpdateNsRequest - HEAL: HealNsRequest - TERMINATE: TerminateNsRequest This attribute shall be present if this data type is returned in a response to reading an individual resource, and may be present according to the chosen attribute selector parameter if this data type is returned in a response to a query of a container resource.\n", - "type":"string", - "enum":[ - "INSTANTIATE", - "SCALE", - "UPDATE", - "HEAL", - "TERMINATE" - ] + "type":"object" }, "isCancelPending":{ "description":"If the LCM operation occurrence is in \"PROCESSING\" or \"ROLLING_BACK\" state and the operation is being cancelled, this attribute shall be set to true. Otherwise, it shall be set to false.\n", @@ -19521,7 +19515,8 @@ }, "statusEnteredTime":{ "description":"Date-time stamp. Representation: String formatted according toas defined by the date-time production in IETF RFC 3339.\n", - "format":"date-time" + "format":"date-time", + "type":"string" }, "nsInstanceId":{ "description":"An identifier with the intention of being globally unique.\n", @@ -19540,7 +19535,8 @@ }, "startTime":{ "description":"Date-time stamp. Representation: String formatted according toas defined by the date-time production in IETF RFC 3339.\n", - "format":"date-time" + "format":"date-time", + "type":"string" }, "isAutomaticInvocation":{ "description":"Set to true if this NS LCM operation occurrence has been automatically triggered by the NFVO. This occurs in the case of auto-scaling, auto-healing and when a nested NS is modified as a result of an operation on its composite NS. Set to false otherwise.\n", @@ -19548,14 +19544,7 @@ }, "operationParams":{ "description":"Input parameters of the LCM operation. This attribute shall be formatted according to the request data type of the related LCM operation. The following mapping between lcmOperationType and the data type of this attribute shall apply: - INSTANTIATE: InstantiateNsRequest - SCALE: ScaleNsRequest - UPDATE: UpdateNsRequest - HEAL: HealNsRequest - TERMINATE: TerminateNsRequest This attribute shall be present if this data type is returned in a response to reading an individual resource, and may be present according to the chosen attribute selector parameter if this data type is returned in a response to a query of a container resource.\n", - "type":"string", - "enum":[ - "INSTANTIATE", - "SCALE", - "UPDATE", - "HEAL", - "TERMINATE" - ] + "type":"object" }, "isCancelPending":{ "description":"If the LCM operation occurrence is in \"PROCESSING\" or \"ROLLING_BACK\" state and the operation is being cancelled, this attribute shall be set to true. Otherwise, it shall be set to false.\n", diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/Application.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/Application.java index 24c09d489e..12f3bfc119 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/Application.java +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/Application.java @@ -1,19 +1,19 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2020 Ericsson. All rights reserved. + * Copyright (C) 2020 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/AsyncThreadExecutorConfiguration.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/AsyncThreadExecutorConfiguration.java index 2eaa710191..4427e1ac2f 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/AsyncThreadExecutorConfiguration.java +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/AsyncThreadExecutorConfiguration.java @@ -1,19 +1,19 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2020 Ericsson. All rights reserved. + * Copyright (C) 2020 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/DefaultToShortClassNameBeanNameGenerator.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/DefaultToShortClassNameBeanNameGenerator.java index 13649ac80c..2546c9c23f 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/DefaultToShortClassNameBeanNameGenerator.java +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/app/DefaultToShortClassNameBeanNameGenerator.java @@ -1,23 +1,22 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix. All rights reserved. + * Copyright (C) 2020 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ - package org.onap.so.etsi.nfvo.ns.lcm.app; import org.springframework.beans.factory.config.BeanDefinition; diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/resources/application.yaml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/resources/application.yaml index 457e956f71..7f0fd93c8d 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/resources/application.yaml +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-application/src/main/resources/application.yaml @@ -11,6 +11,19 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +aai: + auth: 2A11B07DB6214A839394AA1EC5844695F5114FC407FF5422625FB00175A3DCB8A1FF745F22867EFA72D5369D599BBD88DA8BED4233CF5586 + version: v19 + endpoint: https://aai.onap:8443 +camunda: + bpm: + admin-user: + id: admin + password: admin + history-level: full + job-execution: + max-pool-size: 30 + core-pool-size: 3 spring: security: usercredentials: @@ -22,7 +35,35 @@ spring: preferred-json-mapper: gson main: allow-bean-definition-overriding: true + datasource: + hikari: + camunda: + jdbcUrl: jdbc:mariadb://${DB_HOST}:${DB_PORT}/camundabpmn + username: ${DB_USERNAME} + password: ${DB_PASSWORD} + driver-class-name: org.mariadb.jdbc.Driver + pool-name: bpmn-pool + registerMbeans: true + nfvo: + jdbcUrl: jdbc:mariadb://${DB_HOST}:${DB_PORT}/nfvo + username: ${NFVO_USERNAME} + password: ${NFVO_PASSWORD} + driver-class-name: org.mariadb.jdbc.Driver + pool-name: nfvo-pool + registerMbeans: true server: port: 9095 tomcat: - max-threads: 50
\ No newline at end of file + max-threads: 50 +mso: + key: 07a7159d3bf51a0e53be7a8f89699be7 +so: + adapters: + sol003-adapter: + url: https://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1 + auth: Basic dm5mbTpwYXNzd29yZDEk +etsi-catalog-manager: + base: + endpoint: http://modeling-etsicatalog.onap:8806/api +so-etsi-nfvo-ns-lcm: + endpoint: http://so-etsi-nfvo-ns-lcm.onap:9095
\ No newline at end of file diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/pom.xml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/pom.xml index 734d4e071e..1c13ecac25 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/pom.xml +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/pom.xml @@ -8,4 +8,99 @@ </parent> <artifactId>so-etsi-nfvo-ns-lcm-bpmn-flows</artifactId> <name>SO ETSI NFVO NS LCM BPMN Flows</name> + + <build> + <plugins> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <systemPropertyVariables> + <so.log.level>DEBUG</so.log.level> + </systemPropertyVariables> + <rerunFailingTestsCount>2</rerunFailingTestsCount> + <parallel>suites</parallel> + <useUnlimitedThreads>false</useUnlimitedThreads> + <threadCount>1</threadCount> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>org.onap.so.etsi.nfvo</groupId> + <artifactId>so-etsi-nfvo-ns-lcm-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.so.etsi.nfvo</groupId> + <artifactId>so-etsi-nfvo-ns-lcm-database-service</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.so.adapters</groupId> + <artifactId>etsi-sol003-pkgm-ext-clients</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.so.adapters</groupId> + <artifactId>etsi-sol003-lcm-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.so</groupId> + <artifactId>aai-client</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.camunda.bpm.springboot</groupId> + <artifactId>camunda-bpm-spring-boot-starter-rest</artifactId> + <version>${camunda.springboot.version}</version> + <exclusions> + <exclusion> + <groupId>org.camunda.bpmn</groupId> + <artifactId>camunda-engine-rest-core</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.yaml</groupId> + <artifactId>snakeyaml</artifactId> + </dependency> + <dependency> + <groupId>com.shazam</groupId> + <artifactId>shazamcrest</artifactId> + <version>${snakeyaml-version}</version> + <exclusions> + <exclusion> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </exclusion> + <exclusion> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </exclusion> + <exclusion> + <groupId>com.vaadin.external.google</groupId> + <artifactId>android-json</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest</artifactId> + <version>${hamcrest-version}</version> + <scope>test</scope> + </dependency> + </dependencies> </project>
\ No newline at end of file diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaCustomConfiguration.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaCustomConfiguration.java new file mode 100644 index 0000000000..33923f400e --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaCustomConfiguration.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.NS_WORKFLOW_ENGINE; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.TENANT_ID; +import static org.slf4j.LoggerFactory.getLogger; +import org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration; +import org.camunda.bpm.spring.boot.starter.configuration.Ordering; +import org.camunda.bpm.spring.boot.starter.configuration.impl.AbstractCamundaConfiguration; +import org.slf4j.Logger; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Component +@Order(Ordering.DEFAULT_ORDER + 1) +public class CamundaCustomConfiguration extends AbstractCamundaConfiguration { + private static final Logger logger = getLogger(CamundaCustomConfiguration.class); + + @Override + public void preInit(final SpringProcessEngineConfiguration processEngineConfiguration) { + logger.info("Setting DeploymentTenantId to {} and DeploymentName to {}", TENANT_ID, NS_WORKFLOW_ENGINE); + processEngineConfiguration.setDeploymentTenantId(TENANT_ID); + processEngineConfiguration.setDeploymentName(NS_WORKFLOW_ENGINE); + super.preInit(processEngineConfiguration); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaDatabaseConfiguration.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaDatabaseConfiguration.java new file mode 100644 index 0000000000..c803808df1 --- /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.data.jpa.repository.config.EnableJpaRepositories; +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 +@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager") +public class CamundaDatabaseConfiguration { + + private static final String CAMUNDA_DATA_SOURCE_BEAN_NAME = "camundaBpmDataSource"; + + 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 Camunda HikariConfig bean ... "); + return new HikariConfig(); + } + + @Bean(name = CAMUNDA_DATA_SOURCE_BEAN_NAME) + public DataSource camundaDataSource() { + if (mBeanExporter != null) { + mBeanExporter.addExcludedBean(CAMUNDA_DATA_SOURCE_BEAN_NAME); + } + logger.debug("Creating Camunda HikariDataSource bean ... "); + final HikariConfig hikariConfig = this.camundaDbConfig(); + return new HikariDataSource(hikariConfig); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaVariableNameConstants.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaVariableNameConstants.java new file mode 100644 index 0000000000..e90391d51a --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaVariableNameConstants.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class CamundaVariableNameConstants { + + public static final String JOB_ID_PARAM_NAME = "jobId"; + public static final String JOB_BUSINESS_KEY_PARAM_NAME = "jobBusinessKey"; + public static final String CREATE_NS_REQUEST_PARAM_NAME = "createNsRequest"; + public static final String GLOBAL_CUSTOMER_ID_PARAM_NAME = "globalCustomerId"; + public static final String SERVICE_TYPE_PARAM_NAME = "serviceType"; + + + public static final String NS_PACKAGE_MODEL_PARAM_NAME = "NSPackageModel"; + public static final String CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME = + "CreateNsWorkflowProcessingException"; + public static final String CREATE_NS_RESPONSE_PARAM_NAME = "createNsResponse"; + + public static final String INSTANTIATE_NS_REQUEST_PARAM_NAME = "instantiateNsRequest"; + public static final String OCC_ID_PARAM_NAME = "occId"; + public static final String NS_INSTANCE_ID_PARAM_NAME = "NsInstanceId"; + public static final String NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME = "NetworkServiceDescriptor"; + public static final String VNF_CREATE_INSTANTIATE_REQUESTS = "vnfCreateInstantiateRequests"; + + public static final String NF_INST_ID_PARAM_NAME = "NF_INST_ID"; + public static final String CREATE_VNF_RESPONSE_PARAM_NAME = "createVnfResponse"; + public static final String OPERATION_STATUS_PARAM_NAME = "operationStatus"; + + private CamundaVariableNameConstants() {} + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/Constants.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/Constants.java new file mode 100644 index 0000000000..a2128fc2af --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/Constants.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class Constants { + + public static final String TENANT_ID = "ns-workflow-engine-tenant"; + public static final String NS_WORKFLOW_ENGINE = "NS-WORKFLOW-ENGINE"; + public static final String CREATE_NS_WORKFLOW_NAME = "CreateNs"; + public static final String INSTANTIATE_NS_WORKFLOW_NAME = "InstantiateNs"; + public static final String GET_NS_OCCURRENCE_OPERATION_STATUS_NAME = "GetNsOccurrenceOperationStatus"; + + + private Constants() {} + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/GsonProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/GsonProvider.java new file mode 100644 index 0000000000..31961d5b86 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/GsonProvider.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows; + +import java.time.LocalDateTime; +import org.onap.so.etsi.nfvo.ns.lcm.JSON; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.utils.LocalDateTimeTypeAdapter; +import org.springframework.stereotype.Component; +import org.threeten.bp.OffsetDateTime; +import com.google.gson.Gson; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Component +public class GsonProvider { + + private final JSON.OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new JSON.OffsetDateTimeTypeAdapter(); + + public Gson getGson() { + return JSON.createGson().registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter) + .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()).create(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/EtsiCatalogManagerRequestFailureException.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/EtsiCatalogManagerRequestFailureException.java new file mode 100644 index 0000000000..553d2f1cf8 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/EtsiCatalogManagerRequestFailureException.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR) +public class EtsiCatalogManagerRequestFailureException extends RuntimeException { + + private static final long serialVersionUID = 66862444537194516L; + + public EtsiCatalogManagerRequestFailureException(final String message) { + super(message); + } + + public EtsiCatalogManagerRequestFailureException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/NsRequestProcessingException.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/NsRequestProcessingException.java new file mode 100644 index 0000000000..0dcadfd4d8 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/exceptions/NsRequestProcessingException.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions; + +import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * + * @author Waqas Ikram (waqas.ikram@est.tech) + */ +@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR) +public class NsRequestProcessingException extends RuntimeException { + + private static final long serialVersionUID = 66862444537194516L; + private InlineResponse400 problemDetails; + + public NsRequestProcessingException(final String message) { + super(message); + } + + public NsRequestProcessingException(final String message, final InlineResponse400 problemDetails) { + super(message); + this.problemDetails = problemDetails; + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + + public InlineResponse400 getProblemDetails() { + return problemDetails; + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java new file mode 100644 index 0000000000..673662aae8 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiClientProvider.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai; + +import org.onap.aaiclient.client.aai.AAIResourcesClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class AaiClientProvider { + + @Bean + public AAIResourcesClient getAaiClient() { + return new AAIResourcesClient(); + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java new file mode 100644 index 0000000000..3df3580907 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiPropertiesImpl.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai; + +import org.onap.aaiclient.client.aai.AAIProperties; +import org.onap.aaiclient.client.aai.AAIVersion; +import org.onap.so.spring.SpringContextHelper; +import org.springframework.context.ApplicationContext; +import java.net.MalformedURLException; +import java.net.URL; + +public class AaiPropertiesImpl implements AAIProperties { + + private final String endpoint; + private final String encryptedBasicAuth; + private final String encryptionKey; + private final String aaiVersion; + + public AaiPropertiesImpl() { + + final ApplicationContext context = SpringContextHelper.getAppContext(); + this.endpoint = context.getEnvironment().getProperty("aai.endpoint"); + this.encryptedBasicAuth = context.getEnvironment().getProperty("aai.auth"); + this.encryptionKey = context.getEnvironment().getProperty("mso.key"); + this.aaiVersion = context.getEnvironment().getProperty("aai.version"); + } + + @Override + public URL getEndpoint() throws MalformedURLException { + return new URL(endpoint); + } + + @Override + public String getSystemName() { + return "MSO"; + } + + @Override + public AAIVersion getDefaultVersion() { + for (final AAIVersion version : AAIVersion.values()) { + if (version.toString().equalsIgnoreCase(this.aaiVersion)) { + return version; + } ; + + } + return AAIVersion.LATEST; + } + + @Override + public String getAuth() { + return encryptedBasicAuth; + } + + @Override + public String getKey() { + return encryptionKey; + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java new file mode 100644 index 0000000000..53062395cf --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai; + +import org.onap.aai.domain.yang.GenericVnf; +import org.onap.aai.domain.yang.ServiceInstance; +import java.util.Optional; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public interface AaiServiceProvider { + + void createServiceInstance(final String globalCustomerId, final String serviceType, + final ServiceInstance aaiServiceInstance); + + void createGenericVnfAndConnectServiceInstance(final String serviceInstanceId, final String vnfId, + final GenericVnf genericVnf); + + void connectGenericVnfToTenant(final String vnfId, final String cloudOwner, final String cloudRegion, + final String tenantId); + + Optional<GenericVnf> getGenericVnf(final String vnfId); + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java new file mode 100644 index 0000000000..049746c6ab --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai; + +import java.util.Optional; +import org.onap.aai.domain.yang.GenericVnf; +import org.onap.aai.domain.yang.ServiceInstance; +import org.onap.aaiclient.client.aai.AAIObjectType; +import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri; +import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + */ +@Service +public class AaiServiceProviderImpl implements AaiServiceProvider { + private static final Logger logger = LoggerFactory.getLogger(AaiServiceProviderImpl.class); + private final AaiClientProvider aaiClientProvider; + + @Autowired + public AaiServiceProviderImpl(final AaiClientProvider aaiClientProvider) { + this.aaiClientProvider = aaiClientProvider; + } + + @Override + public void createServiceInstance(final String globalCustomerId, final String serviceType, + final ServiceInstance aaiServiceInstance) { + logger.info("Creating service instance in AAI: {}", aaiServiceInstance); + final AAIResourceUri serviceInstanceURI = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, + globalCustomerId, serviceType, aaiServiceInstance.getServiceInstanceId()); + aaiClientProvider.getAaiClient().createIfNotExists(serviceInstanceURI, Optional.of(aaiServiceInstance)); + + } + + @Override + public void createGenericVnfAndConnectServiceInstance(final String serviceInstanceId, final String vnfId, + final GenericVnf genericVnf) { + logger.info("Creating GenericVnf in AAI: {}", genericVnf); + final AAIResourceUri genericVnfURI = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId); + final AAIResourceUri serviceInstanceURI = + AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, serviceInstanceId); + aaiClientProvider.getAaiClient().createIfNotExists(genericVnfURI, Optional.of(genericVnf)) + .connect(genericVnfURI, serviceInstanceURI); + + } + + @Override + public void connectGenericVnfToTenant(final String vnfId, final String cloudOwner, final String cloudRegion, + final String tenantId) { + logger.info("Connecting GenericVnf {} to {}/{}/{} in AAI", vnfId, cloudOwner, cloudRegion, tenantId); + final AAIResourceUri tenantURI = + AAIUriFactory.createResourceUri(AAIObjectType.TENANT, cloudOwner, cloudRegion, tenantId); + final AAIResourceUri genericVnfURI = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId); + aaiClientProvider.getAaiClient().connect(tenantURI, genericVnfURI); + } + + @Override + public Optional<GenericVnf> getGenericVnf(final String vnfId) { + return aaiClientProvider.getAaiClient().get(GenericVnf.class, + AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)); + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java new file mode 100644 index 0000000000..65d982c6cc --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog; + +import java.util.Optional; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public interface EtsiCatalogPackageManagementServiceProvider { + + Optional<NsdInfo> getNSPackageModel(final String nsdId); + + Optional<VnfPkgInfo> getVnfPkgInfo(final String vnfPkgId); + + Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor(final String nsdId); + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java new file mode 100644 index 0000000000..75dd7107a7 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java @@ -0,0 +1,110 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_SERVICE_PROVIDER_BEAN; +import java.util.Optional; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.EtsiCatalogManagerRequestFailureException; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptorParser; +import org.onap.so.rest.service.HttpRestServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class EtsiCatalogPackageManagementServiceProviderImpl implements EtsiCatalogPackageManagementServiceProvider { + + private static final Logger logger = LoggerFactory.getLogger(EtsiCatalogPackageManagementServiceProviderImpl.class); + + private final HttpRestServiceProvider httpServiceProvider; + private final EtsiCatalogUrlProvider etsiCatalogUrlProvider; + private final NetworkServiceDescriptorParser networkServiceDescriptorParser; + + @Autowired + public EtsiCatalogPackageManagementServiceProviderImpl(final EtsiCatalogUrlProvider etsiCatalogUrlProvider, + @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider, + final NetworkServiceDescriptorParser networkServiceDescriptorParser) { + this.etsiCatalogUrlProvider = etsiCatalogUrlProvider; + this.httpServiceProvider = httpServiceProvider; + this.networkServiceDescriptorParser = networkServiceDescriptorParser; + } + + @Override + public Optional<NsdInfo> getNSPackageModel(final String nsdId) { + try { + final ResponseEntity<NsdInfo> response = + httpServiceProvider.getHttpResponse(etsiCatalogUrlProvider.getNsPackageUrl(nsdId), NsdInfo.class); + if (response.getStatusCode().is2xxSuccessful()) { + return Optional.ofNullable(response.getBody()); + } + return Optional.empty(); + } catch (final Exception restProcessingException) { + logger.error("Caught exception while getting NS package model for: {}", nsdId, restProcessingException); + throw new EtsiCatalogManagerRequestFailureException("Internal Server Error Occurred.", + restProcessingException); + } + } + + @Override + public Optional<VnfPkgInfo> getVnfPkgInfo(final String vnfPkgId) { + try { + final ResponseEntity<VnfPkgInfo> response = httpServiceProvider + .getHttpResponse(etsiCatalogUrlProvider.getVnfPackageUrl(vnfPkgId), VnfPkgInfo.class); + if (response.getStatusCode().is2xxSuccessful()) { + return Optional.ofNullable(response.getBody()); + } + return Optional.empty(); + } catch (final Exception restProcessingException) { + logger.error("Caught exception while getting VNF package model for: {}", vnfPkgId, restProcessingException); + throw new EtsiCatalogManagerRequestFailureException("Internal Server Error Occurred.", + restProcessingException); + } + } + + @Override + public Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor(final String nsdId) { + try { + final ResponseEntity<byte[]> response = httpServiceProvider + .getHttpResponse(etsiCatalogUrlProvider.getNsPackageContentUrl(nsdId), byte[].class); + if (response.getStatusCode().is2xxSuccessful()) { + if (response.hasBody()) { + return networkServiceDescriptorParser.parse(response.getBody()); + } + logger.error("Received response without body ..."); + } + return Optional.empty(); + } catch (final Exception restProcessingException) { + logger.error("Caught exception while getting NS package content for: {}", nsdId, restProcessingException); + throw new EtsiCatalogManagerRequestFailureException("Internal Server Error Occurred.", + restProcessingException); + } + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java new file mode 100644 index 0000000000..8c6ea92428 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java @@ -0,0 +1,188 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog; + +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.Iterator; +import java.util.concurrent.TimeUnit; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; +import org.onap.logging.filter.spring.SpringClientPayloadFilter; +import org.onap.so.configuration.rest.BasicHttpHeadersProvider; +import org.onap.so.configuration.rest.HttpClientConnectionConfiguration; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider; +import org.onap.so.logging.jaxrs.filter.SOSpringClientFilter; +import org.onap.so.rest.service.HttpRestServiceProvider; +import org.onap.so.rest.service.HttpRestServiceProviderImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +/** + * Configures the HttpRestServiceProvider to make REST calls to the ETSI Catalog Manager + * + * @author gareth.roper@est.tech + */ + +@Configuration +public class EtsiCatalogServiceProviderConfiguration { + public static final String ETSI_CATALOG_REST_TEMPLATE_BEAN = "etsiCatalogRestTemplate"; + + public static final String ETSI_CATALOG_SERVICE_PROVIDER_BEAN = "etsiCatalogServiceProvider"; + + private final static Logger LOGGER = LoggerFactory.getLogger(EtsiCatalogServiceProviderConfiguration.class); + + private final HttpClientConnectionConfiguration clientConnectionConfiguration; + + @Value("${etsi-catalog-manager.http.client.ssl.trust-store:#{null}}") + private Resource trustStore; + @Value("${etsi-catalog-manager.http.client.ssl.trust-store-password:#{null}}") + private String trustStorePassword; + + private final GsonProvider gsonProvider; + + @Autowired + public EtsiCatalogServiceProviderConfiguration( + final HttpClientConnectionConfiguration clientConnectionConfiguration, final GsonProvider gsonProvider) { + this.clientConnectionConfiguration = clientConnectionConfiguration; + this.gsonProvider = gsonProvider; + } + + @Bean + @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) + public RestTemplate etsiCatalogRestTemplate() { + final RestTemplate restTemplate = new RestTemplate(); + restTemplate.getInterceptors().add(new SOSpringClientFilter()); + restTemplate.getInterceptors().add((new SpringClientPayloadFilter())); + return restTemplate; + } + + @Bean + @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN) + public HttpRestServiceProvider etsiCatalogHttpRestServiceProvider( + @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) final RestTemplate restTemplate) { + setGsonMessageConverter(restTemplate); + + final HttpClientBuilder httpClientBuilder = getHttpClientBuilder(); + if (trustStore != null) { + try { + LOGGER.debug("Setting up HttpComponentsClientHttpRequestFactory with SSL Context"); + LOGGER.debug("Setting client trust-store: {}", trustStore.getURL()); + LOGGER.debug("Creating SSLConnectionSocketFactory with AllowAllHostsVerifier ... "); + final SSLContext sslContext = new SSLContextBuilder() + .loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()).build(); + final SSLConnectionSocketFactory sslConnectionSocketFactory = + new SSLConnectionSocketFactory(sslContext, AllowAllHostsVerifier.INSTANCE); + httpClientBuilder.setSSLSocketFactory(sslConnectionSocketFactory); + final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder + .<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https", sslConnectionSocketFactory).build(); + + httpClientBuilder.setConnectionManager(getConnectionManager(socketFactoryRegistry)); + } catch (final KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException + | IOException exception) { + LOGGER.error("Error reading truststore, TLS connection will fail.", exception); + } + + } else { + LOGGER.debug("Setting connection manager without SSL ConnectionSocketFactory ..."); + httpClientBuilder.setConnectionManager(getConnectionManager()); + } + + final HttpComponentsClientHttpRequestFactory factory = + new HttpComponentsClientHttpRequestFactory(httpClientBuilder.build()); + restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory)); + + return new HttpRestServiceProviderImpl(restTemplate, new BasicHttpHeadersProvider().getHttpHeaders()); + } + + private PoolingHttpClientConnectionManager getConnectionManager( + final Registry<ConnectionSocketFactory> socketFactoryRegistry) { + return new PoolingHttpClientConnectionManager(socketFactoryRegistry, null, null, null, + clientConnectionConfiguration.getTimeToLiveInMins(), TimeUnit.MINUTES); + } + + private PoolingHttpClientConnectionManager getConnectionManager() { + return new PoolingHttpClientConnectionManager(clientConnectionConfiguration.getTimeToLiveInMins(), + TimeUnit.MINUTES); + } + + private HttpClientBuilder getHttpClientBuilder() { + return HttpClientBuilder.create().setMaxConnPerRoute(clientConnectionConfiguration.getMaxConnectionsPerRoute()) + .setMaxConnTotal(clientConnectionConfiguration.getMaxConnections()) + .setDefaultRequestConfig(getRequestConfig()); + } + + private RequestConfig getRequestConfig() { + return RequestConfig.custom().setSocketTimeout(clientConnectionConfiguration.getSocketTimeOutInMiliSeconds()) + .setConnectTimeout(clientConnectionConfiguration.getConnectionTimeOutInMilliSeconds()).build(); + } + + private static final class AllowAllHostsVerifier implements HostnameVerifier { + + private static final AllowAllHostsVerifier INSTANCE = new AllowAllHostsVerifier(); + + @Override + public boolean verify(final String hostname, final SSLSession session) { + LOGGER.debug("Skipping hostname verification ..."); + return true; + } + + } + + public void setGsonMessageConverter(final RestTemplate restTemplate) { + final Iterator<HttpMessageConverter<?>> iterator = restTemplate.getMessageConverters().iterator(); + while (iterator.hasNext()) { + if (iterator.next() instanceof MappingJackson2HttpMessageConverter) { + iterator.remove(); + } + } + restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gsonProvider.getGson())); + } + + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogUrlProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogUrlProvider.java new file mode 100644 index 0000000000..e3c159c7b0 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogUrlProvider.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class EtsiCatalogUrlProvider { + + @Value("${etsi-catalog-manager.base.endpoint}") + private String etsiCatalogManagerEndpoint; + + public EtsiCatalogUrlProvider() {} + + public String getNsPackageUrl(final String nsdId) { + return etsiCatalogManagerEndpoint + "/nsd/v1/ns_descriptors/" + nsdId; + } + + public String getNsPackageContentUrl(final String nsdId) { + return etsiCatalogManagerEndpoint + "/nsd/v1/ns_descriptors/" + nsdId + "/nsd_content"; + } + + public String getVnfPackageUrl(final String vnfPkgId) { + return etsiCatalogManagerEndpoint + "/vnfpkgm/v1/vnf_packages/" + vnfPkgId; + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterConfiguration.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterConfiguration.java new file mode 100644 index 0000000000..fe710ec00b --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterConfiguration.java @@ -0,0 +1,148 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm; + +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.Iterator; +import javax.net.ssl.SSLContext; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContextBuilder; +import org.onap.logging.filter.spring.SpringClientPayloadFilter; +import org.onap.so.configuration.rest.BasicHttpHeadersProvider; +import org.onap.so.configuration.rest.HttpComponentsClientConfiguration; +import org.onap.so.configuration.rest.HttpHeadersProvider; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider; +import org.onap.so.logging.jaxrs.filter.SOSpringClientFilter; +import org.onap.so.rest.service.HttpRestServiceProvider; +import org.onap.so.rest.service.HttpRestServiceProviderImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Configuration +public class Sol003AdapterConfiguration { + + private static final Logger logger = LoggerFactory.getLogger(Sol003AdapterConfiguration.class); + + public static final String SOL003_ADAPTER_REST_TEMPLATE_BEAN = "Sol003AdapterRestTemplateBean"; + public static final String SOL003_ADAPTER_HTTP_REST_SERVICE_PROVIDER_BEAN = + "Sol003AdapterHttpRestServiceProviderBean"; + + @Value("${rest.http.client.configuration.ssl.trustStore:#{null}}") + private Resource trustStore; + + @Value("${rest.http.client.configuration.ssl.trustStorePassword:#{null}}") + private String trustStorePassword; + + @Value("so.adapters.sol003-adapter.auth:Basic dm5mbTpwYXNzd29yZDEk") + private String sol003AdapterBasicAuth; + + @Autowired + private GsonProvider gsonProvider; + + @Autowired + private HttpComponentsClientConfiguration httpComponentsClientConfiguration; + + @Bean + @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN) + public RestTemplate sol003AdapterRestTemplate() { + final HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = + httpComponentsClientConfiguration.httpComponentsClientHttpRequestFactory(); + final RestTemplate restTemplate = + new RestTemplate(new BufferingClientHttpRequestFactory(clientHttpRequestFactory)); + restTemplate.getInterceptors().add(new SOSpringClientFilter()); + restTemplate.getInterceptors().add((new SpringClientPayloadFilter())); + return restTemplate; + + } + + @Bean + @Qualifier(SOL003_ADAPTER_HTTP_REST_SERVICE_PROVIDER_BEAN) + public HttpRestServiceProvider sol003AdapaterHttpRestServiceProvider( + @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN) @Autowired final RestTemplate restTemplate) { + + if (trustStore != null) { + setTrustStore(restTemplate); + } + setGsonMessageConverter(restTemplate); + return getHttpRestServiceProvider(restTemplate, new BasicHttpHeadersProvider(sol003AdapterBasicAuth)); + } + + private void setTrustStore(final RestTemplate restTemplate) { + try { + final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(getSSLContext()); + final HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build(); + final HttpComponentsClientHttpRequestFactory factory = + new HttpComponentsClientHttpRequestFactory(httpClient); + restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory)); + } catch (Exception exception) { + logger.error("Error reading truststore, TLS connection to VNFM will fail.", exception); + } + } + + private SSLContext getSSLContext() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, + CertificateException, IOException { + if (trustStore != null) { + logger.info("Setting truststore: {}", trustStore.getURL()); + return new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()) + .build(); + } + logger.info("Setting Default SSL ..."); + return SSLContext.getDefault(); + + } + + private HttpRestServiceProvider getHttpRestServiceProvider(final RestTemplate restTemplate, + final HttpHeadersProvider httpHeadersProvider) { + return new HttpRestServiceProviderImpl(restTemplate, httpHeadersProvider.getHttpHeaders()); + } + + private void setGsonMessageConverter(final RestTemplate restTemplate) { + final Iterator<HttpMessageConverter<?>> iterator = restTemplate.getMessageConverters().iterator(); + while (iterator.hasNext()) { + if (iterator.next() instanceof MappingJackson2HttpMessageConverter) { + iterator.remove(); + } + } + restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gsonProvider.getGson())); + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProvider.java new file mode 100644 index 0000000000..c053ba94f1 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProvider.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm; + +import java.util.Optional; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfRequest; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse; + +public interface Sol003AdapterServiceProvider { + + Optional<CreateVnfResponse> invokeCreateInstantiationRequest(final String vnfId, final CreateVnfRequest request); + + Optional<QueryJobResponse> getInstantiateOperationJobStatus(final String jobId); + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProviderImpl.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProviderImpl.java new file mode 100644 index 0000000000..09fecc64ae --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProviderImpl.java @@ -0,0 +1,117 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterConfiguration.SOL003_ADAPTER_HTTP_REST_SERVICE_PROVIDER_BEAN; +import java.util.Optional; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfRequest; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse; +import org.onap.so.rest.exceptions.HttpResouceNotFoundException; +import org.onap.so.rest.exceptions.InvalidRestRequestException; +import org.onap.so.rest.exceptions.RestProcessingException; +import org.onap.so.rest.service.HttpRestServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +@Service +public class Sol003AdapterServiceProviderImpl implements Sol003AdapterServiceProvider { + + private static final Logger LOGGER = LoggerFactory.getLogger(Sol003AdapterServiceProviderImpl.class); + public static final String RECEIVED_RESPONSE_WITHOUT_BODY = "Received response without body: {}"; + + private final Sol003AdapterUrlProvider urlProvider; + private final HttpRestServiceProvider httpServiceProvider; + + @Autowired + public Sol003AdapterServiceProviderImpl(final Sol003AdapterUrlProvider urlProvider, + @Qualifier(SOL003_ADAPTER_HTTP_REST_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider) { + this.urlProvider = urlProvider; + this.httpServiceProvider = httpServiceProvider; + } + + @Override + public Optional<CreateVnfResponse> invokeCreateInstantiationRequest(final String vnfId, + final CreateVnfRequest request) { + try { + final String url = urlProvider.getCreateInstantiateUrl(vnfId); + + final ResponseEntity<CreateVnfResponse> response = + httpServiceProvider.postHttpRequest(request, url, CreateVnfResponse.class); + + final HttpStatus httpStatus = response.getStatusCode(); + if (!(httpStatus.equals(HttpStatus.ACCEPTED)) && !(httpStatus.equals(HttpStatus.OK))) { + LOGGER.error("Unable to invoke HTTP POST using URL: {}, Response Code: {}", url, httpStatus.value()); + return Optional.empty(); + } + + if (!response.hasBody()) { + LOGGER.error(RECEIVED_RESPONSE_WITHOUT_BODY, response); + return Optional.empty(); + } + + final CreateVnfResponse createVnfResponse = response.getBody(); + + if (createVnfResponse.getJobId() == null || createVnfResponse.getJobId().isEmpty()) { + LOGGER.error("Received invalid instantiation response: {}", response); + return Optional.empty(); + } + + return Optional.of(createVnfResponse); + } catch (final RestProcessingException | InvalidRestRequestException + | HttpResouceNotFoundException httpInvocationException) { + LOGGER.error("Unexpected error while processing create and instantiation request", httpInvocationException); + return Optional.empty(); + } + + } + + @Override + public Optional<QueryJobResponse> getInstantiateOperationJobStatus(final String jobId) { + try { + final String url = urlProvider.getJobStatusUrl(jobId); + + final ResponseEntity<QueryJobResponse> response = + httpServiceProvider.getHttpResponse(url, QueryJobResponse.class); + + final HttpStatus httpStatus = response.getStatusCode(); + + if (!(httpStatus.equals(HttpStatus.ACCEPTED)) && !(httpStatus.equals(HttpStatus.OK))) { + LOGGER.error("Unable to invoke HTTP GET using URL: {}, Response Code: ", url, httpStatus.value()); + return Optional.empty(); + } + + if (!response.hasBody()) { + LOGGER.error(RECEIVED_RESPONSE_WITHOUT_BODY, response); + return Optional.empty(); + } + return Optional.of(response.getBody()); + } catch (final RestProcessingException | InvalidRestRequestException | HttpResouceNotFoundException exception) { + LOGGER.error("Unexpected error while processing job request", exception); + throw exception; + } + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterUrlProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterUrlProvider.java new file mode 100644 index 0000000000..351d4bf88c --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterUrlProvider.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm; + +import java.net.URI; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.util.UriComponentsBuilder; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class Sol003AdapterUrlProvider { + + private final URI baseUri; + + @Autowired + public Sol003AdapterUrlProvider( + @Value("${so.adapters.sol003-adapter.url:https://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1/}") final String sol003AdapterUrl) { + this.baseUri = UriComponentsBuilder.fromHttpUrl(sol003AdapterUrl).build().toUri(); + } + + /** + * Get VNFM create and instantiate URL + * + * @param vnfId The identifier of the VNF. This must be the vnf-id of an existing generic-vnf in AAI. + * @return VNFM create and instantiate URL + */ + public String getCreateInstantiateUrl(final String vnfId) { + return UriComponentsBuilder.fromUri(baseUri).pathSegment("vnfs").pathSegment(vnfId).build().toString(); + } + + /** + * Get job status URL + * + * @param jobId The instantiation job identifier + * @return job status URL + */ + public String getJobStatusUrl(final String jobId) { + return UriComponentsBuilder.fromUri(baseUri).pathSegment("jobs").pathSegment(jobId).build().toString(); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java new file mode 100644 index 0000000000..58ca2507bd --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java @@ -0,0 +1,111 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Objects; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class FileEntry { + + private boolean isDirectory; + private String filePath; + private byte[] fileContent; + + public boolean isDirectory() { + return isDirectory; + } + + public void setDirectory(final boolean isDirectory) { + this.isDirectory = isDirectory; + } + + public FileEntry isDirectory(final boolean isDirectory) { + this.isDirectory = isDirectory; + return this; + } + + public String getFilePath() { + return filePath; + } + + public void setFilename(final String filePath) { + this.filePath = filePath; + } + + public FileEntry filePath(final String filePath) { + this.filePath = filePath; + return this; + } + + public byte[] getFileContent() { + return fileContent; + } + + public void setFileContent(final byte[] fileContent) { + this.fileContent = fileContent; + } + + public FileEntry fileContent(final byte[] fileContent) { + this.fileContent = fileContent; + return this; + } + + public InputStream getFileContentAsStream() { + if (fileContent == null || fileContent.length == 0) { + return null; + } + return new ByteArrayInputStream(fileContent); + } + + @Override + public int hashCode() { + return Objects.hash(isDirectory, filePath, fileContent); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof FileEntry) { + final FileEntry other = (FileEntry) obj; + return Objects.equals(isDirectory, other.isDirectory) && Objects.equals(filePath, other.filePath) + && Objects.equals(fileContent, other.fileContent); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class FileEntry {\n"); + sb.append(" isDirectory: ").append(toIndentedString(isDirectory)).append("\n"); + sb.append(" filePath: ").append(toIndentedString(filePath)).append("\n"); + sb.append(" fileContent size: ").append(toIndentedString(fileContent != null ? fileContent.length : 0)) + .append("\n"); + sb.append("}"); + return sb.toString(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileParser.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileParser.java new file mode 100644 index 0000000000..9df5262302 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileParser.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import java.util.Map; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public interface FileParser { + + Map<String, Object> getFileContent(final FileEntry entryDefinitionFileEntry); + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptor.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptor.java new file mode 100644 index 0000000000..6b4fee7151 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptor.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class NetworkServiceDescriptor implements Serializable { + + private static final long serialVersionUID = -1739293595041180242L; + + private String type; + + private Map<String, Object> properties = new HashMap<>(); + + private List<VirtualNetworkFunction> vnfs = new ArrayList<>(); + + public String getType() { + return type; + } + + public void setType(final String type) { + this.type = type; + } + + public NetworkServiceDescriptor type(final String type) { + this.type = type; + return this; + } + + public Map<String, Object> getProperties() { + return properties; + } + + public void setProperties(final Map<String, Object> properties) { + this.properties = properties; + } + + public NetworkServiceDescriptor properties(final Map<String, Object> properties) { + this.properties = properties; + return this; + } + + public List<VirtualNetworkFunction> getVnfs() { + return vnfs; + } + + public void setVnfs(final List<VirtualNetworkFunction> vnfs) { + if (vnfs != null) { + this.vnfs = vnfs; + } else { + this.vnfs = new ArrayList<>(); + } + } + + public NetworkServiceDescriptor addVnfPkgIdsItem(final VirtualNetworkFunction vnf) { + if (this.vnfs == null) { + this.vnfs = new ArrayList<>(); + } + this.vnfs.add(vnf); + return this; + } + + public NetworkServiceDescriptor vnfs(final List<VirtualNetworkFunction> vnfs) { + this.vnfs = vnfs; + return this; + } + + @Override + public int hashCode() { + return Objects.hash(type, properties, vnfs); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof NetworkServiceDescriptor) { + final NetworkServiceDescriptor other = (NetworkServiceDescriptor) obj; + return Objects.equals(type, other.type) && Objects.equals(properties, other.properties) + && Objects.equals(vnfs, other.vnfs); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class NetworkServiceDescriptor {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" properties: ").append(toIndentedString(properties)).append("\n"); + sb.append(" vnfs: ").append(toIndentedString(vnfs)).append("\n"); + sb.append("}"); + return sb.toString(); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParser.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParser.java new file mode 100644 index 0000000000..33737f4c17 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParser.java @@ -0,0 +1,209 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class NetworkServiceDescriptorParser { + public static final String NS_NODE_TYPE = "tosca.nodes.nfv.NS"; + private static final String NODE_TYPE = "node_type"; + private static final String SUBSTITUTION_MAPPINGS = "substitution_mappings"; + private static final Logger logger = LoggerFactory.getLogger(NetworkServiceDescriptorParser.class); + private static final String VNF_TYPE = "tosca.nodes.nfv.VNF"; + private static final String PROPERTIES = "properties"; + private static final String TYPE = "type"; + private static final String NODE_TEMPLATES = "node_templates"; + private static final String TOPOLOGY_TEMPLATE = "topology_template"; + private static final String ENTRY_DEFINITIONS = "Entry-Definitions"; + private static final String TOSCA_META_PATH_FILE_NAME = "TOSCA-Metadata/TOSCA.meta"; + private final ToscaMetadataParser toscaMetadataParser; + private final FileParser fileParser; + + @Autowired + public NetworkServiceDescriptorParser(final ToscaMetadataParser toscaMetadataParser, final FileParser fileParser) { + this.toscaMetadataParser = toscaMetadataParser; + this.fileParser = fileParser; + } + + public Optional<NetworkServiceDescriptor> parse(final byte[] zipBytes) { + try { + final Map<String, FileEntry> files = getZipContent(zipBytes); + if (isMetaFilePresent(files)) { + final Optional<ToscaMetadata> optional = + toscaMetadataParser.parse(files.get(TOSCA_META_PATH_FILE_NAME)); + if (optional.isPresent()) { + final ToscaMetadata toscaMetadata = optional.get(); + logger.info("Parsed ToscaMetadata {}", toscaMetadata); + final String entryDefinitionFile = toscaMetadata.getEntry(ENTRY_DEFINITIONS); + if (entryDefinitionFile != null && files.containsKey(entryDefinitionFile)) { + final Map<String, Object> fileContent = + fileParser.getFileContent(files.get(entryDefinitionFile)); + final Map<String, Object> topologyTemplates = getTopologyTemplates(fileContent); + final Map<String, Object> nodeTemplates = getNodeTemplates(topologyTemplates); + + final Optional<NetworkServiceDescriptor> nsdOptional = + getNetworkServiceDescriptor(topologyTemplates);; + if (nsdOptional.isPresent()) { + final NetworkServiceDescriptor networkServiceDescriptor = nsdOptional.get(); + networkServiceDescriptor.setVnfs(getVirtualNetworkFunctions(nodeTemplates)); + return Optional.of(networkServiceDescriptor); + } + + } + } + + } + + } catch (final Exception exception) { + logger.error("Unable to parser nsd zip content", exception); + } + logger.error("Unable to parser nsd zip content"); + return Optional.empty(); + } + + @SuppressWarnings("unchecked") + private Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor( + final Map<String, Object> topologyTemplates) { + final Map<String, Object> substitutionMappings = + (Map<String, Object>) topologyTemplates.get(SUBSTITUTION_MAPPINGS); + final Object nodeType = substitutionMappings.get(NODE_TYPE); + if (substitutionMappings != null && nodeType != null && NS_NODE_TYPE.equals(nodeType)) { + final NetworkServiceDescriptor networkServiceDescriptor = new NetworkServiceDescriptor(); + networkServiceDescriptor.setType(nodeType.toString()); + networkServiceDescriptor.setProperties((Map<String, Object>) substitutionMappings.get(PROPERTIES)); + return Optional.of(networkServiceDescriptor); + } + logger.error("No {} found in fileContent: {}", SUBSTITUTION_MAPPINGS, topologyTemplates); + + return Optional.empty(); + } + + private List<VirtualNetworkFunction> getVirtualNetworkFunctions(final Map<String, Object> nodeTemplates) { + final List<VirtualNetworkFunction> vnfs = new ArrayList<>(); + for (final Entry<String, Object> entry : nodeTemplates.entrySet()) { + @SuppressWarnings("unchecked") + final Map<String, Object> entryValue = (Map<String, Object>) entry.getValue(); + final Object type = entryValue.get(TYPE); + if (type != null && type.equals(VNF_TYPE)) { + @SuppressWarnings("unchecked") + final Map<String, Object> vnfProperties = (Map<String, Object>) entryValue.get(PROPERTIES); + final VirtualNetworkFunction vnf = new VirtualNetworkFunction(); + vnf.setVnfName(entry.getKey()); + + if (vnfProperties != null && !vnfProperties.isEmpty()) { + final Object vnfDescriptorId = vnfProperties.get("descriptor_id"); + @SuppressWarnings("unchecked") + final List<String> vnfmInfoList = (List<String>) vnfProperties.get("vnfm_info"); + if (vnfDescriptorId != null && vnfmInfoList != null) { + vnf.setVnfmInfoList(vnfmInfoList); + vnf.setVnfdId(vnfDescriptorId.toString()); + vnf.setProperties(vnfProperties); + vnfs.add(vnf); + } else { + logger.warn("descriptor_id missing {}", entryValue); + } + } + } + + } + return vnfs; + } + + private Map<String, Object> getNodeTemplates(final Map<String, Object> topologyTemplates) { + @SuppressWarnings("unchecked") + final Map<String, Object> nodeTemplates = (Map<String, Object>) topologyTemplates.get(NODE_TEMPLATES); + if (nodeTemplates != null) { + logger.debug("Found nodeTemplates: {}", topologyTemplates); + return nodeTemplates; + } + logger.error("No {} found in fileContent: {}", NODE_TEMPLATES, topologyTemplates); + return Collections.emptyMap(); + } + + private Map<String, Object> getTopologyTemplates(final Map<String, Object> fileContent) { + @SuppressWarnings("unchecked") + final Map<String, Object> topologyTemplates = (Map<String, Object>) fileContent.get(TOPOLOGY_TEMPLATE); + if (topologyTemplates != null) { + logger.debug("Found {}: {}", TOPOLOGY_TEMPLATE, topologyTemplates); + + return topologyTemplates; + } + logger.error("No {} found in fileContent: {}", TOPOLOGY_TEMPLATE, fileContent); + return Collections.emptyMap(); + } + + private boolean isMetaFilePresent(final Map<String, FileEntry> files) { + return files.containsKey(TOSCA_META_PATH_FILE_NAME); + } + + private Map<String, FileEntry> getZipContent(final byte[] zipBytes) { + final Map<String, FileEntry> files = new HashMap<>(); + try (final ZipInputStream inputZipStream = new ZipInputStream(new ByteArrayInputStream(zipBytes));) { + ZipEntry zipEntry; + while ((zipEntry = inputZipStream.getNextEntry()) != null) { + logger.info("{} : {}", zipEntry.getName(), zipEntry.isDirectory()); + if (files.get(zipEntry.getName()) != null) { + logger.warn("{} File entry already exists ...", zipEntry.getName()); + } else { + final FileEntry fileEntry = new FileEntry().filePath(zipEntry.getName()) + .fileContent(getBytes(inputZipStream)).isDirectory(zipEntry.isDirectory()); + files.put(zipEntry.getName(), fileEntry); + + } + + } + return files; + } catch (final Exception exception) { + logger.error("Unable to parser nsd zip content", exception); + return Collections.emptyMap(); + } + } + + private byte[] getBytes(final ZipInputStream inputZipStream) throws IOException { + try { + return IOUtils.toByteArray(inputZipStream); + } catch (final IOException exception) { + logger.error("Could not read bytes from file", exception); + throw exception; + } + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java new file mode 100644 index 0000000000..c07a55c459 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class ToscaMetadata { + + private Map<String, String> entries = new HashMap<>(); + + public Map<String, String> getEntries() { + return entries; + } + + public void addEntry(final String name, final String value) { + this.entries.put(name, value); + } + + public boolean hasEntry(final String name) { + return this.entries.containsKey(name); + } + + public String getEntry(final String name) { + return this.entries.get(name); + } + + @Override + public int hashCode() { + return Objects.hash(entries); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof ToscaMetadata) { + final ToscaMetadata other = (ToscaMetadata) obj; + return Objects.equals(entries, other.entries); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class ToscaMetadata {\n"); + sb.append(" entries: ").append(toIndentedString(entries)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadataParser.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadataParser.java new file mode 100644 index 0000000000..fe23f5ef8d --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadataParser.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import static org.apache.commons.lang3.StringUtils.isNotBlank; +import java.util.List; +import java.util.Optional; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class ToscaMetadataParser { + private static final String ATTRIBUTE_VALUE_SEPARATOR = ":"; + private static final Logger logger = LoggerFactory.getLogger(ToscaMetadataParser.class); + + public Optional<ToscaMetadata> parse(final FileEntry toscaMetaFile) { + try { + final ToscaMetadata toscaMetadata = new ToscaMetadata(); + final List<String> lines = IOUtils.readLines(toscaMetaFile.getFileContentAsStream(), "utf-8"); + for (final String line : lines) { + final String trimmedLine = line.trim(); + if (!trimmedLine.isEmpty() && trimmedLine.contains(ATTRIBUTE_VALUE_SEPARATOR)) { + final String[] entry = trimmedLine.split(ATTRIBUTE_VALUE_SEPARATOR); + if (entry.length >= 2 && isNotBlank(entry[0]) && isNotBlank(entry[1])) { + toscaMetadata.addEntry(entry[0].trim(), entry[1].trim()); + } else { + logger.warn("Unexpected line in metadata file: {}", line); + } + } else { + logger.warn("Unexpected line does not contain valid separator {} in metadata file: {}", + ATTRIBUTE_VALUE_SEPARATOR, line); + } + + } + return Optional.of(toscaMetadata); + + } catch (final Exception exception) { + logger.error("Unable to parser metadata file content", exception); + } + return Optional.empty(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java new file mode 100644 index 0000000000..f4c3632589 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java @@ -0,0 +1,123 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class VirtualNetworkFunction implements Serializable { + + private static final long serialVersionUID = 3164293220359211834L; + + private String vnfdId; + private String vnfName; + private List<String> vnfmInfoList; + private Map<String, Object> properties = new HashMap<>(); + + public String getVnfdId() { + return vnfdId; + } + + public void setVnfdId(final String vnfdId) { + this.vnfdId = vnfdId; + } + + public VirtualNetworkFunction vnfdId(final String vnfdId) { + this.vnfdId = vnfdId; + return this; + } + + public String getVnfName() { + return vnfName; + } + + public void setVnfName(final String vnfName) { + this.vnfName = vnfName; + } + + public VirtualNetworkFunction vnfName(final String vnfName) { + this.vnfName = vnfName; + return this; + } + + public List<String> getVnfmInfoList() { + return vnfmInfoList; + } + + public void setVnfmInfoList(final List<String> vnfmInfoList) { + this.vnfmInfoList = vnfmInfoList; + } + + public VirtualNetworkFunction vnfmInfoList(final List<String> vnfmInfoList) { + this.vnfmInfoList = vnfmInfoList; + return this; + } + + public Map<String, Object> getProperties() { + return properties; + } + + public void setProperties(final Map<String, Object> properties) { + this.properties = properties; + } + + public VirtualNetworkFunction properties(final Map<String, Object> properties) { + this.properties = properties; + return this; + } + + @Override + public int hashCode() { + return Objects.hash(vnfdId, vnfName, vnfmInfoList, properties); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof VirtualNetworkFunction) { + final VirtualNetworkFunction other = (VirtualNetworkFunction) obj; + return Objects.equals(vnfdId, other.vnfdId) && Objects.equals(vnfName, other.vnfName) + && Objects.equals(vnfmInfoList, other.vnfmInfoList) && Objects.equals(properties, other.properties); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class VirtualNetworkFunction {\n"); + sb.append(" vnfdId: ").append(toIndentedString(vnfdId)).append("\n"); + sb.append(" vnfName: ").append(toIndentedString(vnfName)).append("\n"); + sb.append(" vnfmInfo: ").append(toIndentedString(vnfmInfoList)).append("\n"); + sb.append(" properties: ").append(toIndentedString(properties)).append("\n"); + + sb.append("}"); + return sb.toString(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/YamlFileParser.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/YamlFileParser.java new file mode 100644 index 0000000000..ac8f782a99 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/YamlFileParser.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import java.util.Map; +import org.springframework.stereotype.Service; +import org.yaml.snakeyaml.Yaml; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class YamlFileParser implements FileParser { + + @Override + public Map<String, Object> getFileContent(final FileEntry entryDefinitionFileEntry) { + final Yaml yaml = new Yaml(); + return yaml.load(entryDefinitionFileEntry.getFileContentAsStream()); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java new file mode 100644 index 0000000000..13cdc60b1b --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java @@ -0,0 +1,252 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_REQUEST_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.GLOBAL_CUSTOMER_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.INSTANTIATE_NS_REQUEST_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.JOB_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OCC_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.SERVICE_TYPE_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.CREATE_NS_WORKFLOW_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.INSTANTIATE_NS_WORKFLOW_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction.INSTANTIATE; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.ERROR; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED_WITH_ERROR; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.STARTING; +import static org.slf4j.LoggerFactory.getLogger; +import java.time.Instant; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.NsRequestProcessingException; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpType; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400; +import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import com.google.common.collect.ImmutableSet; +import com.google.gson.Gson; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class JobExecutorService { + + private static final Logger logger = getLogger(JobExecutorService.class); + + private static final ImmutableSet<JobStatusEnum> JOB_FINISHED_STATES = + ImmutableSet.of(FINISHED, ERROR, FINISHED_WITH_ERROR); + + private static final int SLEEP_TIME_IN_SECONDS = 5; + + @Value("${so-etsi-ns-lcm-workflow-engine.requesttimeout.timeoutInSeconds:300}") + private int timeOutInSeconds; + + private final DatabaseServiceProvider databaseServiceProvider; + private final WorkflowExecutorService workflowExecutorService; + private final WorkflowQueryService workflowQueryService; + private Gson gson; + + @Autowired + public JobExecutorService(final DatabaseServiceProvider databaseServiceProvider, + final WorkflowExecutorService workflowExecutorService, final WorkflowQueryService workflowQueryService, + final GsonProvider gsonProvider) { + this.databaseServiceProvider = databaseServiceProvider; + this.workflowExecutorService = workflowExecutorService; + this.workflowQueryService = workflowQueryService; + gson = gsonProvider.getGson(); + } + + public NsInstancesNsInstance runCreateNsJob(final CreateNsRequest createNsRequest, final String globalCustomerId, + final String serviceType) { + logger.info("Starting 'Create NS' workflow job for request:\n{}", createNsRequest); + final NfvoJob newJob = new NfvoJob().startTime(LocalDateTime.now()).jobType("NS").jobAction(JobAction.CREATE) + .resourceId(createNsRequest.getNsdId()).resourceName(createNsRequest.getNsName()) + .status(JobStatusEnum.STARTING).progress(5); + databaseServiceProvider.addJob(newJob); + + logger.info("New job created in database :\n{}", newJob); + + workflowExecutorService.executeWorkflow(newJob.getJobId(), CREATE_NS_WORKFLOW_NAME, + getVariables(newJob.getJobId(), createNsRequest, globalCustomerId, serviceType)); + + final ImmutablePair<String, JobStatusEnum> immutablePair = + waitForJobToFinish(newJob.getJobId(), JOB_FINISHED_STATES); + + if (immutablePair.getRight() == null) { + final String message = "Failed to create NS for request: \n" + createNsRequest; + logger.error(message); + throw new NsRequestProcessingException(message); + } + final JobStatusEnum finalJobStatus = immutablePair.getRight(); + final String processInstanceId = immutablePair.getLeft(); + + if (!FINISHED.equals(finalJobStatus)) { + + final Optional<InlineResponse400> optional = workflowQueryService.getProblemDetails(processInstanceId); + if (optional.isPresent()) { + final InlineResponse400 problemDetails = optional.get(); + final String message = + "Failed to create NS for request: \n" + createNsRequest + " due to \n" + problemDetails; + logger.error(message); + throw new NsRequestProcessingException(message, problemDetails); + } + + final String message = "Received unexpected Job Status: " + finalJobStatus + + " Failed to Create NS for request: \n" + createNsRequest; + logger.error(message); + throw new NsRequestProcessingException(message); + } + + logger.debug("Will query for CreateNsResponse using processInstanceId:{}", processInstanceId); + final Optional<NsInstancesNsInstance> optional = workflowQueryService.getCreateNsResponse(processInstanceId); + if (optional.isEmpty()) { + final String message = + "Unable to find CreateNsReponse in Camunda History for process instance: " + processInstanceId; + logger.error(message); + throw new NsRequestProcessingException(message); + } + return optional.get(); + } + + public String runInstantiateNsJob(final String nsInstanceId, final InstantiateNsRequest instantiateNsRequest) { + + final NfvoJob newJob = new NfvoJob().startTime(LocalDateTime.now()).jobType("NS").jobAction(INSTANTIATE) + .resourceId(nsInstanceId).status(STARTING).progress(0); + databaseServiceProvider.addJob(newJob); + logger.info("New job created in database :\n{}", newJob); + + final LocalDateTime currentDateTime = LocalDateTime.now(); + final NsLcmOpOcc newNsLcmOpOcc = new NsLcmOpOcc().id(nsInstanceId).operation(NsLcmOpType.INSTANTIATE) + .operationState(OperationStateEnum.PROCESSING).stateEnteredTime(currentDateTime) + .startTime(currentDateTime).isAutoInnovation(false).isCancelPending(false) + .operationParams(gson.toJson(instantiateNsRequest)); + databaseServiceProvider.addNSLcmOpOcc(newNsLcmOpOcc); + logger.info("New NSLcmOpOcc created in database :\n{}", newNsLcmOpOcc); + + workflowExecutorService.executeWorkflow(newJob.getJobId(), INSTANTIATE_NS_WORKFLOW_NAME, + getVariables(nsInstanceId, newJob.getJobId(), newNsLcmOpOcc.getId(), instantiateNsRequest)); + + final ImmutableSet<JobStatusEnum> jobFinishedStates = + ImmutableSet.of(FINISHED, ERROR, FINISHED_WITH_ERROR, IN_PROGRESS); + final ImmutablePair<String, JobStatusEnum> immutablePair = + waitForJobToFinish(newJob.getJobId(), jobFinishedStates); + + if (immutablePair.getRight() == null) { + final String message = "Failed to Instantiate NS for request: \n" + instantiateNsRequest; + logger.error(message); + throw new NsRequestProcessingException(message); + } + + final JobStatusEnum finalJobStatus = immutablePair.getRight(); + + if (IN_PROGRESS.equals(finalJobStatus) || FINISHED.equals(finalJobStatus)) { + logger.info("Instantiation Job status: {}", finalJobStatus); + + + return newNsLcmOpOcc.getId(); + } + + final String message = "Received unexpected Job Status: " + finalJobStatus + + " Failed to instantiate NS for request: \n" + instantiateNsRequest; + logger.error(message); + throw new NsRequestProcessingException(message); + } + + private ImmutablePair<String, JobStatusEnum> waitForJobToFinish(final String jobId, + final ImmutableSet<JobStatusEnum> jobFinishedStates) { + try { + final long startTimeInMillis = System.currentTimeMillis(); + final long timeOutTime = startTimeInMillis + TimeUnit.SECONDS.toMillis(timeOutInSeconds); + + logger.info("Will wait till {} for {} job to finish", Instant.ofEpochMilli(timeOutTime).toString(), jobId); + JobStatusEnum currentJobStatus = null; + while (timeOutTime > System.currentTimeMillis()) { + + final Optional<NfvoJob> optional = databaseServiceProvider.getJob(jobId); + + if (optional.isEmpty()) { + logger.error("Unable to find Job using jobId: {}", jobId); + return ImmutablePair.nullPair(); + } + + final NfvoJob nfvoJob = optional.get(); + currentJobStatus = nfvoJob.getStatus(); + logger.info("Received job status response: \n ", nfvoJob); + if (jobFinishedStates.contains(nfvoJob.getStatus())) { + logger.info("Job finished \n {}", currentJobStatus); + return ImmutablePair.of(nfvoJob.getProcessInstanceId(), currentJobStatus); + } + + logger.info("Haven't received one of finish state {} yet, will try again in {} seconds", + jobFinishedStates, SLEEP_TIME_IN_SECONDS); + TimeUnit.SECONDS.sleep(SLEEP_TIME_IN_SECONDS); + + } + logger.warn("Timeout current job status: {}", currentJobStatus); + return ImmutablePair.nullPair(); + } catch (final InterruptedException interruptedException) { + Thread.currentThread().interrupt(); + logger.error("Sleep was interrupted", interruptedException); + return ImmutablePair.nullPair(); + } + } + + private Map<String, Object> getVariables(final String jobId, final CreateNsRequest createNsRequest, + final String globalCustomerId, final String serviceType) { + final Map<String, Object> variables = new HashMap<>(); + variables.put(JOB_ID_PARAM_NAME, jobId); + variables.put(CREATE_NS_REQUEST_PARAM_NAME, createNsRequest); + variables.put(GLOBAL_CUSTOMER_ID_PARAM_NAME, globalCustomerId); + variables.put(SERVICE_TYPE_PARAM_NAME, serviceType); + return variables; + } + + private Map<String, Object> getVariables(final String nsInstanceId, final String jobId, final String occId, + final InstantiateNsRequest instantiateNsRequest) { + final Map<String, Object> variables = new HashMap<>(); + variables.put(NS_INSTANCE_ID_PARAM_NAME, nsInstanceId); + variables.put(JOB_ID_PARAM_NAME, jobId); + variables.put(OCC_ID_PARAM_NAME, occId); + variables.put(INSTANTIATE_NS_REQUEST_PARAM_NAME, instantiateNsRequest); + return variables; + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowExecutorService.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowExecutorService.java new file mode 100644 index 0000000000..fa2b8d5507 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowExecutorService.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.TENANT_ID; +import static org.slf4j.LoggerFactory.getLogger; +import java.util.Map; +import org.camunda.bpm.engine.RuntimeService; +import org.camunda.bpm.engine.runtime.ProcessInstance; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class WorkflowExecutorService { + + private static final Logger logger = getLogger(WorkflowExecutorService.class); + + private final RuntimeService runtimeService; + + @Autowired + public WorkflowExecutorService(final RuntimeService runtimeService) { + this.runtimeService = runtimeService; + } + + @Async + public void executeWorkflow(final String jobId, final String processDefinitionKey, + final Map<String, Object> variables) { + logger.info("Executing {} workflow with business key: {}", processDefinitionKey, jobId); + final ProcessInstance processInstance = runtimeService.createProcessInstanceByKey(processDefinitionKey) + .businessKey(jobId).setVariables(variables).processDefinitionTenantId(TENANT_ID).execute(); + + logger.info("Workflow running with processInstanceId: {} and business key: {}", + processInstance.getProcessInstanceId(), processInstance.getBusinessKey()); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowQueryService.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowQueryService.java new file mode 100644 index 0000000000..297e9c34af --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/WorkflowQueryService.java @@ -0,0 +1,108 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.TENANT_ID; +import static org.slf4j.LoggerFactory.getLogger; +import java.util.Optional; +import org.camunda.bpm.engine.HistoryService; +import org.camunda.bpm.engine.ProcessEngineException; +import org.camunda.bpm.engine.history.HistoricVariableInstance; +import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.google.common.base.Strings; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class WorkflowQueryService { + + private static final Logger logger = getLogger(WorkflowQueryService.class); + + private final HistoryService camundaHistoryService; + + @Autowired + public WorkflowQueryService(final HistoryService camundaHistoryService) { + this.camundaHistoryService = camundaHistoryService; + } + + public Optional<NsInstancesNsInstance> getCreateNsResponse(final String processInstanceId) { + try { + + if (Strings.isNullOrEmpty(processInstanceId)) { + logger.error("Invalid processInstanceId: {}", processInstanceId); + return Optional.empty(); + } + + final HistoricVariableInstance historicVariableInstance = + getVariable(processInstanceId, CREATE_NS_RESPONSE_PARAM_NAME); + + if (historicVariableInstance != null) { + logger.info("Found HistoricVariableInstance : {}", historicVariableInstance); + final Object variableValue = historicVariableInstance.getValue(); + if (variableValue instanceof NsInstancesNsInstance) { + return Optional.ofNullable((NsInstancesNsInstance) variableValue); + } + logger.error("Unknown CreateNsResponse object type {} received value: {}", + historicVariableInstance.getValue() != null ? variableValue.getClass() : null, variableValue); + } + } catch (final ProcessEngineException processEngineException) { + logger.error("Unable to find {} variable using processInstanceId: {}", CREATE_NS_RESPONSE_PARAM_NAME, + processInstanceId, processEngineException); + } + logger.error("Unable to find {} variable using processInstanceId: {}", CREATE_NS_RESPONSE_PARAM_NAME, + processInstanceId); + return Optional.empty(); + + } + + public Optional<InlineResponse400> getProblemDetails(final String processInstanceId) { + try { + final HistoricVariableInstance historicVariableInstance = + getVariable(processInstanceId, CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME); + + logger.info("Found HistoricVariableInstance : {}", historicVariableInstance); + final Object variableValue = historicVariableInstance.getValue(); + if (variableValue instanceof InlineResponse400) { + return Optional.ofNullable((InlineResponse400) variableValue); + } + logger.error("Unknown ProblemDetails object type {} received value: {}", + historicVariableInstance.getValue() != null ? variableValue.getClass() : null, variableValue); + } catch (final ProcessEngineException processEngineException) { + logger.error("Unable to find {} variable using processInstanceId: {}", + CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, processInstanceId, processEngineException); + } + return Optional.empty(); + } + + + private HistoricVariableInstance getVariable(final String processInstanceId, final String name) { + return camundaHistoryService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId) + .variableName(name).tenantIdIn(TENANT_ID).singleResult(); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/AbstractNetworkServiceTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/AbstractNetworkServiceTask.java new file mode 100644 index 0000000000..99116dacad --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/AbstractNetworkServiceTask.java @@ -0,0 +1,117 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.JOB_ID_PARAM_NAME; +import java.time.LocalDateTime; +import java.util.Optional; +import org.camunda.bpm.engine.delegate.BpmnError; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJobStatus; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public abstract class AbstractNetworkServiceTask { + private final Logger logger = LoggerFactory.getLogger(getClass()); + protected final DatabaseServiceProvider databaseServiceProvider; + + public AbstractNetworkServiceTask(final DatabaseServiceProvider jobServiceProvider) { + this.databaseServiceProvider = jobServiceProvider; + } + + public void setJobStatus(final DelegateExecution execution, final JobStatusEnum jobStatus, + final String description) { + logger.info("Setting Job Status to {}", jobStatus); + final NfvoJob nfvoJob = getNfvoJob(execution); + nfvoJob.status(jobStatus); + if (JobStatusEnum.STARTED.equals(jobStatus)) { + nfvoJob.processInstanceId(execution.getProcessInstanceId()); + } + + if (JobStatusEnum.FINISHED.equals(jobStatus)) { + nfvoJob.endTime(LocalDateTime.now()); + } + + nfvoJob.nfvoJobStatus( + new NfvoJobStatus().status(jobStatus).description(description).updatedTime(LocalDateTime.now())); + databaseServiceProvider.addJob(nfvoJob); + + } + + public void setJobStatusToError(final DelegateExecution execution, final String description) { + logger.info("Setting Job Status to {}", JobStatusEnum.ERROR); + + final String jobId = (String) execution.getVariable(JOB_ID_PARAM_NAME); + final Optional<NfvoJob> optional = databaseServiceProvider.getJob(jobId); + if (optional.isPresent()) { + final InlineResponse400 problemDetails = + (InlineResponse400) execution.getVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME); + + final NfvoJob nfvoJob = optional.get(); + nfvoJob.status(JobStatusEnum.ERROR).endTime(LocalDateTime.now()); + + if (problemDetails != null) { + logger.error("Found failed reason: {}", problemDetails); + nfvoJob.nfvoJobStatus(new NfvoJobStatus().status(JobStatusEnum.ERROR) + .description(problemDetails.getDetail()).updatedTime(LocalDateTime.now())); + } + nfvoJob.nfvoJobStatus(new NfvoJobStatus().status(JobStatusEnum.ERROR).description(description) + .updatedTime(LocalDateTime.now())); + + databaseServiceProvider.addJob(nfvoJob); + } + logger.info("Finished setting Job Status to {}", JobStatusEnum.ERROR); + + } + + protected void abortOperation(final DelegateExecution execution, final String message) { + abortOperation(execution, message, new InlineResponse400().detail(message)); + } + + protected void abortOperation(final DelegateExecution execution, final String message, + final InlineResponse400 problemDetails) { + logger.error(message); + execution.setVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, problemDetails); + throw new BpmnError("WORKFLOW_FAILED"); + } + + private NfvoJob getNfvoJob(final DelegateExecution execution) { + final String jobId = (String) execution.getVariable(JOB_ID_PARAM_NAME); + final Optional<NfvoJob> optional = databaseServiceProvider.getJob(jobId); + if (!optional.isPresent()) { + final String message = "Unable to find job using job id: " + jobId; + logger.error(message); + execution.setVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, + new InlineResponse400().detail(message)); + throw new BpmnError("WORKFLOW_FAILED"); + + } + return optional.get(); + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateRequest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateRequest.java new file mode 100644 index 0000000000..569d9b3352 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateRequest.java @@ -0,0 +1,167 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.io.Serializable; +import java.util.Map; +import java.util.Objects; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.Tenant; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class CreateInstantiateRequest implements Serializable { + private static final long serialVersionUID = -4371264952509580468L; + private String nsInstId; + private String vnfdId; + private String vnfName; + private String vnfPkgId; + private String nfType; + private Tenant tenant; + private Map<String, String> additionalParams; + + public String getNsInstId() { + return nsInstId; + } + + public void setNsInstId(final String nsInstId) { + this.nsInstId = nsInstId; + } + + public CreateInstantiateRequest nsInstId(final String nsInstId) { + this.nsInstId = nsInstId; + return this; + } + + public final String getVnfdId() { + return vnfdId; + } + + public final void setVnfdId(final String vnfdId) { + this.vnfdId = vnfdId; + } + + public CreateInstantiateRequest vnfdId(final String vnfdId) { + this.vnfdId = vnfdId; + return this; + } + + public final String getVnfName() { + return vnfName; + } + + public final void setVnfName(final String vnfName) { + this.vnfName = vnfName; + } + + public CreateInstantiateRequest vnfName(final String vnfName) { + this.vnfName = vnfName; + return this; + } + + public final String getVnfPkgId() { + return vnfPkgId; + } + + public final void setVnfPkgId(final String vnfPkgId) { + this.vnfPkgId = vnfPkgId; + } + + public CreateInstantiateRequest vnfPkgId(final String vnfPkgId) { + this.vnfPkgId = vnfPkgId; + return this; + } + + public final String getNfType() { + return nfType; + } + + public final void setNfType(final String nfType) { + this.nfType = nfType; + } + + public CreateInstantiateRequest nfType(final String nfType) { + this.nfType = nfType; + return this; + } + + public final Tenant getTenant() { + return tenant; + } + + public final void setTenant(final Tenant tenant) { + this.tenant = tenant; + } + + public CreateInstantiateRequest tenant(final Tenant tenant) { + this.tenant = tenant; + return this; + } + + public final Map<String, String> getAdditionalParams() { + return additionalParams; + } + + public final void setAdditionalParams(final Map<String, String> additionalParams) { + this.additionalParams = additionalParams; + } + + public CreateInstantiateRequest additionalParams(final Map<String, String> additionalParams) { + this.additionalParams = additionalParams; + return this; + } + + @Override + public int hashCode() { + return Objects.hash(nsInstId, vnfdId, vnfName, vnfPkgId, nfType, tenant, additionalParams); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof CreateInstantiateRequest) { + final CreateInstantiateRequest other = (CreateInstantiateRequest) obj; + return Objects.equals(nsInstId, other.nsInstId) && Objects.equals(vnfdId, other.vnfdId) + && Objects.equals(vnfName, other.vnfName) && Objects.equals(vnfPkgId, other.vnfPkgId) + && Objects.equals(nfType, other.nfType) && Objects.equals(tenant, other.tenant) + && Objects.equals(additionalParams, other.additionalParams); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class CreateInstantiateRequest {\n"); + sb.append(" nsInstId: ").append(toIndentedString(nsInstId)).append("\n"); + sb.append(" vnfdId: ").append(toIndentedString(vnfdId)).append("\n"); + sb.append(" vnfName: ").append(toIndentedString(vnfName)).append("\n"); + sb.append(" vnfPkgId: ").append(toIndentedString(vnfPkgId)).append("\n"); + sb.append(" nfType: ").append(toIndentedString(nfType)).append("\n"); + sb.append(" tenant: ").append(toIndentedString(tenant)).append("\n"); + sb.append(" additionalParams: ").append(toIndentedString(additionalParams)).append("\n"); + + sb.append("}"); + return sb.toString(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateVnfTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateVnfTask.java new file mode 100644 index 0000000000..c33c67e540 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateVnfTask.java @@ -0,0 +1,234 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.ERROR; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS; +import java.time.LocalDateTime; +import java.util.Optional; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.onap.aai.domain.yang.GenericVnf; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfRequest; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.Tenant; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + */ +@Component +public class CreateInstantiateVnfTask extends AbstractNetworkServiceTask { + private static final Logger logger = LoggerFactory.getLogger(CreateInstantiateVnfTask.class); + private static final String NF_INST_ID_PARAM_NAME = "NF_INST_ID"; + public static final String CREATE_VNF_RESPONSE_PARAM_NAME = "createVnfResponse"; + private final AaiServiceProvider aaiServiceProvider; + private final Sol003AdapterServiceProvider sol003AdapterServiceProvider; + + @Autowired + public CreateInstantiateVnfTask(final DatabaseServiceProvider databaseServiceProvider, + final AaiServiceProvider aaiServiceProvider, + final Sol003AdapterServiceProvider sol003AdapterServiceProvider) { + super(databaseServiceProvider); + this.aaiServiceProvider = aaiServiceProvider; + this.sol003AdapterServiceProvider = sol003AdapterServiceProvider; + } + + public void checkIfNfInstanceExistsInDb(final DelegateExecution execution) { + logger.info("Executing checkIfNfInstanceInDb"); + final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request"); + logger.info("request: {}", request); + + setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Checking if NF Instance record exists in database for " + + request.getNsInstId() + " and " + request.getVnfName()); + if (!databaseServiceProvider.isNsInstExists(request.getNsInstId(), request.getVnfName())) { + abortOperation(execution, + request.getNsInstId() + " " + request.getVnfName() + " VNF instance already exists"); + } + logger.info("Finished executing checkIfNfInstanceInDb ..."); + + } + + public void createNfInstanceInDb(final DelegateExecution execution) { + logger.info("Executing createNfInstanceInDb"); + final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request"); + logger.info("request: {}", request); + + setJobStatus(execution, IN_PROGRESS, "Creating NF Instance record in database for " + request.getVnfName()); + + final Optional<NfvoNsInst> optional = databaseServiceProvider.getNfvoNsInst(request.getNsInstId()); + + if (optional.isEmpty()) { + abortOperation(execution, "NfvoNsInst: " + request.getNsInstId() + "not founda"); + } + + final NfvoNsInst nfvoNsInst = optional.get(); + final LocalDateTime now = LocalDateTime.now(); + final NfvoNfInst nfvoNfInst = new NfvoNfInst().status(State.NOT_INSTANTIATED).createTime(now) + .lastUpdateTime(now).name(request.getVnfName()).vnfdId(request.getVnfdId()) + .packageId(request.getVnfPkgId()).nfvoNsInst(nfvoNsInst); + databaseServiceProvider.saveNfvoNfInst(nfvoNfInst); + execution.setVariable(NF_INST_ID_PARAM_NAME, nfvoNfInst.getNfInstId()); + logger.info("Finished executing createNfInstanceInDb ..."); + + } + + public void createGenericVnfInAai(final DelegateExecution execution) { + logger.info("Executing createGenericVnfInAai"); + try { + final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request"); + + setJobStatus(execution, IN_PROGRESS, "Creating GenericVnf record in AAI for " + request.getVnfName()); + + final String nfInstId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME); + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId); + + final GenericVnf genericVnf = new GenericVnf(); + genericVnf.setVnfId(nfInstId); + genericVnf.setVnfName(request.getVnfName()); + genericVnf.setVnfType(nfvoNsInst.getName() + "/" + request.getVnfName()); + genericVnf.setServiceId(request.getNsInstId()); + genericVnf.setNfType(request.getNfType()); + genericVnf.setOperationalStatus("Created"); + genericVnf.setIsClosedLoopDisabled(false); + + aaiServiceProvider.createGenericVnfAndConnectServiceInstance(nsInstId, nfInstId, genericVnf); + + final Tenant tenant = request.getTenant(); + aaiServiceProvider.connectGenericVnfToTenant(nfInstId, tenant.getCloudOwner(), tenant.getRegionName(), + tenant.getTenantId()); + + } catch (final Exception exception) { + final String message = "Unable to Create GenericVnf in AAI"; + logger.error(message, exception); + abortOperation(execution, message); + } + + logger.info("Finished executing createGenericVnfInAai ..."); + } + + public void invokeCreateInstantiationRequest(final DelegateExecution execution) { + logger.info("Executing invokeCreateInstantiationRequest"); + + try { + final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request"); + logger.info("request: {}", request); + + setJobStatus(execution, IN_PROGRESS, + "Invoking SOL003 adapter for creating and instantiating VNF: " + request.getVnfName()); + + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId); + final CreateVnfRequest vnfRequest = new CreateVnfRequest(); + vnfRequest.setTenant(request.getTenant()); + vnfRequest.setName(nfvoNsInst.getName() + "." + request.getVnfName()); + vnfRequest.setPkgId(request.getVnfPkgId()); + vnfRequest.setAdditionalParams(request.getAdditionalParams()); + final String vnfId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME); + final Optional<CreateVnfResponse> optional = + sol003AdapterServiceProvider.invokeCreateInstantiationRequest(vnfId, vnfRequest); + + if (!optional.isPresent()) { + final String errorMessage = "Unexpected error while processing create and instantiation request"; + logger.error(errorMessage); + abortOperation(execution, errorMessage); + } + + final CreateVnfResponse vnfResponse = optional.get(); + + logger.info("Vnf instantiation response: {}", vnfResponse); + execution.setVariable(CREATE_VNF_RESPONSE_PARAM_NAME, vnfResponse); + setJobStatus(execution, IN_PROGRESS, "Successfully invoked SOL003 adapater creating and instantiating VNF: " + + request.getVnfName() + " CreaetVnfResponse Job Id: " + vnfResponse.getJobId()); + logger.debug("Finished executing invokeCreateInstantiationRequest ..."); + } catch (final Exception exception) { + final String message = "Unable to invoke create and instantiation request"; + logger.error(message, exception); + abortOperation(execution, message); + } + + } + + public void updateNfInstanceStatusToInstantiated(final DelegateExecution execution) { + logger.info("Executing updateNfInstanceStatusToInstantiated"); + + updateNfInstanceStatus(execution, State.INSTANTIATED); + final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request"); + setJobStatus(execution, FINISHED, "Successfully created and Instantiated VNF: " + request.getVnfName() + + " will set status to " + State.INSTANTIATED); + + logger.info("Finished executing updateNfInstanceStatusToInstantiated ..."); + + } + + public void updateNfInstanceStatusToFailed(final DelegateExecution execution) { + logger.info("Executing updateNfInstanceStatusToActive"); + + updateNfInstanceStatus(execution, State.FAILED); + final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request"); + setJobStatus(execution, ERROR, "Failed to create and instantiate VNF: " + request.getVnfName() + + " will set status to " + State.FAILED); + + logger.info("Finished executing updateNfInstanceStatusToInstantiated ..."); + + } + + private void updateNfInstanceStatus(final DelegateExecution execution, final State vnfStatus) { + final String nfInstId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME); + + final Optional<NfvoNfInst> optional = databaseServiceProvider.getNfvoNfInst(nfInstId); + if (!optional.isPresent()) { + final String message = "Unable to find NfvoNfInst record in database using nfInstId: " + nfInstId; + logger.error(message); + + abortOperation(execution, message); + + } + + final NfvoNfInst nfvoNfInst = optional.get(); + nfvoNfInst.setStatus(vnfStatus); + databaseServiceProvider.saveNfvoNfInst(nfvoNfInst); + } + + private NfvoNsInst getNfvoNsInst(final DelegateExecution execution, final String nsInstId) { + logger.info("Getting NfvoNsInst to update with nsInstId: {}", nsInstId); + final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstId); + + if (!optionalNfvoNsInst.isPresent()) { + final String message = "Unable to find NS Instance in datababse using id: " + nsInstId; + abortOperation(execution, message); + } + + return optionalNfvoNsInst.get(); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateNsTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateNsTask.java new file mode 100644 index 0000000000..fa7187b388 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateNsTask.java @@ -0,0 +1,221 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_REQUEST_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.GLOBAL_CUSTOMER_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_PACKAGE_MODEL_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.SERVICE_TYPE_PARAM_NAME; +import java.time.LocalDateTime; +import java.util.Optional; +import java.util.UUID; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.onap.aai.domain.yang.ServiceInstance; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.EtsiCatalogManagerRequestFailureException; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogPackageManagementServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance.NsStateEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Component +public class CreateNsTask extends AbstractNetworkServiceTask { + private static final String NETWORK_SERVICE_NAME = "NetworkService"; + private static final String NETWORK_SERVICE_ROLE = "NetworkService"; + private static final String DOES_NS_PACKAGE_EXISTS_PARAM_NAME = "doesNsPackageExists"; + private static final String DOES_NS_INSTANCE_EXISTS_PARAM_NAME = "doesNsInstanceExists"; + private static final Logger logger = LoggerFactory.getLogger(CreateNsTask.class); + private final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider; + private final AaiServiceProvider aaiServiceProvider; + + @Autowired + public CreateNsTask(final DatabaseServiceProvider databaseServiceProvider, + final AaiServiceProvider aaiServiceProvider, + final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider) { + super(databaseServiceProvider); + this.aaiServiceProvider = aaiServiceProvider; + this.etsiCatalogPackageManagementServiceProvider = etsiCatalogPackageManagementServiceProvider; + } + + public void setJobStatusToStarted(final DelegateExecution execution) { + setJobStatus(execution, JobStatusEnum.STARTED, "Create NS workflow process started"); + } + + public void setJobStatusToFinished(final DelegateExecution execution) { + setJobStatus(execution, JobStatusEnum.FINISHED, "Create NS workflow process finished"); + } + + public void setJobStatusToError(final DelegateExecution execution) { + setJobStatusToError(execution, "Create NS workflow process failed"); + } + + public void getNsPackage(final DelegateExecution execution) { + logger.info("Retrieving NS package from ETSI Catalog Manager ..."); + setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Retrieving NS package from ETSI Catalog Manager"); + + final CreateNsRequest createNsRequest = (CreateNsRequest) execution.getVariable(CREATE_NS_REQUEST_PARAM_NAME); + + try { + final Optional<NsdInfo> optional = + etsiCatalogPackageManagementServiceProvider.getNSPackageModel(createNsRequest.getNsdId()); + + if (optional.isPresent()) { + final NsdInfo packageModel = optional.get(); + logger.info("NS Package exists {}", packageModel); + execution.setVariable(NS_PACKAGE_MODEL_PARAM_NAME, packageModel); + execution.setVariable(DOES_NS_PACKAGE_EXISTS_PARAM_NAME, true); + } else { + final String message = "Unable to find NS package using NsdId: " + createNsRequest.getNsdId(); + logger.error(message); + execution.setVariable(DOES_NS_PACKAGE_EXISTS_PARAM_NAME, false); + execution.setVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, + new InlineResponse400().detail(message)); + } + + } catch (final EtsiCatalogManagerRequestFailureException failureException) { + final String message = + "Unexpected exception occured while getting ns package using nsdId: " + createNsRequest.getNsdId(); + logger.error(message, failureException); + + execution.setVariable(DOES_NS_PACKAGE_EXISTS_PARAM_NAME, false); + + execution.setVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, + new InlineResponse400().title(message).detail(message)); + } + + } + + public void doesNsInstanceExistsInDb(final DelegateExecution execution) { + logger.info("Executing doesNsInstanceExistsInDb ..."); + + setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Checking if NS package exists in database"); + + final CreateNsRequest createNsRequest = + (CreateNsRequest) execution.getVariables().get(CREATE_NS_REQUEST_PARAM_NAME); + + final boolean exists = databaseServiceProvider.isNsInstExists(createNsRequest.getNsName()); + logger.info("Ns Instance entry {} exists in database", exists ? "does" : "doesn't"); + execution.setVariable(DOES_NS_INSTANCE_EXISTS_PARAM_NAME, exists); + + if (exists) { + final Optional<NfvoNsInst> optional = + databaseServiceProvider.getNfvoNsInstByName(createNsRequest.getNsName()); + final NfvoNsInst nfvoNsInst = optional.get(); + execution.setVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, new InlineResponse400() + .detail("Ns Instance already exists in database : " + nfvoNsInst.toString())); + } + + logger.info("Finished executing doesNsInstanceExistsInDb ..."); + + } + + public void createNsInstanceInDb(final DelegateExecution execution) { + logger.info("Executing createNsInstanceInDb ..."); + + setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Checking if NS package exists"); + + final CreateNsRequest createNsRequest = (CreateNsRequest) execution.getVariable(CREATE_NS_REQUEST_PARAM_NAME); + final NsdInfo packageMode = (NsdInfo) execution.getVariable(NS_PACKAGE_MODEL_PARAM_NAME); + + final String globalCustomerId = (String) execution.getVariable(GLOBAL_CUSTOMER_ID_PARAM_NAME); + final String serviceType = (String) execution.getVariable(SERVICE_TYPE_PARAM_NAME); + + final String nsInstId = UUID.randomUUID().toString(); + execution.setVariable(NS_INSTANCE_ID_PARAM_NAME, nsInstId); + + databaseServiceProvider.saveNfvoNsInst(new NfvoNsInst().nsInstId(nsInstId).name(createNsRequest.getNsName()) + .nsPackageId(packageMode.getId()).nsdId(packageMode.getNsdId()) + .nsdInvariantId(packageMode.getNsdInvariantId()).description(createNsRequest.getNsDescription()) + .status(State.NOT_INSTANTIATED).statusUpdatedTime(LocalDateTime.now()) + .globalCustomerId(globalCustomerId).serviceType(serviceType)); + logger.info("Finished executing createNsInstanceInDb ..."); + + } + + + public void createNsInstanceInAai(final DelegateExecution execution) { + logger.info("Executing createNsInstanceInAai ..."); + try { + setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Creating NS Instance in AAI"); + + final CreateNsRequest createNsRequest = + (CreateNsRequest) execution.getVariable(CREATE_NS_REQUEST_PARAM_NAME); + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + + final String globalCustomerId = (String) execution.getVariable(GLOBAL_CUSTOMER_ID_PARAM_NAME); + final String serviceType = (String) execution.getVariable(SERVICE_TYPE_PARAM_NAME); + + final ServiceInstance aaiServiceInstance = new ServiceInstance(); + aaiServiceInstance.setServiceInstanceId(nsInstId); + aaiServiceInstance.setServiceInstanceName(createNsRequest.getNsName()); + aaiServiceInstance.setServiceType(NETWORK_SERVICE_NAME); + aaiServiceInstance.setServiceRole(NETWORK_SERVICE_ROLE); + + aaiServiceProvider.createServiceInstance(globalCustomerId, serviceType, aaiServiceInstance); + } catch (final Exception exception) { + final String message = "Unable to Create Service Instance in AAI"; + logger.error(message, exception); + abortOperation(execution, message, new InlineResponse400().detail(message)); + } + logger.info("Finished executing createNsInstanceInAai ..."); + + } + + public void setCreateNsResponse(final DelegateExecution execution) { + logger.info("Executing setCreateNsResponse ..."); + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + final Optional<NfvoNsInst> optional = databaseServiceProvider.getNfvoNsInst(nsInstId); + + if (optional.isPresent()) { + final NfvoNsInst nfvoNsInst = optional.get(); + final NsInstancesNsInstance response = new NsInstancesNsInstance().id(nfvoNsInst.getNsInstId()) + .nsInstanceName(nfvoNsInst.getName()).nsdId(nfvoNsInst.getNsdId()) + .nsdInfoId(nfvoNsInst.getNsPackageId()).nsInstanceDescription(nfvoNsInst.getDescription()) + .nsState(NsStateEnum.fromValue(nfvoNsInst.getStatus().toString())); + logger.info("Saving CreateNsResponse: {} in Execution ...", response); + execution.setVariable(CREATE_NS_RESPONSE_PARAM_NAME, response); + } else { + final String message = "Unable to find NS Instance in datababse using id: " + nsInstId; + logger.error(message); + abortOperation(execution, message); + } + + logger.info("Finished executing setCreateNsResponse ..."); + + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/InstantiateNsTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/InstantiateNsTask.java new file mode 100644 index 0000000000..8d212045ad --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/InstantiateNsTask.java @@ -0,0 +1,416 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.INSTANTIATE_NS_REQUEST_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OCC_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.VNF_CREATE_INSTANTIATE_REQUESTS; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.STARTED; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.Tenant; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.EtsiCatalogManagerRequestFailureException; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogPackageManagementServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.VirtualNetworkFunction; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @author Andrew Lamb (andrew.a.lamb@est.tech) + * + */ +@Component +public class InstantiateNsTask extends AbstractNetworkServiceTask { + + private static final String IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME = "isNsInstantiationSuccessful"; + private static final String VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME = "vnfdIdToVnfPkgIdMapping"; + private static final Logger logger = LoggerFactory.getLogger(InstantiateNsTask.class); + private final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider; + + @Autowired + public InstantiateNsTask(final DatabaseServiceProvider databaseServiceProvider, + final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider) { + super(databaseServiceProvider); + this.etsiCatalogPackageManagementServiceProvider = etsiCatalogPackageManagementServiceProvider; + + } + + public void setJobStatusToStarted(final DelegateExecution execution) { + setJobStatus(execution, STARTED, "Instantiate NS workflow process started"); + } + + public void setJobStatusToFinished(final DelegateExecution execution) { + setJobStatus(execution, FINISHED, "Instantiate NS workflow process finished"); + } + + public void updateNsInstanceStatusToInstantiating(final DelegateExecution execution) { + logger.info("Executing updateNsInstanceStatusToInstantiating"); + setJobStatus(execution, IN_PROGRESS, "Updating NfvoNsInst Status to " + State.INSTANTIATING); + updateNsInstanceStatus(execution, State.INSTANTIATING); + + logger.info("Finished executing updateNsInstanceStatusToInstantiating ..."); + } + + + public void checkIfVnfInstantiationWasSuccessful(final DelegateExecution execution) { + logger.info("Executing checkIfVnfInstantiationWasSuccessful"); + + @SuppressWarnings("unchecked") + final List<CreateInstantiateRequest> requests = + (List<CreateInstantiateRequest>) execution.getVariable(VNF_CREATE_INSTANTIATE_REQUESTS); + + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId); + + if (nfInstances == null || nfInstances.isEmpty()) { + final String message = "Found empty nf instances"; + abortOperation(execution, message); + } + + if (requests.size() != nfInstances.size()) { + final String message = "Missing nf Instance. Request triggered: " + requests.size() + + " Nf Instace reqeust found in database " + nfInstances.size(); + abortOperation(execution, message); + } + + execution.setVariable(IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME, true); + + nfInstances.stream().forEach(instance -> { + if (!State.INSTANTIATED.equals(instance.getStatus())) { + logger.error("VNF : {} {} instantiation failed", instance.getNfInstId(), instance.getName()); + execution.setVariable(IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME, false); + } + }); + + logger.info("Finished executing checkIfVnfInstantiationWasSuccessful ..."); + } + + public void updateNsInstanceStatusToInstantiated(final DelegateExecution execution) { + logger.info("Executing updateNsInstanceStatusToInstantiated"); + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + setJobStatus(execution, FINISHED, "Successfully " + State.INSTANTIATED + " NS: " + nsInstId); + + updateNsInstanceStatus(execution, State.INSTANTIATED); + logger.info("Finished executing updateNsInstanceStatusToInstantiated ..."); + } + + public void getAndParseNsdFromEtsiCatalog(final DelegateExecution execution) { + logger.info("Executing getAndParseNsdFromEtsiCatalog"); + setJobStatus(execution, IN_PROGRESS, "Retrieving and parsing NSD from ETSI Catalog Manager"); + final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution); + final String nsPackageId = nfvoNsInst.getNsPackageId(); + + try { + final Optional<NetworkServiceDescriptor> optional = + etsiCatalogPackageManagementServiceProvider.getNetworkServiceDescriptor(nsPackageId); + + if (!optional.isPresent()) { + final String message = "Unable to parse NSD " + nsPackageId; + logger.error(message); + abortOperation(execution, message); + } + + final NetworkServiceDescriptor networkServiceDescriptor = optional.get(); + logger.info("Found {}", networkServiceDescriptor); + execution.setVariable(NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME, networkServiceDescriptor); + + } catch (final EtsiCatalogManagerRequestFailureException failureException) { + final String message = + "Unexpected exception occured while getting nsd content using nsPackageId: " + nsPackageId; + logger.error(message, failureException); + + abortOperation(execution, message); + } + + logger.info("Finished executing getAndParseNsdFromEtsiCatalog ..."); + + } + + public void prepareCreateInstantiateRequests(final DelegateExecution execution) { + logger.info("Executing prepareCreateInstantiateRequests ..."); + setJobStatus(execution, IN_PROGRESS, "Preparing VNF CreateInstantiate requests"); + final NetworkServiceDescriptor networkServiceDescriptor = + (NetworkServiceDescriptor) execution.getVariable(NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME); + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + + final InstantiateNsRequest instantiateNsRequest = + (InstantiateNsRequest) execution.getVariable(INSTANTIATE_NS_REQUEST_PARAM_NAME); + + final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList = + instantiateNsRequest.getAdditionalParamsForVnf(); + + @SuppressWarnings("unchecked") + final Map<String, String> vnfdIdToVnfPkgIdMapping = + (Map<String, String>) execution.getVariable(VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME); + + final List<CreateInstantiateRequest> requests = new ArrayList<>(); + + for (final VirtualNetworkFunction vnf : networkServiceDescriptor.getVnfs()) { + final List<String> vnfmInfoList = vnf.getVnfmInfoList(); + + final String vnfdId = vnf.getVnfdId(); + final String vnfPkgId = vnfdIdToVnfPkgIdMapping.get(vnfdId); + if (vnfdId == null || vnfmInfoList.isEmpty() || vnfPkgId == null) { + final String message = "Unable to find VnfdId/vnfmInfo/VnfPkgId for vnf: " + vnf; + abortOperation(execution, message); + } + + final Optional<Tenant> optional = getTenant(vnfPkgId, additionalParamsForVnfList); + if (!optional.isPresent()) { + final String message = "Unable to find Tenant information for " + vnfdId + " in instantiateNsRequest : " + + instantiateNsRequest; + abortOperation(execution, message); + } + + final Tenant tenant = optional.get(); + final CreateInstantiateRequest createInstantiateRequest = new CreateInstantiateRequest().nsInstId(nsInstId) + .vnfdId(vnfdId).vnfName(vnf.getVnfName()).vnfPkgId(vnfPkgId).nfType(vnfmInfoList.get(0)) + .tenant(tenant).additionalParams(getAdditionalParams(vnfPkgId, additionalParamsForVnfList)); + + logger.info("Adding request to list: {}", createInstantiateRequest); + requests.add(createInstantiateRequest); + + } + execution.setVariable(VNF_CREATE_INSTANTIATE_REQUESTS, requests); + + logger.info("Finished executing prepareCreateInstantiateRequests ..."); + } + + public void getVnfPkgIdForEachVnfdId(final DelegateExecution execution) { + logger.info("Executing getVnfPkgIdForEachVnfdId ..."); + + setJobStatus(execution, IN_PROGRESS, "Getting VnfPkgId for each VnfdId"); + + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId); + + final String nsPackageId = nfvoNsInst.getNsPackageId(); + final NsdInfo nsdInfo = getNsdInfo(execution, nsPackageId); + + final Map<String, String> vnfdIdToVnfPkgIdMapping = new HashMap<>(); + try { + for (final String vnfPkgId : nsdInfo.getVnfPkgIds()) { + final Optional<VnfPkgInfo> optional = + etsiCatalogPackageManagementServiceProvider.getVnfPkgInfo(vnfPkgId); + + if (!optional.isPresent()) { + final String message = "Unable to find VNF package using NS vnfPkgId: " + vnfPkgId; + logger.error(message); + abortOperation(execution, message); + } + final VnfPkgInfo vnfPkgInfo = optional.get(); + vnfdIdToVnfPkgIdMapping.put(vnfPkgInfo.getVnfdId(), vnfPkgId); + + } + logger.info("vnfdIdToVnfPkgIdMapping: {}", vnfdIdToVnfPkgIdMapping); + execution.setVariable(VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME, vnfdIdToVnfPkgIdMapping); + + } catch (final EtsiCatalogManagerRequestFailureException failureException) { + final String message = + "Unexpected exception occured while getting VNF package using nsPackageId: " + nsPackageId; + logger.error(message, failureException); + + abortOperation(execution, message); + } + + logger.info("Finished executing getVnfPkgIdForEachVnfdId ..."); + + } + + public void logTimeOut(final DelegateExecution execution) { + logger.error("Vnf instantiation timedOut ..."); + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId); + if (nfInstances != null) { + nfInstances.stream().forEach(instance -> { + logger.info("Current status {} of vnf: {}", instance.getStatus(), instance.getName()); + }); + } + } + + public void setJobStatusToError(final DelegateExecution execution) { + updateNsInstanceStatus(execution, State.FAILED); + setJobStatusToError(execution, "Instantiate NS workflow process failed"); + } + + + public void updateNsLcmOpOccStatusToCompleted(final DelegateExecution execution) { + logger.info("Executing updateNsLcmOpOccStatusToCompleted ..."); + final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME); + + final Optional<NsLcmOpOcc> optional = databaseServiceProvider.getNsLcmOpOcc(occId); + + if (!optional.isPresent()) { + final String message = "Unable to find record for NSLcmOpOcc in database using id: " + occId; + logger.error(message); + abortOperation(execution, message); + } + + final NsLcmOpOcc nsLcmOpOcc = optional.get(); + final OperationStateEnum operationStateCompleted = OperationStateEnum.COMPLETED; + logger.info("Setting operation state to {} for id: {}", operationStateCompleted, occId); + nsLcmOpOcc.setOperationState(operationStateCompleted); + databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc); + + logger.info("Finished executing updateNsLcmOpOccStatusToCompleted ..."); + + } + + public void updateNsLcmOpOccStatusToFailed(final DelegateExecution execution) { + logger.info("Executing updateNsLcmOpOccStatusToFailed ..."); + final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME); + + final Optional<NsLcmOpOcc> optional = databaseServiceProvider.getNsLcmOpOcc(occId); + + if (optional.isPresent()) { + final NsLcmOpOcc nsLcmOpOcc = optional.get(); + final OperationStateEnum operationStateFailed = OperationStateEnum.FAILED; + logger.info("Setting operation state to {} for id: {}", operationStateFailed, occId); + nsLcmOpOcc.setOperationState(operationStateFailed); + + databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc); + } else { + logger.error("Unable to find record for NSLcmOpOcc in database using id: {}", occId); + } + + logger.info("Finished executing updateNsLcmOpOccStatusToFailed ..."); + + } + + private NsdInfo getNsdInfo(final DelegateExecution execution, final String nsPackageId) { + try { + final Optional<NsdInfo> optional = + etsiCatalogPackageManagementServiceProvider.getNSPackageModel(nsPackageId); + + if (optional.isPresent()) { + final NsdInfo packageModel = optional.get(); + logger.info("NS Package exists {}", packageModel); + return packageModel; + } + + } catch (final EtsiCatalogManagerRequestFailureException failureException) { + final String message = + "Unexpected exception occured while getting ns package using nsPackageId: " + nsPackageId; + logger.error(message, failureException); + + abortOperation(execution, message); + } + + final String message = "Unable to find NS package using NS package id: " + nsPackageId; + logger.error(message); + abortOperation(execution, message); + return null; + + } + + private void updateNsInstanceStatus(final DelegateExecution execution, final State nsStatus) { + final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution); + logger.info("Updating NfvoNsInst Status to {} and saving to DB", nsStatus); + nfvoNsInst.setStatus(nsStatus); + databaseServiceProvider.saveNfvoNsInst(nfvoNsInst); + } + + private Optional<Tenant> getTenant(final String vnfPkgId, + final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList) { + + final Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> optional = additionalParamsForVnfList + .stream().filter(entry -> vnfPkgId.equals(entry.getVnfProfileId())).findFirst(); + + if (optional.isPresent()) { + final NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf additionalParamsForVnf = optional.get(); + @SuppressWarnings("unchecked") + final Map<String, Object> additionalParams = + (Map<String, Object>) additionalParamsForVnf.getAdditionalParams(); + final String vimId = (String) additionalParams.get("vim_id"); + if (vimId != null) { + final String[] splitString = vimId.split("_"); + if (splitString.length == 3) { + logger.info("Found Tenant in instantiateNsRequest using vnfPkgId: {}", vnfPkgId); + return Optional.of(new Tenant().cloudOwner(splitString[0]).regionName(splitString[1]) + .tenantId(splitString[2])); + } + + } + } + + logger.error("Unable to find Tenant in instantiateNsRequest using vnfPkgId: {}", vnfPkgId); + return Optional.empty(); + } + + @SuppressWarnings("unchecked") + private Map<String, String> getAdditionalParams(final String vnfPkgId, + final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList) { + + final Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> optional = additionalParamsForVnfList + .stream().filter(entry -> vnfPkgId.equals(entry.getVnfProfileId())).findFirst(); + + if (optional.isPresent()) { + final NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf additionalParamsForVnf = optional.get(); + if (additionalParamsForVnf instanceof Map) { + logger.info("Found AdditionalParams in instantiateNsRequest using vnfPkgId: {}", vnfPkgId); + return (Map<String, String>) additionalParamsForVnf.getAdditionalParams(); + } + } + + return Collections.emptyMap(); + + } + + private NfvoNsInst getNfvoNsInst(final DelegateExecution execution) { + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + return getNfvoNsInst(execution, nsInstId); + } + + private NfvoNsInst getNfvoNsInst(final DelegateExecution execution, final String nsInstId) { + logger.info("Getting NfvoNsInst to update with nsInstId: {}", nsInstId); + final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstId); + + if (!optionalNfvoNsInst.isPresent()) { + final String message = "Unable to find NS Instance in database using id: " + nsInstId; + abortOperation(execution, message); + } + + return optionalNfvoNsInst.get(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorInstantiateSol003AdapterNodeTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorInstantiateSol003AdapterNodeTask.java new file mode 100644 index 0000000000..51fa6b9381 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorInstantiateSol003AdapterNodeTask.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks; + +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Component +public class MonitorInstantiateSol003AdapterNodeTask extends MonitorSol003AdapterNodeTask { + public static final String CREATE_VNF_NODE_STATUS = "createVnfNodeStatus"; + public static final String VNF_CREATED = "Created"; + + @Autowired + public MonitorInstantiateSol003AdapterNodeTask(final DatabaseServiceProvider databaseServiceProvider, + final AaiServiceProvider aaiServiceProvider) { + super(databaseServiceProvider, aaiServiceProvider); + } + + @Override + public String getNodeStatusVariableName() { + return CREATE_VNF_NODE_STATUS; + } + + @Override + public boolean isOrchestrationStatusValid(final String orchestrationStatus) { + return VNF_CREATED.equalsIgnoreCase(orchestrationStatus); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterCreateJobTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterCreateJobTask.java new file mode 100644 index 0000000000..3c91598dfb --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterCreateJobTask.java @@ -0,0 +1,105 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_VNF_RESPONSE_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Component +public class MonitorSol003AdapterCreateJobTask extends MonitorSol003AdapterJobTask { + + private static final Logger LOGGER = LoggerFactory.getLogger(MonitorSol003AdapterCreateJobTask.class); + + @Autowired + public MonitorSol003AdapterCreateJobTask(final Sol003AdapterServiceProvider sol003AdapterServiceProvider, + final DatabaseServiceProvider databaseServiceProvider) { + super(sol003AdapterServiceProvider, databaseServiceProvider); + } + + public void getCurrentOperationStatus(final DelegateExecution execution) { + try { + LOGGER.debug("Executing getCurrentOperationStatus ..."); + final CreateVnfResponse vnfInstantiateResponse = + (CreateVnfResponse) execution.getVariable(CREATE_VNF_RESPONSE_PARAM_NAME); + execution.setVariable(OPERATION_STATUS_PARAM_NAME, + getOperationStatus(execution, vnfInstantiateResponse.getJobId())); + LOGGER.debug("Finished executing getCurrentOperationStatus ..."); + } catch (final Exception exception) { + final String message = "Unable to invoke get current Operation status"; + LOGGER.error(message, exception); + abortOperation(execution, message); + + } + } + + /** + * Log and throw exception on timeout for job status + * + * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl} + */ + public void timeOutLogFailue(final DelegateExecution execution) { + final String message = "Instantiation operation time out"; + LOGGER.error(message); + abortOperation(execution, message); + } + + /** + * Check the final status of instantiation throw exception if not completed successfully + * + * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl} + */ + public void checkIfOperationWasSuccessful(final DelegateExecution execution) { + LOGGER.debug("Executing checkIfOperationWasSuccessful ..."); + final OperationStateEnum operationStatus = + (OperationStateEnum) execution.getVariable(OPERATION_STATUS_PARAM_NAME); + final CreateVnfResponse vnfInstantiateResponse = + (CreateVnfResponse) execution.getVariable(CREATE_VNF_RESPONSE_PARAM_NAME); + + if (operationStatus == null) { + final String message = "Unable to instantiate jobId: " + + (vnfInstantiateResponse != null ? vnfInstantiateResponse.getJobId() : "null") + + "Unable to retrieve OperationStatus"; + LOGGER.error(message); + abortOperation(execution, message); + } + if (operationStatus != OperationStateEnum.COMPLETED) { + final String message = "Unable to instantiate jobId: " + + (vnfInstantiateResponse != null ? vnfInstantiateResponse.getJobId() : "null") + + " OperationStatus: " + operationStatus; + LOGGER.error(message); + abortOperation(execution, message); + } + + LOGGER.debug("Successfully completed instatiation of job {}", vnfInstantiateResponse); + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterJobTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterJobTask.java new file mode 100644 index 0000000000..bac79dfa3e --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterJobTask.java @@ -0,0 +1,96 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME; +import java.util.Optional; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStatusRetrievalStatusEnum; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.google.common.collect.ImmutableSet; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Component +public class MonitorSol003AdapterJobTask extends AbstractNetworkServiceTask { + + private static final Logger LOGGER = LoggerFactory.getLogger(MonitorSol003AdapterJobTask.class); + public static final ImmutableSet<OperationStateEnum> OPERATION_FINISHED_STATES = + ImmutableSet.of(OperationStateEnum.COMPLETED, OperationStateEnum.FAILED, OperationStateEnum.ROLLED_BACK); + public static final ImmutableSet<OperationStatusRetrievalStatusEnum> OPERATION_RETRIEVAL_STATES = ImmutableSet + .of(OperationStatusRetrievalStatusEnum.STATUS_FOUND, OperationStatusRetrievalStatusEnum.WAITING_FOR_STATUS); + protected final Sol003AdapterServiceProvider sol003AdapterServiceProvider; + + @Autowired + public MonitorSol003AdapterJobTask(final Sol003AdapterServiceProvider sol003AdapterServiceProvider, + final DatabaseServiceProvider databaseServiceProvider) { + super(databaseServiceProvider); + this.sol003AdapterServiceProvider = sol003AdapterServiceProvider; + } + + public boolean hasOperationFinished(final DelegateExecution execution) { + LOGGER.debug("Executing hasOperationFinished ..."); + + final OperationStateEnum operationStatus = + (OperationStateEnum) execution.getVariable(OPERATION_STATUS_PARAM_NAME); + if (operationStatus != null) { + return OPERATION_FINISHED_STATES.contains(operationStatus); + } + LOGGER.debug("OperationStatus is not present yet... "); + LOGGER.debug("Finished executing hasOperationFinished ..."); + return false; + } + + protected OperationStateEnum getOperationStatus(final DelegateExecution execution, final String jobId) { + + final Optional<QueryJobResponse> instantiateOperationJobStatus = + sol003AdapterServiceProvider.getInstantiateOperationJobStatus(jobId); + + if (instantiateOperationJobStatus.isPresent()) { + final QueryJobResponse queryJobResponse = instantiateOperationJobStatus.get(); + + if (!OPERATION_RETRIEVAL_STATES.contains(queryJobResponse.getOperationStatusRetrievalStatus())) { + final String message = "Received invalid operation retrieval state: " + + queryJobResponse.getOperationStatusRetrievalStatus(); + LOGGER.error(message); + abortOperation(execution, message); + } + if (queryJobResponse.getOperationState() != null) { + final OperationStateEnum operationStatus = queryJobResponse.getOperationState(); + LOGGER.debug("Operation {} with {} and operation retrieval status : {}", queryJobResponse.getId(), + operationStatus, queryJobResponse.getOperationStatusRetrievalStatus()); + return queryJobResponse.getOperationState(); + } + + LOGGER.debug("Operation {} without operationStatus and operation retrieval status :{}", + queryJobResponse.getId(), queryJobResponse.getOperationStatusRetrievalStatus()); + } + return null; + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterNodeTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterNodeTask.java new file mode 100644 index 0000000000..e27e0c1579 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterNodeTask.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NF_INST_ID_PARAM_NAME; +import java.util.Optional; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.onap.aai.domain.yang.GenericVnf; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public abstract class MonitorSol003AdapterNodeTask extends AbstractNetworkServiceTask { + + private static final Logger LOGGER = LoggerFactory.getLogger(MonitorSol003AdapterNodeTask.class); + private final AaiServiceProvider aaiServiceProvider; + + public MonitorSol003AdapterNodeTask(final DatabaseServiceProvider databaseServiceProvider, + final AaiServiceProvider aaiServiceProvider) { + super(databaseServiceProvider); + this.aaiServiceProvider = aaiServiceProvider; + } + + /** + * Check the final status of vnf in A&AI + * + * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl} + */ + public void getNodeStatus(final DelegateExecution execution) { + try { + LOGGER.debug("Executing getNodeStatus ..."); + final String vnfId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME); + + LOGGER.debug("Query A&AI for generic VNF using vnfID: {}", vnfId); + final Optional<GenericVnf> aaiGenericVnfOptional = aaiServiceProvider.getGenericVnf(vnfId); + + if (!aaiGenericVnfOptional.isPresent()) { + abortOperation(execution, "Unable to invoke Sol003 adapter for create and instantiate vnfId" + vnfId); + } + final GenericVnf genericVnf = aaiGenericVnfOptional.get(); + final String orchestrationStatus = genericVnf.getOrchestrationStatus(); + LOGGER.debug("Found generic vnf with orchestration status : {}", orchestrationStatus); + + execution.setVariable(getNodeStatusVariableName(), isOrchestrationStatusValid(orchestrationStatus)); + + } catch (final Exception exception) { + LOGGER.error("Unable to get vnf from AAI", exception); + abortOperation(execution, "Unable to get vnf from AAI"); + } + } + + /** + * Get variable to store in execution context + * + * @return the variable name + */ + public abstract String getNodeStatusVariableName(); + + /** + * @param orchestrationStatus the orchestration status from A&AI + * @return true if valid + */ + public abstract boolean isOrchestrationStatusValid(final String orchestrationStatus); + + public void timeOutLogFailue(final DelegateExecution execution) { + final String message = "Node operation time out"; + LOGGER.error(message); + abortOperation(execution, message); + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java new file mode 100644 index 0000000000..34959ee0f0 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/utils/LocalDateTimeTypeAdapter.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.utils; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class LocalDateTimeTypeAdapter extends TypeAdapter<LocalDateTime> { + + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + @Override + public void write(final JsonWriter out, final LocalDateTime localDateTime) throws IOException { + if (localDateTime == null) { + out.nullValue(); + } else { + out.value(FORMATTER.format(localDateTime)); + } + } + + @Override + public LocalDateTime read(final JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + final String dateTime = in.nextString(); + return LocalDateTime.parse(dateTime, FORMATTER); + } + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn new file mode 100644 index 0000000000..025faa4128 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="UTF-8"?> +<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1uf6nd9" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.0.0"> + <bpmn:process id="CreateInstantiateVnf" name="CreateInstantiateVnf" isExecutable="true"> + <bpmn:startEvent id="StartEvent_1"> + <bpmn:outgoing>Flow_02bjz2v</bpmn:outgoing> + </bpmn:startEvent> + <bpmn:serviceTask id="Activity_19rmtjr" name="Create NF Instance (VNF) record in DB" camunda:expression="${CreateInstantiateVnfTask.createNfInstanceInDb(execution)}"> + <bpmn:incoming>Flow_123uagz</bpmn:incoming> + <bpmn:outgoing>Flow_03p6ifi</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_02bjz2v" sourceRef="StartEvent_1" targetRef="Activity_1cluqgp" /> + <bpmn:endEvent id="Event_14qdixj"> + <bpmn:incoming>Flow_0srinh7</bpmn:incoming> + </bpmn:endEvent> + <bpmn:sequenceFlow id="Flow_03p6ifi" sourceRef="Activity_19rmtjr" targetRef="Activity_0rto3n3" /> + <bpmn:serviceTask id="Activity_0rto3n3" name="Create Generic VNF and Connect to Service Instance in AAI" camunda:expression="${CreateInstantiateVnfTask.createGenericVnfInAai(execution)}"> + <bpmn:incoming>Flow_03p6ifi</bpmn:incoming> + <bpmn:outgoing>Flow_1c3kc4e</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1c3kc4e" sourceRef="Activity_0rto3n3" targetRef="ServiceTask_0iry5yw" /> + <bpmn:serviceTask id="Activity_1cluqgp" name="Check If NF Instance (VNF) exists in DB" camunda:expression="${CreateInstantiateVnfTask.checkIfNfInstanceExistsInDb(execution)}"> + <bpmn:incoming>Flow_02bjz2v</bpmn:incoming> + <bpmn:outgoing>Flow_123uagz</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_123uagz" sourceRef="Activity_1cluqgp" targetRef="Activity_19rmtjr" /> + <bpmn:serviceTask id="ServiceTask_0iry5yw" name=" Invoke VNFM Adaptor " camunda:asyncAfter="true" camunda:expression="${CreateInstantiateVnfTask.invokeCreateInstantiationRequest(execution)}"> + <bpmn:incoming>Flow_1c3kc4e</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_0xzptc2</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:callActivity id="CallActivity_1yilxx3" name="Monitor Sol003 adapter Instantiation Job" calledElement="MonitorSol003AdapterCreateJob"> + <bpmn:extensionElements> + <camunda:in source="createVnfResponse" target="createVnfResponse" /> + <camunda:in source="jobId" target="jobId" /> + </bpmn:extensionElements> + <bpmn:incoming>SequenceFlow_0xzptc2</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_053tvct</bpmn:outgoing> + </bpmn:callActivity> + <bpmn:callActivity id="CallActivity_0p84lpt" name="Monitor Sol003 adapter Create Node Status" calledElement="MonitorSol003AdapterCreateNodeStatus"> + <bpmn:extensionElements> + <camunda:in source="NF_INST_ID" target="NF_INST_ID" /> + <camunda:in source="createVnfResponse" target="createVnfResponse" /> + </bpmn:extensionElements> + <bpmn:incoming>SequenceFlow_053tvct</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_0h7yluk</bpmn:outgoing> + </bpmn:callActivity> + <bpmn:sequenceFlow id="SequenceFlow_0xzptc2" sourceRef="ServiceTask_0iry5yw" targetRef="CallActivity_1yilxx3" /> + <bpmn:sequenceFlow id="SequenceFlow_053tvct" sourceRef="CallActivity_1yilxx3" targetRef="CallActivity_0p84lpt" /> + <bpmn:sequenceFlow id="SequenceFlow_0h7yluk" sourceRef="CallActivity_0p84lpt" targetRef="Activity_0g3dip7" /> + <bpmn:serviceTask id="Activity_0g3dip7" name="Update NF Instance (VNF) Status to INSTANTIATED" camunda:expression="${CreateInstantiateVnfTask.updateNfInstanceStatusToInstantiated(execution)}"> + <bpmn:incoming>SequenceFlow_0h7yluk</bpmn:incoming> + <bpmn:outgoing>Flow_0srinh7</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_0srinh7" sourceRef="Activity_0g3dip7" targetRef="Event_14qdixj" /> + <bpmn:subProcess id="Activity_0qtgdm9" name="Error Handling" triggeredByEvent="true"> + <bpmn:startEvent id="Event_08zcwc2" name="error"> + <bpmn:outgoing>Flow_06q1m6i</bpmn:outgoing> + <bpmn:errorEventDefinition id="ErrorEventDefinition_1ppvn77" /> + </bpmn:startEvent> + <bpmn:endEvent id="Event_1wkm29u" name="end"> + <bpmn:incoming>Flow_0anjylz</bpmn:incoming> + </bpmn:endEvent> + <bpmn:serviceTask id="Activity_0ltxcii" name="Update NF Instance (VNF) Status to FAILED" camunda:asyncBefore="true" camunda:expression="${CreateInstantiateVnfTask.updateNfInstanceStatusToFailed(execution)}"> + <bpmn:incoming>Flow_06q1m6i</bpmn:incoming> + <bpmn:outgoing>Flow_0anjylz</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_06q1m6i" sourceRef="Event_08zcwc2" targetRef="Activity_0ltxcii" /> + <bpmn:sequenceFlow id="Flow_0anjylz" sourceRef="Activity_0ltxcii" targetRef="Event_1wkm29u" /> + </bpmn:subProcess> + </bpmn:process> + <bpmndi:BPMNDiagram id="BPMNDiagram_1"> + <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="CreateInstantiateVnf"> + <bpmndi:BPMNEdge id="SequenceFlow_0h7yluk_di" bpmnElement="SequenceFlow_0h7yluk"> + <di:waypoint x="1030" y="117" /> + <di:waypoint x="1080" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_053tvct_di" bpmnElement="SequenceFlow_053tvct"> + <di:waypoint x="880" y="117" /> + <di:waypoint x="930" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_0xzptc2_di" bpmnElement="SequenceFlow_0xzptc2"> + <di:waypoint x="740" y="117" /> + <di:waypoint x="780" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_123uagz_di" bpmnElement="Flow_123uagz"> + <di:waypoint x="350" y="117" /> + <di:waypoint x="380" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1c3kc4e_di" bpmnElement="Flow_1c3kc4e"> + <di:waypoint x="610" y="117" /> + <di:waypoint x="640" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_03p6ifi_di" bpmnElement="Flow_03p6ifi"> + <di:waypoint x="480" y="117" /> + <di:waypoint x="510" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_02bjz2v_di" bpmnElement="Flow_02bjz2v"> + <di:waypoint x="215" y="117" /> + <di:waypoint x="250" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0srinh7_di" bpmnElement="Flow_0srinh7"> + <di:waypoint x="1180" y="117" /> + <di:waypoint x="1232" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"> + <dc:Bounds x="179" y="99" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_19rmtjr_di" bpmnElement="Activity_19rmtjr"> + <dc:Bounds x="380" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0rto3n3_di" bpmnElement="Activity_0rto3n3"> + <dc:Bounds x="510" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1cluqgp_di" bpmnElement="Activity_1cluqgp"> + <dc:Bounds x="250" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="ServiceTask_0iry5yw_di" bpmnElement="ServiceTask_0iry5yw"> + <dc:Bounds x="640" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="CallActivity_1yilxx3_di" bpmnElement="CallActivity_1yilxx3"> + <dc:Bounds x="780" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="CallActivity_0p84lpt_di" bpmnElement="CallActivity_0p84lpt"> + <dc:Bounds x="930" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_14qdixj_di" bpmnElement="Event_14qdixj"> + <dc:Bounds x="1232" y="99" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0g3dip7_di" bpmnElement="Activity_0g3dip7"> + <dc:Bounds x="1080" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0qtgdm9_di" bpmnElement="Activity_0qtgdm9" isExpanded="true"> + <dc:Bounds x="430" y="270" width="438" height="130" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_06q1m6i_di" bpmnElement="Flow_06q1m6i"> + <di:waypoint x="488" y="333" /> + <di:waypoint x="580" y="333" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0anjylz_di" bpmnElement="Flow_0anjylz"> + <di:waypoint x="680" y="333" /> + <di:waypoint x="812" y="333" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="Event_08zcwc2_di" bpmnElement="Event_08zcwc2"> + <dc:Bounds x="452" y="315" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="458" y="358" width="24" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_1wkm29u_di" bpmnElement="Event_1wkm29u"> + <dc:Bounds x="812" y="315" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="822" y="357" width="19" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0ltxcii_di" bpmnElement="Activity_0ltxcii"> + <dc:Bounds x="580" y="293" width="100" height="80" /> + </bpmndi:BPMNShape> + </bpmndi:BPMNPlane> + </bpmndi:BPMNDiagram> +</bpmn:definitions> diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateNs.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateNs.bpmn new file mode 100644 index 0000000000..815b76c907 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateNs.bpmn @@ -0,0 +1,266 @@ +<?xml version="1.0" encoding="UTF-8"?> +<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1l4zor5" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.0.0"> + <bpmn:process id="CreateNs" name=" CreateNs" isExecutable="true"> + <bpmn:startEvent id="StartEvent_1" name="Start Process"> + <bpmn:outgoing>Flow_1tqn5q5</bpmn:outgoing> + </bpmn:startEvent> + <bpmn:endEvent id="EndEvent_1" name="End Process"> + <bpmn:incoming>Flow_0t87ov3</bpmn:incoming> + </bpmn:endEvent> + <bpmn:sequenceFlow id="Flow_1tqn5q5" sourceRef="StartEvent_1" targetRef="Activity_15ksfz6" /> + <bpmn:serviceTask id="Activity_15ksfz6" name="Set Job Status to STARTED" camunda:asyncBefore="true" camunda:expression="${CreateNsTask.setJobStatusToStarted(execution)}"> + <bpmn:incoming>Flow_1tqn5q5</bpmn:incoming> + <bpmn:outgoing>Flow_0y07mxe</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_0y07mxe" sourceRef="Activity_15ksfz6" targetRef="Activity_12yonzp" /> + <bpmn:serviceTask id="Activity_1r4l8w8" name="Set Job Status to FINISHED" camunda:expression="${CreateNsTask.setJobStatusToFinished(execution)}"> + <bpmn:incoming>Flow_1rtsvpm</bpmn:incoming> + <bpmn:outgoing>Flow_0t87ov3</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_0t87ov3" sourceRef="Activity_1r4l8w8" targetRef="EndEvent_1" /> + <bpmn:exclusiveGateway id="Gateway_0fuwzjj" name="Does Ns Package exists?"> + <bpmn:incoming>Flow_09582uw</bpmn:incoming> + <bpmn:outgoing>Flow_1f4vi10</bpmn:outgoing> + <bpmn:outgoing>Flow_0qabgp7</bpmn:outgoing> + </bpmn:exclusiveGateway> + <bpmn:serviceTask id="Activity_12yonzp" name="Get Ns Package from ETSI Catalog Manager" camunda:expression="${CreateNsTask.getNsPackage(execution)}"> + <bpmn:incoming>Flow_0y07mxe</bpmn:incoming> + <bpmn:outgoing>Flow_09582uw</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_09582uw" sourceRef="Activity_12yonzp" targetRef="Gateway_0fuwzjj" /> + <bpmn:subProcess id="Activity_06ko4e2" name="Error Handling" triggeredByEvent="true"> + <bpmn:startEvent id="Event_1ibvrn2" name="error"> + <bpmn:outgoing>Flow_0554tjv</bpmn:outgoing> + <bpmn:errorEventDefinition id="ErrorEventDefinition_0lc46mh" /> + </bpmn:startEvent> + <bpmn:endEvent id="Event_02f7sr1" name="end"> + <bpmn:incoming>Flow_04xvpee</bpmn:incoming> + </bpmn:endEvent> + <bpmn:sequenceFlow id="Flow_0554tjv" sourceRef="Event_1ibvrn2" targetRef="Activity_1sj0nvr" /> + <bpmn:serviceTask id="Activity_1sj0nvr" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${CreateNsTask.setJobStatusToError(execution)}"> + <bpmn:incoming>Flow_0554tjv</bpmn:incoming> + <bpmn:outgoing>Flow_04xvpee</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_04xvpee" sourceRef="Activity_1sj0nvr" targetRef="Event_02f7sr1" /> + </bpmn:subProcess> + <bpmn:subProcess id="Activity_1dx9fz6" name="Java Exception Handling" triggeredByEvent="true"> + <bpmn:startEvent id="Event_0zne7ch" name="error"> + <bpmn:outgoing>Flow_0j1otrx</bpmn:outgoing> + <bpmn:errorEventDefinition id="ErrorEventDefinition_1p3h4ta" errorRef="Error_0s855yd" camunda:errorCodeVariable="BPMN_javaExpCode" camunda:errorMessageVariable="BPMN_javaExpMsg" /> + </bpmn:startEvent> + <bpmn:endEvent id="Event_0bcyh7u"> + <bpmn:incoming>Flow_0oqv7vl</bpmn:incoming> + </bpmn:endEvent> + <bpmn:sequenceFlow id="Flow_0j1otrx" sourceRef="Event_0zne7ch" targetRef="Activity_15uwy90" /> + <bpmn:serviceTask id="Activity_15uwy90" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${CreateNsTask.setJobStatusToError(execution)}"> + <bpmn:incoming>Flow_0j1otrx</bpmn:incoming> + <bpmn:outgoing>Flow_0oqv7vl</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_0oqv7vl" sourceRef="Activity_15uwy90" targetRef="Event_0bcyh7u" /> + </bpmn:subProcess> + <bpmn:sequenceFlow id="Flow_1f4vi10" name="No" sourceRef="Gateway_0fuwzjj" targetRef="Event_016q8gu"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{not doesNsPackageExists}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:endEvent id="Event_016q8gu"> + <bpmn:incoming>Flow_1f4vi10</bpmn:incoming> + <bpmn:incoming>Flow_1yql1cm</bpmn:incoming> + <bpmn:errorEventDefinition id="ErrorEventDefinition_1ugx52k" errorRef="Error_0rqvnym" /> + </bpmn:endEvent> + <bpmn:sequenceFlow id="Flow_0qabgp7" name="Yes" sourceRef="Gateway_0fuwzjj" targetRef="Activity_0vlb2nk"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{doesNsPackageExists}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:serviceTask id="Activity_0vlb2nk" name="Check NS Instance exists In DB " camunda:expression="${CreateNsTask.doesNsInstanceExistsInDb(execution)}"> + <bpmn:incoming>Flow_0qabgp7</bpmn:incoming> + <bpmn:outgoing>Flow_1exrj2b</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1exrj2b" sourceRef="Activity_0vlb2nk" targetRef="Gateway_0d7n517" /> + <bpmn:exclusiveGateway id="Gateway_0d7n517"> + <bpmn:incoming>Flow_1exrj2b</bpmn:incoming> + <bpmn:outgoing>Flow_1rkg44s</bpmn:outgoing> + <bpmn:outgoing>Flow_1yql1cm</bpmn:outgoing> + </bpmn:exclusiveGateway> + <bpmn:sequenceFlow id="Flow_1rkg44s" name="No" sourceRef="Gateway_0d7n517" targetRef="Activity_09tqz8x"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{not doesNsInstanceExists}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:sequenceFlow id="Flow_1yql1cm" name="Yes" sourceRef="Gateway_0d7n517" targetRef="Event_016q8gu"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{doesNsInstanceExists}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:serviceTask id="Activity_09tqz8x" name="Create NS Instance record in DB" camunda:expression="${CreateNsTask.createNsInstanceInDb(execution)}"> + <bpmn:incoming>Flow_1rkg44s</bpmn:incoming> + <bpmn:outgoing>Flow_1jvfwd2</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1jvfwd2" sourceRef="Activity_09tqz8x" targetRef="Activity_1akc79d" /> + <bpmn:serviceTask id="Activity_1akc79d" name="Create NS Instance in AAI" camunda:expression="${CreateNsTask.createNsInstanceInAai(execution)}"> + <bpmn:incoming>Flow_1jvfwd2</bpmn:incoming> + <bpmn:outgoing>Flow_0e5hvno</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_0e5hvno" sourceRef="Activity_1akc79d" targetRef="Activity_03ht66t" /> + <bpmn:serviceTask id="Activity_03ht66t" name="Set Create NS Response" camunda:expression="${CreateNsTask.setCreateNsResponse(execution)}"> + <bpmn:incoming>Flow_0e5hvno</bpmn:incoming> + <bpmn:outgoing>Flow_1rtsvpm</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1rtsvpm" sourceRef="Activity_03ht66t" targetRef="Activity_1r4l8w8" /> + </bpmn:process> + <bpmn:error id="Error_0s855yd" name="java.lang.Exception" errorCode="java.lang.Exception" /> + <bpmn:error id="Error_0rqvnym" name="CreateNsProcessingException" errorCode="CREATE_NS_PROCESSING_EXCEPTION" /> + <bpmndi:BPMNDiagram id="BPMNDiagram_1"> + <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="CreateNs"> + <bpmndi:BPMNEdge id="Flow_1rtsvpm_di" bpmnElement="Flow_1rtsvpm"> + <di:waypoint x="1160" y="157" /> + <di:waypoint x="1160" y="230" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0e5hvno_di" bpmnElement="Flow_0e5hvno"> + <di:waypoint x="1070" y="117" /> + <di:waypoint x="1110" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1jvfwd2_di" bpmnElement="Flow_1jvfwd2"> + <di:waypoint x="930" y="117" /> + <di:waypoint x="970" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1yql1cm_di" bpmnElement="Flow_1yql1cm"> + <di:waypoint x="760" y="142" /> + <di:waypoint x="760" y="230" /> + <di:waypoint x="668" y="230" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="766" y="183" width="19" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1rkg44s_di" bpmnElement="Flow_1rkg44s"> + <di:waypoint x="785" y="117" /> + <di:waypoint x="830" y="117" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="799" y="99" width="14" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1exrj2b_di" bpmnElement="Flow_1exrj2b"> + <di:waypoint x="700" y="117" /> + <di:waypoint x="735" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0qabgp7_di" bpmnElement="Flow_0qabgp7"> + <di:waypoint x="565" y="117" /> + <di:waypoint x="600" y="117" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="579" y="99" width="19" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1f4vi10_di" bpmnElement="Flow_1f4vi10"> + <di:waypoint x="540" y="142" /> + <di:waypoint x="540" y="230" /> + <di:waypoint x="632" y="230" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="548" y="183" width="14" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_09582uw_di" bpmnElement="Flow_09582uw"> + <di:waypoint x="480" y="117" /> + <di:waypoint x="515" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0t87ov3_di" bpmnElement="Flow_0t87ov3"> + <di:waypoint x="1160" y="310" /> + <di:waypoint x="1160" y="357" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0y07mxe_di" bpmnElement="Flow_0y07mxe"> + <di:waypoint x="350" y="117" /> + <di:waypoint x="380" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1tqn5q5_di" bpmnElement="Flow_1tqn5q5"> + <di:waypoint x="208" y="117" /> + <di:waypoint x="250" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"> + <dc:Bounds x="172" y="99" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="158" y="142" width="67" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_0db1w1a_di" bpmnElement="EndEvent_1"> + <dc:Bounds x="1142" y="357" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1129" y="400" width="63" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_15ksfz6_di" bpmnElement="Activity_15ksfz6"> + <dc:Bounds x="250" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1r4l8w8_di" bpmnElement="Activity_1r4l8w8"> + <dc:Bounds x="1110" y="230" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Gateway_0fuwzjj_di" bpmnElement="Gateway_0fuwzjj" isMarkerVisible="true"> + <dc:Bounds x="515" y="92" width="50" height="50" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="498" y="62" width="88" height="27" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_12yonzp_di" bpmnElement="Activity_12yonzp"> + <dc:Bounds x="380" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_06ko4e2_di" bpmnElement="Activity_06ko4e2" isExpanded="true"> + <dc:Bounds x="431" y="310" width="438" height="130" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_04xvpee_di" bpmnElement="Flow_04xvpee"> + <di:waypoint x="681" y="373" /> + <di:waypoint x="813" y="373" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0554tjv_di" bpmnElement="Flow_0554tjv"> + <di:waypoint x="489" y="373" /> + <di:waypoint x="581" y="373" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="Event_1ibvrn2_di" bpmnElement="Event_1ibvrn2"> + <dc:Bounds x="453" y="355" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="459" y="398" width="24" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_02f7sr1_di" bpmnElement="Event_02f7sr1"> + <dc:Bounds x="813" y="355" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="823" y="397" width="19" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1sj0nvr_di" bpmnElement="Activity_1sj0nvr"> + <dc:Bounds x="581" y="333" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1dx9fz6_di" bpmnElement="Activity_1dx9fz6" isExpanded="true"> + <dc:Bounds x="431" y="470" width="438" height="130" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_0oqv7vl_di" bpmnElement="Flow_0oqv7vl"> + <di:waypoint x="680" y="533" /> + <di:waypoint x="772" y="533" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0j1otrx_di" bpmnElement="Flow_0j1otrx"> + <di:waypoint x="522" y="533" /> + <di:waypoint x="580" y="533" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="Event_0zne7ch_di" bpmnElement="Event_0zne7ch"> + <dc:Bounds x="486" y="515" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="493" y="558" width="24" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_0bcyh7u_di" bpmnElement="Event_0bcyh7u"> + <dc:Bounds x="772" y="515" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_15uwy90_di" bpmnElement="Activity_15uwy90"> + <dc:Bounds x="580" y="493" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_0spfqz1_di" bpmnElement="Event_016q8gu"> + <dc:Bounds x="632" y="212" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0vlb2nk_di" bpmnElement="Activity_0vlb2nk"> + <dc:Bounds x="600" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Gateway_0d7n517_di" bpmnElement="Gateway_0d7n517" isMarkerVisible="true"> + <dc:Bounds x="735" y="92" width="50" height="50" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_09tqz8x_di" bpmnElement="Activity_09tqz8x"> + <dc:Bounds x="830" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1akc79d_di" bpmnElement="Activity_1akc79d"> + <dc:Bounds x="970" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_03ht66t_di" bpmnElement="Activity_03ht66t"> + <dc:Bounds x="1110" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + </bpmndi:BPMNPlane> + </bpmndi:BPMNDiagram> +</bpmn:definitions> diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/InstantiateNs.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/InstantiateNs.bpmn new file mode 100644 index 0000000000..ba9e641d84 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/InstantiateNs.bpmn @@ -0,0 +1,331 @@ +<?xml version="1.0" encoding="UTF-8"?> +<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_0mdda96" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.0.0"> + <bpmn:process id="InstantiateNs" name="InstantiateNs" isExecutable="true"> + <bpmn:startEvent id="StartEvent_1" name="Start Process"> + <bpmn:outgoing>SequenceFlow_16k0f61</bpmn:outgoing> + </bpmn:startEvent> + <bpmn:sequenceFlow id="SequenceFlow_16k0f61" sourceRef="StartEvent_1" targetRef="Activity_194tqy0" /> + <bpmn:serviceTask id="Task_0opnwx0" name="Update NS Instance status to INSTANTIATING" camunda:expression="${InstantiateNsTask.updateNsInstanceStatusToInstantiating(execution)}"> + <bpmn:incoming>Flow_04pxtdd</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_0bdznyp</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:endEvent id="EndEvent_0szswbo" name="End Process"> + <bpmn:incoming>Flow_1pcu8aa</bpmn:incoming> + </bpmn:endEvent> + <bpmn:sequenceFlow id="SequenceFlow_0bdznyp" sourceRef="Task_0opnwx0" targetRef="Activity_1jrym1e" /> + <bpmn:serviceTask id="Activity_194tqy0" name="Set Job Status to STARTED" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.setJobStatusToStarted(execution)}"> + <bpmn:incoming>SequenceFlow_16k0f61</bpmn:incoming> + <bpmn:outgoing>Flow_04pxtdd</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_04pxtdd" sourceRef="Activity_194tqy0" targetRef="Task_0opnwx0" /> + <bpmn:subProcess id="Activity_0pjxszh" name="Error Handling" triggeredByEvent="true"> + <bpmn:startEvent id="Event_1rpzcl3" name="error"> + <bpmn:outgoing>Flow_07bh7l7</bpmn:outgoing> + <bpmn:errorEventDefinition id="ErrorEventDefinition_0m2e0oa" /> + </bpmn:startEvent> + <bpmn:endEvent id="Event_1fcw3ei" name="end"> + <bpmn:incoming>Flow_1wa1jpl</bpmn:incoming> + </bpmn:endEvent> + <bpmn:serviceTask id="Activity_0ddja9m" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.setJobStatusToError(execution)}"> + <bpmn:incoming>Flow_0n3dai5</bpmn:incoming> + <bpmn:outgoing>Flow_1wa1jpl</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1wa1jpl" sourceRef="Activity_0ddja9m" targetRef="Event_1fcw3ei" /> + <bpmn:sequenceFlow id="Flow_07bh7l7" sourceRef="Event_1rpzcl3" targetRef="Activity_1miy3hw" /> + <bpmn:serviceTask id="Activity_1miy3hw" name="Update NSLcmOpOcc operation status to FAILED" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.updateNsLcmOpOccStatusToFailed(execution)}"> + <bpmn:incoming>Flow_07bh7l7</bpmn:incoming> + <bpmn:outgoing>Flow_0n3dai5</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_0n3dai5" sourceRef="Activity_1miy3hw" targetRef="Activity_0ddja9m" /> + </bpmn:subProcess> + <bpmn:subProcess id="Activity_0mtscwq" name="Java Exception Handling" triggeredByEvent="true"> + <bpmn:startEvent id="Event_0lqr6al" name="error"> + <bpmn:outgoing>Flow_05lo00r</bpmn:outgoing> + <bpmn:errorEventDefinition id="ErrorEventDefinition_02lwl19" errorRef="Error_0jsct8p" camunda:errorCodeVariable="BPMN_javaExpCode" camunda:errorMessageVariable="BPMN_javaExpMsg" /> + </bpmn:startEvent> + <bpmn:endEvent id="Event_05ty7c4"> + <bpmn:incoming>Flow_16aryg5</bpmn:incoming> + </bpmn:endEvent> + <bpmn:serviceTask id="Activity_1ezu7d4" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.setJobStatusToError(execution)}"> + <bpmn:incoming>Flow_09zcw2a</bpmn:incoming> + <bpmn:outgoing>Flow_16aryg5</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_16aryg5" sourceRef="Activity_1ezu7d4" targetRef="Event_05ty7c4" /> + <bpmn:sequenceFlow id="Flow_05lo00r" sourceRef="Event_0lqr6al" targetRef="Activity_17leldb" /> + <bpmn:serviceTask id="Activity_17leldb" name="Update NSLcmOpOcc operation status to FAILED" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.updateNsLcmOpOccStatusToFailed(execution)}"> + <bpmn:incoming>Flow_05lo00r</bpmn:incoming> + <bpmn:outgoing>Flow_09zcw2a</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_09zcw2a" sourceRef="Activity_17leldb" targetRef="Activity_1ezu7d4" /> + </bpmn:subProcess> + <bpmn:serviceTask id="Activity_1w09i1k" name="Set Job Status to FINISHED" camunda:expression="${InstantiateNsTask.setJobStatusToFinished(execution)}"> + <bpmn:incoming>Flow_1i36dw4</bpmn:incoming> + <bpmn:outgoing>Flow_1pcu8aa</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1pcu8aa" sourceRef="Activity_1w09i1k" targetRef="EndEvent_0szswbo" /> + <bpmn:serviceTask id="Activity_1jrym1e" name="Get and parse NSD from ETSI Catalog" camunda:expression="${InstantiateNsTask.getAndParseNsdFromEtsiCatalog(execution)}"> + <bpmn:incoming>SequenceFlow_0bdznyp</bpmn:incoming> + <bpmn:outgoing>Flow_10zjw0w</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_10zjw0w" sourceRef="Activity_1jrym1e" targetRef="Activity_1kikjaf" /> + <bpmn:callActivity id="Activity_1b2s2wr" name="Create and Instantiate each Vnf" calledElement="CreateInstantiateVnf"> + <bpmn:extensionElements> + <camunda:in source="request" target="request" /> + <camunda:in source="jobId" target="jobId" /> + <camunda:in source="NsInstanceId" target="NsInstanceId" /> + </bpmn:extensionElements> + <bpmn:incoming>Flow_1irbp9b</bpmn:incoming> + <bpmn:outgoing>Flow_0mi4nqa</bpmn:outgoing> + <bpmn:multiInstanceLoopCharacteristics camunda:asyncAfter="true" camunda:collection="${vnfCreateInstantiateRequests}" camunda:elementVariable="request" /> + </bpmn:callActivity> + <bpmn:boundaryEvent id="Event_0rbb817" name="Overall Wait" attachedToRef="Activity_1b2s2wr"> + <bpmn:outgoing>Flow_17zn7we</bpmn:outgoing> + <bpmn:timerEventDefinition id="TimerEventDefinition_13ud1f4"> + <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT3H</bpmn:timeDuration> + </bpmn:timerEventDefinition> + </bpmn:boundaryEvent> + <bpmn:sequenceFlow id="Flow_17zn7we" sourceRef="Event_0rbb817" targetRef="Activity_16z66xm" /> + <bpmn:serviceTask id="Activity_0eou3y4" name="Prepare Create Instantiate requests" camunda:expression="${InstantiateNsTask.prepareCreateInstantiateRequests(execution)}"> + <bpmn:incoming>Flow_01ju1mj</bpmn:incoming> + <bpmn:outgoing>Flow_1irbp9b</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1irbp9b" sourceRef="Activity_0eou3y4" targetRef="Activity_1b2s2wr" /> + <bpmn:serviceTask id="Activity_1kikjaf" name="Get Vnf Pkg ID for each VNFD ID" camunda:expression="${InstantiateNsTask.getVnfPkgIdForEachVnfdId(execution)}"> + <bpmn:incoming>Flow_10zjw0w</bpmn:incoming> + <bpmn:outgoing>Flow_01ju1mj</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_01ju1mj" sourceRef="Activity_1kikjaf" targetRef="Activity_0eou3y4" /> + <bpmn:serviceTask id="Activity_16cvdbw" name="Update NS Instance status to INSTANTIATED" camunda:expression="${InstantiateNsTask.updateNsInstanceStatusToInstantiated(execution)}"> + <bpmn:incoming>Flow_1nieng0</bpmn:incoming> + <bpmn:outgoing>Flow_0xptc0r</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_0xptc0r" sourceRef="Activity_16cvdbw" targetRef="Activity_0gkpdft" /> + <bpmn:endEvent id="Event_1e4bwip"> + <bpmn:incoming>Flow_10oprxr</bpmn:incoming> + <bpmn:incoming>Flow_1p21p1m</bpmn:incoming> + <bpmn:errorEventDefinition id="ErrorEventDefinition_0vg6v5r" errorRef="Error_0jsct8p" /> + </bpmn:endEvent> + <bpmn:exclusiveGateway id="Gateway_0nxf0rv" name="is Successful?"> + <bpmn:incoming>Flow_15m4nm1</bpmn:incoming> + <bpmn:outgoing>Flow_1nieng0</bpmn:outgoing> + <bpmn:outgoing>Flow_10oprxr</bpmn:outgoing> + </bpmn:exclusiveGateway> + <bpmn:sequenceFlow id="Flow_1nieng0" name="Yes" sourceRef="Gateway_0nxf0rv" targetRef="Activity_16cvdbw"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{isNsInstantiationSuccessful}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:serviceTask id="Activity_14iwa8x" name="Check if VNF Instantiation was Successful" camunda:expression="${InstantiateNsTask.checkIfVnfInstantiationWasSuccessful(execution)}"> + <bpmn:incoming>Flow_0mi4nqa</bpmn:incoming> + <bpmn:outgoing>Flow_15m4nm1</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_0mi4nqa" sourceRef="Activity_1b2s2wr" targetRef="Activity_14iwa8x" /> + <bpmn:sequenceFlow id="Flow_15m4nm1" sourceRef="Activity_14iwa8x" targetRef="Gateway_0nxf0rv" /> + <bpmn:serviceTask id="Activity_16z66xm" name="Log TimeOut" camunda:expression="${InstantiateNsTask.logTimeOut(execution)}"> + <bpmn:incoming>Flow_17zn7we</bpmn:incoming> + <bpmn:outgoing>Flow_1p21p1m</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_10oprxr" name="No" sourceRef="Gateway_0nxf0rv" targetRef="Event_1e4bwip"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{not isNsInstantiationSuccessful}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:sequenceFlow id="Flow_1p21p1m" sourceRef="Activity_16z66xm" targetRef="Event_1e4bwip" /> + <bpmn:serviceTask id="Activity_0gkpdft" name="Update NSLcmOpOcc operation status to COMPLETED" camunda:expression="${InstantiateNsTask.updateNsLcmOpOccStatusToCompleted(execution)}"> + <bpmn:incoming>Flow_0xptc0r</bpmn:incoming> + <bpmn:outgoing>Flow_1i36dw4</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1i36dw4" sourceRef="Activity_0gkpdft" targetRef="Activity_1w09i1k" /> + </bpmn:process> + <bpmn:error id="Error_0jsct8p" name="InstantiateNsProcessingException" errorCode="INSTANTIATE_NS_PROCESSING_EXCEPTION" /> + <bpmndi:BPMNDiagram id="BPMNDiagram_1"> + <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="InstantiateNs"> + <bpmndi:BPMNEdge id="Flow_1p21p1m_di" bpmnElement="Flow_1p21p1m"> + <di:waypoint x="1250" y="270" /> + <di:waypoint x="1332" y="270" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_10oprxr_di" bpmnElement="Flow_10oprxr"> + <di:waypoint x="1350" y="146" /> + <di:waypoint x="1350" y="252" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1358" y="196" width="14" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_15m4nm1_di" bpmnElement="Flow_15m4nm1"> + <di:waypoint x="1250" y="121" /> + <di:waypoint x="1325" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0mi4nqa_di" bpmnElement="Flow_0mi4nqa"> + <di:waypoint x="1090" y="121" /> + <di:waypoint x="1150" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1nieng0_di" bpmnElement="Flow_1nieng0"> + <di:waypoint x="1375" y="121" /> + <di:waypoint x="1430" y="121" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1393" y="103" width="19" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0xptc0r_di" bpmnElement="Flow_0xptc0r"> + <di:waypoint x="1530" y="121" /> + <di:waypoint x="1580" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_01ju1mj_di" bpmnElement="Flow_01ju1mj"> + <di:waypoint x="800" y="121" /> + <di:waypoint x="850" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1irbp9b_di" bpmnElement="Flow_1irbp9b"> + <di:waypoint x="950" y="121" /> + <di:waypoint x="990" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_17zn7we_di" bpmnElement="Flow_17zn7we"> + <di:waypoint x="1070" y="179" /> + <di:waypoint x="1070" y="270" /> + <di:waypoint x="1150" y="270" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_10zjw0w_di" bpmnElement="Flow_10zjw0w"> + <di:waypoint x="649" y="121" /> + <di:waypoint x="700" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1pcu8aa_di" bpmnElement="Flow_1pcu8aa"> + <di:waypoint x="1820" y="121" /> + <di:waypoint x="1862" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_04pxtdd_di" bpmnElement="Flow_04pxtdd"> + <di:waypoint x="360" y="121" /> + <di:waypoint x="400" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_0bdznyp_di" bpmnElement="SequenceFlow_0bdznyp"> + <di:waypoint x="500" y="121" /> + <di:waypoint x="549" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_16k0f61_di" bpmnElement="SequenceFlow_16k0f61"> + <di:waypoint x="208" y="121" /> + <di:waypoint x="260" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1i36dw4_di" bpmnElement="Flow_1i36dw4"> + <di:waypoint x="1680" y="121" /> + <di:waypoint x="1720" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"> + <dc:Bounds x="172" y="103" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="157" y="146" width="67" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="ServiceTask_1y7xfqt_di" bpmnElement="Task_0opnwx0"> + <dc:Bounds x="400" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_194tqy0_di" bpmnElement="Activity_194tqy0"> + <dc:Bounds x="260" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="EndEvent_0szswbo_di" bpmnElement="EndEvent_0szswbo"> + <dc:Bounds x="1862" y="103" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1848" y="79" width="63" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1w09i1k_di" bpmnElement="Activity_1w09i1k"> + <dc:Bounds x="1720" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0gkpdft_di" bpmnElement="Activity_0gkpdft"> + <dc:Bounds x="1580" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0pjxszh_di" bpmnElement="Activity_0pjxszh" isExpanded="true"> + <dc:Bounds x="380" y="270" width="510" height="130" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_07bh7l7_di" bpmnElement="Flow_07bh7l7"> + <di:waypoint x="438" y="333" /> + <di:waypoint x="500" y="333" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1wa1jpl_di" bpmnElement="Flow_1wa1jpl"> + <di:waypoint x="760" y="333" /> + <di:waypoint x="822" y="333" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0n3dai5_di" bpmnElement="Flow_0n3dai5"> + <di:waypoint x="600" y="333" /> + <di:waypoint x="660" y="333" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="Event_1rpzcl3_di" bpmnElement="Event_1rpzcl3"> + <dc:Bounds x="402" y="315" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="408" y="358" width="24" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1miy3hw_di" bpmnElement="Activity_1miy3hw"> + <dc:Bounds x="500" y="293" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0ddja9m_di" bpmnElement="Activity_0ddja9m"> + <dc:Bounds x="660" y="293" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_1fcw3ei_di" bpmnElement="Event_1fcw3ei"> + <dc:Bounds x="822" y="315" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="832" y="357" width="19" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0mtscwq_di" bpmnElement="Activity_0mtscwq" isExpanded="true"> + <dc:Bounds x="380" y="430" width="510" height="130" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_05lo00r_di" bpmnElement="Flow_05lo00r"> + <di:waypoint x="438" y="493" /> + <di:waypoint x="500" y="493" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_16aryg5_di" bpmnElement="Flow_16aryg5"> + <di:waypoint x="760" y="493" /> + <di:waypoint x="822" y="493" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_09zcw2a_di" bpmnElement="Flow_09zcw2a"> + <di:waypoint x="600" y="493" /> + <di:waypoint x="660" y="493" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="Event_0lqr6al_di" bpmnElement="Event_0lqr6al"> + <dc:Bounds x="402" y="475" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="409" y="518" width="24" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_17leldb_di" bpmnElement="Activity_17leldb"> + <dc:Bounds x="500" y="453" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1ezu7d4_di" bpmnElement="Activity_1ezu7d4"> + <dc:Bounds x="660" y="453" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_05ty7c4_di" bpmnElement="Event_05ty7c4"> + <dc:Bounds x="822" y="475" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1jrym1e_di" bpmnElement="Activity_1jrym1e"> + <dc:Bounds x="549" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1xjmizv_di" bpmnElement="Activity_1b2s2wr"> + <dc:Bounds x="990" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0eou3y4_di" bpmnElement="Activity_0eou3y4"> + <dc:Bounds x="850" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1kikjaf_di" bpmnElement="Activity_1kikjaf"> + <dc:Bounds x="700" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_16cvdbw_di" bpmnElement="Activity_16cvdbw"> + <dc:Bounds x="1430" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_16umj30_di" bpmnElement="Event_1e4bwip"> + <dc:Bounds x="1332" y="252" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Gateway_0nxf0rv_di" bpmnElement="Gateway_0nxf0rv" isMarkerVisible="true"> + <dc:Bounds x="1325" y="96" width="50" height="50" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1320" y="66" width="71" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_14iwa8x_di" bpmnElement="Activity_14iwa8x"> + <dc:Bounds x="1150" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_16z66xm_di" bpmnElement="Activity_16z66xm"> + <dc:Bounds x="1150" y="230" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_0rbb817_di" bpmnElement="Event_0rbb817"> + <dc:Bounds x="1052" y="143" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1000" y="183" width="60" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + </bpmndi:BPMNPlane> + </bpmndi:BPMNDiagram> +</bpmn:definitions> diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/META-INF/services/org.onap.so.client.RestProperties b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/META-INF/services/org.onap.so.client.RestProperties new file mode 100644 index 0000000000..9d9ba7371a --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/META-INF/services/org.onap.so.client.RestProperties @@ -0,0 +1 @@ +org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiPropertiesImpl
\ No newline at end of file diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterCreateJob.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterCreateJob.bpmn new file mode 100644 index 0000000000..a9204ec442 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterCreateJob.bpmn @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="UTF-8"?> +<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_12gnsyw" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.4.1"> + <bpmn:process id="MonitorSol003AdapterCreateJob" name="MonitorSol003AdapterCreateJob" isExecutable="true"> + <bpmn:startEvent id="StartEvent_1"> + <bpmn:outgoing>SequenceFlow_1x3tbl0</bpmn:outgoing> + </bpmn:startEvent> + <bpmn:endEvent id="EndEvent_0rf1gde"> + <bpmn:incoming>SequenceFlow_1543qy7</bpmn:incoming> + </bpmn:endEvent> + <bpmn:subProcess id="SubProcess_19j0v63"> + <bpmn:incoming>SequenceFlow_1x3tbl0</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_1v4yr3f</bpmn:outgoing> + <bpmn:startEvent id="StartEvent_01r97z2"> + <bpmn:outgoing>SequenceFlow_0s1plu9</bpmn:outgoing> + </bpmn:startEvent> + <bpmn:exclusiveGateway id="ExclusiveGateway_1hkl6yy" default="SequenceFlow_1vmxw9g"> + <bpmn:incoming>SequenceFlow_153a3kp</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_1vmxw9g</bpmn:outgoing> + <bpmn:outgoing>SequenceFlow_0is7myf</bpmn:outgoing> + </bpmn:exclusiveGateway> + <bpmn:intermediateCatchEvent id="IntermediateCatchEvent_1besn3n" name="Wait between checks" camunda:asyncAfter="true"> + <bpmn:incoming>SequenceFlow_1vmxw9g</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_0etw572</bpmn:outgoing> + <bpmn:timerEventDefinition id="TimerEventDefinition_0qgh11t"> + <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT15S</bpmn:timeDuration> + </bpmn:timerEventDefinition> + </bpmn:intermediateCatchEvent> + <bpmn:endEvent id="EndEvent_1ohsce9"> + <bpmn:incoming>SequenceFlow_0is7myf</bpmn:incoming> + </bpmn:endEvent> + <bpmn:sequenceFlow id="SequenceFlow_0s1plu9" sourceRef="StartEvent_01r97z2" targetRef="ServiceTask_17jlnng" /> + <bpmn:sequenceFlow id="SequenceFlow_0etw572" sourceRef="IntermediateCatchEvent_1besn3n" targetRef="ServiceTask_17jlnng" /> + <bpmn:serviceTask id="ServiceTask_17jlnng" name=" Get Current Operation Status " camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterCreateJobTask.getCurrentOperationStatus(execution)}"> + <bpmn:incoming>SequenceFlow_0etw572</bpmn:incoming> + <bpmn:incoming>SequenceFlow_0s1plu9</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_153a3kp</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="SequenceFlow_1vmxw9g" sourceRef="ExclusiveGateway_1hkl6yy" targetRef="IntermediateCatchEvent_1besn3n" /> + <bpmn:sequenceFlow id="SequenceFlow_0is7myf" sourceRef="ExclusiveGateway_1hkl6yy" targetRef="EndEvent_1ohsce9"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${MonitorSol003AdapterCreateJobTask.hasOperationFinished(execution)}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:sequenceFlow id="SequenceFlow_153a3kp" sourceRef="ServiceTask_17jlnng" targetRef="ExclusiveGateway_1hkl6yy" /> + </bpmn:subProcess> + <bpmn:endEvent id="EndEvent_1w3t3t0" name="Timeout Exception"> + <bpmn:incoming>SequenceFlow_0bcgtzj</bpmn:incoming> + <bpmn:terminateEventDefinition id="TerminateEventDefinition_0fjecl3" /> + </bpmn:endEvent> + <bpmn:boundaryEvent id="BoundaryEvent_0xiabzp" name="Overall Wait" attachedToRef="SubProcess_19j0v63"> + <bpmn:outgoing>SequenceFlow_1i1o9sh</bpmn:outgoing> + <bpmn:timerEventDefinition id="TimerEventDefinition_10kqw61"> + <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT3H</bpmn:timeDuration> + </bpmn:timerEventDefinition> + </bpmn:boundaryEvent> + <bpmn:sequenceFlow id="SequenceFlow_1v4yr3f" sourceRef="SubProcess_19j0v63" targetRef="ServiceTask_1gms128" /> + <bpmn:sequenceFlow id="SequenceFlow_1i1o9sh" sourceRef="BoundaryEvent_0xiabzp" targetRef="ServiceTask_1s87b92" /> + <bpmn:sequenceFlow id="SequenceFlow_1x3tbl0" sourceRef="StartEvent_1" targetRef="SubProcess_19j0v63" /> + <bpmn:serviceTask id="ServiceTask_1s87b92" name=" Time Out Log Failure " camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterCreateJobTask.timeOutLogFailue(execution)}"> + <bpmn:incoming>SequenceFlow_1i1o9sh</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_0bcgtzj</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="SequenceFlow_0bcgtzj" sourceRef="ServiceTask_1s87b92" targetRef="EndEvent_1w3t3t0" /> + <bpmn:serviceTask id="ServiceTask_1gms128" name=" Check if operation was successful " camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterCreateJobTask.checkIfOperationWasSuccessful(execution)}"> + <bpmn:incoming>SequenceFlow_1v4yr3f</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_1543qy7</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="SequenceFlow_1543qy7" sourceRef="ServiceTask_1gms128" targetRef="EndEvent_0rf1gde" /> + </bpmn:process> + <bpmndi:BPMNDiagram id="BPMNDiagram_1"> + <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="MonitorSol003AdapterCreateJob"> + <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"> + <dc:Bounds x="161" y="330" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="EndEvent_0rf1gde_di" bpmnElement="EndEvent_0rf1gde"> + <dc:Bounds x="1102" y="100" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="SubProcess_19j0v63_di" bpmnElement="SubProcess_19j0v63" isExpanded="true"> + <dc:Bounds x="301" y="248" width="523" height="200" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="EndEvent_1w3t3t0_di" bpmnElement="EndEvent_1w3t3t0"> + <dc:Bounds x="1102" y="322" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1095" y="282" width="49" height="27" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="BoundaryEvent_0xiabzp_di" bpmnElement="BoundaryEvent_0xiabzp"> + <dc:Bounds x="806" y="322" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="794" y="361" width="61" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="SequenceFlow_1v4yr3f_di" bpmnElement="SequenceFlow_1v4yr3f"> + <di:waypoint x="563" y="248" /> + <di:waypoint x="563" y="118" /> + <di:waypoint x="923" y="118" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_1i1o9sh_di" bpmnElement="SequenceFlow_1i1o9sh"> + <di:waypoint x="842" y="340" /> + <di:waypoint x="923" y="340" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="StartEvent_01r97z2_di" bpmnElement="StartEvent_01r97z2"> + <dc:Bounds x="330" y="306" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="ExclusiveGateway_1hkl6yy_di" bpmnElement="ExclusiveGateway_1hkl6yy" isMarkerVisible="true"> + <dc:Bounds x="609" y="299" width="50" height="50" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="IntermediateCatchEvent_1besn3n_di" bpmnElement="IntermediateCatchEvent_1besn3n"> + <dc:Bounds x="550" y="378" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="537" y="421" width="66" height="27" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="EndEvent_1ohsce9_di" bpmnElement="EndEvent_1ohsce9"> + <dc:Bounds x="722" y="306" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="SequenceFlow_1x3tbl0_di" bpmnElement="SequenceFlow_1x3tbl0"> + <di:waypoint x="197" y="348" /> + <di:waypoint x="301" y="348" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="ServiceTask_17jlnng_di" bpmnElement="ServiceTask_17jlnng"> + <dc:Bounds x="425" y="284" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="SequenceFlow_0s1plu9_di" bpmnElement="SequenceFlow_0s1plu9"> + <di:waypoint x="366" y="324" /> + <di:waypoint x="425" y="324" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_0etw572_di" bpmnElement="SequenceFlow_0etw572"> + <di:waypoint x="550" y="396" /> + <di:waypoint x="486" y="396" /> + <di:waypoint x="486" y="367" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_1vmxw9g_di" bpmnElement="SequenceFlow_1vmxw9g"> + <di:waypoint x="634" y="349" /> + <di:waypoint x="634" y="396" /> + <di:waypoint x="586" y="396" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_0is7myf_di" bpmnElement="SequenceFlow_0is7myf"> + <di:waypoint x="659" y="324" /> + <di:waypoint x="722" y="324" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_153a3kp_di" bpmnElement="SequenceFlow_153a3kp"> + <di:waypoint x="525" y="324" /> + <di:waypoint x="609" y="324" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="ServiceTask_1s87b92_di" bpmnElement="ServiceTask_1s87b92"> + <dc:Bounds x="923" y="300" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="SequenceFlow_0bcgtzj_di" bpmnElement="SequenceFlow_0bcgtzj"> + <di:waypoint x="1023" y="340" /> + <di:waypoint x="1102" y="340" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="ServiceTask_1gms128_di" bpmnElement="ServiceTask_1gms128"> + <dc:Bounds x="923" y="78" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="SequenceFlow_1543qy7_di" bpmnElement="SequenceFlow_1543qy7"> + <di:waypoint x="1023" y="118" /> + <di:waypoint x="1102" y="118" /> + </bpmndi:BPMNEdge> + </bpmndi:BPMNPlane> + </bpmndi:BPMNDiagram> +</bpmn:definitions> diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterCreateNodeStatus.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterCreateNodeStatus.bpmn new file mode 100644 index 0000000000..c0de5e0352 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterCreateNodeStatus.bpmn @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1ko0frn" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.4.1"> + <bpmn:process id="MonitorSol003AdapterCreateNodeStatus" name="MonitorSol003AdapterCreateNodeStatus" isExecutable="true"> + <bpmn:startEvent id="StartEvent_0k0qfjb"> + <bpmn:outgoing>SequenceFlow_1miob62</bpmn:outgoing> + </bpmn:startEvent> + <bpmn:subProcess id="SubProcess_10wotbc"> + <bpmn:incoming>SequenceFlow_1miob62</bpmn:incoming> + <bpmn:startEvent id="StartEvent_0r9qf43"> + <bpmn:outgoing>SequenceFlow_1moaz0q</bpmn:outgoing> + </bpmn:startEvent> + <bpmn:exclusiveGateway id="ExclusiveGateway_00xtlfj" default="SequenceFlow_1luu31f"> + <bpmn:incoming>SequenceFlow_0qvy3sn</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_1rxbeqi</bpmn:outgoing> + <bpmn:outgoing>SequenceFlow_1luu31f</bpmn:outgoing> + </bpmn:exclusiveGateway> + <bpmn:intermediateCatchEvent id="IntermediateCatchEvent_0xuznv9" name="Wait between checks" camunda:asyncAfter="true"> + <bpmn:incoming>SequenceFlow_1luu31f</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_09t51ao</bpmn:outgoing> + <bpmn:timerEventDefinition id="TimerEventDefinition_0vrbrge"> + <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT15S</bpmn:timeDuration> + </bpmn:timerEventDefinition> + </bpmn:intermediateCatchEvent> + <bpmn:endEvent id="EndEvent_0tei3i9"> + <bpmn:incoming>SequenceFlow_1rxbeqi</bpmn:incoming> + </bpmn:endEvent> + <bpmn:serviceTask id="ServiceTask_0y71su8" name=" Get node status " camunda:asyncAfter="true" camunda:expression="${MonitorInstantiateSol003AdapterNodeTask.getNodeStatus(execution)}"> + <bpmn:incoming>SequenceFlow_1moaz0q</bpmn:incoming> + <bpmn:incoming>SequenceFlow_09t51ao</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_0qvy3sn</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="SequenceFlow_1rxbeqi" name=" create vnf success " sourceRef="ExclusiveGateway_00xtlfj" targetRef="EndEvent_0tei3i9"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${execution.getVariable("createVnfNodeStatus")}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:sequenceFlow id="SequenceFlow_1luu31f" sourceRef="ExclusiveGateway_00xtlfj" targetRef="IntermediateCatchEvent_0xuznv9" /> + <bpmn:sequenceFlow id="SequenceFlow_1moaz0q" sourceRef="StartEvent_0r9qf43" targetRef="ServiceTask_0y71su8" /> + <bpmn:sequenceFlow id="SequenceFlow_0qvy3sn" sourceRef="ServiceTask_0y71su8" targetRef="ExclusiveGateway_00xtlfj" /> + <bpmn:sequenceFlow id="SequenceFlow_09t51ao" sourceRef="IntermediateCatchEvent_0xuznv9" targetRef="ServiceTask_0y71su8" /> + </bpmn:subProcess> + <bpmn:endEvent id="EndEvent_1b83rci" name="Timeout Exception"> + <bpmn:incoming>SequenceFlow_0uiqnl8</bpmn:incoming> + <bpmn:terminateEventDefinition id="TerminateEventDefinition_12rjfva" /> + </bpmn:endEvent> + <bpmn:serviceTask id="ServiceTask_12qp0ty" name=" Time Out Log Failure " camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterNodeTask.timeOutLogFailue(execution)}"> + <bpmn:incoming>SequenceFlow_0qcc5x4</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_0uiqnl8</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:boundaryEvent id="BoundaryEvent_1f5o5i9" name="Overall Wait" attachedToRef="SubProcess_10wotbc"> + <bpmn:outgoing>SequenceFlow_0qcc5x4</bpmn:outgoing> + <bpmn:timerEventDefinition id="TimerEventDefinition_1t3ya63"> + <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT3H</bpmn:timeDuration> + </bpmn:timerEventDefinition> + </bpmn:boundaryEvent> + <bpmn:sequenceFlow id="SequenceFlow_1miob62" sourceRef="StartEvent_0k0qfjb" targetRef="SubProcess_10wotbc" /> + <bpmn:sequenceFlow id="SequenceFlow_0uiqnl8" sourceRef="ServiceTask_12qp0ty" targetRef="EndEvent_1b83rci" /> + <bpmn:sequenceFlow id="SequenceFlow_0qcc5x4" sourceRef="BoundaryEvent_1f5o5i9" targetRef="ServiceTask_12qp0ty" /> + </bpmn:process> + <bpmndi:BPMNDiagram id="BPMNDiagram_1"> + <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="MonitorSol003AdapterCreateNodeStatus"> + <bpmndi:BPMNShape id="StartEvent_0k0qfjb_di" bpmnElement="StartEvent_0k0qfjb"> + <dc:Bounds x="155" y="159" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="SubProcess_10wotbc_di" bpmnElement="SubProcess_10wotbc" isExpanded="true"> + <dc:Bounds x="293" y="77" width="523" height="200" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="EndEvent_1b83rci_di" bpmnElement="EndEvent_1b83rci"> + <dc:Bounds x="1096" y="151" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1089" y="111" width="49" height="27" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="ServiceTask_12qp0ty_di" bpmnElement="ServiceTask_12qp0ty"> + <dc:Bounds x="917" y="129" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="BoundaryEvent_1f5o5i9_di" bpmnElement="BoundaryEvent_1f5o5i9"> + <dc:Bounds x="800" y="151" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="788" y="190" width="61" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="SequenceFlow_1miob62_di" bpmnElement="SequenceFlow_1miob62"> + <di:waypoint x="191" y="177" /> + <di:waypoint x="293" y="177" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_0uiqnl8_di" bpmnElement="SequenceFlow_0uiqnl8"> + <di:waypoint x="1017" y="169" /> + <di:waypoint x="1096" y="169" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_0qcc5x4_di" bpmnElement="SequenceFlow_0qcc5x4"> + <di:waypoint x="836" y="169" /> + <di:waypoint x="917" y="169" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="StartEvent_0r9qf43_di" bpmnElement="StartEvent_0r9qf43"> + <dc:Bounds x="324" y="135" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="ExclusiveGateway_00xtlfj_di" bpmnElement="ExclusiveGateway_00xtlfj" isMarkerVisible="true"> + <dc:Bounds x="603" y="128" width="50" height="50" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="IntermediateCatchEvent_0xuznv9_di" bpmnElement="IntermediateCatchEvent_0xuznv9"> + <dc:Bounds x="544" y="207" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="532" y="250" width="66" height="27" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="EndEvent_0tei3i9_di" bpmnElement="EndEvent_0tei3i9"> + <dc:Bounds x="716" y="135" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="ServiceTask_0y71su8_di" bpmnElement="ServiceTask_0y71su8"> + <dc:Bounds x="412" y="113" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="SequenceFlow_1rxbeqi_di" bpmnElement="SequenceFlow_1rxbeqi"> + <di:waypoint x="653" y="153" /> + <di:waypoint x="716" y="153" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="660" y="135" width="50" height="80" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_1luu31f_di" bpmnElement="SequenceFlow_1luu31f"> + <di:waypoint x="628" y="178" /> + <di:waypoint x="628" y="225" /> + <di:waypoint x="580" y="225" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_1moaz0q_di" bpmnElement="SequenceFlow_1moaz0q"> + <di:waypoint x="360" y="153" /> + <di:waypoint x="412" y="153" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_0qvy3sn_di" bpmnElement="SequenceFlow_0qvy3sn"> + <di:waypoint x="512" y="153" /> + <di:waypoint x="603" y="153" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_09t51ao_di" bpmnElement="SequenceFlow_09t51ao"> + <di:waypoint x="544" y="225" /> + <di:waypoint x="451" y="225" /> + <di:waypoint x="452" y="193" /> + </bpmndi:BPMNEdge> + </bpmndi:BPMNPlane> + </bpmndi:BPMNDiagram> +</bpmn:definitions> diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/BaseTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/BaseTest.java new file mode 100644 index 0000000000..86f2879966 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/BaseTest.java @@ -0,0 +1,150 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows; + +import static org.camunda.bpm.engine.history.HistoricProcessInstance.STATE_ACTIVE; +import static org.slf4j.LoggerFactory.getLogger; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import org.camunda.bpm.engine.HistoryService; +import org.camunda.bpm.engine.RuntimeService; +import org.camunda.bpm.engine.history.HistoricProcessInstance; +import org.camunda.bpm.engine.history.HistoricVariableInstance; +import org.camunda.bpm.engine.runtime.ProcessInstance; +import org.junit.runner.RunWith; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import com.github.tomakehurst.wiremock.WireMockServer; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +@ContextConfiguration +@AutoConfigureWireMock(port = 0) +public abstract class BaseTest { + protected static final String ETSI_CATALOG_URL = "http://modeling-etsicatalog.onap:8806/api"; + protected static final String SOL003_ADAPTER_ENDPOINT_URL = "https://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1"; + protected static final String GLOBAL_CUSTOMER_ID = UUID.randomUUID().toString(); + protected static final String NSD_INVARIANT_ID = UUID.randomUUID().toString(); + protected static final String SERVICE_TYPE = "NetworkService"; + protected static final String UUID_REGEX = + "[0-9a-zA-Z]{8}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{12}"; + protected static final String RANDOM_JOB_ID = UUID.randomUUID().toString(); + + protected static final Logger logger = getLogger(BaseTest.class); + + private static final long TIME_OUT_IN_SECONDS = 60; + private static final int SLEEP_TIME_IN_SECONDS = 5; + + @Autowired + private HistoryService historyService; + + @Autowired + private RuntimeService runtimeService; + + @Autowired + protected DatabaseServiceProvider databaseServiceProvider; + + @Autowired + protected WireMockServer wireMockServer; + + public NfvoJob createNewNfvoJob(final String jobAction, final String nsdId, final String nsName) { + final NfvoJob newJob = new NfvoJob().startTime(LocalDateTime.now()).jobType("NS").jobAction(JobAction.CREATE) + .status(JobStatusEnum.STARTING).resourceId(nsdId).resourceName(nsName); + databaseServiceProvider.addJob(newJob); + return newJob; + } + + public Optional<NfvoJob> getNfvoJob(final String jobId) { + return databaseServiceProvider.getJob(jobId); + } + + public Optional<NfvoJob> getJobByResourceId(final String resourceId) { + return databaseServiceProvider.getJobByResourceId(resourceId); + } + + public ProcessInstance executeWorkflow(final String processDefinitionKey, final String businessKey, + final Map<String, Object> variables) { + return runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variables); + } + + public HistoricProcessInstance getHistoricProcessInstance(final String processInstanceId) { + return historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); + } + + public HistoricVariableInstance getVariable(final String processInstanceId, final String name) { + return historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId) + .variableName(name).singleResult(); + } + + public List<HistoricVariableInstance> getVariables(final String processInstanceId) { + return historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).list(); + } + + public boolean waitForProcessInstanceToFinish(final String processInstanceId) throws InterruptedException { + final long startTimeInMillis = System.currentTimeMillis(); + final long timeOutTime = startTimeInMillis + TimeUnit.SECONDS.toMillis(TIME_OUT_IN_SECONDS); + while (timeOutTime > System.currentTimeMillis()) { + + if (isProcessEndedByProcessInstanceId(processInstanceId)) { + logger.info("processInstanceId: {} is finished", processInstanceId); + return true; + } + logger.info("processInstanceId: {} is still running", processInstanceId); + logger.info("Process instance {} not finished yet, will try again in {} seconds", processInstanceId, + SLEEP_TIME_IN_SECONDS); + TimeUnit.SECONDS.sleep(SLEEP_TIME_IN_SECONDS); + } + logger.warn("Timeout {} process didn't finished ", processInstanceId); + return false; + } + + + public boolean isProcessEndedByProcessInstanceId(final String processInstanceId) { + return !isProcessInstanceActive(processInstanceId) && isProcessInstanceEnded(processInstanceId); + } + + private boolean isProcessInstanceActive(final String processInstanceId) { + final HistoricProcessInstance processInstance = getHistoricProcessInstance(processInstanceId); + return processInstance != null && STATE_ACTIVE.equalsIgnoreCase(processInstance.getState()); + } + + private boolean isProcessInstanceEnded(final String processInstanceId) { + return runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult() == null; + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/DefaultToShortClassNameBeanNameGenerator.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/DefaultToShortClassNameBeanNameGenerator.java new file mode 100644 index 0000000000..f91cf9d0c3 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/DefaultToShortClassNameBeanNameGenerator.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.AnnotationBeanNameGenerator; +import org.springframework.util.ClassUtils; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class DefaultToShortClassNameBeanNameGenerator extends AnnotationBeanNameGenerator { + + @Override + protected String buildDefaultBeanName(final BeanDefinition definition) { + return ClassUtils.getShortName(definition.getBeanClassName()); + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/TestApplication.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/TestApplication.java new file mode 100644 index 0000000000..18d601930c --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/TestApplication.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.ComponentScan.Filter; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@SpringBootApplication(scanBasePackages = {"org.onap.so"}) +@EnableAutoConfiguration(exclude = {JacksonAutoConfiguration.class}) +@ComponentScan(basePackages = {"org.onap"}, nameGenerator = DefaultToShortClassNameBeanNameGenerator.class, + excludeFilters = {@Filter(type = FilterType.ANNOTATION, classes = SpringBootApplication.class)}) +public class TestApplication { + + public static void main(final String[] args) { + new SpringApplication(TestApplication.class).run(args); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParserTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParserTest.java new file mode 100644 index 0000000000..2bebf1c30a --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParserTest.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Map; +import java.util.Optional; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.TestApplication; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +public class NetworkServiceDescriptorParserTest { + + private static final String VALID_ETSI_NSD_FILE = "src/test/resources/ns.csar"; + private static final String INVALID_ETSI_NSD_FILE = "src/test/resources/invalid_ns.csar"; + + @Autowired + private NetworkServiceDescriptorParser objUnderTest; + + @Test + public void testValidEtsiNsd_ableToParseIt() throws IOException { + final byte[] zipBytes = Files.readAllBytes(Paths.get(getAbsolutePath(VALID_ETSI_NSD_FILE))); + final Optional<NetworkServiceDescriptor> optional = objUnderTest.parse(zipBytes); + assertTrue(optional.isPresent()); + final NetworkServiceDescriptor actualNsd = optional.get(); + assertEquals(NetworkServiceDescriptorParser.NS_NODE_TYPE, actualNsd.getType()); + assertFalse(actualNsd.getProperties().isEmpty()); + + final Map<String, Object> actualNsdProperties = actualNsd.getProperties(); + assertEquals(5, actualNsdProperties.size()); + assertEquals("ffdddc5d-a44b-45ae-8fc3-e6551cce350f", actualNsdProperties.get("descriptor_id")); + assertEquals(5, actualNsd.getVnfs().size()); + + } + + @Test + public void testEmptyEtsiNsd_returnEmptyOptional() throws IOException { + assertFalse(objUnderTest.parse(new byte[] {}).isPresent()); + } + + @Test + public void testInvalidEtsiNsd_returnEmptyOptional() throws IOException { + final byte[] zipBytes = Files.readAllBytes(Paths.get(getAbsolutePath(INVALID_ETSI_NSD_FILE))); + assertFalse(objUnderTest.parse(zipBytes).isPresent()); + } + + private String getAbsolutePath(final String path) { + final File file = new File(path); + return file.getAbsolutePath(); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/CreateNsTaskTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/CreateNsTaskTest.java new file mode 100644 index 0000000000..05213a344f --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/CreateNsTaskTest.java @@ -0,0 +1,387 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.workflow.engine.tasks; + +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.notFound; +import static com.github.tomakehurst.wiremock.client.WireMock.ok; +import static com.github.tomakehurst.wiremock.client.WireMock.put; +import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_REST_TEMPLATE_BEAN; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import org.camunda.bpm.engine.history.HistoricProcessInstance; +import org.camunda.bpm.engine.history.HistoricVariableInstance; +import org.camunda.bpm.engine.runtime.ProcessInstance; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.BaseTest; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.NsRequestProcessingException; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.JobExecutorService; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.WorkflowQueryService; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State; +import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance.NsStateEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestTemplate; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.google.gson.Gson; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class CreateNsTaskTest extends BaseTest { + private static final String NSD_ID = UUID.randomUUID().toString(); + private static final String NS_NAME = "CreateNetworkService-" + NSD_ID; + private static final String CREATE_NS_WORKFLOW_NAME = "CreateNs"; + + @Autowired + @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) + private RestTemplate restTemplate; + + @Autowired + private GsonProvider gsonProvider; + + @Autowired + private JobExecutorService objUnderTest; + + @Autowired + private WorkflowQueryService workflowQueryService; + + private MockRestServiceServer mockRestServiceServer; + + private Gson gson; + + @Before + public void before() { + wireMockServer.resetAll(); + final MockRestServiceServer.MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(restTemplate); + builder.ignoreExpectOrder(true); + mockRestServiceServer = builder.build(); + gson = gsonProvider.getGson(); + restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson)); + } + + @After + public void after() { + wireMockServer.resetAll(); + mockRestServiceServer.reset(); + } + + @Test + public void testCreateNsWorkflow_SuccessfullCase() throws InterruptedException { + final CreateNsRequest createNsRequest = getCreateNsRequest(); + + mockEtsiCatalogEndpoints(); + mockAAIEndpoints(createNsRequest); + + final NsInstancesNsInstance nsResponse = + objUnderTest.runCreateNsJob(createNsRequest, GLOBAL_CUSTOMER_ID, SERVICE_TYPE); + assertNotNull(nsResponse); + assertNotNull(nsResponse.getId()); + + final Optional<NfvoJob> optional = getJobByResourceId(createNsRequest.getNsdId()); + assertTrue(optional.isPresent()); + final NfvoJob nfvoJob = optional.get(); + + assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId())); + + mockRestServiceServer.verify(); + final HistoricProcessInstance historicProcessInstance = + getHistoricProcessInstance(nfvoJob.getProcessInstanceId()); + assertNotNull(historicProcessInstance); + + assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState()); + assertTrue(databaseServiceProvider.isNsInstExists(createNsRequest.getNsName())); + + final NfvoJob actualJob = optional.get(); + assertEquals(JobStatusEnum.FINISHED, actualJob.getStatus()); + + assertEquals(NS_NAME, nsResponse.getNsInstanceName()); + assertEquals(NsStateEnum.NOT_INSTANTIATED, nsResponse.getNsState()); + + final HistoricVariableInstance doesNsPackageExistsVar = + getVariable(nfvoJob.getProcessInstanceId(), "doesNsPackageExists"); + assertNotNull(doesNsPackageExistsVar); + assertTrue((boolean) doesNsPackageExistsVar.getValue()); + + final HistoricVariableInstance doesNsInstanceExistsVar = + getVariable(nfvoJob.getProcessInstanceId(), "doesNsInstanceExists"); + assertNotNull(doesNsInstanceExistsVar); + assertFalse((boolean) doesNsInstanceExistsVar.getValue()); + + } + + @Test + public void testCreateNsWorkflow_FailsToGetNsPackage() throws InterruptedException { + final String nsdId = UUID.randomUUID().toString(); + final String nsdName = NS_NAME + "-" + System.currentTimeMillis(); + final CreateNsRequest createNsRequest = getCreateNsRequest(nsdId, nsdName); + + mockRestServiceServer.expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId)) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.NOT_FOUND)); + + try { + objUnderTest.runCreateNsJob(createNsRequest, GLOBAL_CUSTOMER_ID, SERVICE_TYPE); + fail("runCreateNsJob should throw exception"); + } catch (final Exception exception) { + assertEquals(NsRequestProcessingException.class, exception.getClass()); + } + + final Optional<NfvoJob> optional = getJobByResourceId(createNsRequest.getNsdId()); + assertTrue(optional.isPresent()); + final NfvoJob nfvoJob = optional.get(); + assertEquals(JobStatusEnum.ERROR, nfvoJob.getStatus()); + + assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId())); + + mockRestServiceServer.verify(); + final HistoricProcessInstance historicProcessInstance = + getHistoricProcessInstance(nfvoJob.getProcessInstanceId()); + assertNotNull(historicProcessInstance); + + assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState()); + + + final HistoricVariableInstance nsResponseVariable = + getVariable(nfvoJob.getProcessInstanceId(), CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME); + assertNull(nsResponseVariable); + + final Optional<InlineResponse400> problemDetailsOptional = + workflowQueryService.getProblemDetails(nfvoJob.getProcessInstanceId()); + assertTrue(problemDetailsOptional.isPresent()); + + final InlineResponse400 problemDetails = problemDetailsOptional.get(); + assertNotNull(problemDetails); + assertNotNull(problemDetails.getDetail()); + + final HistoricVariableInstance doesNsPackageExistsVar = + getVariable(nfvoJob.getProcessInstanceId(), "doesNsPackageExists"); + assertNotNull(doesNsPackageExistsVar); + assertFalse((boolean) doesNsPackageExistsVar.getValue()); + assertEquals("Unexpected exception occured while getting ns package using nsdId: " + nsdId, + problemDetails.getDetail()); + } + + @Test + public void testCreateNsWorkflow_FailsToFindJobUsingJobId() throws InterruptedException { + final String nsdId = UUID.randomUUID().toString(); + final String nsdName = NS_NAME + "-" + System.currentTimeMillis(); + final CreateNsRequest createNsRequest = getCreateNsRequest(nsdId, nsdName); + + final String randomJobId = UUID.randomUUID().toString(); + final ProcessInstance processInstance = + executeWorkflow(CREATE_NS_WORKFLOW_NAME, randomJobId, getVariables(randomJobId, createNsRequest)); + assertTrue(waitForProcessInstanceToFinish(processInstance.getProcessInstanceId())); + + mockRestServiceServer.verify(); + final HistoricProcessInstance historicProcessInstance = + getHistoricProcessInstance(processInstance.getProcessInstanceId()); + assertNotNull(historicProcessInstance); + + assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState()); + + final HistoricVariableInstance nsResponseVariable = getVariable(processInstance.getProcessInstanceId(), + CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME); + + assertNull(nsResponseVariable); + + final HistoricVariableInstance workflowExceptionVariable = getVariable(processInstance.getProcessInstanceId(), + CamundaVariableNameConstants.CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME); + + final InlineResponse400 problemDetails = (InlineResponse400) workflowExceptionVariable.getValue(); + assertNotNull(problemDetails); + assertNotNull(problemDetails.getDetail()); + assertEquals("Unable to find job using job id: " + randomJobId, problemDetails.getDetail()); + + } + + @Test + public void testCreateNsWorkflow_NsInstanceExistsInDb() throws InterruptedException { + final String nsdId = UUID.randomUUID().toString(); + final String nsdName = NS_NAME + "-" + System.currentTimeMillis(); + final CreateNsRequest createNsRequest = getCreateNsRequest(nsdId, nsdName); + + databaseServiceProvider.saveNfvoNsInst(new NfvoNsInst().nsInstId(nsdId).name(createNsRequest.getNsName()) + .nsPackageId(UUID.randomUUID().toString()).nsdId(nsdId).nsdInvariantId(nsdId) + .description(createNsRequest.getNsDescription()).status(State.INSTANTIATED) + .statusUpdatedTime(LocalDateTime.now()).globalCustomerId(GLOBAL_CUSTOMER_ID).serviceType(SERVICE_TYPE)); + + mockEtsiCatalogEndpoints(nsdId); + + try { + objUnderTest.runCreateNsJob(createNsRequest, GLOBAL_CUSTOMER_ID, SERVICE_TYPE); + fail("runCreateNsJob should throw exception"); + } catch (final Exception exception) { + assertEquals(NsRequestProcessingException.class, exception.getClass()); + } + + final Optional<NfvoJob> optional = getJobByResourceId(createNsRequest.getNsdId()); + assertTrue(optional.isPresent()); + final NfvoJob nfvoJob = optional.get(); + assertEquals(JobStatusEnum.ERROR, nfvoJob.getStatus()); + + assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId())); + + mockRestServiceServer.verify(); + final HistoricProcessInstance historicProcessInstance = + getHistoricProcessInstance(nfvoJob.getProcessInstanceId()); + assertNotNull(historicProcessInstance); + + assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState()); + assertTrue(databaseServiceProvider.isNsInstExists(createNsRequest.getNsName())); + + final HistoricVariableInstance historicVariableInstance = + getVariable(nfvoJob.getProcessInstanceId(), CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME); + + assertNull(historicVariableInstance); + + final Optional<InlineResponse400> problemDetailsOptional = + workflowQueryService.getProblemDetails(nfvoJob.getProcessInstanceId()); + + final InlineResponse400 problemDetails = problemDetailsOptional.get(); + assertNotNull(problemDetails); + assertNotNull(problemDetails.getDetail()); + assertTrue(problemDetails.getDetail().startsWith("Ns Instance already exists in database")); + + final HistoricVariableInstance doesNsInstanceExistsVar = + getVariable(nfvoJob.getProcessInstanceId(), "doesNsInstanceExists"); + assertNotNull(doesNsInstanceExistsVar); + assertTrue((boolean) doesNsInstanceExistsVar.getValue()); + + } + + @Test + public void testCreateNsWorkflow_FailToCreateResouceInAai() throws InterruptedException { + final String nsdId = UUID.randomUUID().toString(); + final String nsdName = NS_NAME + "-" + System.currentTimeMillis(); + final CreateNsRequest createNsRequest = getCreateNsRequest(nsdId, nsdName); + + mockEtsiCatalogEndpoints(nsdId); + + final String modelEndpoint = getAiaServiceInstancelEndPoint(createNsRequest); + wireMockServer.stubFor(put(urlMatching(modelEndpoint)).willReturn(WireMock.serverError())); + wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(WireMock.serverError())); + + try { + objUnderTest.runCreateNsJob(createNsRequest, GLOBAL_CUSTOMER_ID, SERVICE_TYPE); + fail("runCreateNsJob should throw exception"); + } catch (final Exception exception) { + assertEquals(NsRequestProcessingException.class, exception.getClass()); + } + final Optional<NfvoJob> optional = getJobByResourceId(createNsRequest.getNsdId()); + assertTrue(optional.isPresent()); + final NfvoJob nfvoJob = optional.get(); + assertEquals(JobStatusEnum.ERROR, nfvoJob.getStatus()); + + mockRestServiceServer.verify(); + final HistoricProcessInstance historicProcessInstance = + getHistoricProcessInstance(nfvoJob.getProcessInstanceId()); + assertNotNull(historicProcessInstance); + + assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState()); + assertTrue(databaseServiceProvider.isNsInstExists(createNsRequest.getNsName())); + + final Optional<InlineResponse400> problemDetailsOptional = + workflowQueryService.getProblemDetails(nfvoJob.getProcessInstanceId()); + + final InlineResponse400 problemDetails = problemDetailsOptional.get(); + assertNotNull(problemDetails); + assertEquals("Unable to Create Service Instance in AAI", problemDetails.getDetail()); + + } + + private void mockAAIEndpoints(final CreateNsRequest createNsRequest) { + final String modelEndpoint = getAiaServiceInstancelEndPoint(createNsRequest); + + wireMockServer.stubFor(put(urlMatching(modelEndpoint)).willReturn(ok())); + wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(notFound())); + } + + private String getAiaServiceInstancelEndPoint(final CreateNsRequest createNsRequest) { + return "/aai/v[0-9]+/business/customers/customer/" + GLOBAL_CUSTOMER_ID + + "/service-subscriptions/service-subscription/" + SERVICE_TYPE + + "/service-instances/service-instance/.*"; + } + + private void mockEtsiCatalogEndpoints(final String nsdId) { + mockRestServiceServer.expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId)) + .andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(gson.toJson(getNSPackageModel(NSD_ID)), MediaType.APPLICATION_JSON)); + } + + private void mockEtsiCatalogEndpoints() { + mockEtsiCatalogEndpoints(NSD_ID);; + } + + private NsdInfo getNSPackageModel(final String nsdId) { + return new NsdInfo().id(nsdId).nsdId(nsdId).nsdInvariantId(NSD_INVARIANT_ID).nsdName("vcpe").nsdDesigner("ONAP") + .vnfPkgIds(Arrays.asList(GLOBAL_CUSTOMER_ID)); + } + + private CreateNsRequest getCreateNsRequest() { + return getCreateNsRequest(NSD_ID, NS_NAME); + } + + private CreateNsRequest getCreateNsRequest(final String nsdId, final String nsName) { + return new CreateNsRequest().nsdId(nsdId).nsName(nsName); + } + + private Map<String, Object> getVariables(final String jobId, final CreateNsRequest createNsRequest) { + final Map<String, Object> variables = new HashMap<>(); + variables.put(CamundaVariableNameConstants.JOB_ID_PARAM_NAME, jobId); + variables.put(CamundaVariableNameConstants.CREATE_NS_REQUEST_PARAM_NAME, createNsRequest); + variables.put(CamundaVariableNameConstants.GLOBAL_CUSTOMER_ID_PARAM_NAME, GLOBAL_CUSTOMER_ID); + variables.put(CamundaVariableNameConstants.SERVICE_TYPE_PARAM_NAME, SERVICE_TYPE); + + return variables; + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/InstantiateNsTaskTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/InstantiateNsTaskTest.java new file mode 100644 index 0000000000..00e9433eac --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/InstantiateNsTaskTest.java @@ -0,0 +1,327 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.workflow.engine.tasks; + +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.notFound; +import static com.github.tomakehurst.wiremock.client.WireMock.ok; +import static com.github.tomakehurst.wiremock.client.WireMock.okJson; +import static com.github.tomakehurst.wiremock.client.WireMock.put; +import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.onap.aaiclient.client.aai.AAIVersion.V19; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_REST_TEMPLATE_BEAN; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterConfiguration.SOL003_ADAPTER_REST_TEMPLATE_BEAN; +import static org.springframework.test.web.client.ExpectedCount.times; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import org.camunda.bpm.engine.history.HistoricProcessInstance; +import org.camunda.bpm.engine.history.HistoricVariableInstance; +import org.hamcrest.text.MatchesPattern; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.aaiclient.client.aai.entities.Results; +import org.onap.aaiclient.client.graphinventory.entities.Resource; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStatusRetrievalStatusEnum; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.BaseTest; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.JobExecutorService; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestTemplate; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; + +/** + * @author Andrew Lamb (andrew.a.lamb@est.tech) + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class InstantiateNsTaskTest extends BaseTest { + + private static final String TENANT_ID = "6ca8680feba04dad9254f423c6e28e1c"; + private static final String CLOUD_REGION = "regionOne"; + private static final String CLOUD_OWNER = "CloudOwner"; + private static final String UUID_REGEX = + "[0-9a-zA-Z]{8}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{12}"; + private static final String VCPE_VBRGEMU_VNFD_ID = "b1bb0ce7-2222-4fa7-95ed-4840d70a1102"; + private static final String VCPE_VBNG = "b1bb0ce7-2222-4fa7-95ed-4840d70a1101"; + private static final String VCPE_INFRA_VNFD_ID = "b1bb0ce7-2222-4fa7-95ed-4840d70a1100"; + private static final String VGMUX_VNFD_ID = "0408f076-e6c0-4c82-9940-272fddbb82de"; + private static final String VGW_VNFD_ID = "3fca3543-07f5-492f-812c-ed462e4f94f4"; + private static final String[] VCPE_VNFDS = + new String[] {VGW_VNFD_ID, VGMUX_VNFD_ID, VCPE_INFRA_VNFD_ID, VCPE_VBNG, VCPE_VBRGEMU_VNFD_ID}; + private static final String SAMPLE_NSD_FILE = "src/test/resources/ns.csar"; + private static final String NS_NAME = "InstantiateNetworkService"; + + @Autowired + private DatabaseServiceProvider databaseServiceProvider; + + @Autowired + @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) + private RestTemplate etsiCatalogRestTemplate; + + @Autowired + @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN) + private RestTemplate sol003AdapterRestTemplate; + + private MockRestServiceServer mockEtsiCatalogRestServiceServer; + + private MockRestServiceServer mockSol003AdapterRestServiceServer; + + @Autowired + private JobExecutorService objUnderTest; + + @Autowired + private GsonProvider gsonProvider; + + private Gson gson; + + private static final Map<String, String> VNFD_ID_TO_VNFPKG_ID_MAPPING = new HashMap<>(); + static { + for (final String vnfd : VCPE_VNFDS) { + VNFD_ID_TO_VNFPKG_ID_MAPPING.put(vnfd, UUID.randomUUID().toString()); + } + } + + @Before + public void before() { + wireMockServer.resetAll(); + gson = gsonProvider.getGson(); + + mockEtsiCatalogRestServiceServer = + MockRestServiceServer.bindTo(etsiCatalogRestTemplate).ignoreExpectOrder(true).build(); + mockSol003AdapterRestServiceServer = + MockRestServiceServer.bindTo(sol003AdapterRestTemplate).ignoreExpectOrder(true).build(); + + etsiCatalogRestTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson)); + sol003AdapterRestTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson)); + + } + + @After + public void after() { + wireMockServer.resetAll(); + mockEtsiCatalogRestServiceServer.reset(); + } + + @Test + public void testInstantiateNsWorkflow_JustUpdateStatus_SuccessfullCase() throws InterruptedException, IOException { + final String nsdId = UUID.randomUUID().toString(); + final String nsdName = NS_NAME + "-" + System.currentTimeMillis(); + + final NfvoNsInst newNfvoNsInst = new NfvoNsInst().nsInstId(nsdId).name(nsdName) + .nsPackageId(UUID.randomUUID().toString()).nsPackageId(nsdId).nsdId(nsdId).nsdInvariantId(nsdId) + .status(State.NOT_INSTANTIATED).statusUpdatedTime(LocalDateTime.now()); + + databaseServiceProvider.saveNfvoNsInst(newNfvoNsInst); + + mockSol003AdapterEndpoints(); + mockAAIEndpoints(nsdId); + mockEtsiCatalogEndpoints(nsdId); + + final String nsLcmOpOccId = + objUnderTest.runInstantiateNsJob(newNfvoNsInst.getNsInstId(), getInstantiateNsRequest()); + + final Optional<NfvoJob> optional = getJobByResourceId(newNfvoNsInst.getNsInstId()); + assertTrue(optional.isPresent()); + final NfvoJob nfvoJob = optional.get(); + + assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId())); + + final HistoricProcessInstance historicProcessInstance = + getHistoricProcessInstance(nfvoJob.getProcessInstanceId()); + assertNotNull(historicProcessInstance); + + assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState()); + + // check if value in database has updated + final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsdId); + final NfvoNsInst nfvoNsInst = optionalNfvoNsInst.get(); + assertEquals(State.INSTANTIATED, nfvoNsInst.getStatus()); + + final HistoricVariableInstance historicVariableInstance = + getVariable(nfvoJob.getProcessInstanceId(), NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME); + assertNotNull(historicVariableInstance); + final NetworkServiceDescriptor nsd = (NetworkServiceDescriptor) historicVariableInstance.getValue(); + assertNotNull(nsd); + + assertEquals(VNFD_ID_TO_VNFPKG_ID_MAPPING.size(), nsd.getVnfs().size()); + + final List<NfvoNfInst> nfvoNfInsts = databaseServiceProvider.getNfvoNfInstByNsInstId(nsdId); + assertNotNull(nsd); + assertEquals(VNFD_ID_TO_VNFPKG_ID_MAPPING.size(), nfvoNfInsts.size()); + + final Optional<NsLcmOpOcc> optionalNsLcmOpOcc = databaseServiceProvider.getNsLcmOpOcc(nsLcmOpOccId); + assertTrue(optionalNsLcmOpOcc.isPresent()); + + assertEquals(OperationStateEnum.COMPLETED, optionalNsLcmOpOcc.get().getOperationState()); + + final Map<String, NfvoNfInst> nfvoNfInstsMap = + nfvoNfInsts.stream().collect(Collectors.toMap(NfvoNfInst::getVnfdId, nfvoNfInst -> nfvoNfInst)); + + for (final Entry<String, String> entry : VNFD_ID_TO_VNFPKG_ID_MAPPING.entrySet()) { + assertTrue(nfvoNfInstsMap.containsKey(entry.getKey())); + assertEquals(State.INSTANTIATED, nfvoNfInstsMap.get(entry.getKey()).getStatus()); + + } + + } + + private void mockSol003AdapterEndpoints() { + mockSol003AdapterRestServiceServer + .expect(times(VNFD_ID_TO_VNFPKG_ID_MAPPING.size()), + requestTo(MatchesPattern.matchesPattern(SOL003_ADAPTER_ENDPOINT_URL + "/vnfs/.*"))) + .andExpect(method(HttpMethod.POST)) + .andRespond(withSuccess(gson.toJson(new CreateVnfResponse().jobId(UUID.randomUUID().toString())), + MediaType.APPLICATION_JSON)); + + mockSol003AdapterRestServiceServer + .expect(times(VNFD_ID_TO_VNFPKG_ID_MAPPING.size()), + requestTo(MatchesPattern.matchesPattern(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/.*"))) + .andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(gson.toJson( + new org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse().operationState( + org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum.COMPLETED) + .operationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.STATUS_FOUND)), + MediaType.APPLICATION_JSON)); + } + + private void mockEtsiCatalogEndpoints(final String nsdId) throws IOException { + mockEtsiCatalogRestServiceServer.expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId)) + .andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(gson.toJson(getNSPackageModel(nsdId)), MediaType.APPLICATION_JSON)); + mockEtsiCatalogRestServiceServer + .expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId + "/nsd_content")) + .andExpect(method(HttpMethod.GET)).andRespond(withSuccess( + getFileContent(getAbsolutePath(SAMPLE_NSD_FILE)), MediaType.APPLICATION_OCTET_STREAM)); + + for (final Entry<String, String> entry : VNFD_ID_TO_VNFPKG_ID_MAPPING.entrySet()) { + mockEtsiCatalogRestServiceServer + .expect(requestTo(ETSI_CATALOG_URL + "/vnfpkgm/v1/vnf_packages/" + entry.getValue())) + .andExpect(method(HttpMethod.GET)).andRespond(withSuccess( + gson.toJson(getVnfPkgInfo(entry.getKey(), entry.getValue())), MediaType.APPLICATION_JSON)); + } + + } + + private VnfPkgInfo getVnfPkgInfo(final String vnfdId, final String vnfPkgId) { + return new VnfPkgInfo().id(vnfPkgId).vnfdId(vnfdId); + } + + private InstantiateNsRequest getInstantiateNsRequest() { + final Map<String, Object> additionalParams = new HashMap<>(); + additionalParams.put("vim_id", CLOUD_OWNER + "_" + CLOUD_REGION + "_" + TENANT_ID); + + final InstantiateNsRequest instantiateNsRequest = new InstantiateNsRequest().nsFlavourId("default"); + + for (final Entry<String, String> entry : VNFD_ID_TO_VNFPKG_ID_MAPPING.entrySet()) { + instantiateNsRequest + .addAdditionalParamsForVnfItem(new NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf() + .vnfProfileId(entry.getValue()).additionalParams(additionalParams)); + } + + return instantiateNsRequest; + } + + private NsdInfo getNSPackageModel(final String nsdId) { + return new NsdInfo().id(nsdId).nsdId(nsdId).nsdInvariantId(NSD_INVARIANT_ID).nsdName("vcpe").nsdDesigner("ONAP") + .vnfPkgIds(new ArrayList<>(VNFD_ID_TO_VNFPKG_ID_MAPPING.values())); + } + + private byte[] getFileContent(final String path) throws IOException { + return Files.readAllBytes(Paths.get(path)); + } + + + private String getAbsolutePath(final String path) { + return new File(path).getAbsolutePath(); + } + + private void mockAAIEndpoints(final String nsdId) throws JsonProcessingException { + final String modelEndpoint = "/aai/" + V19 + "/network/generic-vnfs/generic-vnf/" + UUID_REGEX; + + wireMockServer.stubFor( + get(urlMatching(modelEndpoint + "\\?resultIndex=0&resultSize=1&format=count")).willReturn(notFound())); + + wireMockServer.stubFor(put(urlMatching(modelEndpoint)).willReturn(ok())); + wireMockServer.stubFor(put(urlMatching(modelEndpoint + "/relationship-list/relationship")).willReturn(ok())); + + wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(ok()) + .willReturn(okJson("{\"orchestration-status\": \"Created\"}"))); + + wireMockServer.stubFor(get(urlMatching("/aai/" + V19 + "/nodes/service-instances/service-instance/.*")) + .willReturn(okJson(getResourceResultsResponseAsJson(nsdId)))); + + wireMockServer.stubFor( + put(urlMatching("/aai/" + V19 + "/cloud-infrastructure/cloud-regions/cloud-region/" + CLOUD_OWNER + "/" + + CLOUD_REGION + "/tenants/tenant/" + TENANT_ID + "/relationship-list/relationship")) + .willReturn(ok())); + + } + + private String getResourceResultsResponseAsJson(final String nsdId) throws JsonProcessingException { + final Resource resource = new Resource(); + resource.setResourceType("service-instance"); + resource.setResourceLink("/aai/" + V19 + "/business/customers/customer/" + GLOBAL_CUSTOMER_ID + + "/service-subscriptions/service-subscription/NetworkService/service-instances/service-instance/" + + nsdId); + final Results<Resource> results = new Results<>(); + results.getResult().add(resource); + return new ObjectMapper().writeValueAsString(results); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/MonitorInstantiateSol003AdapterNodeTaskTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/MonitorInstantiateSol003AdapterNodeTaskTest.java new file mode 100644 index 0000000000..ea720cd73b --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/MonitorInstantiateSol003AdapterNodeTaskTest.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.workflow.engine.tasks; + +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.ok; +import static com.github.tomakehurst.wiremock.client.WireMock.okJson; +import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import org.camunda.bpm.engine.history.HistoricProcessInstance; +import org.camunda.bpm.engine.history.HistoricVariableInstance; +import org.camunda.bpm.engine.runtime.ProcessInstance; +import org.junit.Before; +import org.junit.Test; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.BaseTest; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks.MonitorInstantiateSol003AdapterNodeTask; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class MonitorInstantiateSol003AdapterNodeTaskTest extends BaseTest { + + private static final String RANDOWM_GENERIC_VNF_ID = UUID.randomUUID().toString(); + private static final String MONITOR_SOL003_ADAPTER_CREATE_NODE_STATUS_WORKFLOW = + "MonitorSol003AdapterCreateNodeStatus"; + + @Before + public void before() { + wireMockServer.resetAll(); + } + + @Test + public void testMonitorSol003AdapterCreateNodeStatus_SuccessfullCase() throws InterruptedException { + + final String modelEndpoint = "/aai/v[0-9]+/network/generic-vnfs/generic-vnf/" + UUID_REGEX; + + wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(ok()) + .willReturn(okJson("{\"orchestration-status\": \"Created\"}"))); + + + final ProcessInstance processInstance = executeWorkflow(MONITOR_SOL003_ADAPTER_CREATE_NODE_STATUS_WORKFLOW, + RANDOM_JOB_ID, getVariables(RANDOM_JOB_ID, RANDOWM_GENERIC_VNF_ID)); + + assertTrue(waitForProcessInstanceToFinish(processInstance.getProcessInstanceId())); + + final HistoricProcessInstance historicProcessInstance = + getHistoricProcessInstance(processInstance.getProcessInstanceId()); + assertNotNull(historicProcessInstance); + + assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState()); + + final HistoricVariableInstance nsResponseVariable = getVariable(processInstance.getProcessInstanceId(), + MonitorInstantiateSol003AdapterNodeTask.CREATE_VNF_NODE_STATUS); + + assertNotNull(nsResponseVariable); + assertTrue((boolean) nsResponseVariable.getValue()); + + } + + private Map<String, Object> getVariables(final String jobId, final String vnfId) { + final Map<String, Object> variables = new HashMap<>(); + variables.put(CamundaVariableNameConstants.JOB_ID_PARAM_NAME, jobId); + variables.put(CamundaVariableNameConstants.NF_INST_ID_PARAM_NAME, vnfId); + + return variables; + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/MonitorSol003AdapterCreateJobTaskTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/MonitorSol003AdapterCreateJobTaskTest.java new file mode 100644 index 0000000000..ff5c2a9105 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/MonitorSol003AdapterCreateJobTaskTest.java @@ -0,0 +1,156 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.workflow.engine.tasks; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum.COMPLETED; +import static org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStatusRetrievalStatusEnum.STATUS_FOUND; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterConfiguration.SOL003_ADAPTER_REST_TEMPLATE_BEAN; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; +import java.util.HashMap; +import java.util.Map; +import org.camunda.bpm.engine.history.HistoricProcessInstance; +import org.camunda.bpm.engine.history.HistoricVariableInstance; +import org.camunda.bpm.engine.runtime.ProcessInstance; +import org.junit.Before; +import org.junit.Test; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.BaseTest; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider; +import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestTemplate; +import com.google.gson.Gson; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class MonitorSol003AdapterCreateJobTaskTest extends BaseTest { + + private static final String MONITOR_SOL003_ADAPTER_CREATE_JOB_WORKFLOW = "MonitorSol003AdapterCreateJob"; + + @Autowired + @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN) + private RestTemplate restTemplate; + + @Autowired + private GsonProvider gsonProvider; + + private MockRestServiceServer mockRestServiceServer; + private Gson gson; + + @Before + public void before() { + wireMockServer.resetAll(); + final MockRestServiceServer.MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(restTemplate); + builder.ignoreExpectOrder(true); + mockRestServiceServer = builder.build(); + + gson = gsonProvider.getGson(); + restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson)); + } + + + @Test + public void testMonitorSol003AdapterCreateJobTaskWorkflow_SuccessfullCase() throws InterruptedException { + + mockRestServiceServer.expect(requestTo(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/" + RANDOM_JOB_ID)) + .andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(gson.toJson(getQueryJobResponse()), MediaType.APPLICATION_JSON)); + + final ProcessInstance processInstance = executeWorkflow(MONITOR_SOL003_ADAPTER_CREATE_JOB_WORKFLOW, + RANDOM_JOB_ID, getVariables(RANDOM_JOB_ID, new CreateVnfResponse().jobId(RANDOM_JOB_ID))); + + assertTrue(waitForProcessInstanceToFinish(processInstance.getProcessInstanceId())); + + final HistoricProcessInstance historicProcessInstance = + getHistoricProcessInstance(processInstance.getProcessInstanceId()); + assertNotNull(historicProcessInstance); + + assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState()); + + final HistoricVariableInstance nsResponseVariable = getVariable(processInstance.getProcessInstanceId(), + CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME); + + assertNotNull(nsResponseVariable); + assertEquals(COMPLETED, nsResponseVariable.getValue()); + + } + + @Test + public void testMonitorSol003AdapterCreateJobTaskWorkflow_FailurelCase() throws InterruptedException { + + mockRestServiceServer.expect(requestTo(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/" + RANDOM_JOB_ID)) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.NOT_FOUND)); + + final ProcessInstance processInstance = executeWorkflow(MONITOR_SOL003_ADAPTER_CREATE_JOB_WORKFLOW, + RANDOM_JOB_ID, getVariables(RANDOM_JOB_ID, new CreateVnfResponse().jobId(RANDOM_JOB_ID))); + + assertTrue(waitForProcessInstanceToFinish(processInstance.getProcessInstanceId())); + + final HistoricProcessInstance historicProcessInstance = + getHistoricProcessInstance(processInstance.getProcessInstanceId()); + assertNotNull(historicProcessInstance); + + assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState()); + + final HistoricVariableInstance nsResponseVariable = getVariable(processInstance.getProcessInstanceId(), + CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME); + + assertNull(nsResponseVariable); + + final HistoricVariableInstance workflowExceptionVariable = getVariable(processInstance.getProcessInstanceId(), + CamundaVariableNameConstants.CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME); + + final InlineResponse400 problemDetails = (InlineResponse400) workflowExceptionVariable.getValue(); + assertNotNull(problemDetails); + assertNotNull(problemDetails.getDetail()); + } + + + private QueryJobResponse getQueryJobResponse() { + return new QueryJobResponse().id(RANDOM_JOB_ID).operationState(COMPLETED) + .operationStatusRetrievalStatus(STATUS_FOUND); + } + + private Map<String, Object> getVariables(final String jobId, final CreateVnfResponse createVnfResponse) { + final Map<String, Object> variables = new HashMap<>(); + variables.put(CamundaVariableNameConstants.JOB_ID_PARAM_NAME, jobId); + variables.put(CamundaVariableNameConstants.CREATE_VNF_RESPONSE_PARAM_NAME, createVnfResponse); + + return variables; + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml new file mode 100644 index 0000000000..1fabfbaac9 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml @@ -0,0 +1,49 @@ +# Copyright © 2020 Nordix Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +spring: + main: + allow-bean-definition-overriding: true + datasource: + hikari: + camunda: + jdbcUrl: jdbc:h2:mem:example-simple;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + driver-class-name: org.h2.Driver + pool-name: ns-lcm-bpmn-pool + registerMbeans: true + nfvo: + jdbcUrl: jdbc:h2:mem:nfvo;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS nfvo; + driver-class-name: org.h2.Driver + pool-name: ns-lcm-bpmn-pool + registerMbeans: true + jpa: + generate-ddl: true + hibernate: + ddl-auto: create +hibernate: + dialect: org.hibernate.dialect.H2Dialect + hbm2ddl: + auto: create +aai: + version: v19 + endpoint: http://localhost:${wiremock.server.port} +etsi-catalog-manager: + base: + endpoint: http://modeling-etsicatalog.onap:8806/api +so-etsi-ns-lcm-workflow-engine: + requesttimeout: + timeoutInSeconds: 60 + +logging: + level: + org.reflections.Reflections: ERROR
\ No newline at end of file diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/invalid_ns.csar b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/invalid_ns.csar Binary files differnew file mode 100644 index 0000000000..63bad965b7 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/invalid_ns.csar diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csar b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csar Binary files differnew file mode 100644 index 0000000000..eb19c762ae --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csar diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/pom.xml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/pom.xml index 8e1fba43f0..e0439073bb 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/pom.xml +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/pom.xml @@ -8,4 +8,28 @@ </parent> <artifactId>so-etsi-nfvo-ns-lcm-database-service</artifactId> <name>SO ETSI NFVO NS LCM Database Service</name> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-jpa</artifactId> + </dependency> + <dependency> + <groupId>org.mariadb.jdbc</groupId> + <artifactId>mariadb-java-client</artifactId> + </dependency> + <dependency> + <groupId>org.flywaydb</groupId> + <artifactId>flyway-core</artifactId> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + </dependencies> </project>
\ No newline at end of file diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobAction.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobAction.java new file mode 100644 index 0000000000..8a22689f8a --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobAction.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.beans; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public enum JobAction { + CREATE, INSTANTIATE, TERMINATE, DELETE; + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobStatusEnum.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobStatusEnum.java new file mode 100644 index 0000000000..c67a3cc692 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/JobStatusEnum.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.beans; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public enum JobStatusEnum { + STARTING, STARTED, IN_PROGRESS, ERROR, FINISHED, FINISHED_WITH_ERROR; + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJob.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJob.java new file mode 100644 index 0000000000..9453caac9e --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJob.java @@ -0,0 +1,274 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.beans; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils; + + +@Entity +@Table(name = "JOB") +public class NfvoJob { + + @Id + @Column(name = "JOB_ID") + private String jobId; + + @Column(name = "JOB_TYPE") + private String jobType; + + @Enumerated(EnumType.STRING) + @Column(name = "JOB_ACTION") + private JobAction jobAction; + + @Column(name = "RESOURCE_ID") + private String resourceId; + + @Column(name = "RESOURCE_NAME") + private String resourceName; + + @Enumerated(EnumType.STRING) + @Column(name = "STATUS") + private JobStatusEnum status; + + @Column(name = "START_TIME") + private LocalDateTime startTime; + + @Column(name = "END_TIME") + private LocalDateTime endTime; + + @Column(name = "PROGRESS") + private int progress; + + @Column(name = "PROCESS_INSTANCE_ID") + private String processInstanceId; + + @OneToMany(mappedBy = "nfvoJob", cascade = CascadeType.ALL, fetch = FetchType.EAGER) + private List<NfvoJobStatus> nfvoJobStatuses = new ArrayList<>(); + + public NfvoJob() { + this.jobId = UUID.randomUUID().toString(); + } + + public void setJobId(final String jobId) { + this.jobId = jobId; + } + + public String getJobId() { + return jobId; + } + + public NfvoJob jobId(final String jobId) { + this.jobId = jobId; + return this; + } + + public String getJobType() { + return jobType; + } + + public void setJobType(final String jobType) { + this.jobType = jobType; + } + + public NfvoJob jobType(final String jobType) { + this.jobType = jobType; + return this; + } + + public JobAction getJobAction() { + return jobAction; + } + + public void setJobAction(final JobAction jobAction) { + this.jobAction = jobAction; + } + + public NfvoJob jobAction(final JobAction jobAction) { + this.jobAction = jobAction; + return this; + } + + public String getResourceId() { + return resourceId; + } + + public void setResourceId(final String resourceId) { + this.resourceId = resourceId; + } + + public NfvoJob resourceId(final String resourceId) { + this.resourceId = resourceId; + return this; + } + + public JobStatusEnum getStatus() { + return status; + } + + public void setStatus(final JobStatusEnum status) { + this.status = status; + } + + public NfvoJob status(final JobStatusEnum status) { + this.status = status; + return this; + } + + public LocalDateTime getStartTime() { + return startTime; + } + + public void setStartTime(final LocalDateTime startTime) { + this.startTime = startTime; + } + + public NfvoJob startTime(final LocalDateTime startTime) { + this.startTime = startTime; + return this; + } + + public LocalDateTime getEndTime() { + return endTime; + } + + public void setEndTime(final LocalDateTime endTime) { + this.endTime = endTime; + } + + public NfvoJob endTime(final LocalDateTime endTime) { + this.endTime = endTime; + return this; + } + + public int getProgress() { + return progress; + } + + public void setProgress(final int progress) { + this.progress = progress; + } + + public NfvoJob progress(final int progress) { + this.progress = progress; + return this; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(final String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public NfvoJob processInstanceId(final String processInstanceId) { + this.processInstanceId = processInstanceId; + return this; + } + + public String getResourceName() { + return resourceName; + } + + public void setResourceName(final String resourceName) { + this.resourceName = resourceName; + } + + public NfvoJob resourceName(final String resourceName) { + this.resourceName = resourceName; + return this; + } + + public List<NfvoJobStatus> getNfvoJobStatuses() { + return nfvoJobStatuses; + } + + public void setJobStatuses(final List<NfvoJobStatus> nfvoJobStatuses) { + this.nfvoJobStatuses = nfvoJobStatuses; + } + + public NfvoJob nfvoJobStatuses(final List<NfvoJobStatus> nfvoJobStatuses) { + this.nfvoJobStatuses = nfvoJobStatuses; + return this; + } + + public NfvoJob nfvoJobStatus(final NfvoJobStatus nfvoJobStatus) { + nfvoJobStatus.setNfvoJob(this); + this.nfvoJobStatuses.add(nfvoJobStatus); + return this; + } + + @Override + public int hashCode() { + return Objects.hash(jobId, processInstanceId, jobType, jobAction, startTime, endTime, status, progress, + resourceId, resourceName, nfvoJobStatuses); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof NfvoJob) { + final NfvoJob other = (NfvoJob) obj; + return Objects.equals(jobId, other.jobId) && Objects.equals(processInstanceId, other.processInstanceId) + && Objects.equals(jobType, other.jobType) && Objects.equals(jobAction, other.jobAction) + && Objects.equals(progress, other.progress) && Objects.equals(status, other.status) + && Objects.equals(startTime, other.startTime) && Objects.equals(endTime, other.endTime) + && Objects.equals(status, other.status) && Objects.equals(resourceId, other.resourceId) + && Objects.equals(resourceName, other.resourceName) + && Utils.isEquals(nfvoJobStatuses, other.nfvoJobStatuses); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class NfvoJob {\n"); + sb.append(" jobId: ").append(toIndentedString(jobId)).append("\n"); + sb.append(" processInstanceId: ").append(toIndentedString(processInstanceId)).append("\n"); + sb.append(" jobType: ").append(toIndentedString(jobType)).append("\n"); + sb.append(" jobAction: ").append(toIndentedString(jobAction)).append("\n"); + sb.append(" progress: ").append(toIndentedString(progress)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" startTime: ").append(toIndentedString(startTime)).append("\n"); + sb.append(" endTime: ").append(toIndentedString(endTime)).append("\n"); + sb.append(" resId: ").append(toIndentedString(resourceId)).append("\n"); + sb.append(" resName: ").append(toIndentedString(resourceName)).append("\n"); + sb.append(" nfvoJobStatuses: ").append(toIndentedString(nfvoJobStatuses)).append("\n"); + + sb.append("}"); + return sb.toString(); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJobStatus.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJobStatus.java new file mode 100644 index 0000000000..89e07701ed --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoJobStatus.java @@ -0,0 +1,147 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.beans; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.time.LocalDateTime; +import java.util.Objects; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "JOB_STATUS") +public class NfvoJobStatus { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "ID") + private int id; + + @Enumerated(EnumType.STRING) + @Column(name = "STATUS") + private JobStatusEnum status; + + @Column(name = "DESCRIPTION", columnDefinition = "LONGTEXT") + private String description; + + @Column(name = "UPDATED_TIME") + private LocalDateTime updatedTime; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "JOB_ID") + private NfvoJob nfvoJob; + + public int getId() { + return id; + } + + public JobStatusEnum getStatus() { + return status; + } + + public void setStatus(final JobStatusEnum status) { + this.status = status; + } + + public NfvoJobStatus status(final JobStatusEnum status) { + this.status = status; + return this; + } + + public String getDescription() { + return description; + } + + public void setDescription(final String description) { + this.description = description; + } + + public NfvoJobStatus description(final String description) { + this.description = description; + return this; + } + + public LocalDateTime getUpdatedTime() { + return updatedTime; + } + + public void setUpdatedTime(final LocalDateTime updatedTime) { + this.updatedTime = updatedTime; + } + + public NfvoJobStatus updatedTime(final LocalDateTime addTime) { + this.updatedTime = addTime; + return this; + } + + public NfvoJob getNfvoJob() { + return nfvoJob; + } + + public void setNfvoJob(final NfvoJob nfvoJob) { + this.nfvoJob = nfvoJob; + } + + public NfvoJobStatus nfvoJob(final NfvoJob nfvoJob) { + this.nfvoJob = nfvoJob; + return this; + } + + + @Override + public int hashCode() { + return Objects.hash(id, status, updatedTime, description, nfvoJob.getJobId()); + } + + @Override + public boolean equals(final Object obj) { + + if (obj instanceof NfvoJobStatus) { + final NfvoJobStatus other = (NfvoJobStatus) obj; + return Objects.equals(id, other.id) && Objects.equals(status, other.status) + && Objects.equals(updatedTime, other.updatedTime) && Objects.equals(description, other.description) + && Objects.equals(nfvoJob.getJobId(), other.nfvoJob.getJobId()); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class NfvoJobStatus {\n"); + sb.append(" Id: ").append(toIndentedString(id)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" descp: ").append(toIndentedString(description)).append("\n"); + sb.append(" updatedTime: ").append(toIndentedString(updatedTime)).append("\n"); + sb.append(" jobId: ").append(nfvoJob != null ? toIndentedString(nfvoJob.getJobId()) : "").append("\n"); + sb.append("}"); + return sb.toString(); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNfInst.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNfInst.java new file mode 100644 index 0000000000..e901e10596 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNfInst.java @@ -0,0 +1,213 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.beans; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.time.LocalDateTime; +import java.util.Objects; +import java.util.UUID; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * @author mukeshsharma (mukeshsharma@est.tech) + */ +@Entity +@Table(name = "NF_INST") +public class NfvoNfInst { + + @Id + @Column(name = "NF_INST_ID") + private String nfInstId; + + @Column(name = "NAME") + private String name; + + @Column(name = "VNFD_ID") + private String vnfdId; + + @Column(name = "PACKAGE_ID") + private String packageId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "NS_INST_ID") + private NfvoNsInst nsInst; + + @Enumerated(EnumType.STRING) + @Column(name = "STATUS") + private State status; + + @Column(name = "CREATE_TIME") + private LocalDateTime createTime; + + @Column(name = "LAST_UPDATE_TIME") + private LocalDateTime lastUpdateTime; + + public NfvoNfInst() { + this.nfInstId = UUID.randomUUID().toString(); + } + + public String getNfInstId() { + return nfInstId; + } + + public void setNfInstId(final String nfInstId) { + this.nfInstId = nfInstId; + } + + public NfvoNfInst nfInstId(final String nfInstId) { + this.nfInstId = nfInstId; + return this; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public NfvoNfInst name(final String name) { + this.name = name; + return this; + } + + public String getVnfdId() { + return vnfdId; + } + + public void setVnfdId(final String vnfdId) { + this.vnfdId = vnfdId; + } + + public NfvoNfInst vnfdId(final String vnfdId) { + this.vnfdId = vnfdId; + return this; + } + + public String getPackageId() { + return packageId; + } + + public void setPackageId(final String packageId) { + this.packageId = packageId; + } + + public NfvoNfInst packageId(final String packageId) { + this.packageId = packageId; + return this; + } + + public NfvoNsInst getNsInst() { + return nsInst; + } + + public void setNsInst(final NfvoNsInst nsInst) { + this.nsInst = nsInst; + } + + public NfvoNfInst nfvoNsInst(final NfvoNsInst nfvoNsInst) { + this.nsInst = nfvoNsInst; + return this; + } + + public State getStatus() { + return status; + } + + public void setStatus(final State status) { + this.status = status; + } + + public NfvoNfInst status(final State status) { + this.status = status; + return this; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(final LocalDateTime createTime) { + this.createTime = createTime; + } + + public NfvoNfInst createTime(final LocalDateTime createTime) { + this.createTime = createTime; + return this; + } + + public LocalDateTime getLastUpdateTime() { + return lastUpdateTime; + } + + public void setLastUpdateTime(final LocalDateTime lastUpdateTime) { + this.lastUpdateTime = lastUpdateTime; + } + + public NfvoNfInst lastUpdateTime(final LocalDateTime lastUpdateTime) { + this.lastUpdateTime = lastUpdateTime; + return this; + } + + @Override + public boolean equals(final Object object) { + if (this == object) + return true; + if (object == null || getClass() != object.getClass()) + return false; + final NfvoNfInst that = (NfvoNfInst) object; + return Objects.equals(nfInstId, that.nfInstId) && Objects.equals(name, that.name) + && Objects.equals(vnfdId, that.vnfdId) && Objects.equals(packageId, that.packageId) + && Objects.equals(nsInst, that.nsInst) && Objects.equals(status, that.status) + && Objects.equals(createTime, that.createTime) && Objects.equals(lastUpdateTime, that.lastUpdateTime); + } + + @Override + public int hashCode() { + return Objects.hash(nfInstId, name, vnfdId, packageId, nsInst, status, createTime, lastUpdateTime); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class NfvoNfInst {\n"); + sb.append(" nfInstId: ").append(toIndentedString(nfInstId)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" vnfdId: ").append(toIndentedString(vnfdId)).append("\n"); + sb.append(" packageId: ").append(toIndentedString(packageId)).append("\n"); + sb.append(" nsInst: ").append(nsInst != null ? toIndentedString(nsInst.getNsInstId()) : null).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" createTime: ").append(toIndentedString(createTime)).append("\n"); + sb.append(" lastUpdateTime: ").append(toIndentedString(lastUpdateTime)).append("\n"); + + sb.append("}"); + return sb.toString(); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNsInst.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNsInst.java new file mode 100644 index 0000000000..dd8448fe56 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NfvoNsInst.java @@ -0,0 +1,289 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.beans; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Entity +@Table(name = "NS_INST") +public class NfvoNsInst { + + @Id + @Column(name = "NS_INST_ID") + private String nsInstId; + + @Column(name = "NAME") + private String name; + + @Column(name = "NS_PACKAGE_ID") + private String nsPackageId; + + @Column(name = "NSD_ID") + private String nsdId; + + @Column(name = "NSD_INVARIANT_ID") + private String nsdInvariantId; + + @Column(name = "DESCRIPTION", columnDefinition = "LONGTEXT") + private String description; + + @Enumerated(EnumType.STRING) + @Column(name = "STATUS") + private State status; + + @Column(name = "STATUS_UPDATED_TIME") + private LocalDateTime statusUpdatedTime; + + @Column(name = "GLOBAL_CUSTOMER_ID") + private String globalCustomerId; + + @Column(name = "SERVICE_TYPE") + private String serviceType; + + @OneToMany(mappedBy = "nsInst", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private List<NfvoNfInst> nfvoNfInsts = new ArrayList<>(); + + @OneToMany(mappedBy = "nfvoNsInst", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private List<NsLcmOpOcc> nsLcmOpOccs = new ArrayList<>(); + + public NfvoNsInst() { + this.nsInstId = UUID.randomUUID().toString(); + } + + public String getNsInstId() { + return nsInstId; + } + + public void setNsInstId(final String nsInstId) { + this.nsInstId = nsInstId; + } + + public NfvoNsInst nsInstId(final String nsInstId) { + this.nsInstId = nsInstId; + return this; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public NfvoNsInst name(final String name) { + this.name = name; + return this; + } + + public String getNsPackageId() { + return nsPackageId; + } + + public void setNsPackageId(final String nsPackageId) { + this.nsPackageId = nsPackageId; + } + + public NfvoNsInst nsPackageId(final String nsPackageId) { + this.nsPackageId = nsPackageId; + return this; + } + + public String getNsdId() { + return nsdId; + } + + public void setNsdId(final String nsdId) { + this.nsdId = nsdId; + } + + public NfvoNsInst nsdId(final String nsdId) { + this.nsdId = nsdId; + return this; + } + + public String getNsdInvariantId() { + return nsdInvariantId; + } + + public void setNsdInvariantId(final String nsdInvariantId) { + this.nsdInvariantId = nsdInvariantId; + } + + public NfvoNsInst nsdInvariantId(final String nsdInvariantId) { + this.nsdInvariantId = nsdInvariantId; + return this; + } + + public String getDescription() { + return description; + } + + public void setDescription(final String description) { + this.description = description; + } + + public NfvoNsInst description(final String description) { + this.description = description; + return this; + } + + public State getStatus() { + return status; + } + + public void setStatus(final State status) { + this.status = status; + } + + public NfvoNsInst status(final State status) { + this.status = status; + return this; + } + + public LocalDateTime getStatusUpdatedTime() { + return statusUpdatedTime; + } + + public void setStatusUpdatedTime(final LocalDateTime statusUpdatedTime) { + this.statusUpdatedTime = statusUpdatedTime; + } + + public NfvoNsInst statusUpdatedTime(final LocalDateTime statusUpdatedTime) { + this.statusUpdatedTime = statusUpdatedTime; + return this; + } + + public String getGlobalCustomerId() { + return globalCustomerId; + } + + public void setGlobalCustomerId(final String globalCustomerId) { + this.globalCustomerId = globalCustomerId; + } + + public NfvoNsInst globalCustomerId(final String globalCustomerId) { + this.globalCustomerId = globalCustomerId; + return this; + } + + public String getServiceType() { + return serviceType; + } + + public void setServiceType(final String serviceType) { + this.serviceType = serviceType; + } + + public NfvoNsInst serviceType(final String serviceType) { + this.serviceType = serviceType; + return this; + } + + public List<NfvoNfInst> getNfvoNfInsts() { + return nfvoNfInsts; + } + + public void setNfvoNfInsts(final List<NfvoNfInst> nfvoNfInsts) { + this.nfvoNfInsts = nfvoNfInsts; + } + + public NfvoNsInst nfvoNfInsts(final NfvoNfInst nfvoNfInsts) { + nfvoNfInsts.nfvoNsInst(this); + this.nfvoNfInsts.add(nfvoNfInsts); + return this; + } + + public List<NsLcmOpOcc> getNsLcmOpOccs() { + return nsLcmOpOccs; + } + + public void setNsLcmOpOccs(final List<NsLcmOpOcc> nsLcmOpOccs) { + this.nsLcmOpOccs = nsLcmOpOccs; + } + + public NfvoNsInst nsLcmOpOccs(final NsLcmOpOcc nsLcmOpOcc) { + nsLcmOpOcc.nfvoNsInst(this); + this.nsLcmOpOccs.add(nsLcmOpOcc); + return this; + } + + @Override + public int hashCode() { + return Objects.hash(nsInstId, name, nsPackageId, nsdId, nsdInvariantId, description, status, statusUpdatedTime, + globalCustomerId, serviceType, nfvoNfInsts, nsLcmOpOccs); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof NfvoNsInst) { + final NfvoNsInst other = (NfvoNsInst) obj; + return Objects.equals(nsInstId, other.nsInstId) && Objects.equals(name, other.name) + && Objects.equals(nsPackageId, other.nsPackageId) && Objects.equals(nsdId, other.nsdId) + && Objects.equals(nsdInvariantId, other.nsdInvariantId) + && Objects.equals(description, other.description) && Objects.equals(status, other.status) + && Objects.equals(statusUpdatedTime, other.statusUpdatedTime) + && Objects.equals(globalCustomerId, other.globalCustomerId) + && Objects.equals(serviceType, other.serviceType) && Objects.equals(nfvoNfInsts, other.nfvoNfInsts) + && Objects.equals(nsLcmOpOccs, other.nsLcmOpOccs); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class NfvoNsInst {\n"); + sb.append(" nsInstId: ").append(toIndentedString(nsInstId)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" nsPackageId: ").append(toIndentedString(nsPackageId)).append("\n"); + sb.append(" nsdId: ").append(toIndentedString(nsdId)).append("\n"); + sb.append(" nsdInvariantId: ").append(toIndentedString(nsdInvariantId)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" statusUpdatedTime: ").append(toIndentedString(statusUpdatedTime)).append("\n"); + sb.append(" globalCustomerId: ").append(toIndentedString(globalCustomerId)).append("\n"); + sb.append(" serviceType: ").append(toIndentedString(serviceType)).append("\n"); + sb.append(" nfvoNfInsts: ").append(toIndentedString(nfvoNfInsts)).append("\n"); + sb.append(" nsLcmOpOccs: ").append(toIndentedString(nsLcmOpOccs)).append("\n"); + + sb.append("}"); + return sb.toString(); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpOcc.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpOcc.java new file mode 100644 index 0000000000..cb8f92070a --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpOcc.java @@ -0,0 +1,233 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.beans; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.time.LocalDateTime; +import java.util.Objects; +import java.util.UUID; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * @author mukeshsharma(mukeshsharma@est.tech) + */ +@Entity +@Table(name = "NS_LCM_OP_OCCS") +public class NsLcmOpOcc { + + @Id + @Column(name = "ID") + private String id; + + @Enumerated(EnumType.STRING) + @Column(name = "OPERATION_STATE") + private OperationStateEnum operationState; + + @Column(name = "STATE_ENTERED_TIME") + private LocalDateTime stateEnteredTime; + + @Column(name = "START_TIME") + private LocalDateTime startTime; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "NS_INST_ID") + private NfvoNsInst nfvoNsInst; + + @Enumerated(EnumType.STRING) + @Column(name = "OPERATION") + private NsLcmOpType operation; + + @Column(name = "IS_AUTO_INNOVATION") + private boolean isAutoInnovation; + + @Column(name = "OPERATION_PARAMS", columnDefinition = "LONGTEXT") + private String operationParams; + + @Column(name = "IS_CANCEL_PENDING") + private boolean isCancelPending; + + public NsLcmOpOcc() { + this.id = UUID.randomUUID().toString(); + } + + public String getId() { + return id; + } + + public void setId(final String id) { + this.id = id; + } + + public NsLcmOpOcc id(final String id) { + this.id = id; + return this; + } + + public OperationStateEnum getOperationState() { + return operationState; + } + + public void setOperationState(final OperationStateEnum operationState) { + this.operationState = operationState; + } + + public NsLcmOpOcc operationState(final OperationStateEnum operationState) { + this.operationState = operationState; + return this; + } + + public LocalDateTime getStateEnteredTime() { + return stateEnteredTime; + } + + public void setStateEnteredTime(final LocalDateTime stateEnteredTime) { + this.stateEnteredTime = stateEnteredTime; + } + + public NsLcmOpOcc stateEnteredTime(final LocalDateTime stateEnteredTime) { + this.stateEnteredTime = stateEnteredTime; + return this; + } + + public LocalDateTime getStartTime() { + return startTime; + } + + public void setStartTime(final LocalDateTime startTime) { + this.startTime = startTime; + } + + public NsLcmOpOcc startTime(final LocalDateTime startTime) { + this.startTime = startTime; + return this; + } + + public NfvoNsInst getNfvoNsInst() { + return nfvoNsInst; + } + + public void setNfvoNsInst(final NfvoNsInst nfvoNsInst) { + this.nfvoNsInst = nfvoNsInst; + } + + public NsLcmOpOcc nfvoNsInst(final NfvoNsInst nfvoNsInst) { + this.nfvoNsInst = nfvoNsInst; + return this; + } + + public NsLcmOpType getOperation() { + return operation; + } + + public void setOperation(final NsLcmOpType operation) { + this.operation = operation; + } + + public NsLcmOpOcc operation(final NsLcmOpType operation) { + this.operation = operation; + return this; + } + + public boolean getIsAutoInnovation() { + return isAutoInnovation; + } + + public void setIsAutoInnovation(final boolean isAutoInnovation) { + this.isAutoInnovation = isAutoInnovation; + } + + public NsLcmOpOcc isAutoInnovation(final boolean isAutoInnovation) { + this.isAutoInnovation = isAutoInnovation; + return this; + } + + public String getOperationParams() { + return operationParams; + } + + public void setOperationParams(final String operationParams) { + this.operationParams = operationParams; + } + + public NsLcmOpOcc operationParams(final String operationParams) { + this.operationParams = operationParams; + return this; + } + + public boolean getIsCancelPending() { + return isCancelPending; + } + + public void setIsCancelPending(final boolean isCancelPending) { + this.isCancelPending = isCancelPending; + } + + public NsLcmOpOcc isCancelPending(final boolean isCancelPending) { + this.isCancelPending = isCancelPending; + return this; + } + + @Override + public boolean equals(final Object object) { + if (this == object) + return true; + if (object == null || getClass() != object.getClass()) + return false; + final NsLcmOpOcc that = (NsLcmOpOcc) object; + return Objects.equals(id, that.id) && Objects.equals(operationState, that.operationState) + && Objects.equals(stateEnteredTime, that.stateEnteredTime) && Objects.equals(startTime, that.startTime) + && Objects.equals(nfvoNsInst, that.nfvoNsInst) && Objects.equals(operation, that.operation) + && Objects.equals(isAutoInnovation, that.isAutoInnovation) + && Objects.equals(operationParams, that.operationParams) + && Objects.equals(isCancelPending, that.isCancelPending); + } + + @Override + public int hashCode() { + return Objects.hash(id, operationState, stateEnteredTime, startTime, nfvoNsInst, operation, isAutoInnovation, + operationParams, isCancelPending); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class NfvoNsInst {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" operationState: ").append(toIndentedString(operationState)).append("\n"); + sb.append(" stateEnteredTime: ").append(toIndentedString(stateEnteredTime)).append("\n"); + sb.append(" startTime: ").append(toIndentedString(startTime)).append("\n"); + sb.append(" nfvoNsInst: ").append(nfvoNsInst != null ? toIndentedString(nfvoNsInst.getNsInstId()) : null) + .append("\n"); + sb.append(" operation: ").append(toIndentedString(operation)).append("\n"); + sb.append(" isAutoInnovation: ").append(toIndentedString(isAutoInnovation)).append("\n"); + sb.append(" operationParams: ").append(toIndentedString(operationParams)).append("\n"); + sb.append(" isCancelPending: ").append(toIndentedString(isCancelPending)).append("\n"); + sb.append("}"); + return sb.toString(); + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpType.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpType.java new file mode 100644 index 0000000000..351f9611c5 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpType.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.beans; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public enum NsLcmOpType { + INSTANTIATE, TERMINATE, SCALE, UPDATE, HEAL; +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/OperationStateEnum.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/OperationStateEnum.java new file mode 100644 index 0000000000..236652e027 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/OperationStateEnum.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.beans; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public enum OperationStateEnum { + PROCESSING, COMPLETED, PARTIALLY_COMPLETED, FAILED_TEMP, FAILED, ROLLING_BACK, ROLLED_BACK; + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/State.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/State.java new file mode 100644 index 0000000000..390c7fd776 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/State.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.beans; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public enum State { + NOT_INSTANTIATED, INSTANTIATING, INSTANTIATED, FAILED; + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/Utils.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/Utils.java new file mode 100644 index 0000000000..c55ef5728e --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/Utils.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils; + +import java.util.List; +import java.util.Objects; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class Utils { + + private Utils() {} + + public static final String toIndentedString(final Object object) { + return object == null ? "null" : object.toString().replace("\n", "\n "); + } + + + public static boolean isEquals(final List<?> first, List<?> second) { + if (first == null) { + return second == null; + } + if (first.isEmpty()) { + return second.isEmpty(); + } + if (first.size() == second.size()) { + for (int index = 0; index < first.size(); index++) { + if (!Objects.equals(first.get(index), second.get(index))) { + return false; + } + } + return true; + + } + return false; + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/config/NfvoDatabaseConfiguration.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/config/NfvoDatabaseConfiguration.java new file mode 100644 index 0000000000..1b4e40985a --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/config/NfvoDatabaseConfiguration.java @@ -0,0 +1,95 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.config; + +import static org.slf4j.LoggerFactory.getLogger; +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.flyway.FlywayDataSource; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jmx.export.MBeanExporter; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory", + basePackages = {"org.onap.so.etsi.nfvo.ns.lcm.database.repository"}) +public class NfvoDatabaseConfiguration { + private static final Logger logger = getLogger(NfvoDatabaseConfiguration.class); + + private static final String PERSISTENCE_UNIT = "nfvo"; + private static final String NFVO_DATA_SOURCE_QUALIFIER = "nfvoDataSource"; + + @Autowired(required = false) + private MBeanExporter mBeanExporter; + + @Bean + @ConfigurationProperties(prefix = "spring.datasource.hikari.nfvo") + public HikariConfig nfvoDbConfig() { + logger.debug("Creating NFVO HikariConfig bean ... "); + return new HikariConfig(); + } + + @Primary + @FlywayDataSource + @Bean(name = NFVO_DATA_SOURCE_QUALIFIER) + public DataSource dataSource() { + if (mBeanExporter != null) { + mBeanExporter.addExcludedBean(NFVO_DATA_SOURCE_QUALIFIER); + } + logger.debug("Creating NFVO HikariDataSource bean ... "); + final HikariConfig hikariConfig = this.nfvoDbConfig(); + return new HikariDataSource(hikariConfig); + } + + @Primary + @Bean(name = "entityManagerFactory") + public LocalContainerEntityManagerFactoryBean entityManagerFactory(final EntityManagerFactoryBuilder builder, + @Qualifier(NFVO_DATA_SOURCE_QUALIFIER) final DataSource dataSource) { + return builder.dataSource(dataSource).packages(NfvoJob.class.getPackage().getName()) + .persistenceUnit(PERSISTENCE_UNIT).build(); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager( + @Qualifier("entityManagerFactory") final EntityManagerFactory entityManagerFactory) { + return new JpaTransactionManager(entityManagerFactory); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NSLcmOpOccRepository.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NSLcmOpOccRepository.java new file mode 100644 index 0000000000..696c7be5dd --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NSLcmOpOccRepository.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.repository; + +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc; +import org.springframework.data.repository.CrudRepository; +import java.util.Optional; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * @author mukeshsharma(mukeshsharma@est.tech) + */ +public interface NSLcmOpOccRepository extends CrudRepository<NsLcmOpOcc, String> { + + Optional<NsLcmOpOcc> findById(final String id); +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobRepository.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobRepository.java new file mode 100644 index 0000000000..844f60827e --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobRepository.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.repository; + +import java.util.Optional; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob; +import org.springframework.data.repository.CrudRepository; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public interface NfvoJobRepository extends CrudRepository<NfvoJob, String> { + + Optional<NfvoJob> findByResourceId(final String resourceId); + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobStatusRepository.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobStatusRepository.java new file mode 100644 index 0000000000..c3fe469ff6 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobStatusRepository.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.repository; + +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJobStatus; +import org.springframework.data.repository.CrudRepository; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public interface NfvoJobStatusRepository extends CrudRepository<NfvoJobStatus, Integer> { +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNfInstRepository.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNfInstRepository.java new file mode 100644 index 0000000000..de14d43de4 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNfInstRepository.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.repository; + +import java.util.List; +import java.util.Optional; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst; +import org.springframework.data.repository.CrudRepository; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * @author mukeshsharma(mukeshsharma@est.tech) + */ +public interface NfvoNfInstRepository extends CrudRepository<NfvoNfInst, String> { + + Optional<NfvoNfInst> findByNfInstId(final String nfInstId); + + List<NfvoNfInst> findByNsInstNsInstId(final String nsInstId); + + List<NfvoNfInst> findByNsInstNsInstIdAndName(final String nsInstId, final String name); +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNsInstRepository.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNsInstRepository.java new file mode 100644 index 0000000000..beeeacf8cf --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoNsInstRepository.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.repository; + +import java.util.Optional; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst; +import org.springframework.data.repository.CrudRepository; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public interface NfvoNsInstRepository extends CrudRepository<NfvoNsInst, String> { + + Optional<NfvoNsInst> findByName(final String name); + + Optional<NfvoNsInst> findByNsInstId(final String nsInstId); + + boolean existsNfvoNsInstByName(final String name); + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/service/DatabaseServiceProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/service/DatabaseServiceProvider.java new file mode 100644 index 0000000000..368242515b --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/service/DatabaseServiceProvider.java @@ -0,0 +1,141 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.service; + +import java.util.List; +import java.util.Optional; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc; +import org.onap.so.etsi.nfvo.ns.lcm.database.repository.NSLcmOpOccRepository; +import org.onap.so.etsi.nfvo.ns.lcm.database.repository.NfvoJobRepository; +import org.onap.so.etsi.nfvo.ns.lcm.database.repository.NfvoNfInstRepository; +import org.onap.so.etsi.nfvo.ns.lcm.database.repository.NfvoNsInstRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ + +@Service +public class DatabaseServiceProvider { + private static final Logger logger = LoggerFactory.getLogger(DatabaseServiceProvider.class); + + private final NfvoJobRepository nfvoJobRepository; + + private final NfvoNsInstRepository nfvoNsInstRepository; + + private final NfvoNfInstRepository nfvoNfInstRepository; + + private final NSLcmOpOccRepository nsLcmOpOccRepository; + + @Autowired + public DatabaseServiceProvider(final NfvoJobRepository nfvoJobRepository, + final NfvoNsInstRepository nfvoNsInstRepository, final NfvoNfInstRepository nfvoNfInstRepository, + final NSLcmOpOccRepository nsLcmOpOccRepository) { + this.nfvoJobRepository = nfvoJobRepository; + this.nfvoNsInstRepository = nfvoNsInstRepository; + this.nfvoNfInstRepository = nfvoNfInstRepository; + this.nsLcmOpOccRepository = nsLcmOpOccRepository; + } + + public boolean addJob(final NfvoJob job) { + logger.info("Adding NfvoJob: {} to database", job); + return nfvoJobRepository.save(job) != null; + } + + public Optional<NfvoJob> getJob(final String jobId) { + logger.info("Querying database for NfvoJob using jobId: {}", jobId); + return nfvoJobRepository.findById(jobId); + } + + public Optional<NfvoJob> getJobByResourceId(final String resourceId) { + logger.info("Querying database for NfvoJob using resourceId: {}", resourceId); + return nfvoJobRepository.findByResourceId(resourceId); + } + + public boolean isNsInstExists(final String name) { + logger.info("Checking if NfvoNsInst entry exists in database using name: {}", name); + return nfvoNsInstRepository.existsNfvoNsInstByName(name); + } + + public boolean isNsInstExists(final String nsInstId, final String nfName) { + logger.info("Checking if NfvoNfInst entry exists in database using nsInstId: {} and nfName: {}", nsInstId, + nfName); + return nfvoNfInstRepository.findByNsInstNsInstIdAndName(nsInstId, nfName).isEmpty(); + } + + public boolean saveNfvoNsInst(final NfvoNsInst nfvoNsInst) { + logger.info("Saving NfvoNsInst: {} to database", nfvoNsInst); + return nfvoNsInstRepository.save(nfvoNsInst) != null; + } + + public Optional<NfvoNsInst> getNfvoNsInst(final String nsInstId) { + logger.info("Querying database for NfvoNsInst using nsInstId: {}", nsInstId); + return nfvoNsInstRepository.findById(nsInstId); + } + + public Optional<NfvoNsInst> getNfvoNsInstByName(final String name) { + logger.info("Querying database for NfvoNsInst using name: {}", name); + return nfvoNsInstRepository.findByName(name); + } + + public boolean saveNfvoNfInst(final NfvoNfInst nfvoNfInst) { + logger.info("Saving NfvoNfInst: {} to database", nfvoNfInst); + return nfvoNfInstRepository.save(nfvoNfInst) != null; + } + + public Optional<NfvoNfInst> getNfvoNfInstByNfInstId(final String nfInstId) { + logger.info("Querying database for NfvoNfInst using nfInstId: {}", nfInstId); + return nfvoNfInstRepository.findByNfInstId(nfInstId); + } + + public List<NfvoNfInst> getNfvoNfInstByNsInstId(final String nsInstId) { + logger.info("Querying database for NfvoNfInst using nsInstId: {}", nsInstId); + return nfvoNfInstRepository.findByNsInstNsInstId(nsInstId); + } + + public List<NfvoNfInst> getNfvoNfInstByNsInstIdAndNfName(final String nsInstId, final String name) { + logger.info("Querying database for NfvoNfInst using nsInstId: {} and name : {} ", nsInstId, name); + return nfvoNfInstRepository.findByNsInstNsInstIdAndName(nsInstId, name); + } + + public Optional<NfvoNfInst> getNfvoNfInst(final String nfInstId) { + logger.info("Querying database for NfvoNfInst using nfInstId: {}", nfInstId); + return nfvoNfInstRepository.findByNfInstId(nfInstId); + } + + public boolean addNSLcmOpOcc(final NsLcmOpOcc nsLcmOpOcc) { + logger.info("Adding NSLcmOpOcc: {} to database", nsLcmOpOcc); + return nsLcmOpOccRepository.save(nsLcmOpOcc) != null; + } + + public Optional<NsLcmOpOcc> getNsLcmOpOcc(final String id) { + logger.info("Querying database for NsLcmOpOcc using id: {}", id); + return nsLcmOpOccRepository.findById(id); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/resources/db/migration/V1_1__create_nfvo_tables.sql b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/resources/db/migration/V1_1__create_nfvo_tables.sql new file mode 100644 index 0000000000..f41a8206e0 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/resources/db/migration/V1_1__create_nfvo_tables.sql @@ -0,0 +1,74 @@ +use nfvo; + +CREATE TABLE IF NOT EXISTS `JOB` ( + `JOB_ID` varchar(255) NOT NULL, + `JOB_TYPE` varchar(255) NOT NULL, + `JOB_ACTION` varchar(255) NOT NULL, + `RESOURCE_ID` varchar(255) NOT NULL, + `RESOURCE_NAME` varchar(255) DEFAULT NULL, + `STATUS` varchar(255) NOT NULL, + `START_TIME` DATETIME DEFAULT NULL, + `END_TIME` DATETIME DEFAULT NULL, + `PROGRESS` int(11) DEFAULT NULL, + `PROCESS_INSTANCE_ID` varchar(255) DEFAULT NULL, + PRIMARY KEY (`JOB_ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + + +CREATE TABLE IF NOT EXISTS `JOB_STATUS` ( + `ID` INT NOT NULL AUTO_INCREMENT, + `UPDATED_TIME` DATETIME NOT NULL, + `DESCRIPTION` longtext DEFAULT NULL, + `STATUS` varchar(255) NOT NULL, + `JOB_ID` varchar(255) NOT NULL, + PRIMARY KEY (`ID`), + FOREIGN KEY (JOB_ID) + REFERENCES JOB(JOB_ID) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `NS_INST` ( + `NS_INST_ID` varchar(255) NOT NULL, + `NAME` varchar(255) NOT NULL, + `NS_PACKAGE_ID` varchar(255) DEFAULT NULL, + `NSD_ID` varchar(255) NOT NULL, + `NSD_INVARIANT_ID` varchar(255) NOT NULL, + `DESCRIPTION` longtext DEFAULT NULL, + `STATUS` varchar(255) NOT NULL, + `STATUS_UPDATED_TIME` DATETIME NOT NULL, + `GLOBAL_CUSTOMER_ID` varchar(255) DEFAULT NULL, + `SERVICE_TYPE` varchar(255) DEFAULT NULL, + PRIMARY KEY (`NS_INST_ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `NF_INST` ( + `NF_INST_ID` varchar(255) NOT NULL, + `NAME` varchar(255) DEFAULT NULL, + `VNFD_ID` varchar(255) DEFAULT NULL, + `PACKAGE_ID` varchar(255) DEFAULT NULL, + `NS_INST_ID` varchar(255) NOT NULL, + `STATUS` varchar(255) NOT NULL, + `CREATE_TIME` DATETIME DEFAULT NULL, + `LAST_UPDATE_TIME` DATETIME DEFAULT NULL, + PRIMARY KEY (`NF_INST_ID`), + FOREIGN KEY (NS_INST_ID) + REFERENCES NS_INST(NS_INST_ID) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `NS_LCM_OP_OCCS` ( + `ID` varchar(255) NOT NULL, + `OPERATION_STATE` varchar(255) NOT NULL, + `STATE_ENTERED_TIME` DATETIME DEFAULT NULL, + `START_TIME` DATETIME DEFAULT NULL, + `NS_INST_ID` varchar(255) NOT NULL, + `OPERATION` varchar(255) NOT NULL, + `IS_AUTO_INNOVATION` varchar(255) NOT NULL, + `OPERATION_PARAMS` longtext NOT NULL, + `IS_CANCEL_PENDING` varchar(255) NOT NULL, + PRIMARY KEY (`ID`), + FOREIGN KEY (NS_INST_ID) + REFERENCES NS_INST(NS_INST_ID) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/DatabaseServiceProviderTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/DatabaseServiceProviderTest.java new file mode 100644 index 0000000000..42579fd5e8 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/DatabaseServiceProviderTest.java @@ -0,0 +1,176 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJobStatus; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpType; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +public class DatabaseServiceProviderTest { + + private static final String RANDOM_ID = UUID.randomUUID().toString(); + private static final String DUMMY_NAME = "NAME"; + private static final LocalDateTime CURRENT_DATE_TIME = LocalDateTime.now(); + @Autowired + private DatabaseServiceProvider databaseServiceProvider; + + @Test + public void testAddJob_StoredInDatabase() { + final NfvoJob expected = new NfvoJob().jobType("TYPE").jobAction(JobAction.CREATE).resourceId(RANDOM_ID) + .resourceName(DUMMY_NAME).startTime(CURRENT_DATE_TIME).status(JobStatusEnum.STARTED); + databaseServiceProvider.addJob(expected); + + final Optional<NfvoJob> actual = databaseServiceProvider.getJob(expected.getJobId()); + assertEquals(expected, actual.get()); + } + + @Test + public void testAddJobWithJobStatus_StoredInDatabase() { + final NfvoJob job = new NfvoJob().jobType("TYPE").jobAction(JobAction.CREATE).resourceId(RANDOM_ID) + .resourceName(DUMMY_NAME).startTime(CURRENT_DATE_TIME).status(JobStatusEnum.STARTED); + databaseServiceProvider.addJob(job); + + final NfvoJobStatus jobStatus = new NfvoJobStatus().status(JobStatusEnum.STARTED) + .description("Create NS workflow process started").updatedTime(CURRENT_DATE_TIME); + databaseServiceProvider.addJob(job.nfvoJobStatus(jobStatus)); + + final Optional<NfvoJob> actual = databaseServiceProvider.getJob(job.getJobId()); + final NfvoJob actualNfvoJob = actual.get(); + + assertEquals(job.getJobId(), actualNfvoJob.getJobId()); + assertFalse(actualNfvoJob.getNfvoJobStatuses().isEmpty()); + assertEquals(job.getJobId(), actualNfvoJob.getNfvoJobStatuses().get(0).getNfvoJob().getJobId()); + + } + + @Test + public void testAddNsInst_StoredInDatabase_ableTofindByQuery() { + + final NfvoNsInst nsInst = new NfvoNsInst().name(DUMMY_NAME).nsdId(RANDOM_ID).status(State.NOT_INSTANTIATED) + .nsdInvariantId(RANDOM_ID).statusUpdatedTime(CURRENT_DATE_TIME); + + databaseServiceProvider.saveNfvoNsInst(nsInst); + + Optional<NfvoNsInst> actual = databaseServiceProvider.getNfvoNsInst(nsInst.getNsInstId()); + NfvoNsInst actualNfvoNsInst = actual.get(); + assertEquals(nsInst.getNsInstId(), actualNfvoNsInst.getNsInstId()); + assertEquals(RANDOM_ID, actualNfvoNsInst.getNsdId()); + assertEquals(State.NOT_INSTANTIATED, actualNfvoNsInst.getStatus()); + assertEquals(RANDOM_ID, actualNfvoNsInst.getNsdInvariantId()); + assertEquals(CURRENT_DATE_TIME, actualNfvoNsInst.getStatusUpdatedTime()); + + actual = databaseServiceProvider.getNfvoNsInstByName(DUMMY_NAME); + actualNfvoNsInst = actual.get(); + + assertEquals(nsInst.getNsInstId(), actualNfvoNsInst.getNsInstId()); + assertEquals(RANDOM_ID, actualNfvoNsInst.getNsdId()); + assertEquals(State.NOT_INSTANTIATED, actualNfvoNsInst.getStatus()); + assertEquals(RANDOM_ID, actualNfvoNsInst.getNsdInvariantId()); + assertEquals(CURRENT_DATE_TIME, actualNfvoNsInst.getStatusUpdatedTime()); + + + assertTrue(databaseServiceProvider.isNsInstExists(DUMMY_NAME)); + } + + @Test + public void testAddNfInst_StoredInDatabase_ableTofindByQuery() { + + final NfvoNsInst nsInst = new NfvoNsInst().name(DUMMY_NAME).nsdId(RANDOM_ID).status(State.NOT_INSTANTIATED) + .nsdInvariantId(RANDOM_ID).statusUpdatedTime(CURRENT_DATE_TIME); + + databaseServiceProvider.saveNfvoNsInst(nsInst); + + final NfvoNfInst nfInst = new NfvoNfInst().nfvoNsInst(nsInst).name(DUMMY_NAME).vnfdId(RANDOM_ID) + .status(State.NOT_INSTANTIATED).createTime(CURRENT_DATE_TIME).lastUpdateTime(CURRENT_DATE_TIME); + databaseServiceProvider.saveNfvoNfInst(nfInst); + + final Optional<NfvoNfInst> actual = databaseServiceProvider.getNfvoNfInstByNfInstId(nfInst.getNfInstId()); + final NfvoNfInst actualNfvoNfInst = actual.get(); + assertEquals(nsInst.getNsInstId(), actualNfvoNfInst.getNsInst().getNsInstId()); + assertEquals(nfInst.getNfInstId(), actualNfvoNfInst.getNfInstId()); + assertEquals(nfInst.getName(), actualNfvoNfInst.getName()); + assertEquals(nfInst.getVnfdId(), actualNfvoNfInst.getVnfdId()); + assertEquals(nfInst.getStatus(), actualNfvoNfInst.getStatus()); + assertEquals(nfInst.getCreateTime(), actualNfvoNfInst.getCreateTime()); + assertEquals(nfInst.getLastUpdateTime(), actualNfvoNfInst.getLastUpdateTime()); + + + List<NfvoNfInst> nfvoNfInstList = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInst.getNsInstId()); + assertFalse(nfvoNfInstList.isEmpty()); + assertEquals(nsInst.getNsInstId(), nfvoNfInstList.get(0).getNsInst().getNsInstId()); + + nfvoNfInstList = databaseServiceProvider.getNfvoNfInstByNsInstIdAndNfName(nsInst.getNsInstId(), DUMMY_NAME); + + assertFalse(nfvoNfInstList.isEmpty()); + assertEquals(nsInst.getNsInstId(), nfvoNfInstList.get(0).getNsInst().getNsInstId()); + assertEquals(DUMMY_NAME, nfvoNfInstList.get(0).getName()); + } + + @Test + public void testAddNsLcmOpOcc_StoredInDatabase_ableTofindByQuery() { + + final NfvoNsInst nsInst = new NfvoNsInst().name(DUMMY_NAME).nsdId(RANDOM_ID).status(State.NOT_INSTANTIATED) + .nsdInvariantId(RANDOM_ID).statusUpdatedTime(CURRENT_DATE_TIME); + + databaseServiceProvider.saveNfvoNsInst(nsInst); + + final NsLcmOpOcc nsLcmOpOcc = new NsLcmOpOcc().nfvoNsInst(nsInst).operationState(OperationStateEnum.PROCESSING) + .isCancelPending(false).isAutoInnovation(false).operation(NsLcmOpType.INSTANTIATE) + .startTime(CURRENT_DATE_TIME).stateEnteredTime(CURRENT_DATE_TIME).operationParams(""); + + + databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc); + + final Optional<NsLcmOpOcc> actual = databaseServiceProvider.getNsLcmOpOcc(nsLcmOpOcc.getId()); + final NsLcmOpOcc actualLcmOpOcc = actual.get(); + assertEquals(nsLcmOpOcc.getId(), actualLcmOpOcc.getId()); + + assertEquals(nsInst.getNsInstId(), actualLcmOpOcc.getNfvoNsInst().getNsInstId()); + + } +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/TestApplication.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/TestApplication.java new file mode 100644 index 0000000000..921cae2343 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/TestApplication.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.etsi.nfvo.ns.lcm.database; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.ComponentScan.Filter; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@SpringBootApplication(scanBasePackages = {"org.onap.so"}) +@EnableAutoConfiguration(exclude = {JacksonAutoConfiguration.class}) +@ComponentScan(basePackages = {"org.onap"}, + excludeFilters = {@Filter(type = FilterType.ANNOTATION, classes = SpringBootApplication.class)}) +public class TestApplication { + + public static void main(final String[] args) { + new SpringApplication(TestApplication.class).run(args); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/UtilsTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/UtilsTest.java new file mode 100644 index 0000000000..632bda937c --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/utils/UtilsTest.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import java.util.Arrays; +import java.util.Collections; +import org.junit.Test; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class UtilsTest { + + @Test + public void testTwoEmptyLists_equal() { + assertTrue(Utils.isEquals(Collections.emptyList(), Collections.emptyList())); + } + + @Test + public void testEmptyListAndNonEmpty_notEqual() { + assertFalse(Utils.isEquals(Collections.emptyList(), Arrays.asList("A"))); + } + + @Test + public void testTwoNullLists_equal() { + assertTrue(Utils.isEquals(null, null)); + } + + @Test + public void testNullListAndEmptyList_notEqual() { + assertFalse(Utils.isEquals(null, Collections.emptyList())); + } + + @Test + public void testTwoNotEmptyListsContainSameObjects_equal() { + assertTrue(Utils.isEquals(Arrays.asList("A"), Arrays.asList("A"))); + } + + @Test + public void testTwoNotEmptyListsContainsDifferentObjects_equal() { + assertFalse(Utils.isEquals(Arrays.asList("A"), Arrays.asList(1))); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/resources/application.yaml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/resources/application.yaml new file mode 100644 index 0000000000..adc36aca1d --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/resources/application.yaml @@ -0,0 +1,31 @@ +# Copyright © 2020 Nordix Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +spring: + main: + web-application-type: none + datasource: + hikari: + nfvo: + jdbcUrl: jdbc:h2:mem:nfvo;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS nfvo; + driver-class-name: org.h2.Driver + pool-name: ns-lcm-bpmn-pool + registerMbeans: true + jpa: + generate-ddl: true + hibernate: + ddl-auto: create +hibernate: + dialect: org.hibernate.dialect.H2Dialect + hbm2ddl: + auto: create
\ No newline at end of file diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/pom.xml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/pom.xml index 2c3c394d01..6605602f53 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/pom.xml +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/pom.xml @@ -16,6 +16,11 @@ <version>${project.version}</version> </dependency> <dependency> + <groupId>org.onap.so.etsi.nfvo</groupId> + <artifactId>so-etsi-nfvo-ns-lcm-bpmn-flows</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> @@ -50,9 +55,24 @@ <version>${project.version}</version> </dependency> <dependency> + <groupId>org.onap.so.etsi.nfvo</groupId> + <artifactId>so-etsi-nfvo-ns-lcm-bpmn-flows</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <scope>test</scope> + </dependency> </dependencies> </project>
\ No newline at end of file diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/Constants.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/Constants.java index 97ad1743bc..d330df3bae 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/Constants.java +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/Constants.java @@ -1,19 +1,19 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix. All rights reserved. + * Copyright (C) 2020 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/EtsiSoNsLcmManagerUrlProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/EtsiSoNsLcmManagerUrlProvider.java new file mode 100644 index 0000000000..da1649de57 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/EtsiSoNsLcmManagerUrlProvider.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm; + +import java.net.URI; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Configuration +public class EtsiSoNsLcmManagerUrlProvider { + + private final String etsiNsLcmManagerEndpoint; + + @Autowired + public EtsiSoNsLcmManagerUrlProvider( + @Value("${so-etsi-nfvo-ns-lcm.endpoint:http://so-etsi-nfvo-ns-lcm.onap:9095}") final String etsiNsLcmManagerEndpoint) { + this.etsiNsLcmManagerEndpoint = etsiNsLcmManagerEndpoint; + } + + public URI getCreatedNsResourceUri(final String nsInstanceId) { + return URI.create(etsiNsLcmManagerEndpoint + Constants.NS_LIFE_CYCLE_MANAGEMENT_BASE_URL + "/ns_instances/" + + nsInstanceId); + } + + public URI getInstantiatedOccUri(final String nsLcmOpOccId) { + return URI.create(etsiNsLcmManagerEndpoint + Constants.NS_LIFE_CYCLE_MANAGEMENT_BASE_URL + "/ns_lcm_op_occs/" + + nsLcmOpOccId); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/GsonSerializerConfiguration.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/GsonSerializerConfiguration.java new file mode 100644 index 0000000000..2e11adae01 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/GsonSerializerConfiguration.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm; + +import java.time.LocalDateTime; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.utils.LocalDateTimeTypeAdapter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.google.gson.GsonBuilder; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Configuration +public class GsonSerializerConfiguration { + + @Bean + public GsonBuilder gsonBuilder() { + return new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()); + } + +} + + diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/lifecycle/NsLifeCycleManager.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/lifecycle/NsLifeCycleManager.java new file mode 100644 index 0000000000..792ffdd00a --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/lifecycle/NsLifeCycleManager.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.lifecycle; + +import static org.slf4j.LoggerFactory.getLogger; +import java.net.URI; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.onap.so.etsi.nfvo.ns.lcm.EtsiSoNsLcmManagerUrlProvider; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.JobExecutorService; +import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class NsLifeCycleManager { + private static final Logger logger = getLogger(NsLifeCycleManager.class); + + private final JobExecutorService jobExecutorService; + + @Value("${etsi-so-ns-workflow-engine.requesttimeout.create.timeoutInSeconds:300}") + private int timeOutInSeconds; + + private final EtsiSoNsLcmManagerUrlProvider etsiSoNsLcmManagerUrlProvider; + + @Autowired + public NsLifeCycleManager(final JobExecutorService jobExecutorService, + final EtsiSoNsLcmManagerUrlProvider etsiSoNsLcmManagerUrlProvider) { + this.jobExecutorService = jobExecutorService; + this.etsiSoNsLcmManagerUrlProvider = etsiSoNsLcmManagerUrlProvider; + } + + public ImmutablePair<URI, NsInstancesNsInstance> createNs(final CreateNsRequest createNsRequest, + final String globalCustomerId, final String serviceType) { + logger.info("Will execute Create Ns for CreateNsRequest: {}, globalCustomerId: {} and serviceType: {}", + createNsRequest, globalCustomerId, serviceType); + final NsInstancesNsInstance nsInstanceResponse = + jobExecutorService.runCreateNsJob(createNsRequest, globalCustomerId, serviceType); + + return ImmutablePair.of(etsiSoNsLcmManagerUrlProvider.getCreatedNsResourceUri(nsInstanceResponse.getId()), + nsInstanceResponse); + } + + public URI instantiateNs(final String nsInstanceId, final InstantiateNsRequest instantiateNsRequest) { + logger.info("Will execute Instantiate Ns for InstantiateNsRequest: {} and nsInstanceId: {}", + instantiateNsRequest, nsInstanceId); + final String nsLcmOpOccId = jobExecutorService.runInstantiateNsJob(nsInstanceId, instantiateNsRequest); + + return etsiSoNsLcmManagerUrlProvider.getInstantiatedOccUri(nsLcmOpOccId); + + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesController.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesController.java index aed4f4b9dd..ec79ce6329 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesController.java +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesController.java @@ -1,19 +1,19 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix. All rights reserved. + * Copyright (C) 2020 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementController.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementController.java index 4dd12589a0..87ec8420c6 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementController.java +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementController.java @@ -1,19 +1,19 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix. All rights reserved. + * Copyright (C) 2020 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ @@ -24,12 +24,17 @@ import static org.onap.so.etsi.nfvo.ns.lcm.Constants.HTTP_SERVICETYPE_HEADER_DEF import static org.onap.so.etsi.nfvo.ns.lcm.Constants.HTTP_SERVICETYPE_HEADER_PARM_NAME; import static org.onap.so.etsi.nfvo.ns.lcm.Constants.NS_LIFE_CYCLE_MANAGEMENT_BASE_URL; import static org.slf4j.LoggerFactory.getLogger; +import java.net.URI; import javax.ws.rs.core.MediaType; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.onap.so.etsi.nfvo.ns.lcm.lifecycle.NsLifeCycleManager; import org.onap.so.etsi.nfvo.ns.lcm.model.Body; import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest; import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance; import org.onap.so.etsi.nfvo.ns.lcm.model.TerminateNsRequest; import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; @@ -53,6 +58,12 @@ import org.springframework.web.bind.annotation.RequestMapping; public class NsLifecycleManagementController { private static final Logger logger = getLogger(NsLifecycleManagementController.class); + private final NsLifeCycleManager nsLifeCycleManager; + + @Autowired + public NsLifecycleManagementController(final NsLifeCycleManager nsLifeCycleManager) { + this.nsLifeCycleManager = nsLifeCycleManager; + } /** * The POST method creates new {@link Body new NS instance resource} request. See Section Number: 6.3.1 for more @@ -74,7 +85,17 @@ public class NsLifecycleManagementController { @RequestBody final CreateNsRequest createNsRequest) { logger.info("Received Create NS Request: {}\n with globalCustomerId: {}\n serviceType: {}\n", createNsRequest, globalCustomerId, serviceType); - return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).body("Operation is not supported yet"); + + final ImmutablePair<URI, NsInstancesNsInstance> nsInstance = + nsLifeCycleManager.createNs(createNsRequest, globalCustomerId, serviceType); + + final URI resourceUri = nsInstance.getLeft(); + final NsInstancesNsInstance createdNsresponse = nsInstance.getRight(); + + logger.info("NS resource created successfully. Resource location: {}, response: {}", resourceUri, + createdNsresponse); + + return ResponseEntity.created(resourceUri).body(createdNsresponse); } /** @@ -104,7 +125,10 @@ public class NsLifecycleManagementController { public ResponseEntity<?> instantiateNs(@PathVariable("nsInstanceId") final String nsInstanceId, @RequestBody final InstantiateNsRequest instantiateNsRequest) { logger.debug("Received instantiate NS request: {}\n with nsInstanceId: {}", instantiateNsRequest, nsInstanceId); - return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).body("Operation is not supported yet"); + final URI resourceUri = nsLifeCycleManager.instantiateNs(nsInstanceId, instantiateNsRequest); + logger.info("{} Ns Instantiation started successfully. Resource Operation Occurrence uri: {}", nsInstanceId, + resourceUri); + return ResponseEntity.accepted().location(resourceUri).build(); } /** diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/exceptions/NsLcmControllerExceptionHandler.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/exceptions/NsLcmControllerExceptionHandler.java new file mode 100644 index 0000000000..3db04fcfe8 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/exceptions/NsLcmControllerExceptionHandler.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.rest.exceptions; + +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.NsRequestProcessingException; +import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400; +import org.onap.so.etsi.nfvo.ns.lcm.rest.NsLifecycleManagementController; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@ControllerAdvice(assignableTypes = NsLifecycleManagementController.class) +public class NsLcmControllerExceptionHandler { + + @ExceptionHandler(NsRequestProcessingException.class) + public ResponseEntity<InlineResponse400> handleNsRequestProcessingException( + final NsRequestProcessingException nsRequestProcessingException) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(getInlineResponse400(nsRequestProcessingException)); + } + + @ExceptionHandler(Exception.class) + public ResponseEntity<InlineResponse400> handleNsRequestProcessingException(final Exception exception) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new InlineResponse400() + .status(HttpStatus.INTERNAL_SERVER_ERROR.value()).detail(exception.getMessage())); + } + + private InlineResponse400 getInlineResponse400(final NsRequestProcessingException nsRequestProcessingException) { + if (nsRequestProcessingException.getProblemDetails() != null) { + return nsRequestProcessingException.getProblemDetails(); + } + return new InlineResponse400().status(HttpStatus.INTERNAL_SERVER_ERROR.value()) + .detail(nsRequestProcessingException.getMessage()); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/TestApplication.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/TestApplication.java index 6e5f6c0467..d6f4a83811 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/TestApplication.java +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/TestApplication.java @@ -1,19 +1,19 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2020 Ericsson. All rights reserved. + * Copyright (C) 2020 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesControllerTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesControllerTest.java index ae491b6f1e..9eace927d6 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesControllerTest.java +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLcmOperationOccurrencesControllerTest.java @@ -1,19 +1,19 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2020 Ericsson. All rights reserved. + * Copyright (C) 2020 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementControllerTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementControllerTest.java index 6f25092050..81c4e8fd68 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementControllerTest.java +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementControllerTest.java @@ -1,19 +1,19 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2020 Ericsson. All rights reserved. + * Copyright (C) 2020 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ @@ -24,18 +24,30 @@ package org.onap.so.etsi.nfvo.ns.lcm.rest; * */ import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; +import java.net.URISyntaxException; import java.time.LocalDateTime; +import java.util.List; import java.util.UUID; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.onap.so.etsi.nfvo.ns.lcm.Constants; -import org.onap.so.etsi.nfvo.ns.lcm.JSON; import org.onap.so.etsi.nfvo.ns.lcm.TestApplication; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.NsRequestProcessingException; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.JobExecutorService; import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400; import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance; import org.onap.so.etsi.nfvo.ns.lcm.model.TerminateNsRequest; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.server.LocalServerPort; @@ -57,27 +69,107 @@ import com.google.gson.Gson; @SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("test") public class NsLifecycleManagementControllerTest { + private static final String EXPECTED_BASE_URL = + "http://so-etsi-nfvo-ns-lcm.onap:9095/so/so-etsi-nfvo-ns-lcm/v1/api/nslcm/v1"; + private static final String RANDOM_NS_LCM_OP_OCC_ID = UUID.randomUUID().toString(); + private static final String RANDOM_NS_INST_ID = UUID.randomUUID().toString(); + private static final String SERVICE_TYPE = "NetworkService"; + private static final String GLOBAL_CUSTOMER_ID = UUID.randomUUID().toString(); + private static final String EXPECTED_CREATE_REQ_LOCATION_URL = + EXPECTED_BASE_URL + "/ns_instances/" + RANDOM_NS_INST_ID; + private static final String EXPECTED_INSTANTIATE_REQ_LOCATION_URL = + EXPECTED_BASE_URL + "/ns_lcm_op_occs/" + RANDOM_NS_LCM_OP_OCC_ID; + @LocalServerPort private int port; private TestRestTemplate testRestTemplate; + @Autowired + private GsonProvider gsonProvider; + + @MockBean + private JobExecutorService mockedJobExecutorService; + @Before public void setUp() { - final Gson gson = JSON.createGson().create(); + final Gson gson = gsonProvider.getGson(); testRestTemplate = new TestRestTemplate( new RestTemplateBuilder().additionalMessageConverters(new GsonHttpMessageConverter(gson))); } @Test - public void testCreateNs_ValidCreateNsRequest() { + public void testCreateNs_ValidCreateNsRequest() throws URISyntaxException { + + final CreateNsRequest createNsRequest = getCreateNsRequest(); + + when(mockedJobExecutorService.runCreateNsJob(eq(createNsRequest), eq(GLOBAL_CUSTOMER_ID), eq(SERVICE_TYPE))) + .thenReturn(new NsInstancesNsInstance().id(RANDOM_NS_INST_ID)); + final String baseUrl = getNsLcmBaseUrl() + "/ns_instances"; final HttpHeaders headers = new HttpHeaders(); - headers.add(Constants.HTTP_GLOBAL_CUSTOMER_ID_HTTP_HEADER_PARM_NAME, "GLOBAL_CUSTOMER_ID"); - final HttpEntity<?> request = new HttpEntity<>(getCreateNsRequest(), headers); - final ResponseEntity<Void> responseEntity = - testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, Void.class); - assertEquals(HttpStatus.NOT_IMPLEMENTED, responseEntity.getStatusCode()); + headers.add(Constants.HTTP_GLOBAL_CUSTOMER_ID_HTTP_HEADER_PARM_NAME, GLOBAL_CUSTOMER_ID); + final HttpEntity<?> request = new HttpEntity<>(createNsRequest, headers); + final ResponseEntity<NsInstancesNsInstance> responseEntity = + testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, NsInstancesNsInstance.class); + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); + assertTrue(responseEntity.hasBody()); + assertNotNull(responseEntity.getBody()); + + final HttpHeaders httpHeaders = responseEntity.getHeaders(); + assertTrue(httpHeaders.containsKey(HttpHeaders.LOCATION)); + final List<String> actual = httpHeaders.get(HttpHeaders.LOCATION); + assertEquals(1, actual.size()); + assertEquals(EXPECTED_CREATE_REQ_LOCATION_URL, actual.get(0)); + } + + @Test + public void testCreateNs_createNsRequest_nsRequestProcessingExceptionThrown_returnInlineResponse400() + throws URISyntaxException { + + final CreateNsRequest createNsRequest = getCreateNsRequest(); + + final String message = "Unable to process request"; + when(mockedJobExecutorService.runCreateNsJob(eq(createNsRequest), eq(GLOBAL_CUSTOMER_ID), eq(SERVICE_TYPE))) + .thenThrow(new NsRequestProcessingException(message, new InlineResponse400().detail(message))); + + final String baseUrl = getNsLcmBaseUrl() + "/ns_instances"; + final HttpHeaders headers = new HttpHeaders(); + headers.add(Constants.HTTP_GLOBAL_CUSTOMER_ID_HTTP_HEADER_PARM_NAME, GLOBAL_CUSTOMER_ID); + final HttpEntity<?> request = new HttpEntity<>(createNsRequest, headers); + final ResponseEntity<InlineResponse400> responseEntity = + testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, InlineResponse400.class); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + assertTrue(responseEntity.hasBody()); + assertNotNull(responseEntity.getBody()); + + final InlineResponse400 body = responseEntity.getBody(); + assertEquals(message, body.getDetail()); + + } + + @Test + public void testCreateNs_createNsRequest_exceptionThrown_returnInlineResponse400() throws URISyntaxException { + + final CreateNsRequest createNsRequest = getCreateNsRequest(); + + final String message = "Unable to process request"; + when(mockedJobExecutorService.runCreateNsJob(eq(createNsRequest), eq(GLOBAL_CUSTOMER_ID), eq(SERVICE_TYPE))) + .thenThrow(new RuntimeException(message)); + + final String baseUrl = getNsLcmBaseUrl() + "/ns_instances"; + final HttpHeaders headers = new HttpHeaders(); + headers.add(Constants.HTTP_GLOBAL_CUSTOMER_ID_HTTP_HEADER_PARM_NAME, GLOBAL_CUSTOMER_ID); + final HttpEntity<?> request = new HttpEntity<>(createNsRequest, headers); + final ResponseEntity<InlineResponse400> responseEntity = + testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, InlineResponse400.class); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + assertTrue(responseEntity.hasBody()); + assertNotNull(responseEntity.getBody()); + + final InlineResponse400 body = responseEntity.getBody(); + assertEquals(message, body.getDetail()); + } @Test @@ -90,11 +182,39 @@ public class NsLifecycleManagementControllerTest { @Test public void testInstantiateNs_ValidInstantiateNsRequest() { - final String baseUrl = getNsLcmBaseUrl() + "/ns_instances/" + UUID.randomUUID().toString() + "/instantiate"; - final HttpEntity<?> request = new HttpEntity<>(getInstantiateNsRequest()); + + final InstantiateNsRequest instantiateNsRequest = getInstantiateNsRequest(); + when(mockedJobExecutorService.runInstantiateNsJob(eq(RANDOM_NS_INST_ID), eq(instantiateNsRequest))) + .thenReturn(RANDOM_NS_LCM_OP_OCC_ID); + + final String baseUrl = getNsLcmBaseUrl() + "/ns_instances/" + RANDOM_NS_INST_ID + "/instantiate"; + final HttpEntity<?> request = new HttpEntity<>(instantiateNsRequest); final ResponseEntity<Void> responseEntity = testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, Void.class); - assertEquals(HttpStatus.NOT_IMPLEMENTED, responseEntity.getStatusCode()); + assertEquals(HttpStatus.ACCEPTED, responseEntity.getStatusCode()); + + final HttpHeaders httpHeaders = responseEntity.getHeaders(); + assertTrue(httpHeaders.containsKey(HttpHeaders.LOCATION)); + final List<String> actual = httpHeaders.get(HttpHeaders.LOCATION); + assertEquals(1, actual.size()); + assertEquals(EXPECTED_INSTANTIATE_REQ_LOCATION_URL, actual.get(0)); + } + + @Test + public void testInstantiateNs_instantiateNsRequest_nsRequestProcessingExceptionThrown_returnInlineResponse400() { + final String message = "Unable to process request"; + final InstantiateNsRequest instantiateNsRequest = getInstantiateNsRequest(); + when(mockedJobExecutorService.runInstantiateNsJob(eq(RANDOM_NS_INST_ID), eq(instantiateNsRequest))) + .thenThrow(new NsRequestProcessingException(message, new InlineResponse400().detail(message))); + + final String baseUrl = getNsLcmBaseUrl() + "/ns_instances/" + RANDOM_NS_INST_ID + "/instantiate"; + final HttpEntity<?> request = new HttpEntity<>(instantiateNsRequest); + final ResponseEntity<InlineResponse400> responseEntity = + testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, InlineResponse400.class); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + assertTrue(responseEntity.hasBody()); + assertNotNull(responseEntity.getBody()); } @Test @@ -116,7 +236,7 @@ public class NsLifecycleManagementControllerTest { } private CreateNsRequest getCreateNsRequest() { - return new CreateNsRequest().nsdId(UUID.randomUUID().toString()); + return new CreateNsRequest().nsdId(RANDOM_NS_INST_ID); } private String getNsLcmBaseUrl() { diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/resources/application.yaml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/resources/application.yaml new file mode 100644 index 0000000000..44acda20a4 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/resources/application.yaml @@ -0,0 +1,39 @@ +# Copyright © 2020 Nordix Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +spring: + main: + allow-bean-definition-overriding: true + flyway: + baseline-on-migrate: false + datasource: + hikari: + camunda: + jdbcUrl: jdbc:h2:mem:example-simple;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + driver-class-name: org.h2.Driver + pool-name: ns-lcm-bpmn-pool + registerMbeans: true + nfvo: + jdbcUrl: jdbc:h2:mem:NFVO;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS NFVO; + driver-class-name: org.h2.Driver + pool-name: ns-lcm-nfvo-pool + registerMbeans: true + jpa: + hibernate: + ddl-auto: none +logging: + level: + org.reflections.Reflections: ERROR +etsi-catalog-manager: + base: + endpoint: http://modeling-etsicatalog.onap:8806/api
\ No newline at end of file |