diff options
38 files changed, 2508 insertions, 45 deletions
diff --git a/bpmn/MSOCommonBPMN/src/test/resources/__files/ExecuteBuildingBlock/aaiL3NetworkInputWithSubnets.json b/bpmn/MSOCommonBPMN/src/test/resources/__files/ExecuteBuildingBlock/aaiL3NetworkInputWithSubnets.json index 9b32a4c446..8e4e3632e9 100644 --- a/bpmn/MSOCommonBPMN/src/test/resources/__files/ExecuteBuildingBlock/aaiL3NetworkInputWithSubnets.json +++ b/bpmn/MSOCommonBPMN/src/test/resources/__files/ExecuteBuildingBlock/aaiL3NetworkInputWithSubnets.json @@ -72,7 +72,7 @@ "aggregateRoutes": { "aggregateRoute": [ { - "routeId": "routeId", + "aggRouteId": "routeId", "networkStartAddress": "10.80.12.0", "cidrMask": "23", "ipVersion": "4" diff --git a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CnfAdapterBB.bpmn b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CnfAdapterBB.bpmn new file mode 100644 index 0000000000..6cd2c20ab9 --- /dev/null +++ b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CnfAdapterBB.bpmn @@ -0,0 +1,80 @@ +<?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_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.10.0"> + <bpmn:process id="Process_1" isExecutable="true"> + <bpmn:startEvent id="StartEvent_1"> + <bpmn:outgoing>SequenceFlow_0xb4elc</bpmn:outgoing> + </bpmn:startEvent> + <bpmn:endEvent id="EndEvent_1ee5kqt"> + <bpmn:incoming>SequenceFlow_0lc785k</bpmn:incoming> + </bpmn:endEvent> + <bpmn:sequenceFlow id="SequenceFlow_0xb4elc" sourceRef="StartEvent_1" targetRef="Task_0amo55n" /> + <bpmn:sequenceFlow id="SequenceFlow_0lc785k" sourceRef="Task_0amo55n" targetRef="EndEvent_1ee5kqt" /> + <bpmn:serviceTask id="Task_0amo55n" name="Call CnfAdapter" camunda:expression="${CnfAdapter.callCnfAdapter(execution)}"> + <bpmn:incoming>SequenceFlow_0xb4elc</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_0lc785k</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:subProcess id="SubProcess_12ghmoa" name="Java Exception Handling Sub Process" triggeredByEvent="true"> + <bpmn:startEvent id="StartEvent_1pwqeib" name="error"> + <bpmn:outgoing>SequenceFlow_0hqxgyk</bpmn:outgoing> + <bpmn:errorEventDefinition errorRef="Error_0oqb77k" camunda:errorCodeVariable="BPMN_javaExpCode" camunda:errorMessageVariable="BPMN_javaExpMsg" /> + </bpmn:startEvent> + <bpmn:endEvent id="EndEvent_1ysk6aa"> + <bpmn:incoming>SequenceFlow_0hqxgyk</bpmn:incoming> + </bpmn:endEvent> + <bpmn:sequenceFlow id="SequenceFlow_0hqxgyk" sourceRef="StartEvent_1pwqeib" targetRef="EndEvent_1ysk6aa" /> + </bpmn:subProcess> + </bpmn:process> + <bpmn:error id="Error_0oqb77k" name="java.lang.Exception" errorCode="java.lang.Exception" /> + <bpmndi:BPMNDiagram id="BPMNDiagram_1"> + <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1"> + <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"> + <dc:Bounds x="173" y="102" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="EndEvent_1ee5kqt_di" bpmnElement="EndEvent_1ee5kqt"> + <dc:Bounds x="636" y="102" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="654" y="142" width="0" height="12" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="SequenceFlow_0xb4elc_di" bpmnElement="SequenceFlow_0xb4elc"> + <di:waypoint xsi:type="dc:Point" x="209" y="120" /> + <di:waypoint xsi:type="dc:Point" x="377" y="120" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="293" y="99" width="0" height="12" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_0lc785k_di" bpmnElement="SequenceFlow_0lc785k"> + <di:waypoint xsi:type="dc:Point" x="477" y="120" /> + <di:waypoint xsi:type="dc:Point" x="636" y="120" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="556.5" y="99" width="0" height="12" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="ServiceTask_1vbkgmd_di" bpmnElement="Task_0amo55n"> + <dc:Bounds x="377" y="80" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="SubProcess_12ghmoa_di" bpmnElement="SubProcess_12ghmoa" isExpanded="true"> + <dc:Bounds x="225" y="284" width="404" height="165" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="StartEvent_1pwqeib_di" bpmnElement="StartEvent_1pwqeib"> + <dc:Bounds x="340" y="350" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="346" y="393" width="26" height="12" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="EndEvent_1ysk6aa_di" bpmnElement="EndEvent_1ysk6aa"> + <dc:Bounds x="472" y="350" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="-235" y="114" width="0" height="12" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="SequenceFlow_0hqxgyk_di" bpmnElement="SequenceFlow_0hqxgyk"> + <di:waypoint xsi:type="dc:Point" x="376" y="368" /> + <di:waypoint xsi:type="dc:Point" x="472" y="368" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="424" y="347" width="0" height="12" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNEdge> + </bpmndi:BPMNPlane> + </bpmndi:BPMNDiagram> +</bpmn:definitions> diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnf/tasks/CnfAdapter.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnf/tasks/CnfAdapter.java new file mode 100644 index 0000000000..c21b467a95 --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnf/tasks/CnfAdapter.java @@ -0,0 +1,36 @@ +package org.onap.so.bpmn.infrastructure.adapter.cnf.tasks; + +import java.io.IOException; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowAction; +import org.onap.so.client.adapter.cnf.CnfAdapterClient; +import org.onap.so.client.adapter.cnf.CnfAdapterClientException; +import org.onap.so.client.adapter.cnf.entities.InstanceRequest; +import org.onap.so.client.adapter.cnf.entities.InstanceResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +@Component +public class CnfAdapter { + + @Autowired + private CnfAdapterClient cnfAdapterClient; + + private static final Logger logger = LoggerFactory.getLogger(CnfAdapter.class); + + public void callCnfAdapter(DelegateExecution execution) throws Exception { + try { + final String instanceRequest = (String) execution.getVariable("instanceRequest"); + InstanceRequest request = new ObjectMapper().readValue(instanceRequest, InstanceRequest.class); + InstanceResponse response = cnfAdapterClient.createVfModule(request); + } catch (Exception ex) { + logger.error("Exception in callCnfAdapter", ex); + throw ex; + } + } +} diff --git a/docs/developer_info/Cxf_Logging.rst b/docs/developer_info/Cxf_Logging.rst new file mode 100644 index 0000000000..ea2bbf56ce --- /dev/null +++ b/docs/developer_info/Cxf_Logging.rst @@ -0,0 +1,210 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +.. Copyright 2020 Huawei Technologies Co., Ltd. + +CXF-logging: +============= +It is a logging framework from SO. Here basically we are having 2 interceptors which extends AbstractSoapInterceptor. + +SOAPLoggingInInterceptor: ++++++++++++++++++++++++++++ + +* This interceptor is responsible for Capturing requestId , client ip address , invocation id, service name, instance id, entry timestamp , log timestamp, Elapsed time for each request and update the MDC logger with staus In-progress. + +SOAPLoggingOutInterceptor: +++++++++++++++++++++++++++++ +* This interceptor is responsible for log timestamp , elapsed time for each request and checks for if there is any exception update the MDC loggers with 500 response code otherwise update the status as completed. + + +cxf-logging Used By below components of SO: +++++++++++++++++++++++++++++++++++++++++++++ +The cxf-logging framework is used by below components of so. + +mso-openstack-adapter. +mso-requests-db-adapter. +mso-sdnc-adapter. +mso-infrastructure-bpmn. + +cxf-logging dependency for using in other components: +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + <dependency> + <groupId>org.onap.so</groupId> + <artifactId>cxf-logging</artifactId> + <version>${project.version}</version> + + </dependency> + +pom.xml: ++++++++++ +<?xml version="1.0"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <parent> + + <groupId>org.onap.so</groupId> + <artifactId>so</artifactId> + <version>1.6.0-SNAPSHOT</version> + + </parent> + <name>CXFLogging</name> + <description>Common CXF Logging Classes</description> + <dependencies> + + <dependency> + + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-client</artifactId> + <version>${cxf.version}</version> + + </dependency> + + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-bindings-soap</artifactId> + <version>${cxf.version}</version> + + </dependency> + + <dependency> + + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-transports-http</artifactId> + <version>${cxf.version}</version> + + </dependency> + + <dependency> + + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + + </dependency> + + <dependency> + + <groupId>org.slf4j</groupId> + <artifactId>slf4j-ext</artifactId> + + </dependency> + + <dependency> + + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + + </dependency> + + </dependencies> + + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + + </resource> + + <resource> + + <directory>src/main/java</directory> + + <includes> + + <include>*.java</include> + + </includes> + + </resource> + + </resources> + + </build> + + <artifactId>cxf-logging</artifactId> + +</project> + +Configuration file: +++++++++++++++++++++ +Here we can do configure the logger properties for the cxf-logging. + +<configuration> + + <property name="p_tim" value="%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX", UTC}"/> + + <property name="p_lvl" value="%level"/> + + <property name="p_log" value="%logger"/> + + <property name="p_mdc" value="%replace(%replace(%mdc){'\t','\\\\t'}){'\n', '\\\\n'}"/> + + <property name="p_msg" value="%replace(%replace(%msg){'\t', '\\\\t'}){'\n','\\\\n'}"/> + + <property name="p_exc" value="%replace(%replace(%rootException){'\t', '\\\\t'}){'\n','\\\\n'}"/> + + <property name="p_mak" value="%replace(%replace(%marker){'\t', '\\\\t'}){'\n','\\\\n'}"/> + + <property name="p_thr" value="%thread"/> + + <property name="pattern" value="%nopexception${p_tim}\t${p_thr}\t${p_lvl}\t${p_log}\t${p_mdc}\t${p_msg}\t${p_exc}\t${p_mak}\t%n"/> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + + <encoder> + + <pattern>${pattern}</pattern> + + </encoder> + + </appender> + + <appender name="test" + class="org.onap.so.utils.TestAppender" /> + + <logger name="com.att.ecomp.audit" level="info" additivity="false"> + + <appender-ref ref="STDOUT" /> + + </logger> + + <logger name="com.att.eelf.metrics" level="info" additivity="false"> + + <appender-ref ref="STDOUT" /> + + </logger> + + <logger name="com.att.eelf.error" level="WARN" additivity="false"> + + <appender-ref ref="STDOUT" /> + + </logger> + + <logger name="org.onap" level="${so.log.level:-DEBUG}" additivity="false"> + <appender-ref ref="STDOUT" /> + + <appender-ref ref="test" /> + + </logger> + + <logger name="org.flywaydb" level="DEBUG" additivity="false"> + <appender-ref ref="STDOUT" /> + + </logger> + + <logger name="ch.vorburger" level="WARN" additivity="false"> + <appender-ref ref="STDOUT" /> + + </logger> + + <root level="WARN"> + <appender-ref ref="STDOUT" /> + <appender-ref ref="test" /> + + </root> + +</configuration> + diff --git a/docs/developer_info/developer_information.rst b/docs/developer_info/developer_information.rst index 1b9e83b840..a060da60b0 100644 --- a/docs/developer_info/developer_information.rst +++ b/docs/developer_info/developer_information.rst @@ -21,5 +21,6 @@ SO Developer Information BPMN_Project_Deployment_Strategy.rst BPMN-INFRA_Workflow_Understanding.rst Mso_Openstack_Adapter.rst + Cxf_Logging.rst instantiate/index.rst FAQs.rst diff --git a/docs/developer_info/mso_adapter_restinterface.rst b/docs/developer_info/mso_adapter_restinterface.rst new file mode 100644 index 0000000000..49a9cadba4 --- /dev/null +++ b/docs/developer_info/mso_adapter_restinterface.rst @@ -0,0 +1,288 @@ +Mso-adapters-rest-interface +--------------------------- +.. image:: ../images/module_structure.png + +It mainly contains the payload that is provided to different rest calls in SO + +Network +-------- +# 1. Network contain beans( classes with multiple attributes and thier setters and getters) and their corresponding mappers which will be used by the network adapter of SO. Contrail networking is used for cloud network automation + +Beans +----- + # a. ContrailPolicyRef : this class has following attribute + private ContrailPolicyRefSeq seq; + + Usage: adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterImpl.java- while creating network in openstack, network stack is created depending on stackParams. So if pFqdns(FQDN address object is used in order to use DNS names in firewall policies) are there in the inputrequest to createNetwork, then mergePolicyRefs method is called, where for each input pFqdns, a new ContrailPolicyRef is created and appended to a list. Then this is added as value to stackParams with policy_refsdata as key. + + # b. ContrailPolicyRefSeq : Attributes are + private String major; + + private String minor ; + + Usage: adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterImpl.java- As this is an attribute to the ContrailPolicyRef explained above. So when a new ContrailPolicyRef() is created in mergePolicyRefs method, correspondingly a new ContrailPolicyRefSeq should be created. + + # c. ContrailSubnet – Its a subnetwork having attributes + private ContrailSubnetIp subnet = new ContrailSubnetIp(); + + private String defaultGateway; + + private String subnetName; + + private Boolean enableDhcp(dynamic host config); + + private Boolean addrFromStart = true; + + private List<ContrailSubnetPool> allocationPools = new ArrayList<>(); + + private ContrailSubnetHostRoutes hostRoutes = new ContrailSubnetHostRoutes(); + + Usage : adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterImpl.java- While creating network mergeSubnetsAIC3 is called if a list of subnets are present. The subnets are mapped to ContrailSubnet using ContrailSubnetMapper, and then are added to the heat template and stackparams which are used for network creation in openstack. + + # d. ContrailSubnetHostRoute : This is an attribute defined in contrailsubnet and has following attributes + private String prefix; + + private String nextHop; + + Usage : This is an attribute of ContrailSubnetHostRoutes , which is used within the contrailSubnet and thus is used in network creation and updation. + + # e. ContrailSubnetHostRoutes : This class is used to store an list of ContrailSubnetHostRoute + + private List<ContrailSubnetHostRoute> hostRoutes = new ArrayList<>(); + + Usage : attribute of contrailSubnet + + # f. ContrailSubnetIp : attributes are + private String ipPrefix; + + private String ipPrefixLen; + + This class is used to store the cidr value , which is used as a interrouting table, taking as ipaddress/total no . Eg : 10.0.0.0/24 means starting ip is 10.0.0.0, and total no of ip address possible here is 256 (2^(32-24)), the last address being 10.0.0.255. + + Usage : important attribute of contrailSubnet + + # g. ContrailSubnetPool : attributes are starting and ending ip address of the subnet + private String start; + + private String end; + + Usage: a list of ContrailSubnetPool forms an important attribute of contrailSubnet + +Mappers +------- + + # a. ContrailSubnetMapper : It is used to map the inputsubnet to a contrailSubnet + public ContrailSubnetMapper(Subnet inputSubnet) { + this.inputSubnet = inputSubnet; + + } + + The map method within is used for the mapping. Here first a contrailSubnet is created, and depending on whether the subnet has name or id, the contrailSubnet’s name is initialized, then if it has cidr , then a contrailSubnetIp is created, and is added into it, which is then added to contrailSubnet created before. Depending on whether input has allocationpool or hostroutes, these are casted into ContrailSubnetPool and ContrailSubnetHostRoute using ContrailSubnetPoolMapper and ContrailSubnetPoolMapper respectively. + + Usage: adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterImpl.java :The subnets are mapped to ContrailSubnet using ContrailSubnetMapper, and then are added to the heat template and stackparams which are used for network creation + + # b. ContrailSubnetPoolMapper : It is used to map the pool within the subnets to contrailSubnetPool. Used within contrailSubnetMapper. Here, the particular pool is added only if it has both the start and end ip address. + + # c. ContrailSubnetHostRoute : It is used to map the host routes within the subnets to contrailSubnetHostRoute. Used within contrailSubnetMapper. Here, the particular host route is added if either of the next hop or ip prefix is defined. + +Network request +--------------- + +#2. Network request : It contains the payloads for different types of network requests + + # a. ContrailNetwork : + private String shared = "false"; + + private String external = "false"; + + private List<RouteTarget> routeTargets; + + private List<String> policyFqdns; + + private List<String> routeTableFqdns; + + Usage: contrailNetwork is an important attribute of CreateNetworkRequest, So is to be used where all the request to createNetwork is required. + + # 1. adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/orchestration/StackService.java : Here the input to createNetwork requires contrailNetwork parameter, so here it checks whether contrailNetwork is already present, if not a new is created. + + # 2.bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/network/mapper/NetworkAdapterObjectMapper.java : Here in createNetworkRequestMapper, createNetworkRequest is formed where in buildContrailNetwork, a new contrailNetwork is created and initialized. This request is used to create a network and set the corresponding execution variable + + # b. CreateNetworkError: It extends NetworkExceptionResponse. And is used when an error occurs during network creation + + # c. NetworkExceptionResponse : it extends NetworkResponseCommon. Attributes are + private String message; + + private MsoExceptionCategory category; + + private Boolean rolledBack; + + # d. NetworkResponseCommon: Attribute is + private String messageId; + + # e. CreateNetworkRequest: extends NetworkRequestCommon + private String cloudSiteId; + + private String tenantId; + + private String networkId; + + private String networkName; + + private String networkType; + + private String networkTypeVersion; + + private String modelCustomizationUuid; + + private String networkTechnology = "NEUTRON"; + + private List<Subnet> subnets; + + private ProviderVlanNetwork providerVlanNetwork; + + private ContrailNetwork contrailNetwork; + + private Boolean failIfExists = false; + + private Boolean backout = true; + + private Map<String, String> networkParams = new HashMap<>(); + + private MsoRequest msoRequest = new MsoRequest(); + + private boolean contrailRequest; + + Usage : + #1) bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/aai/tasks/AAIQueryTasks.java: Here in getNetworkVpnBinding, where VPN Binding data from AAI result is extracted. There in routeTargets is got, and is updated in the execution variable(“createNetworkRequest”). + + #2)bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/network/tasks/NetworkAdapterCreateTasks.java – Here in createnetwork returns a CreateNetworkRequest which is updated in execution variable(“networkAdapterRequest”) + + #3)bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/flowspecific/tasks/CreateNetwork.java - + Here in createnetwork returns a CreateNetworkRequest which is updated in execution variable(“createNetworkRequest”) + + #4) bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/network/NetworkAdapterClientImpl.java -Here createNetwork request is processed as a restclient post process with CreateNetworkRequest as input. + + # f. CreateNetworkResponse : extends NetworkResponseCommon + private String networkId; + + private String neutronNetworkId; + + private String networkStackId; + + private String networkFqdn; + + private Boolean networkCreated; + + private Map<String, String> subnetMap; + + private NetworkRollback rollback = new NetworkRollback(); + + Usage: + #1)bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/aai/tasks/AAIUpdateTasks.java :here after the network is created, the l3 network is updated with those parameters which come from execution variable("createNetworkResponse") + + #2)bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/network/tasks/NetworkAdapterCreateTasks.java – depending on variable networkCreated of response, networkAdapterCreateRollback is set to true. + + #3)bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/network/NetworkAdapterClientImpl.java -Here createNetwork request is processed as a restclient post process with CreateNetworkRequest as input and CreateNetworkResponse as output + + # g.DeleteNetworkError : extends NetworkExceptionResponse + + # h. DeleteNetworkRequest:extends NetworkRequestCommon + private String cloudSiteId; + + private String tenantId; + + private String networkId; + + private String networkStackId; + + private String networkType; + + private String modelCustomizationUuid; + + private MsoRequest msoRequest = new MsoRequest(); + + Usage: + #1)bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/network/tasks/NetworkAdapterDeleteTasks.java – deleteNetworkRequestMapper returns a DeleteNetworkRequest, which is set to the execution variable(“networkAdapterRequest”) + + #2)bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/network/NetworkAdapterClientImpl.java - Here deleteNetwork request is processed as a restclient delete process with DeleteNetworkRequest as input. + + #3)bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/network/mapper/NetworkAdapterObjectMapper.java – Here the deleteNetworkRequestMapper forms DeleteNetworkRequest object + + Similarly others are also implemented and used + +.. image:: ../images/nwrest.png + +Sdnc request +------------ + +#3. Sdnc request -These are required by the mso-sdnc-adapter + + # a. RequestInformation – This is an important parameter of SDNCServiceRequest. Thud is used during the conversion of SDNCServiceRequest to XMLstring. + + # b. ServiceInformation – This stores the important information like serviceId, servicetype and SubscriberName. Its parameter of SDNCServiceRequest. + + # c. SDNCErrorCommon – it extends SDNCResponseCommon . + + Usage : adapters/mso-sdnc-adapter/src/main/java/org/onap/so/adapters/sdnc/sdncrest/SDNCServiceRequestConnector.java – catching exception if any happens during request creation and a new SDNCErrorCommon is created. + + # d. SDNCRequestCommon – SDNCServiceRequest extends SDNCRequestCommon. It has some attributes like bpNotificationUrl(Endpoint on which BPMN can receive notifications from the SDNC adapter), bpTimeout ans sdncrequestId. + + # e. SDNCServiceRequest + Usage: adapters/mso-sdnc-adapter/src/main/java/org/onap/so/adapters/sdnc/sdncrest/SDNCServiceRequestTask.java – Here the runRequest is happening, where we are posting this request using a restclient call with SDNCServiceRequest as input. + + # f. SDNCServiceResponse and SDNCServiceError + Usage:adapters/mso-sdnc-adapter/src/main/java/org/onap/so/adapters/sdnc/sdncrest/SDNCServiceRequestTask.java – Here if the above runRequest returns a 2xx response code then a corresponding SDNCServiceResponse is created and returned or else SDNCServiceError is created and returned + +Tenant request +--------------- + +#4. These provide classes to be used by the so-adapters.tenant. + +The operator of a cloud can present unchangeable networks to the users, or give users the option to create, delete, connect and generally manipulate networks. The latter type of networks is called “tenant networks”. + +Used in adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tenant/TenantAdapterRest.java + +The implementation and usage is similiar to the above classes + +.. image:: ../images/tenantrest.png + +VDU +--- + +#5. Vdu – these are used for the deployment and management of (cloud-agnostic) VDU . The abstract classes for instantiation of vdu, query vdu, delete vdu, update vdu are defined in here. + +These are implemented in adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/utils/MsoCloudifyUtils.java and adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java + +Vnfrest +------- + +#6. Vnfrest – These are used to manage vnfs and vgs. +These are used in the project similiar to networkrest +Foreg : Usage of DeleteVfModuleRequest: + +1)bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/vnf/tasks/VnfAdapterDeleteTasks.java – Here in deleteVfModuleRequestMapper creates a new DeleteVfModuleRequest, and is set to the execution variable(“VNFREST_REQUEST” ) and “deleteVfModuleRequest” execution variable is set true + +2)bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/vnf/VnfAdapterClientImpl.java - Here a delete rest request is send + +.. image:: ../images/vnfrest.png + + +OPENSTACK +--------- +Openstack is classified into beans, exceptions, and mappers + +MAPPERS +------- + # 1) JAXBContext: It is used to convert a object to xml(marshalling) and to convert xml to object (unmarshalling) . These marshalling and unmarshalling are overriden in the map adapters in mappers. + + # 2)NetworkInfoMapper – used to Capture the data from a Neutron Network object and cast it into a networkInfo( present in beans of openstack). Here in vlan information is located depending on network.getProviderNetworkType() , and if not then the segments within the network is iterated and is checked for the same. + Usage: It is used in adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoNeutronUtils.java , where on createNetwork, queryNetwork and updateNetwork , the network is mapped by NetworkInfoMapper into networkInfo and returned. + + # 3) StackInfoMapper – used to Capture the data from a Stack object and cast it into a stackInfo( present in beans of openstack). + Usage: It is used in adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils , where all createStack, queryStack, updateStack, deleteStack is done, a new instance of stackInfo is returned + +Exceptions +---------- +These are set of msoexceptions provided, and would be used depending on what exception needs to be handled + +.. image:: ../images/msoexception.png diff --git a/docs/images/module_structure.png b/docs/images/module_structure.png Binary files differnew file mode 100644 index 0000000000..c25441bd8e --- /dev/null +++ b/docs/images/module_structure.png diff --git a/docs/images/msoexception.png b/docs/images/msoexception.png Binary files differnew file mode 100644 index 0000000000..b9d2dfd5da --- /dev/null +++ b/docs/images/msoexception.png diff --git a/docs/images/nwrest.png b/docs/images/nwrest.png Binary files differnew file mode 100644 index 0000000000..58b66d59e0 --- /dev/null +++ b/docs/images/nwrest.png diff --git a/docs/images/tenantrest.png b/docs/images/tenantrest.png Binary files differnew file mode 100644 index 0000000000..ec1c77e61b --- /dev/null +++ b/docs/images/tenantrest.png diff --git a/docs/images/vnfrest.png b/docs/images/vnfrest.png Binary files differnew file mode 100644 index 0000000000..f61720708d --- /dev/null +++ b/docs/images/vnfrest.png diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java index 87e5a2f23e..60e9c3b30a 100644 --- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java +++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java @@ -518,20 +518,16 @@ public class RequestHandlerUtils extends AbstractRestHandler { } protected String setServiceInstanceId(String requestScope, ServiceInstancesRequest sir) { + String serviceInstanceId = null; if (sir.getServiceInstanceId() != null) { - return sir.getServiceInstanceId(); - } else if (requestScope.equalsIgnoreCase(ModelType.instanceGroup.toString())) { - RelatedInstanceList[] relatedInstances = sir.getRequestDetails().getRelatedInstanceList(); - if (relatedInstances != null) { - for (RelatedInstanceList relatedInstanceList : relatedInstances) { - RelatedInstance relatedInstance = relatedInstanceList.getRelatedInstance(); - if (relatedInstance.getModelInfo().getModelType() == ModelType.service) { - return relatedInstance.getInstanceId(); - } - } + serviceInstanceId = sir.getServiceInstanceId(); + } else { + Optional<String> serviceInstanceIdForInstance = getServiceInstanceIdForInstanceGroup(requestScope, sir); + if (serviceInstanceIdForInstance.isPresent()) { + serviceInstanceId = serviceInstanceIdForInstance.get(); } } - return null; + return serviceInstanceId; } private String requestScopeFromUri(String requestUri) { @@ -916,6 +912,30 @@ public class RequestHandlerUtils extends AbstractRestHandler { return null; } + protected Optional<String> getServiceInstanceIdForValidationError(ServiceInstancesRequest sir, + HashMap<String, String> instanceIdMap, String requestScope) { + if (instanceIdMap != null && !instanceIdMap.isEmpty() && instanceIdMap.get("serviceInstanceId") != null) { + return Optional.of(instanceIdMap.get("serviceInstanceId")); + } else { + return getServiceInstanceIdForInstanceGroup(requestScope, sir); + } + } + + protected Optional<String> getServiceInstanceIdForInstanceGroup(String requestScope, ServiceInstancesRequest sir) { + if (requestScope.equalsIgnoreCase(ModelType.instanceGroup.toString())) { + RelatedInstanceList[] relatedInstances = sir.getRequestDetails().getRelatedInstanceList(); + if (relatedInstances != null) { + for (RelatedInstanceList relatedInstanceList : relatedInstances) { + RelatedInstance relatedInstance = relatedInstanceList.getRelatedInstance(); + if (relatedInstance.getModelInfo().getModelType() == ModelType.service) { + return Optional.ofNullable(relatedInstance.getInstanceId()); + } + } + } + } + return Optional.empty(); + } + private RecipeLookupResult getDefaultVnfUri(ServiceInstancesRequest sir, Actions action) { String defaultSource = getDefaultModel(sir); VnfRecipe vnfRecipe = catalogDbClient.getFirstVnfRecipeByNfRoleAndAction(defaultSource, action.toString()); diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/ServiceInstances.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/ServiceInstances.java index 107aa57974..2c8e92633c 100644 --- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/ServiceInstances.java +++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/ServiceInstances.java @@ -829,7 +829,8 @@ public class ServiceInstances extends AbstractRestHandler { requestValidatorListenerRunner.runValidations(requestUri, instanceIdMap, sir, queryParams, action); } catch (ApiException e) { msoRequest.createErrorRequestRecord(Status.FAILED, requestId, e.getMessage(), action, requestScope, - requestJSON, sir.getServiceInstanceId()); + requestJSON, requestHandlerUtils + .getServiceInstanceIdForValidationError(sir, instanceIdMap, requestScope).orElse(null)); throw e; } diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/RequestHandlerUtilsTest.java b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/RequestHandlerUtilsTest.java index 7f9ff98b19..2ba646fba0 100644 --- a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/RequestHandlerUtilsTest.java +++ b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/RequestHandlerUtilsTest.java @@ -39,6 +39,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.HashMap; import java.util.List; import javax.ws.rs.core.MediaType; import org.apache.http.HttpStatus; @@ -338,4 +339,34 @@ public class RequestHandlerUtilsTest extends BaseTest { assertEquals(expectedBasicAuth, basicAuth); } + @Test + public void getServiceInstanceIdForValidationErrorTest() { + ServiceInstancesRequest sir = new ServiceInstancesRequest(); + String requestScope = "vnf"; + HashMap<String, String> instanceIdMap = new HashMap<String, String>(); + instanceIdMap.put("serviceInstanceId", "testServiceInstanceId"); + String serviceInstanceId = + requestHandlerUtils.getServiceInstanceIdForValidationError(sir, instanceIdMap, requestScope).get(); + assertEquals("testServiceInstanceId", serviceInstanceId); + } + + @Test + public void getServiceInstanceIdForValidationErrorInstanceGroupTest() throws Exception { + ServiceInstancesRequest sir = + mapper.readValue(inputStream("/CreateInstanceGroup.json"), ServiceInstancesRequest.class); + String requestScope = "instanceGroup"; + String serviceInstanceId = + requestHandlerUtils.getServiceInstanceIdForValidationError(sir, null, requestScope).get(); + assertEquals("ddcbbf3d-f2c1-4ca0-8852-76a807285efc", serviceInstanceId); + } + + @Test + public void getServiceInstanceIdForInstanceGroupTest() throws Exception { + ServiceInstancesRequest sir = + mapper.readValue(inputStream("/CreateInstanceGroup.json"), ServiceInstancesRequest.class); + String requestScope = "instanceGroup"; + String serviceInstanceId = requestHandlerUtils.getServiceInstanceIdForInstanceGroup(requestScope, sir).get(); + assertEquals("ddcbbf3d-f2c1-4ca0-8852-76a807285efc", serviceInstanceId); + } + } diff --git a/packages/docker/src/main/docker/docker-files/configs/logging/logback-spring.xml b/packages/docker/src/main/docker/docker-files/configs/logging/logback-spring.xml index dd14091daf..e4be7094df 100644 --- a/packages/docker/src/main/docker/docker-files/configs/logging/logback-spring.xml +++ b/packages/docker/src/main/docker/docker-files/configs/logging/logback-spring.xml @@ -56,6 +56,12 @@ \t%thread \t%n" /> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>${errorPattern}</pattern> + </encoder> + </appender> + <appender name="Audit" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator"> @@ -186,11 +192,12 @@ <appender-ref ref="asyncMetric" /> </logger> - <root level="WARN"> + <root level="INFO"> <appender-ref ref="asyncDebug" /> <appender-ref ref="asyncError" /> <appender-ref ref="asyncAudit" /> <appender-ref ref="asyncMetric" /> + <appender-ref ref="STDOUT" /> </root> </configuration>
\ No newline at end of file @@ -962,7 +962,7 @@ <dependency> <groupId>org.onap.aai.schema-service</groupId> <artifactId>aai-schema</artifactId> - <version>1.7.2</version> + <version>1.7.8</version> </dependency> </dependencies> </dependencyManagement> diff --git a/so-etsi-nfvo/pom.xml b/so-etsi-nfvo/pom.xml index 0b87b259c1..fa85460086 100644 --- a/so-etsi-nfvo/pom.xml +++ b/so-etsi-nfvo/pom.xml @@ -27,6 +27,7 @@ <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-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 6dfe635098..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 @@ -65,5 +65,5 @@ so: etsi-catalog-manager: base: endpoint: http://modeling-etsicatalog.onap:8806/api -etsi-so-ns-lcm-manager: - endpoint: http://so-etsi-nfvo-ns-lcm:9095
\ No newline at end of file +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 39acdd8f50..1c13ecac25 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/pom.xml +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/pom.xml @@ -96,5 +96,11 @@ <artifactId>h2</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest</artifactId> + <version>${hamcrest-version}</version> + <scope>test</scope> + </dependency> </dependencies> </project>
\ No newline at end of file diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java index a373df43e7..65d982c6cc 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java @@ -22,6 +22,7 @@ package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog; import java.util.Optional; import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo; import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor; /** * @author Waqas Ikram (waqas.ikram@est.tech) @@ -33,4 +34,6 @@ public interface EtsiCatalogPackageManagementServiceProvider { Optional<VnfPkgInfo> getVnfPkgInfo(final String vnfPkgId); + Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor(final String nsdId); + } diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java index 32f7cc1182..75dd7107a7 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProviderImpl.java @@ -24,6 +24,8 @@ import java.util.Optional; import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo; import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo; import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.EtsiCatalogManagerRequestFailureException; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptorParser; import org.onap.so.rest.service.HttpRestServiceProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,12 +45,15 @@ public class EtsiCatalogPackageManagementServiceProviderImpl implements EtsiCata private final HttpRestServiceProvider httpServiceProvider; private final EtsiCatalogUrlProvider etsiCatalogUrlProvider; + private final NetworkServiceDescriptorParser networkServiceDescriptorParser; @Autowired public EtsiCatalogPackageManagementServiceProviderImpl(final EtsiCatalogUrlProvider etsiCatalogUrlProvider, - @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider) { + @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider, + final NetworkServiceDescriptorParser networkServiceDescriptorParser) { this.etsiCatalogUrlProvider = etsiCatalogUrlProvider; this.httpServiceProvider = httpServiceProvider; + this.networkServiceDescriptorParser = networkServiceDescriptorParser; } @Override @@ -83,4 +88,23 @@ public class EtsiCatalogPackageManagementServiceProviderImpl implements EtsiCata } } + @Override + public Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor(final String nsdId) { + try { + final ResponseEntity<byte[]> response = httpServiceProvider + .getHttpResponse(etsiCatalogUrlProvider.getNsPackageContentUrl(nsdId), byte[].class); + if (response.getStatusCode().is2xxSuccessful()) { + if (response.hasBody()) { + return networkServiceDescriptorParser.parse(response.getBody()); + } + logger.error("Received response without body ..."); + } + return Optional.empty(); + } catch (final Exception restProcessingException) { + logger.error("Caught exception while getting NS package content for: {}", nsdId, restProcessingException); + throw new EtsiCatalogManagerRequestFailureException("Internal Server Error Occurred.", + restProcessingException); + } + } + } diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java index 692aff62cd..f3c38e537f 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java @@ -21,12 +21,19 @@ package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service; import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_REQUEST_PARAM_NAME; import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.GLOBAL_CUSTOMER_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.INSTANTIATE_NS_REQUEST_PARAM_NAME; import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.JOB_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OCC_ID_PARAM_NAME; import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.SERVICE_TYPE_PARAM_NAME; import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.CREATE_NS_WORKFLOW_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.INSTANTIATE_NS_WORKFLOW_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction.INSTANTIATE; import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.ERROR; import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED; import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED_WITH_ERROR; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.STARTING; import static org.slf4j.LoggerFactory.getLogger; import java.time.Instant; import java.time.LocalDateTime; @@ -35,19 +42,25 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.tuple.ImmutablePair; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider; import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.NsRequestProcessingException; import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction; import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum; import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpType; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum; import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest; import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400; +import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest; import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.google.common.collect.ImmutableSet; +import com.google.gson.Gson; /** * @author Waqas Ikram (waqas.ikram@est.tech) @@ -69,13 +82,16 @@ public class JobExecutorService { private final DatabaseServiceProvider databaseServiceProvider; private final WorkflowExecutorService workflowExecutorService; private final WorkflowQueryService workflowQueryService; + private Gson gson; @Autowired public JobExecutorService(final DatabaseServiceProvider databaseServiceProvider, - final WorkflowExecutorService workflowExecutorService, final WorkflowQueryService workflowQueryService) { + final WorkflowExecutorService workflowExecutorService, final WorkflowQueryService workflowQueryService, + final GsonProvider gsonProvider) { this.databaseServiceProvider = databaseServiceProvider; this.workflowExecutorService = workflowExecutorService; this.workflowQueryService = workflowQueryService; + gson = gsonProvider.getGson(); } public NsInstancesNsInstance runCreateNsJob(final CreateNsRequest createNsRequest, final String globalCustomerId, @@ -130,6 +146,50 @@ public class JobExecutorService { return optional.get(); } + public String runInstantiateNsJob(final String nsInstanceId, final InstantiateNsRequest instantiateNsRequest) { + + final NfvoJob newJob = new NfvoJob().startTime(LocalDateTime.now()).jobType("NS").jobAction(INSTANTIATE) + .resourceId(nsInstanceId).status(STARTING).progress(0); + databaseServiceProvider.addJob(newJob); + logger.info("New job created in database :\n{}", newJob); + + final LocalDateTime currentDateTime = LocalDateTime.now(); + final NsLcmOpOcc newNsLcmOpOcc = new NsLcmOpOcc().id(nsInstanceId).operation(NsLcmOpType.INSTANTIATE) + .operationState(OperationStateEnum.PROCESSING).stateEnteredTime(currentDateTime) + .startTime(currentDateTime).isAutoInnovation(false).isCancelPending(false) + .operationParams(gson.toJson(instantiateNsRequest)); + databaseServiceProvider.addNSLcmOpOcc(newNsLcmOpOcc); + logger.info("New NSLcmOpOcc created in database :\n{}", newNsLcmOpOcc); + + workflowExecutorService.executeWorkflow(newJob.getJobId(), INSTANTIATE_NS_WORKFLOW_NAME, + getVariables(nsInstanceId, newJob.getJobId(), newNsLcmOpOcc.getId(), instantiateNsRequest)); + + final ImmutableSet<JobStatusEnum> jobFinishedStates = + ImmutableSet.of(FINISHED, ERROR, FINISHED_WITH_ERROR, IN_PROGRESS); + final ImmutablePair<String, JobStatusEnum> immutablePair = + waitForJobToFinish(newJob.getJobId(), jobFinishedStates); + + if (immutablePair.getRight() == null) { + final String message = "Failed to Instantiate NS for request: \n" + instantiateNsRequest; + logger.error(message); + throw new NsRequestProcessingException(message); + } + + final JobStatusEnum finalJobStatus = immutablePair.getRight(); + + if (IN_PROGRESS.equals(finalJobStatus) || FINISHED.equals(finalJobStatus)) { + logger.info("Instantiation Job status: {}", finalJobStatus); + + + return newNsLcmOpOcc.getId(); + } + + final String message = "Received unexpected Job Status: " + finalJobStatus + + " Failed to instantiate NS for request: \n" + instantiateNsRequest; + logger.error(message); + throw new NsRequestProcessingException(message); + } + private ImmutablePair<String, JobStatusEnum> waitForJobToFinish(final String jobId, final ImmutableSet<JobStatusEnum> jobFinishedStates) { try { @@ -179,4 +239,14 @@ public class JobExecutorService { return variables; } + private Map<String, Object> getVariables(final String nsInstanceId, final String jobId, final String occId, + final InstantiateNsRequest instantiateNsRequest) { + final Map<String, Object> variables = new HashMap<>(); + variables.put(NS_INSTANCE_ID_PARAM_NAME, nsInstanceId); + variables.put(JOB_ID_PARAM_NAME, jobId); + variables.put(OCC_ID_PARAM_NAME, occId); + variables.put(INSTANTIATE_NS_REQUEST_PARAM_NAME, instantiateNsRequest); + return variables; + } + } diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateRequest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateRequest.java new file mode 100644 index 0000000000..569d9b3352 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateRequest.java @@ -0,0 +1,167 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.io.Serializable; +import java.util.Map; +import java.util.Objects; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.Tenant; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class CreateInstantiateRequest implements Serializable { + private static final long serialVersionUID = -4371264952509580468L; + private String nsInstId; + private String vnfdId; + private String vnfName; + private String vnfPkgId; + private String nfType; + private Tenant tenant; + private Map<String, String> additionalParams; + + public String getNsInstId() { + return nsInstId; + } + + public void setNsInstId(final String nsInstId) { + this.nsInstId = nsInstId; + } + + public CreateInstantiateRequest nsInstId(final String nsInstId) { + this.nsInstId = nsInstId; + return this; + } + + public final String getVnfdId() { + return vnfdId; + } + + public final void setVnfdId(final String vnfdId) { + this.vnfdId = vnfdId; + } + + public CreateInstantiateRequest vnfdId(final String vnfdId) { + this.vnfdId = vnfdId; + return this; + } + + public final String getVnfName() { + return vnfName; + } + + public final void setVnfName(final String vnfName) { + this.vnfName = vnfName; + } + + public CreateInstantiateRequest vnfName(final String vnfName) { + this.vnfName = vnfName; + return this; + } + + public final String getVnfPkgId() { + return vnfPkgId; + } + + public final void setVnfPkgId(final String vnfPkgId) { + this.vnfPkgId = vnfPkgId; + } + + public CreateInstantiateRequest vnfPkgId(final String vnfPkgId) { + this.vnfPkgId = vnfPkgId; + return this; + } + + public final String getNfType() { + return nfType; + } + + public final void setNfType(final String nfType) { + this.nfType = nfType; + } + + public CreateInstantiateRequest nfType(final String nfType) { + this.nfType = nfType; + return this; + } + + public final Tenant getTenant() { + return tenant; + } + + public final void setTenant(final Tenant tenant) { + this.tenant = tenant; + } + + public CreateInstantiateRequest tenant(final Tenant tenant) { + this.tenant = tenant; + return this; + } + + public final Map<String, String> getAdditionalParams() { + return additionalParams; + } + + public final void setAdditionalParams(final Map<String, String> additionalParams) { + this.additionalParams = additionalParams; + } + + public CreateInstantiateRequest additionalParams(final Map<String, String> additionalParams) { + this.additionalParams = additionalParams; + return this; + } + + @Override + public int hashCode() { + return Objects.hash(nsInstId, vnfdId, vnfName, vnfPkgId, nfType, tenant, additionalParams); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof CreateInstantiateRequest) { + final CreateInstantiateRequest other = (CreateInstantiateRequest) obj; + return Objects.equals(nsInstId, other.nsInstId) && Objects.equals(vnfdId, other.vnfdId) + && Objects.equals(vnfName, other.vnfName) && Objects.equals(vnfPkgId, other.vnfPkgId) + && Objects.equals(nfType, other.nfType) && Objects.equals(tenant, other.tenant) + && Objects.equals(additionalParams, other.additionalParams); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class CreateInstantiateRequest {\n"); + sb.append(" nsInstId: ").append(toIndentedString(nsInstId)).append("\n"); + sb.append(" vnfdId: ").append(toIndentedString(vnfdId)).append("\n"); + sb.append(" vnfName: ").append(toIndentedString(vnfName)).append("\n"); + sb.append(" vnfPkgId: ").append(toIndentedString(vnfPkgId)).append("\n"); + sb.append(" nfType: ").append(toIndentedString(nfType)).append("\n"); + sb.append(" tenant: ").append(toIndentedString(tenant)).append("\n"); + sb.append(" additionalParams: ").append(toIndentedString(additionalParams)).append("\n"); + + sb.append("}"); + return sb.toString(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateVnfTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateVnfTask.java new file mode 100644 index 0000000000..c33c67e540 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateVnfTask.java @@ -0,0 +1,234 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.ERROR; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS; +import java.time.LocalDateTime; +import java.util.Optional; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.onap.aai.domain.yang.GenericVnf; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfRequest; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.Tenant; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + */ +@Component +public class CreateInstantiateVnfTask extends AbstractNetworkServiceTask { + private static final Logger logger = LoggerFactory.getLogger(CreateInstantiateVnfTask.class); + private static final String NF_INST_ID_PARAM_NAME = "NF_INST_ID"; + public static final String CREATE_VNF_RESPONSE_PARAM_NAME = "createVnfResponse"; + private final AaiServiceProvider aaiServiceProvider; + private final Sol003AdapterServiceProvider sol003AdapterServiceProvider; + + @Autowired + public CreateInstantiateVnfTask(final DatabaseServiceProvider databaseServiceProvider, + final AaiServiceProvider aaiServiceProvider, + final Sol003AdapterServiceProvider sol003AdapterServiceProvider) { + super(databaseServiceProvider); + this.aaiServiceProvider = aaiServiceProvider; + this.sol003AdapterServiceProvider = sol003AdapterServiceProvider; + } + + public void checkIfNfInstanceExistsInDb(final DelegateExecution execution) { + logger.info("Executing checkIfNfInstanceInDb"); + final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request"); + logger.info("request: {}", request); + + setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Checking if NF Instance record exists in database for " + + request.getNsInstId() + " and " + request.getVnfName()); + if (!databaseServiceProvider.isNsInstExists(request.getNsInstId(), request.getVnfName())) { + abortOperation(execution, + request.getNsInstId() + " " + request.getVnfName() + " VNF instance already exists"); + } + logger.info("Finished executing checkIfNfInstanceInDb ..."); + + } + + public void createNfInstanceInDb(final DelegateExecution execution) { + logger.info("Executing createNfInstanceInDb"); + final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request"); + logger.info("request: {}", request); + + setJobStatus(execution, IN_PROGRESS, "Creating NF Instance record in database for " + request.getVnfName()); + + final Optional<NfvoNsInst> optional = databaseServiceProvider.getNfvoNsInst(request.getNsInstId()); + + if (optional.isEmpty()) { + abortOperation(execution, "NfvoNsInst: " + request.getNsInstId() + "not founda"); + } + + final NfvoNsInst nfvoNsInst = optional.get(); + final LocalDateTime now = LocalDateTime.now(); + final NfvoNfInst nfvoNfInst = new NfvoNfInst().status(State.NOT_INSTANTIATED).createTime(now) + .lastUpdateTime(now).name(request.getVnfName()).vnfdId(request.getVnfdId()) + .packageId(request.getVnfPkgId()).nfvoNsInst(nfvoNsInst); + databaseServiceProvider.saveNfvoNfInst(nfvoNfInst); + execution.setVariable(NF_INST_ID_PARAM_NAME, nfvoNfInst.getNfInstId()); + logger.info("Finished executing createNfInstanceInDb ..."); + + } + + public void createGenericVnfInAai(final DelegateExecution execution) { + logger.info("Executing createGenericVnfInAai"); + try { + final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request"); + + setJobStatus(execution, IN_PROGRESS, "Creating GenericVnf record in AAI for " + request.getVnfName()); + + final String nfInstId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME); + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId); + + final GenericVnf genericVnf = new GenericVnf(); + genericVnf.setVnfId(nfInstId); + genericVnf.setVnfName(request.getVnfName()); + genericVnf.setVnfType(nfvoNsInst.getName() + "/" + request.getVnfName()); + genericVnf.setServiceId(request.getNsInstId()); + genericVnf.setNfType(request.getNfType()); + genericVnf.setOperationalStatus("Created"); + genericVnf.setIsClosedLoopDisabled(false); + + aaiServiceProvider.createGenericVnfAndConnectServiceInstance(nsInstId, nfInstId, genericVnf); + + final Tenant tenant = request.getTenant(); + aaiServiceProvider.connectGenericVnfToTenant(nfInstId, tenant.getCloudOwner(), tenant.getRegionName(), + tenant.getTenantId()); + + } catch (final Exception exception) { + final String message = "Unable to Create GenericVnf in AAI"; + logger.error(message, exception); + abortOperation(execution, message); + } + + logger.info("Finished executing createGenericVnfInAai ..."); + } + + public void invokeCreateInstantiationRequest(final DelegateExecution execution) { + logger.info("Executing invokeCreateInstantiationRequest"); + + try { + final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request"); + logger.info("request: {}", request); + + setJobStatus(execution, IN_PROGRESS, + "Invoking SOL003 adapter for creating and instantiating VNF: " + request.getVnfName()); + + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId); + final CreateVnfRequest vnfRequest = new CreateVnfRequest(); + vnfRequest.setTenant(request.getTenant()); + vnfRequest.setName(nfvoNsInst.getName() + "." + request.getVnfName()); + vnfRequest.setPkgId(request.getVnfPkgId()); + vnfRequest.setAdditionalParams(request.getAdditionalParams()); + final String vnfId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME); + final Optional<CreateVnfResponse> optional = + sol003AdapterServiceProvider.invokeCreateInstantiationRequest(vnfId, vnfRequest); + + if (!optional.isPresent()) { + final String errorMessage = "Unexpected error while processing create and instantiation request"; + logger.error(errorMessage); + abortOperation(execution, errorMessage); + } + + final CreateVnfResponse vnfResponse = optional.get(); + + logger.info("Vnf instantiation response: {}", vnfResponse); + execution.setVariable(CREATE_VNF_RESPONSE_PARAM_NAME, vnfResponse); + setJobStatus(execution, IN_PROGRESS, "Successfully invoked SOL003 adapater creating and instantiating VNF: " + + request.getVnfName() + " CreaetVnfResponse Job Id: " + vnfResponse.getJobId()); + logger.debug("Finished executing invokeCreateInstantiationRequest ..."); + } catch (final Exception exception) { + final String message = "Unable to invoke create and instantiation request"; + logger.error(message, exception); + abortOperation(execution, message); + } + + } + + public void updateNfInstanceStatusToInstantiated(final DelegateExecution execution) { + logger.info("Executing updateNfInstanceStatusToInstantiated"); + + updateNfInstanceStatus(execution, State.INSTANTIATED); + final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request"); + setJobStatus(execution, FINISHED, "Successfully created and Instantiated VNF: " + request.getVnfName() + + " will set status to " + State.INSTANTIATED); + + logger.info("Finished executing updateNfInstanceStatusToInstantiated ..."); + + } + + public void updateNfInstanceStatusToFailed(final DelegateExecution execution) { + logger.info("Executing updateNfInstanceStatusToActive"); + + updateNfInstanceStatus(execution, State.FAILED); + final CreateInstantiateRequest request = (CreateInstantiateRequest) execution.getVariable("request"); + setJobStatus(execution, ERROR, "Failed to create and instantiate VNF: " + request.getVnfName() + + " will set status to " + State.FAILED); + + logger.info("Finished executing updateNfInstanceStatusToInstantiated ..."); + + } + + private void updateNfInstanceStatus(final DelegateExecution execution, final State vnfStatus) { + final String nfInstId = (String) execution.getVariable(NF_INST_ID_PARAM_NAME); + + final Optional<NfvoNfInst> optional = databaseServiceProvider.getNfvoNfInst(nfInstId); + if (!optional.isPresent()) { + final String message = "Unable to find NfvoNfInst record in database using nfInstId: " + nfInstId; + logger.error(message); + + abortOperation(execution, message); + + } + + final NfvoNfInst nfvoNfInst = optional.get(); + nfvoNfInst.setStatus(vnfStatus); + databaseServiceProvider.saveNfvoNfInst(nfvoNfInst); + } + + private NfvoNsInst getNfvoNsInst(final DelegateExecution execution, final String nsInstId) { + logger.info("Getting NfvoNsInst to update with nsInstId: {}", nsInstId); + final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstId); + + if (!optionalNfvoNsInst.isPresent()) { + final String message = "Unable to find NS Instance in datababse using id: " + nsInstId; + abortOperation(execution, message); + } + + return optionalNfvoNsInst.get(); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/InstantiateNsTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/InstantiateNsTask.java new file mode 100644 index 0000000000..8d212045ad --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/InstantiateNsTask.java @@ -0,0 +1,416 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks; + +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.INSTANTIATE_NS_REQUEST_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OCC_ID_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.VNF_CREATE_INSTANTIATE_REQUESTS; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS; +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.STARTED; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.Tenant; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.EtsiCatalogManagerRequestFailureException; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogPackageManagementServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.VirtualNetworkFunction; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @author Andrew Lamb (andrew.a.lamb@est.tech) + * + */ +@Component +public class InstantiateNsTask extends AbstractNetworkServiceTask { + + private static final String IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME = "isNsInstantiationSuccessful"; + private static final String VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME = "vnfdIdToVnfPkgIdMapping"; + private static final Logger logger = LoggerFactory.getLogger(InstantiateNsTask.class); + private final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider; + + @Autowired + public InstantiateNsTask(final DatabaseServiceProvider databaseServiceProvider, + final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider) { + super(databaseServiceProvider); + this.etsiCatalogPackageManagementServiceProvider = etsiCatalogPackageManagementServiceProvider; + + } + + public void setJobStatusToStarted(final DelegateExecution execution) { + setJobStatus(execution, STARTED, "Instantiate NS workflow process started"); + } + + public void setJobStatusToFinished(final DelegateExecution execution) { + setJobStatus(execution, FINISHED, "Instantiate NS workflow process finished"); + } + + public void updateNsInstanceStatusToInstantiating(final DelegateExecution execution) { + logger.info("Executing updateNsInstanceStatusToInstantiating"); + setJobStatus(execution, IN_PROGRESS, "Updating NfvoNsInst Status to " + State.INSTANTIATING); + updateNsInstanceStatus(execution, State.INSTANTIATING); + + logger.info("Finished executing updateNsInstanceStatusToInstantiating ..."); + } + + + public void checkIfVnfInstantiationWasSuccessful(final DelegateExecution execution) { + logger.info("Executing checkIfVnfInstantiationWasSuccessful"); + + @SuppressWarnings("unchecked") + final List<CreateInstantiateRequest> requests = + (List<CreateInstantiateRequest>) execution.getVariable(VNF_CREATE_INSTANTIATE_REQUESTS); + + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId); + + if (nfInstances == null || nfInstances.isEmpty()) { + final String message = "Found empty nf instances"; + abortOperation(execution, message); + } + + if (requests.size() != nfInstances.size()) { + final String message = "Missing nf Instance. Request triggered: " + requests.size() + + " Nf Instace reqeust found in database " + nfInstances.size(); + abortOperation(execution, message); + } + + execution.setVariable(IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME, true); + + nfInstances.stream().forEach(instance -> { + if (!State.INSTANTIATED.equals(instance.getStatus())) { + logger.error("VNF : {} {} instantiation failed", instance.getNfInstId(), instance.getName()); + execution.setVariable(IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME, false); + } + }); + + logger.info("Finished executing checkIfVnfInstantiationWasSuccessful ..."); + } + + public void updateNsInstanceStatusToInstantiated(final DelegateExecution execution) { + logger.info("Executing updateNsInstanceStatusToInstantiated"); + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + setJobStatus(execution, FINISHED, "Successfully " + State.INSTANTIATED + " NS: " + nsInstId); + + updateNsInstanceStatus(execution, State.INSTANTIATED); + logger.info("Finished executing updateNsInstanceStatusToInstantiated ..."); + } + + public void getAndParseNsdFromEtsiCatalog(final DelegateExecution execution) { + logger.info("Executing getAndParseNsdFromEtsiCatalog"); + setJobStatus(execution, IN_PROGRESS, "Retrieving and parsing NSD from ETSI Catalog Manager"); + final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution); + final String nsPackageId = nfvoNsInst.getNsPackageId(); + + try { + final Optional<NetworkServiceDescriptor> optional = + etsiCatalogPackageManagementServiceProvider.getNetworkServiceDescriptor(nsPackageId); + + if (!optional.isPresent()) { + final String message = "Unable to parse NSD " + nsPackageId; + logger.error(message); + abortOperation(execution, message); + } + + final NetworkServiceDescriptor networkServiceDescriptor = optional.get(); + logger.info("Found {}", networkServiceDescriptor); + execution.setVariable(NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME, networkServiceDescriptor); + + } catch (final EtsiCatalogManagerRequestFailureException failureException) { + final String message = + "Unexpected exception occured while getting nsd content using nsPackageId: " + nsPackageId; + logger.error(message, failureException); + + abortOperation(execution, message); + } + + logger.info("Finished executing getAndParseNsdFromEtsiCatalog ..."); + + } + + public void prepareCreateInstantiateRequests(final DelegateExecution execution) { + logger.info("Executing prepareCreateInstantiateRequests ..."); + setJobStatus(execution, IN_PROGRESS, "Preparing VNF CreateInstantiate requests"); + final NetworkServiceDescriptor networkServiceDescriptor = + (NetworkServiceDescriptor) execution.getVariable(NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME); + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + + final InstantiateNsRequest instantiateNsRequest = + (InstantiateNsRequest) execution.getVariable(INSTANTIATE_NS_REQUEST_PARAM_NAME); + + final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList = + instantiateNsRequest.getAdditionalParamsForVnf(); + + @SuppressWarnings("unchecked") + final Map<String, String> vnfdIdToVnfPkgIdMapping = + (Map<String, String>) execution.getVariable(VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME); + + final List<CreateInstantiateRequest> requests = new ArrayList<>(); + + for (final VirtualNetworkFunction vnf : networkServiceDescriptor.getVnfs()) { + final List<String> vnfmInfoList = vnf.getVnfmInfoList(); + + final String vnfdId = vnf.getVnfdId(); + final String vnfPkgId = vnfdIdToVnfPkgIdMapping.get(vnfdId); + if (vnfdId == null || vnfmInfoList.isEmpty() || vnfPkgId == null) { + final String message = "Unable to find VnfdId/vnfmInfo/VnfPkgId for vnf: " + vnf; + abortOperation(execution, message); + } + + final Optional<Tenant> optional = getTenant(vnfPkgId, additionalParamsForVnfList); + if (!optional.isPresent()) { + final String message = "Unable to find Tenant information for " + vnfdId + " in instantiateNsRequest : " + + instantiateNsRequest; + abortOperation(execution, message); + } + + final Tenant tenant = optional.get(); + final CreateInstantiateRequest createInstantiateRequest = new CreateInstantiateRequest().nsInstId(nsInstId) + .vnfdId(vnfdId).vnfName(vnf.getVnfName()).vnfPkgId(vnfPkgId).nfType(vnfmInfoList.get(0)) + .tenant(tenant).additionalParams(getAdditionalParams(vnfPkgId, additionalParamsForVnfList)); + + logger.info("Adding request to list: {}", createInstantiateRequest); + requests.add(createInstantiateRequest); + + } + execution.setVariable(VNF_CREATE_INSTANTIATE_REQUESTS, requests); + + logger.info("Finished executing prepareCreateInstantiateRequests ..."); + } + + public void getVnfPkgIdForEachVnfdId(final DelegateExecution execution) { + logger.info("Executing getVnfPkgIdForEachVnfdId ..."); + + setJobStatus(execution, IN_PROGRESS, "Getting VnfPkgId for each VnfdId"); + + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId); + + final String nsPackageId = nfvoNsInst.getNsPackageId(); + final NsdInfo nsdInfo = getNsdInfo(execution, nsPackageId); + + final Map<String, String> vnfdIdToVnfPkgIdMapping = new HashMap<>(); + try { + for (final String vnfPkgId : nsdInfo.getVnfPkgIds()) { + final Optional<VnfPkgInfo> optional = + etsiCatalogPackageManagementServiceProvider.getVnfPkgInfo(vnfPkgId); + + if (!optional.isPresent()) { + final String message = "Unable to find VNF package using NS vnfPkgId: " + vnfPkgId; + logger.error(message); + abortOperation(execution, message); + } + final VnfPkgInfo vnfPkgInfo = optional.get(); + vnfdIdToVnfPkgIdMapping.put(vnfPkgInfo.getVnfdId(), vnfPkgId); + + } + logger.info("vnfdIdToVnfPkgIdMapping: {}", vnfdIdToVnfPkgIdMapping); + execution.setVariable(VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME, vnfdIdToVnfPkgIdMapping); + + } catch (final EtsiCatalogManagerRequestFailureException failureException) { + final String message = + "Unexpected exception occured while getting VNF package using nsPackageId: " + nsPackageId; + logger.error(message, failureException); + + abortOperation(execution, message); + } + + logger.info("Finished executing getVnfPkgIdForEachVnfdId ..."); + + } + + public void logTimeOut(final DelegateExecution execution) { + logger.error("Vnf instantiation timedOut ..."); + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId); + if (nfInstances != null) { + nfInstances.stream().forEach(instance -> { + logger.info("Current status {} of vnf: {}", instance.getStatus(), instance.getName()); + }); + } + } + + public void setJobStatusToError(final DelegateExecution execution) { + updateNsInstanceStatus(execution, State.FAILED); + setJobStatusToError(execution, "Instantiate NS workflow process failed"); + } + + + public void updateNsLcmOpOccStatusToCompleted(final DelegateExecution execution) { + logger.info("Executing updateNsLcmOpOccStatusToCompleted ..."); + final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME); + + final Optional<NsLcmOpOcc> optional = databaseServiceProvider.getNsLcmOpOcc(occId); + + if (!optional.isPresent()) { + final String message = "Unable to find record for NSLcmOpOcc in database using id: " + occId; + logger.error(message); + abortOperation(execution, message); + } + + final NsLcmOpOcc nsLcmOpOcc = optional.get(); + final OperationStateEnum operationStateCompleted = OperationStateEnum.COMPLETED; + logger.info("Setting operation state to {} for id: {}", operationStateCompleted, occId); + nsLcmOpOcc.setOperationState(operationStateCompleted); + databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc); + + logger.info("Finished executing updateNsLcmOpOccStatusToCompleted ..."); + + } + + public void updateNsLcmOpOccStatusToFailed(final DelegateExecution execution) { + logger.info("Executing updateNsLcmOpOccStatusToFailed ..."); + final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME); + + final Optional<NsLcmOpOcc> optional = databaseServiceProvider.getNsLcmOpOcc(occId); + + if (optional.isPresent()) { + final NsLcmOpOcc nsLcmOpOcc = optional.get(); + final OperationStateEnum operationStateFailed = OperationStateEnum.FAILED; + logger.info("Setting operation state to {} for id: {}", operationStateFailed, occId); + nsLcmOpOcc.setOperationState(operationStateFailed); + + databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc); + } else { + logger.error("Unable to find record for NSLcmOpOcc in database using id: {}", occId); + } + + logger.info("Finished executing updateNsLcmOpOccStatusToFailed ..."); + + } + + private NsdInfo getNsdInfo(final DelegateExecution execution, final String nsPackageId) { + try { + final Optional<NsdInfo> optional = + etsiCatalogPackageManagementServiceProvider.getNSPackageModel(nsPackageId); + + if (optional.isPresent()) { + final NsdInfo packageModel = optional.get(); + logger.info("NS Package exists {}", packageModel); + return packageModel; + } + + } catch (final EtsiCatalogManagerRequestFailureException failureException) { + final String message = + "Unexpected exception occured while getting ns package using nsPackageId: " + nsPackageId; + logger.error(message, failureException); + + abortOperation(execution, message); + } + + final String message = "Unable to find NS package using NS package id: " + nsPackageId; + logger.error(message); + abortOperation(execution, message); + return null; + + } + + private void updateNsInstanceStatus(final DelegateExecution execution, final State nsStatus) { + final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution); + logger.info("Updating NfvoNsInst Status to {} and saving to DB", nsStatus); + nfvoNsInst.setStatus(nsStatus); + databaseServiceProvider.saveNfvoNsInst(nfvoNsInst); + } + + private Optional<Tenant> getTenant(final String vnfPkgId, + final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList) { + + final Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> optional = additionalParamsForVnfList + .stream().filter(entry -> vnfPkgId.equals(entry.getVnfProfileId())).findFirst(); + + if (optional.isPresent()) { + final NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf additionalParamsForVnf = optional.get(); + @SuppressWarnings("unchecked") + final Map<String, Object> additionalParams = + (Map<String, Object>) additionalParamsForVnf.getAdditionalParams(); + final String vimId = (String) additionalParams.get("vim_id"); + if (vimId != null) { + final String[] splitString = vimId.split("_"); + if (splitString.length == 3) { + logger.info("Found Tenant in instantiateNsRequest using vnfPkgId: {}", vnfPkgId); + return Optional.of(new Tenant().cloudOwner(splitString[0]).regionName(splitString[1]) + .tenantId(splitString[2])); + } + + } + } + + logger.error("Unable to find Tenant in instantiateNsRequest using vnfPkgId: {}", vnfPkgId); + return Optional.empty(); + } + + @SuppressWarnings("unchecked") + private Map<String, String> getAdditionalParams(final String vnfPkgId, + final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList) { + + final Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> optional = additionalParamsForVnfList + .stream().filter(entry -> vnfPkgId.equals(entry.getVnfProfileId())).findFirst(); + + if (optional.isPresent()) { + final NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf additionalParamsForVnf = optional.get(); + if (additionalParamsForVnf instanceof Map) { + logger.info("Found AdditionalParams in instantiateNsRequest using vnfPkgId: {}", vnfPkgId); + return (Map<String, String>) additionalParamsForVnf.getAdditionalParams(); + } + } + + return Collections.emptyMap(); + + } + + private NfvoNsInst getNfvoNsInst(final DelegateExecution execution) { + final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME); + return getNfvoNsInst(execution, nsInstId); + } + + private NfvoNsInst getNfvoNsInst(final DelegateExecution execution, final String nsInstId) { + logger.info("Getting NfvoNsInst to update with nsInstId: {}", nsInstId); + final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstId); + + if (!optionalNfvoNsInst.isPresent()) { + final String message = "Unable to find NS Instance in database using id: " + nsInstId; + abortOperation(execution, message); + } + + return optionalNfvoNsInst.get(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn new file mode 100644 index 0000000000..025faa4128 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/CreateInstantiateVnf.bpmn @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="UTF-8"?> +<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1uf6nd9" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.0.0"> + <bpmn:process id="CreateInstantiateVnf" name="CreateInstantiateVnf" isExecutable="true"> + <bpmn:startEvent id="StartEvent_1"> + <bpmn:outgoing>Flow_02bjz2v</bpmn:outgoing> + </bpmn:startEvent> + <bpmn:serviceTask id="Activity_19rmtjr" name="Create NF Instance (VNF) record in DB" camunda:expression="${CreateInstantiateVnfTask.createNfInstanceInDb(execution)}"> + <bpmn:incoming>Flow_123uagz</bpmn:incoming> + <bpmn:outgoing>Flow_03p6ifi</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_02bjz2v" sourceRef="StartEvent_1" targetRef="Activity_1cluqgp" /> + <bpmn:endEvent id="Event_14qdixj"> + <bpmn:incoming>Flow_0srinh7</bpmn:incoming> + </bpmn:endEvent> + <bpmn:sequenceFlow id="Flow_03p6ifi" sourceRef="Activity_19rmtjr" targetRef="Activity_0rto3n3" /> + <bpmn:serviceTask id="Activity_0rto3n3" name="Create Generic VNF and Connect to Service Instance in AAI" camunda:expression="${CreateInstantiateVnfTask.createGenericVnfInAai(execution)}"> + <bpmn:incoming>Flow_03p6ifi</bpmn:incoming> + <bpmn:outgoing>Flow_1c3kc4e</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1c3kc4e" sourceRef="Activity_0rto3n3" targetRef="ServiceTask_0iry5yw" /> + <bpmn:serviceTask id="Activity_1cluqgp" name="Check If NF Instance (VNF) exists in DB" camunda:expression="${CreateInstantiateVnfTask.checkIfNfInstanceExistsInDb(execution)}"> + <bpmn:incoming>Flow_02bjz2v</bpmn:incoming> + <bpmn:outgoing>Flow_123uagz</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_123uagz" sourceRef="Activity_1cluqgp" targetRef="Activity_19rmtjr" /> + <bpmn:serviceTask id="ServiceTask_0iry5yw" name=" Invoke VNFM Adaptor " camunda:asyncAfter="true" camunda:expression="${CreateInstantiateVnfTask.invokeCreateInstantiationRequest(execution)}"> + <bpmn:incoming>Flow_1c3kc4e</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_0xzptc2</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:callActivity id="CallActivity_1yilxx3" name="Monitor Sol003 adapter Instantiation Job" calledElement="MonitorSol003AdapterCreateJob"> + <bpmn:extensionElements> + <camunda:in source="createVnfResponse" target="createVnfResponse" /> + <camunda:in source="jobId" target="jobId" /> + </bpmn:extensionElements> + <bpmn:incoming>SequenceFlow_0xzptc2</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_053tvct</bpmn:outgoing> + </bpmn:callActivity> + <bpmn:callActivity id="CallActivity_0p84lpt" name="Monitor Sol003 adapter Create Node Status" calledElement="MonitorSol003AdapterCreateNodeStatus"> + <bpmn:extensionElements> + <camunda:in source="NF_INST_ID" target="NF_INST_ID" /> + <camunda:in source="createVnfResponse" target="createVnfResponse" /> + </bpmn:extensionElements> + <bpmn:incoming>SequenceFlow_053tvct</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_0h7yluk</bpmn:outgoing> + </bpmn:callActivity> + <bpmn:sequenceFlow id="SequenceFlow_0xzptc2" sourceRef="ServiceTask_0iry5yw" targetRef="CallActivity_1yilxx3" /> + <bpmn:sequenceFlow id="SequenceFlow_053tvct" sourceRef="CallActivity_1yilxx3" targetRef="CallActivity_0p84lpt" /> + <bpmn:sequenceFlow id="SequenceFlow_0h7yluk" sourceRef="CallActivity_0p84lpt" targetRef="Activity_0g3dip7" /> + <bpmn:serviceTask id="Activity_0g3dip7" name="Update NF Instance (VNF) Status to INSTANTIATED" camunda:expression="${CreateInstantiateVnfTask.updateNfInstanceStatusToInstantiated(execution)}"> + <bpmn:incoming>SequenceFlow_0h7yluk</bpmn:incoming> + <bpmn:outgoing>Flow_0srinh7</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_0srinh7" sourceRef="Activity_0g3dip7" targetRef="Event_14qdixj" /> + <bpmn:subProcess id="Activity_0qtgdm9" name="Error Handling" triggeredByEvent="true"> + <bpmn:startEvent id="Event_08zcwc2" name="error"> + <bpmn:outgoing>Flow_06q1m6i</bpmn:outgoing> + <bpmn:errorEventDefinition id="ErrorEventDefinition_1ppvn77" /> + </bpmn:startEvent> + <bpmn:endEvent id="Event_1wkm29u" name="end"> + <bpmn:incoming>Flow_0anjylz</bpmn:incoming> + </bpmn:endEvent> + <bpmn:serviceTask id="Activity_0ltxcii" name="Update NF Instance (VNF) Status to FAILED" camunda:asyncBefore="true" camunda:expression="${CreateInstantiateVnfTask.updateNfInstanceStatusToFailed(execution)}"> + <bpmn:incoming>Flow_06q1m6i</bpmn:incoming> + <bpmn:outgoing>Flow_0anjylz</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_06q1m6i" sourceRef="Event_08zcwc2" targetRef="Activity_0ltxcii" /> + <bpmn:sequenceFlow id="Flow_0anjylz" sourceRef="Activity_0ltxcii" targetRef="Event_1wkm29u" /> + </bpmn:subProcess> + </bpmn:process> + <bpmndi:BPMNDiagram id="BPMNDiagram_1"> + <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="CreateInstantiateVnf"> + <bpmndi:BPMNEdge id="SequenceFlow_0h7yluk_di" bpmnElement="SequenceFlow_0h7yluk"> + <di:waypoint x="1030" y="117" /> + <di:waypoint x="1080" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_053tvct_di" bpmnElement="SequenceFlow_053tvct"> + <di:waypoint x="880" y="117" /> + <di:waypoint x="930" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_0xzptc2_di" bpmnElement="SequenceFlow_0xzptc2"> + <di:waypoint x="740" y="117" /> + <di:waypoint x="780" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_123uagz_di" bpmnElement="Flow_123uagz"> + <di:waypoint x="350" y="117" /> + <di:waypoint x="380" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1c3kc4e_di" bpmnElement="Flow_1c3kc4e"> + <di:waypoint x="610" y="117" /> + <di:waypoint x="640" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_03p6ifi_di" bpmnElement="Flow_03p6ifi"> + <di:waypoint x="480" y="117" /> + <di:waypoint x="510" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_02bjz2v_di" bpmnElement="Flow_02bjz2v"> + <di:waypoint x="215" y="117" /> + <di:waypoint x="250" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0srinh7_di" bpmnElement="Flow_0srinh7"> + <di:waypoint x="1180" y="117" /> + <di:waypoint x="1232" y="117" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"> + <dc:Bounds x="179" y="99" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_19rmtjr_di" bpmnElement="Activity_19rmtjr"> + <dc:Bounds x="380" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0rto3n3_di" bpmnElement="Activity_0rto3n3"> + <dc:Bounds x="510" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1cluqgp_di" bpmnElement="Activity_1cluqgp"> + <dc:Bounds x="250" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="ServiceTask_0iry5yw_di" bpmnElement="ServiceTask_0iry5yw"> + <dc:Bounds x="640" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="CallActivity_1yilxx3_di" bpmnElement="CallActivity_1yilxx3"> + <dc:Bounds x="780" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="CallActivity_0p84lpt_di" bpmnElement="CallActivity_0p84lpt"> + <dc:Bounds x="930" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_14qdixj_di" bpmnElement="Event_14qdixj"> + <dc:Bounds x="1232" y="99" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0g3dip7_di" bpmnElement="Activity_0g3dip7"> + <dc:Bounds x="1080" y="77" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0qtgdm9_di" bpmnElement="Activity_0qtgdm9" isExpanded="true"> + <dc:Bounds x="430" y="270" width="438" height="130" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_06q1m6i_di" bpmnElement="Flow_06q1m6i"> + <di:waypoint x="488" y="333" /> + <di:waypoint x="580" y="333" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0anjylz_di" bpmnElement="Flow_0anjylz"> + <di:waypoint x="680" y="333" /> + <di:waypoint x="812" y="333" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="Event_08zcwc2_di" bpmnElement="Event_08zcwc2"> + <dc:Bounds x="452" y="315" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="458" y="358" width="24" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_1wkm29u_di" bpmnElement="Event_1wkm29u"> + <dc:Bounds x="812" y="315" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="822" y="357" width="19" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0ltxcii_di" bpmnElement="Activity_0ltxcii"> + <dc:Bounds x="580" y="293" width="100" height="80" /> + </bpmndi:BPMNShape> + </bpmndi:BPMNPlane> + </bpmndi:BPMNDiagram> +</bpmn:definitions> diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/InstantiateNs.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/InstantiateNs.bpmn new file mode 100644 index 0000000000..ba9e641d84 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/InstantiateNs.bpmn @@ -0,0 +1,331 @@ +<?xml version="1.0" encoding="UTF-8"?> +<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_0mdda96" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.0.0"> + <bpmn:process id="InstantiateNs" name="InstantiateNs" isExecutable="true"> + <bpmn:startEvent id="StartEvent_1" name="Start Process"> + <bpmn:outgoing>SequenceFlow_16k0f61</bpmn:outgoing> + </bpmn:startEvent> + <bpmn:sequenceFlow id="SequenceFlow_16k0f61" sourceRef="StartEvent_1" targetRef="Activity_194tqy0" /> + <bpmn:serviceTask id="Task_0opnwx0" name="Update NS Instance status to INSTANTIATING" camunda:expression="${InstantiateNsTask.updateNsInstanceStatusToInstantiating(execution)}"> + <bpmn:incoming>Flow_04pxtdd</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_0bdznyp</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:endEvent id="EndEvent_0szswbo" name="End Process"> + <bpmn:incoming>Flow_1pcu8aa</bpmn:incoming> + </bpmn:endEvent> + <bpmn:sequenceFlow id="SequenceFlow_0bdznyp" sourceRef="Task_0opnwx0" targetRef="Activity_1jrym1e" /> + <bpmn:serviceTask id="Activity_194tqy0" name="Set Job Status to STARTED" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.setJobStatusToStarted(execution)}"> + <bpmn:incoming>SequenceFlow_16k0f61</bpmn:incoming> + <bpmn:outgoing>Flow_04pxtdd</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_04pxtdd" sourceRef="Activity_194tqy0" targetRef="Task_0opnwx0" /> + <bpmn:subProcess id="Activity_0pjxszh" name="Error Handling" triggeredByEvent="true"> + <bpmn:startEvent id="Event_1rpzcl3" name="error"> + <bpmn:outgoing>Flow_07bh7l7</bpmn:outgoing> + <bpmn:errorEventDefinition id="ErrorEventDefinition_0m2e0oa" /> + </bpmn:startEvent> + <bpmn:endEvent id="Event_1fcw3ei" name="end"> + <bpmn:incoming>Flow_1wa1jpl</bpmn:incoming> + </bpmn:endEvent> + <bpmn:serviceTask id="Activity_0ddja9m" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.setJobStatusToError(execution)}"> + <bpmn:incoming>Flow_0n3dai5</bpmn:incoming> + <bpmn:outgoing>Flow_1wa1jpl</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1wa1jpl" sourceRef="Activity_0ddja9m" targetRef="Event_1fcw3ei" /> + <bpmn:sequenceFlow id="Flow_07bh7l7" sourceRef="Event_1rpzcl3" targetRef="Activity_1miy3hw" /> + <bpmn:serviceTask id="Activity_1miy3hw" name="Update NSLcmOpOcc operation status to FAILED" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.updateNsLcmOpOccStatusToFailed(execution)}"> + <bpmn:incoming>Flow_07bh7l7</bpmn:incoming> + <bpmn:outgoing>Flow_0n3dai5</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_0n3dai5" sourceRef="Activity_1miy3hw" targetRef="Activity_0ddja9m" /> + </bpmn:subProcess> + <bpmn:subProcess id="Activity_0mtscwq" name="Java Exception Handling" triggeredByEvent="true"> + <bpmn:startEvent id="Event_0lqr6al" name="error"> + <bpmn:outgoing>Flow_05lo00r</bpmn:outgoing> + <bpmn:errorEventDefinition id="ErrorEventDefinition_02lwl19" errorRef="Error_0jsct8p" camunda:errorCodeVariable="BPMN_javaExpCode" camunda:errorMessageVariable="BPMN_javaExpMsg" /> + </bpmn:startEvent> + <bpmn:endEvent id="Event_05ty7c4"> + <bpmn:incoming>Flow_16aryg5</bpmn:incoming> + </bpmn:endEvent> + <bpmn:serviceTask id="Activity_1ezu7d4" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.setJobStatusToError(execution)}"> + <bpmn:incoming>Flow_09zcw2a</bpmn:incoming> + <bpmn:outgoing>Flow_16aryg5</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_16aryg5" sourceRef="Activity_1ezu7d4" targetRef="Event_05ty7c4" /> + <bpmn:sequenceFlow id="Flow_05lo00r" sourceRef="Event_0lqr6al" targetRef="Activity_17leldb" /> + <bpmn:serviceTask id="Activity_17leldb" name="Update NSLcmOpOcc operation status to FAILED" camunda:asyncBefore="true" camunda:expression="${InstantiateNsTask.updateNsLcmOpOccStatusToFailed(execution)}"> + <bpmn:incoming>Flow_05lo00r</bpmn:incoming> + <bpmn:outgoing>Flow_09zcw2a</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_09zcw2a" sourceRef="Activity_17leldb" targetRef="Activity_1ezu7d4" /> + </bpmn:subProcess> + <bpmn:serviceTask id="Activity_1w09i1k" name="Set Job Status to FINISHED" camunda:expression="${InstantiateNsTask.setJobStatusToFinished(execution)}"> + <bpmn:incoming>Flow_1i36dw4</bpmn:incoming> + <bpmn:outgoing>Flow_1pcu8aa</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1pcu8aa" sourceRef="Activity_1w09i1k" targetRef="EndEvent_0szswbo" /> + <bpmn:serviceTask id="Activity_1jrym1e" name="Get and parse NSD from ETSI Catalog" camunda:expression="${InstantiateNsTask.getAndParseNsdFromEtsiCatalog(execution)}"> + <bpmn:incoming>SequenceFlow_0bdznyp</bpmn:incoming> + <bpmn:outgoing>Flow_10zjw0w</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_10zjw0w" sourceRef="Activity_1jrym1e" targetRef="Activity_1kikjaf" /> + <bpmn:callActivity id="Activity_1b2s2wr" name="Create and Instantiate each Vnf" calledElement="CreateInstantiateVnf"> + <bpmn:extensionElements> + <camunda:in source="request" target="request" /> + <camunda:in source="jobId" target="jobId" /> + <camunda:in source="NsInstanceId" target="NsInstanceId" /> + </bpmn:extensionElements> + <bpmn:incoming>Flow_1irbp9b</bpmn:incoming> + <bpmn:outgoing>Flow_0mi4nqa</bpmn:outgoing> + <bpmn:multiInstanceLoopCharacteristics camunda:asyncAfter="true" camunda:collection="${vnfCreateInstantiateRequests}" camunda:elementVariable="request" /> + </bpmn:callActivity> + <bpmn:boundaryEvent id="Event_0rbb817" name="Overall Wait" attachedToRef="Activity_1b2s2wr"> + <bpmn:outgoing>Flow_17zn7we</bpmn:outgoing> + <bpmn:timerEventDefinition id="TimerEventDefinition_13ud1f4"> + <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT3H</bpmn:timeDuration> + </bpmn:timerEventDefinition> + </bpmn:boundaryEvent> + <bpmn:sequenceFlow id="Flow_17zn7we" sourceRef="Event_0rbb817" targetRef="Activity_16z66xm" /> + <bpmn:serviceTask id="Activity_0eou3y4" name="Prepare Create Instantiate requests" camunda:expression="${InstantiateNsTask.prepareCreateInstantiateRequests(execution)}"> + <bpmn:incoming>Flow_01ju1mj</bpmn:incoming> + <bpmn:outgoing>Flow_1irbp9b</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1irbp9b" sourceRef="Activity_0eou3y4" targetRef="Activity_1b2s2wr" /> + <bpmn:serviceTask id="Activity_1kikjaf" name="Get Vnf Pkg ID for each VNFD ID" camunda:expression="${InstantiateNsTask.getVnfPkgIdForEachVnfdId(execution)}"> + <bpmn:incoming>Flow_10zjw0w</bpmn:incoming> + <bpmn:outgoing>Flow_01ju1mj</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_01ju1mj" sourceRef="Activity_1kikjaf" targetRef="Activity_0eou3y4" /> + <bpmn:serviceTask id="Activity_16cvdbw" name="Update NS Instance status to INSTANTIATED" camunda:expression="${InstantiateNsTask.updateNsInstanceStatusToInstantiated(execution)}"> + <bpmn:incoming>Flow_1nieng0</bpmn:incoming> + <bpmn:outgoing>Flow_0xptc0r</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_0xptc0r" sourceRef="Activity_16cvdbw" targetRef="Activity_0gkpdft" /> + <bpmn:endEvent id="Event_1e4bwip"> + <bpmn:incoming>Flow_10oprxr</bpmn:incoming> + <bpmn:incoming>Flow_1p21p1m</bpmn:incoming> + <bpmn:errorEventDefinition id="ErrorEventDefinition_0vg6v5r" errorRef="Error_0jsct8p" /> + </bpmn:endEvent> + <bpmn:exclusiveGateway id="Gateway_0nxf0rv" name="is Successful?"> + <bpmn:incoming>Flow_15m4nm1</bpmn:incoming> + <bpmn:outgoing>Flow_1nieng0</bpmn:outgoing> + <bpmn:outgoing>Flow_10oprxr</bpmn:outgoing> + </bpmn:exclusiveGateway> + <bpmn:sequenceFlow id="Flow_1nieng0" name="Yes" sourceRef="Gateway_0nxf0rv" targetRef="Activity_16cvdbw"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{isNsInstantiationSuccessful}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:serviceTask id="Activity_14iwa8x" name="Check if VNF Instantiation was Successful" camunda:expression="${InstantiateNsTask.checkIfVnfInstantiationWasSuccessful(execution)}"> + <bpmn:incoming>Flow_0mi4nqa</bpmn:incoming> + <bpmn:outgoing>Flow_15m4nm1</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_0mi4nqa" sourceRef="Activity_1b2s2wr" targetRef="Activity_14iwa8x" /> + <bpmn:sequenceFlow id="Flow_15m4nm1" sourceRef="Activity_14iwa8x" targetRef="Gateway_0nxf0rv" /> + <bpmn:serviceTask id="Activity_16z66xm" name="Log TimeOut" camunda:expression="${InstantiateNsTask.logTimeOut(execution)}"> + <bpmn:incoming>Flow_17zn7we</bpmn:incoming> + <bpmn:outgoing>Flow_1p21p1m</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_10oprxr" name="No" sourceRef="Gateway_0nxf0rv" targetRef="Event_1e4bwip"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{not isNsInstantiationSuccessful}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:sequenceFlow id="Flow_1p21p1m" sourceRef="Activity_16z66xm" targetRef="Event_1e4bwip" /> + <bpmn:serviceTask id="Activity_0gkpdft" name="Update NSLcmOpOcc operation status to COMPLETED" camunda:expression="${InstantiateNsTask.updateNsLcmOpOccStatusToCompleted(execution)}"> + <bpmn:incoming>Flow_0xptc0r</bpmn:incoming> + <bpmn:outgoing>Flow_1i36dw4</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1i36dw4" sourceRef="Activity_0gkpdft" targetRef="Activity_1w09i1k" /> + </bpmn:process> + <bpmn:error id="Error_0jsct8p" name="InstantiateNsProcessingException" errorCode="INSTANTIATE_NS_PROCESSING_EXCEPTION" /> + <bpmndi:BPMNDiagram id="BPMNDiagram_1"> + <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="InstantiateNs"> + <bpmndi:BPMNEdge id="Flow_1p21p1m_di" bpmnElement="Flow_1p21p1m"> + <di:waypoint x="1250" y="270" /> + <di:waypoint x="1332" y="270" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_10oprxr_di" bpmnElement="Flow_10oprxr"> + <di:waypoint x="1350" y="146" /> + <di:waypoint x="1350" y="252" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1358" y="196" width="14" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_15m4nm1_di" bpmnElement="Flow_15m4nm1"> + <di:waypoint x="1250" y="121" /> + <di:waypoint x="1325" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0mi4nqa_di" bpmnElement="Flow_0mi4nqa"> + <di:waypoint x="1090" y="121" /> + <di:waypoint x="1150" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1nieng0_di" bpmnElement="Flow_1nieng0"> + <di:waypoint x="1375" y="121" /> + <di:waypoint x="1430" y="121" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1393" y="103" width="19" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0xptc0r_di" bpmnElement="Flow_0xptc0r"> + <di:waypoint x="1530" y="121" /> + <di:waypoint x="1580" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_01ju1mj_di" bpmnElement="Flow_01ju1mj"> + <di:waypoint x="800" y="121" /> + <di:waypoint x="850" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1irbp9b_di" bpmnElement="Flow_1irbp9b"> + <di:waypoint x="950" y="121" /> + <di:waypoint x="990" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_17zn7we_di" bpmnElement="Flow_17zn7we"> + <di:waypoint x="1070" y="179" /> + <di:waypoint x="1070" y="270" /> + <di:waypoint x="1150" y="270" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_10zjw0w_di" bpmnElement="Flow_10zjw0w"> + <di:waypoint x="649" y="121" /> + <di:waypoint x="700" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1pcu8aa_di" bpmnElement="Flow_1pcu8aa"> + <di:waypoint x="1820" y="121" /> + <di:waypoint x="1862" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_04pxtdd_di" bpmnElement="Flow_04pxtdd"> + <di:waypoint x="360" y="121" /> + <di:waypoint x="400" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_0bdznyp_di" bpmnElement="SequenceFlow_0bdznyp"> + <di:waypoint x="500" y="121" /> + <di:waypoint x="549" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="SequenceFlow_16k0f61_di" bpmnElement="SequenceFlow_16k0f61"> + <di:waypoint x="208" y="121" /> + <di:waypoint x="260" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1i36dw4_di" bpmnElement="Flow_1i36dw4"> + <di:waypoint x="1680" y="121" /> + <di:waypoint x="1720" y="121" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"> + <dc:Bounds x="172" y="103" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="157" y="146" width="67" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="ServiceTask_1y7xfqt_di" bpmnElement="Task_0opnwx0"> + <dc:Bounds x="400" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_194tqy0_di" bpmnElement="Activity_194tqy0"> + <dc:Bounds x="260" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="EndEvent_0szswbo_di" bpmnElement="EndEvent_0szswbo"> + <dc:Bounds x="1862" y="103" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1848" y="79" width="63" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1w09i1k_di" bpmnElement="Activity_1w09i1k"> + <dc:Bounds x="1720" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0gkpdft_di" bpmnElement="Activity_0gkpdft"> + <dc:Bounds x="1580" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0pjxszh_di" bpmnElement="Activity_0pjxszh" isExpanded="true"> + <dc:Bounds x="380" y="270" width="510" height="130" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_07bh7l7_di" bpmnElement="Flow_07bh7l7"> + <di:waypoint x="438" y="333" /> + <di:waypoint x="500" y="333" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1wa1jpl_di" bpmnElement="Flow_1wa1jpl"> + <di:waypoint x="760" y="333" /> + <di:waypoint x="822" y="333" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0n3dai5_di" bpmnElement="Flow_0n3dai5"> + <di:waypoint x="600" y="333" /> + <di:waypoint x="660" y="333" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="Event_1rpzcl3_di" bpmnElement="Event_1rpzcl3"> + <dc:Bounds x="402" y="315" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="408" y="358" width="24" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1miy3hw_di" bpmnElement="Activity_1miy3hw"> + <dc:Bounds x="500" y="293" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0ddja9m_di" bpmnElement="Activity_0ddja9m"> + <dc:Bounds x="660" y="293" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_1fcw3ei_di" bpmnElement="Event_1fcw3ei"> + <dc:Bounds x="822" y="315" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="832" y="357" width="19" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0mtscwq_di" bpmnElement="Activity_0mtscwq" isExpanded="true"> + <dc:Bounds x="380" y="430" width="510" height="130" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_05lo00r_di" bpmnElement="Flow_05lo00r"> + <di:waypoint x="438" y="493" /> + <di:waypoint x="500" y="493" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_16aryg5_di" bpmnElement="Flow_16aryg5"> + <di:waypoint x="760" y="493" /> + <di:waypoint x="822" y="493" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_09zcw2a_di" bpmnElement="Flow_09zcw2a"> + <di:waypoint x="600" y="493" /> + <di:waypoint x="660" y="493" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="Event_0lqr6al_di" bpmnElement="Event_0lqr6al"> + <dc:Bounds x="402" y="475" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="409" y="518" width="24" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_17leldb_di" bpmnElement="Activity_17leldb"> + <dc:Bounds x="500" y="453" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1ezu7d4_di" bpmnElement="Activity_1ezu7d4"> + <dc:Bounds x="660" y="453" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_05ty7c4_di" bpmnElement="Event_05ty7c4"> + <dc:Bounds x="822" y="475" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1jrym1e_di" bpmnElement="Activity_1jrym1e"> + <dc:Bounds x="549" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1xjmizv_di" bpmnElement="Activity_1b2s2wr"> + <dc:Bounds x="990" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0eou3y4_di" bpmnElement="Activity_0eou3y4"> + <dc:Bounds x="850" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1kikjaf_di" bpmnElement="Activity_1kikjaf"> + <dc:Bounds x="700" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_16cvdbw_di" bpmnElement="Activity_16cvdbw"> + <dc:Bounds x="1430" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_16umj30_di" bpmnElement="Event_1e4bwip"> + <dc:Bounds x="1332" y="252" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Gateway_0nxf0rv_di" bpmnElement="Gateway_0nxf0rv" isMarkerVisible="true"> + <dc:Bounds x="1325" y="96" width="50" height="50" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1320" y="66" width="71" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_14iwa8x_di" bpmnElement="Activity_14iwa8x"> + <dc:Bounds x="1150" y="81" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_16z66xm_di" bpmnElement="Activity_16z66xm"> + <dc:Bounds x="1150" y="230" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_0rbb817_di" bpmnElement="Event_0rbb817"> + <dc:Bounds x="1052" y="143" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="1000" y="183" width="60" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + </bpmndi:BPMNPlane> + </bpmndi:BPMNDiagram> +</bpmn:definitions> diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/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 index fc9f2a2195..86f2879966 100644 --- 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 @@ -19,6 +19,7 @@ */ 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; @@ -134,9 +135,16 @@ public abstract class BaseTest { 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 - && !HistoricProcessInstance.STATE_ACTIVE.equalsIgnoreCase(processInstance.getState()); + 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/workflow/engine/tasks/InstantiateNsTaskTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/InstantiateNsTaskTest.java new file mode 100644 index 0000000000..bfccddcbcc --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/workflow/engine/tasks/InstantiateNsTaskTest.java @@ -0,0 +1,319 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.etsi.nfvo.ns.workflow.engine.tasks; + +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.notFound; +import static com.github.tomakehurst.wiremock.client.WireMock.ok; +import static com.github.tomakehurst.wiremock.client.WireMock.okJson; +import static com.github.tomakehurst.wiremock.client.WireMock.put; +import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_REST_TEMPLATE_BEAN; +import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterConfiguration.SOL003_ADAPTER_REST_TEMPLATE_BEAN; +import static org.springframework.test.web.client.ExpectedCount.times; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import org.camunda.bpm.engine.history.HistoricProcessInstance; +import org.camunda.bpm.engine.history.HistoricVariableInstance; +import org.hamcrest.text.MatchesPattern; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse; +import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStatusRetrievalStatusEnum; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.BaseTest; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.JobExecutorService; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum; +import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State; +import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider; +import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest; +import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestTemplate; +import com.google.gson.Gson; + +/** + * @author Andrew Lamb (andrew.a.lamb@est.tech) + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class InstantiateNsTaskTest extends BaseTest { + + private static final String TENANT_ID = "6ca8680feba04dad9254f423c6e28e1c"; + private static final String CLOUD_REGION = "regionOne"; + private static final String CLOUD_OWNER = "CloudOwner"; + private static final String UUID_REGEX = + "[0-9a-zA-Z]{8}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{12}"; + private static final String VCPE_VBRGEMU_VNFD_ID = "b1bb0ce7-2222-4fa7-95ed-4840d70a1102"; + private static final String VCPE_VBNG = "b1bb0ce7-2222-4fa7-95ed-4840d70a1101"; + private static final String VCPE_INFRA_VNFD_ID = "b1bb0ce7-2222-4fa7-95ed-4840d70a1100"; + private static final String VGMUX_VNFD_ID = "0408f076-e6c0-4c82-9940-272fddbb82de"; + private static final String VGW_VNFD_ID = "3fca3543-07f5-492f-812c-ed462e4f94f4"; + private static final String[] VCPE_VNFDS = + new String[] {VGW_VNFD_ID, VGMUX_VNFD_ID, VCPE_INFRA_VNFD_ID, VCPE_VBNG, VCPE_VBRGEMU_VNFD_ID}; + private static final String SAMPLE_NSD_FILE = "src/test/resources/ns.csar"; + private static final String NS_NAME = "InstantiateNetworkService"; + + @Autowired + private DatabaseServiceProvider databaseServiceProvider; + + @Autowired + @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) + private RestTemplate etsiCatalogRestTemplate; + + @Autowired + @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN) + private RestTemplate sol003AdapterRestTemplate; + + private MockRestServiceServer mockEtsiCatalogRestServiceServer; + + private MockRestServiceServer mockSol003AdapterRestServiceServer; + + @Autowired + private JobExecutorService objUnderTest; + + @Autowired + private GsonProvider gsonProvider; + + private Gson gson; + + private static final Map<String, String> VNFD_ID_TO_VNFPKG_ID_MAPPING = new HashMap<>(); + static { + for (final String vnfd : VCPE_VNFDS) { + VNFD_ID_TO_VNFPKG_ID_MAPPING.put(vnfd, UUID.randomUUID().toString()); + } + } + + @Before + public void before() { + wireMockServer.resetAll(); + gson = gsonProvider.getGson(); + + mockEtsiCatalogRestServiceServer = + MockRestServiceServer.bindTo(etsiCatalogRestTemplate).ignoreExpectOrder(true).build(); + mockSol003AdapterRestServiceServer = + MockRestServiceServer.bindTo(sol003AdapterRestTemplate).ignoreExpectOrder(true).build(); + + etsiCatalogRestTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson)); + sol003AdapterRestTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson)); + + } + + @After + public void after() { + wireMockServer.resetAll(); + mockEtsiCatalogRestServiceServer.reset(); + } + + @Test + public void testInstantiateNsWorkflow_JustUpdateStatus_SuccessfullCase() throws InterruptedException, IOException { + final String nsdId = UUID.randomUUID().toString(); + final String nsdName = NS_NAME + "-" + System.currentTimeMillis(); + + final NfvoNsInst newNfvoNsInst = new NfvoNsInst().nsInstId(nsdId).name(nsdName) + .nsPackageId(UUID.randomUUID().toString()).nsPackageId(nsdId).nsdId(nsdId).nsdInvariantId(nsdId) + .status(State.NOT_INSTANTIATED).statusUpdatedTime(LocalDateTime.now()); + + databaseServiceProvider.saveNfvoNsInst(newNfvoNsInst); + + mockSol003AdapterEndpoints(); + mockAAIEndpoints(nsdId); + mockEtsiCatalogEndpoints(nsdId); + + final String nsLcmOpOccId = + objUnderTest.runInstantiateNsJob(newNfvoNsInst.getNsInstId(), getInstantiateNsRequest()); + + final Optional<NfvoJob> optional = getJobByResourceId(newNfvoNsInst.getNsInstId()); + assertTrue(optional.isPresent()); + final NfvoJob nfvoJob = optional.get(); + + assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId())); + + final HistoricProcessInstance historicProcessInstance = + getHistoricProcessInstance(nfvoJob.getProcessInstanceId()); + assertNotNull(historicProcessInstance); + + assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState()); + + // check if value in database has updated + final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsdId); + final NfvoNsInst nfvoNsInst = optionalNfvoNsInst.get(); + assertEquals(State.INSTANTIATED, nfvoNsInst.getStatus()); + + final HistoricVariableInstance historicVariableInstance = + getVariable(nfvoJob.getProcessInstanceId(), NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME); + assertNotNull(historicVariableInstance); + final NetworkServiceDescriptor nsd = (NetworkServiceDescriptor) historicVariableInstance.getValue(); + assertNotNull(nsd); + + assertEquals(VNFD_ID_TO_VNFPKG_ID_MAPPING.size(), nsd.getVnfs().size()); + + final List<NfvoNfInst> nfvoNfInsts = databaseServiceProvider.getNfvoNfInstByNsInstId(nsdId); + assertNotNull(nsd); + assertEquals(VNFD_ID_TO_VNFPKG_ID_MAPPING.size(), nfvoNfInsts.size()); + + final Optional<NsLcmOpOcc> optionalNsLcmOpOcc = databaseServiceProvider.getNsLcmOpOcc(nsLcmOpOccId); + assertTrue(optionalNsLcmOpOcc.isPresent()); + + assertEquals(OperationStateEnum.COMPLETED, optionalNsLcmOpOcc.get().getOperationState()); + + final Map<String, NfvoNfInst> nfvoNfInstsMap = + nfvoNfInsts.stream().collect(Collectors.toMap(NfvoNfInst::getVnfdId, nfvoNfInst -> nfvoNfInst)); + + for (final Entry<String, String> entry : VNFD_ID_TO_VNFPKG_ID_MAPPING.entrySet()) { + assertTrue(nfvoNfInstsMap.containsKey(entry.getKey())); + assertEquals(State.INSTANTIATED, nfvoNfInstsMap.get(entry.getKey()).getStatus()); + + } + + } + + private void mockSol003AdapterEndpoints() { + mockSol003AdapterRestServiceServer + .expect(times(VNFD_ID_TO_VNFPKG_ID_MAPPING.size()), + requestTo(MatchesPattern.matchesPattern(SOL003_ADAPTER_ENDPOINT_URL + "/vnfs/.*"))) + .andExpect(method(HttpMethod.POST)) + .andRespond(withSuccess(gson.toJson(new CreateVnfResponse().jobId(UUID.randomUUID().toString())), + MediaType.APPLICATION_JSON)); + + mockSol003AdapterRestServiceServer + .expect(times(VNFD_ID_TO_VNFPKG_ID_MAPPING.size()), + requestTo(MatchesPattern.matchesPattern(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/.*"))) + .andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(gson.toJson( + new org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse().operationState( + org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum.COMPLETED) + .operationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.STATUS_FOUND)), + MediaType.APPLICATION_JSON)); + } + + private void mockEtsiCatalogEndpoints(final String nsdId) throws IOException { + mockEtsiCatalogRestServiceServer.expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId)) + .andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(gson.toJson(getNSPackageModel(nsdId)), MediaType.APPLICATION_JSON)); + mockEtsiCatalogRestServiceServer + .expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId + "/nsd_content")) + .andExpect(method(HttpMethod.GET)).andRespond(withSuccess( + getFileContent(getAbsolutePath(SAMPLE_NSD_FILE)), MediaType.APPLICATION_OCTET_STREAM)); + + for (final Entry<String, String> entry : VNFD_ID_TO_VNFPKG_ID_MAPPING.entrySet()) { + mockEtsiCatalogRestServiceServer + .expect(requestTo(ETSI_CATALOG_URL + "/vnfpkgm/v1/vnf_packages/" + entry.getValue())) + .andExpect(method(HttpMethod.GET)).andRespond(withSuccess( + gson.toJson(getVnfPkgInfo(entry.getKey(), entry.getValue())), MediaType.APPLICATION_JSON)); + } + + } + + private VnfPkgInfo getVnfPkgInfo(final String vnfdId, final String vnfPkgId) { + return new VnfPkgInfo().id(vnfPkgId).vnfdId(vnfdId); + } + + private InstantiateNsRequest getInstantiateNsRequest() { + final Map<String, Object> additionalParams = new HashMap<>(); + additionalParams.put("vim_id", CLOUD_OWNER + "_" + CLOUD_REGION + "_" + TENANT_ID); + + final InstantiateNsRequest instantiateNsRequest = new InstantiateNsRequest().nsFlavourId("default"); + + for (final Entry<String, String> entry : VNFD_ID_TO_VNFPKG_ID_MAPPING.entrySet()) { + instantiateNsRequest + .addAdditionalParamsForVnfItem(new NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf() + .vnfProfileId(entry.getValue()).additionalParams(additionalParams)); + } + + return instantiateNsRequest; + } + + private NsdInfo getNSPackageModel(final String nsdId) { + return new NsdInfo().id(nsdId).nsdId(nsdId).nsdInvariantId(NSD_INVARIANT_ID).nsdName("vcpe").nsdDesigner("ONAP") + .vnfPkgIds(new ArrayList<>(VNFD_ID_TO_VNFPKG_ID_MAPPING.values())); + } + + private byte[] getFileContent(final String path) throws IOException { + return Files.readAllBytes(Paths.get(path)); + } + + + private String getAbsolutePath(final String path) { + return new File(path).getAbsolutePath(); + } + + private void mockAAIEndpoints(final String nsdId) { + final String modelEndpoint = "/aai/v[0-9]+/network/generic-vnfs/generic-vnf/" + UUID_REGEX; + wireMockServer.stubFor( + get(urlMatching(modelEndpoint + "\\?resultIndex=0&resultSize=1&format=count")).willReturn(notFound())); + + wireMockServer.stubFor(put(urlMatching(modelEndpoint)).willReturn(ok())); + wireMockServer.stubFor(put(urlMatching(modelEndpoint + "/relationship-list/relationship")).willReturn(ok())); + + wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(ok()) + .willReturn(okJson("{\"orchestration-status\": \"Created\"}"))); + + final String resourceType = "service-instance"; + final String resourceLink = "/aai/v20/business/customers/customer/" + GLOBAL_CUSTOMER_ID + + "/service-subscriptions/service-subscription/NetworkService/service-instances/service-instance/" + + nsdId; + + final String body = "{\n" + " \"results\": [{\n" + " \"resource-type\": \"" + resourceType + "\",\n" + + " \"resource-link\": \"" + resourceLink + "\"\n" + " }]\n" + "}"; + + wireMockServer.stubFor( + get(urlMatching("/aai/v[0-9]+/nodes/service-instances/service-instance/" + nsdId + "\\?format=pathed")) + .willReturn(okJson(body))); + + wireMockServer + .stubFor(put(urlMatching("/aai/v[0-9]+/cloud-infrastructure/cloud-regions/cloud-region/" + CLOUD_OWNER + + "/" + CLOUD_REGION + "/tenants/tenant/" + TENANT_ID + "/relationship-list/relationship")) + .willReturn(ok())); + + } + +} 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 index 7549b49264..cb8f92070a 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/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 @@ -65,7 +65,7 @@ public class NsLcmOpOcc { @Column(name = "IS_AUTO_INNOVATION") private boolean isAutoInnovation; - @Column(name = "OPERATION_PARAMS") + @Column(name = "OPERATION_PARAMS", columnDefinition = "LONGTEXT") private String operationParams; @Column(name = "IS_CANCEL_PENDING") 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 index 08dbef3866..390c7fd776 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/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 @@ -24,6 +24,6 @@ package org.onap.so.etsi.nfvo.ns.lcm.database.beans; * */ public enum State { - NOT_INSTANTIATED, INSTANTIATED; + 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/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 index 254a3698c9..368242515b 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/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 @@ -81,6 +81,12 @@ public class DatabaseServiceProvider { 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; @@ -116,6 +122,11 @@ public class DatabaseServiceProvider { 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; @@ -127,5 +138,4 @@ public class DatabaseServiceProvider { } - } 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 index baf11193cf..da1649de57 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/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 @@ -36,7 +36,7 @@ public class EtsiSoNsLcmManagerUrlProvider { @Autowired public EtsiSoNsLcmManagerUrlProvider( - @Value("${etsi-so-ns-lcm-manager.endpoint}") final String etsiNsLcmManagerEndpoint) { + @Value("${so-etsi-nfvo-ns-lcm.endpoint:http://so-etsi-nfvo-ns-lcm.onap:9095}") final String etsiNsLcmManagerEndpoint) { this.etsiNsLcmManagerEndpoint = etsiNsLcmManagerEndpoint; } 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 index f295731cb6..792ffdd00a 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/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 @@ -25,6 +25,7 @@ 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; @@ -64,4 +65,13 @@ public class NsLifeCycleManager { 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/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 fb0a2503a2..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 @@ -125,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 index 8d9fdbe339..3db04fcfe8 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/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 @@ -41,21 +41,18 @@ public class NsLcmControllerExceptionHandler { .body(getInlineResponse400(nsRequestProcessingException)); } - private InlineResponse400 getInlineResponse400(final NsRequestProcessingException 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()); - - } - - @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())); } } 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 4ff74eaaa1..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 @@ -69,11 +69,16 @@ 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_LOCATION_URL = "http://etsi-so-ns-lcm-manager-service:9095" - + "/so/so-etsi-nfvo-ns-lcm/v1/" + "api/nslcm/v1/ns_instances/" + RANDOM_NS_INST_ID; + 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; @@ -115,7 +120,7 @@ public class NsLifecycleManagementControllerTest { assertTrue(httpHeaders.containsKey(HttpHeaders.LOCATION)); final List<String> actual = httpHeaders.get(HttpHeaders.LOCATION); assertEquals(1, actual.size()); - assertEquals(EXPECTED_LOCATION_URL, actual.get(0)); + assertEquals(EXPECTED_CREATE_REQ_LOCATION_URL, actual.get(0)); } @Test @@ -177,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 diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/resources/application.yaml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/resources/application.yaml index 6c8a7997af..44acda20a4 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/resources/application.yaml +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/resources/application.yaml @@ -26,7 +26,7 @@ spring: 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 + pool-name: ns-lcm-nfvo-pool registerMbeans: true jpa: hibernate: @@ -36,6 +36,4 @@ logging: org.reflections.Reflections: ERROR etsi-catalog-manager: base: - endpoint: http://modeling-etsicatalog.onap:8806/api -etsi-so-ns-lcm-manager: - endpoint: http://etsi-so-ns-lcm-manager-service:9095
\ No newline at end of file + endpoint: http://modeling-etsicatalog.onap:8806/api
\ No newline at end of file |