[SO] Release so 1.13.0 image
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DoCreateResources.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License")
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.infrastructure.scripts
24
25
26 import com.google.common.reflect.TypeToken
27 import com.google.gson.Gson
28 import org.apache.http.util.EntityUtils
29 import org.onap.so.bpmn.common.resource.InstanceResourceList
30 import org.onap.so.bpmn.common.scripts.CatalogDbUtilsFactory
31 import org.onap.so.bpmn.core.domain.ModelInfo
32 import org.onap.so.bpmn.core.domain.ResourceType
33 import org.onap.so.bpmn.infrastructure.properties.BPMNProperties
34 import org.apache.commons.lang3.StringUtils
35 import org.apache.http.HttpResponse
36 import org.camunda.bpm.engine.delegate.BpmnError
37 import org.camunda.bpm.engine.delegate.DelegateExecution
38 import org.json.JSONObject
39 import org.onap.so.bpmn.common.recipe.BpmnRestClient
40 import org.onap.so.bpmn.common.recipe.ResourceInput
41 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
42 import org.onap.so.bpmn.common.scripts.CatalogDbUtils
43 import org.onap.so.bpmn.common.scripts.ExceptionUtil
44 import org.onap.so.bpmn.core.domain.AllottedResource
45 import org.onap.so.bpmn.core.domain.NetworkResource
46 import org.onap.so.bpmn.core.domain.Resource
47 import org.onap.so.bpmn.core.domain.ServiceDecomposition
48 import org.onap.so.bpmn.core.domain.VnfResource
49 import org.onap.so.bpmn.core.json.JsonUtils
50 import org.onap.so.bpmn.common.resource.ResourceRequestBuilder
51 import org.slf4j.Logger
52 import org.slf4j.LoggerFactory
53
54 import java.lang.reflect.Type
55
56
57 /**
58  * This groovy class supports the <class>DoCreateResources.bpmn</class> process.
59  *
60  * Inputs:
61  * @param - msoRequestId
62  * @param - globalSubscriberId - O
63  * @param - subscriptionServiceType - O
64  * @param - serviceInstanceId
65  * @param - serviceInstanceName - O
66  * @param - serviceInputParams (should contain aic_zone for serviceTypes TRANSPORT,ATM)
67  * @param - sdncVersion
68  *
69  * @param - addResourceList
70  *
71  * Outputs:
72  * @param - WorkflowException
73  */
74 public class DoCreateResources extends AbstractServiceTaskProcessor{
75     private static final Logger logger = LoggerFactory.getLogger( DoCreateResources.class)
76
77     ExceptionUtil exceptionUtil = new ExceptionUtil()
78     JsonUtils jsonUtil = new JsonUtils()
79     CatalogDbUtils catalogDbUtils = new CatalogDbUtilsFactory().create()
80
81      void preProcessRequest(DelegateExecution execution) {
82         logger.trace("preProcessRequest ")
83         String msg = ""
84
85         List addResourceList = execution.getVariable("addResourceList")
86         if (addResourceList == null) {
87             msg = "Input addResourceList is null"
88             logger.info(msg)
89             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
90         }
91         else if (addResourceList.size() == 0) {
92             msg = "No resource in addResourceList"
93             logger.info(msg)
94         }
95         logger.trace("Exit preProcessRequest ")
96     }
97
98      void sequenceResoure(DelegateExecution execution) {
99         logger.trace("Start sequenceResoure Process ")
100
101         String incomingRequest = execution.getVariable("uuiRequest")
102         String serviceModelUuid = jsonUtil.getJsonValue(incomingRequest,"service.serviceUuid")
103
104         List<Resource> addResourceList = execution.getVariable("addResourceList")
105
106         List<NetworkResource> networkResourceList = new ArrayList<NetworkResource>()
107
108         List<Resource> sequencedResourceList = new ArrayList<Resource>()
109
110         String serviceDecompose = execution.getVariable("serviceDecomposition")
111         String serviceModelName = jsonUtil.getJsonValue(serviceDecompose, "serviceResources.modelInfo.modelName")
112
113         // get Sequence from properties
114         def resourceSequence = BPMNProperties.getResourceSequenceProp(serviceModelName)
115
116         // get Sequence from csar(model)
117         if(resourceSequence == null) {
118             resourceSequence = ResourceRequestBuilder.getResourceSequence(serviceModelUuid)
119             logger.info("Get Sequence from csar : " + resourceSequence)
120         }
121
122         if(resourceSequence != null) {
123             for (resourceType in resourceSequence) {
124                 for (resource in addResourceList) {
125                     if (StringUtils.containsIgnoreCase(resource.getModelInfo().getModelName(), resourceType)) {
126
127
128                         // if resource type is vnfResource then check for groups also
129                         // Did not use continue because if same model type is used twice
130                         // then we would like to add it twice for processing
131                         // ex-1. S{ V1{G1, G2}} --> S{ V1{G1, G1, G2}}
132                         // ex-2. S{ V1{G1, G2}} --> S{ V1{G1, G2, G2, G2} V1 {G1, G1, G2}}
133                         if ((resource.getResourceType() == ResourceType.VNF) && (resource instanceof VnfResource)) {
134
135                             // check the size of VNF/Group list from UUI
136                             List<Resource> sequencedInstanceResourceList = InstanceResourceList.getInstanceResourceList((VnfResource) resource, incomingRequest)
137                             sequencedResourceList.addAll(sequencedInstanceResourceList)
138                         } else {
139                             sequencedResourceList.add(resource)
140                         }
141                         if (resource instanceof NetworkResource) {
142                             networkResourceList.add(resource)
143                         }
144                     }
145                 }
146             }
147         } else {
148
149             //define sequenced resource list, we deploy vf first and then network and then ar
150             //this is default sequence
151             List<VnfResource> vnfResourceList = new ArrayList<VnfResource>()
152             List<AllottedResource> arResourceList = new ArrayList<AllottedResource>()
153
154             for (Resource rc : addResourceList){
155                 if (rc instanceof VnfResource) {
156                     // check the size of VNF/Group list from UUI
157                     List<Resource> sequencedGroupResourceList = InstanceResourceList.getInstanceResourceList((VnfResource) rc, incomingRequest)
158                     vnfResourceList.addAll(sequencedGroupResourceList)
159                 } else if (rc instanceof NetworkResource) {
160                     networkResourceList.add(rc)
161                 } else if (rc instanceof AllottedResource) {
162                     arResourceList.add(rc)
163                 }
164             }
165             sequencedResourceList.addAll(vnfResourceList)
166             sequencedResourceList.addAll(networkResourceList)
167             sequencedResourceList.addAll(arResourceList)
168         }
169
170         String isContainsWanResource = networkResourceList.isEmpty() ? "false" : "true"
171         //if no networkResource, get SDNC config from properties file
172         if( "false".equals(isContainsWanResource)) {
173             String serviceNeedSDNC = "mso.workflow.custom." + serviceModelName + ".sdnc.need"
174             isContainsWanResource = BPMNProperties.getProperty(serviceNeedSDNC, isContainsWanResource)
175         }
176
177         execution.setVariable("isContainsWanResource", isContainsWanResource)
178         execution.setVariable("currentResourceIndex", 0)
179         execution.setVariable("sequencedResourceList", sequencedResourceList)
180         logger.info("sequencedResourceList: " + sequencedResourceList)
181         logger.trace("COMPLETED sequenceResoure Process ")
182     }
183
184      void prepareServiceTopologyRequest(DelegateExecution execution) {
185
186         logger.trace("======== Start prepareServiceTopologyRequest Process ======== ")
187
188         String serviceDecompose = execution.getVariable("serviceDecomposition")
189
190         execution.setVariable("operationType", "create")
191         execution.setVariable("resourceType", "")
192
193         String serviceInvariantUuid = jsonUtil.getJsonValue(serviceDecompose, "serviceResources.modelInfo.modelInvariantUuid")
194         String serviceUuid = jsonUtil.getJsonValue(serviceDecompose, "serviceResources.modelInfo.modelUuid")
195         String serviceModelName = jsonUtil.getJsonValue(serviceDecompose, "serviceResources.modelInfo.modelName")
196
197         execution.setVariable("modelInvariantUuid", serviceInvariantUuid)
198         execution.setVariable("modelUuid", serviceUuid)
199         execution.setVariable("serviceModelName", serviceModelName)
200
201         logger.trace("======== End prepareServiceTopologyRequest Process ======== ")
202     }
203
204      void getCurrentResoure(DelegateExecution execution){
205         logger.trace("Start getCurrentResoure Process ")
206         def currentIndex = execution.getVariable("currentResourceIndex")
207         List<Resource> sequencedResourceList = execution.getVariable("sequencedResourceList")
208         Resource currentResource = sequencedResourceList.get(currentIndex)
209         execution.setVariable("resourceType", currentResource.getModelInfo().getModelName())
210         logger.info("Now we deal with resource:" + currentResource.getModelInfo().getModelName())
211         logger.trace("COMPLETED getCurrentResource Process ")
212     }
213
214      void parseNextResource(DelegateExecution execution){
215         logger.trace("Start parseNextResource Process ")
216         def currentIndex = execution.getVariable("currentResourceIndex")
217         def nextIndex =  currentIndex + 1
218         execution.setVariable("currentResourceIndex", nextIndex)
219         List<Resource> sequencedResourceList = execution.getVariable("sequencedResourceList")
220         if(nextIndex >= sequencedResourceList.size()){
221             execution.setVariable("allResourceFinished", "true")
222         }else{
223             execution.setVariable("allResourceFinished", "false")
224         }
225         logger.trace("COMPLETED parseNextResource Process ")
226     }
227
228      void prepareResourceRecipeRequest(DelegateExecution execution){
229         logger.trace("Start prepareResourceRecipeRequest Process ")
230         ResourceInput resourceInput = new ResourceInput()
231         String serviceInstanceName = execution.getVariable("serviceInstanceName")
232         String resourceType = execution.getVariable("resourceType")
233         String resourceInstanceName = resourceType + "_" + serviceInstanceName
234         resourceInput.setResourceInstanceName(resourceInstanceName)
235         logger.info("Prepare Resource Request resourceInstanceName:" + resourceInstanceName)
236         String globalSubscriberId = execution.getVariable("globalSubscriberId")
237         String serviceType = execution.getVariable("serviceType")
238         String serviceInstanceId = execution.getVariable("serviceInstanceId")
239         String operationId = execution.getVariable("operationId")
240         String operationType = "createInstance"
241         resourceInput.setGlobalSubscriberId(globalSubscriberId)
242         resourceInput.setServiceType(serviceType)
243         resourceInput.setServiceInstanceId(serviceInstanceId)
244         resourceInput.setOperationId(operationId)
245         resourceInput.setOperationType(operationType)
246         def currentIndex = execution.getVariable("currentResourceIndex")
247         List<Resource> sequencedResourceList = execution.getVariable("sequencedResourceList")
248         Resource currentResource = sequencedResourceList.get(currentIndex)
249         resourceInput.setResourceModelInfo(currentResource.getModelInfo())
250         resourceInput.getResourceModelInfo().setModelType(currentResource.getResourceType().toString())
251         ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
252
253         if (currentResource.getResourceType() == ResourceType.VNF) {
254             execution.setVariable("vfModelInfo", currentResource.getModelInfo())
255         }
256
257         resourceInput.setVfModelInfo(execution.getVariable("vfModelInfo") as ModelInfo)
258         String vnfId = execution.getVariable("vnf-id")
259         if (vnfId != null) {
260             resourceInput.setVnfId(vnfId)
261         }
262
263
264         resourceInput.setServiceModelInfo(serviceDecomposition.getModelInfo())
265
266         String incomingRequest = execution.getVariable("uuiRequest")
267         //set the requestInputs from template  To Be Done
268         String uuiServiceParameters = jsonUtil.getJsonValue(incomingRequest, "service.parameters")
269
270         // current vfdata holds information for preparing input for resource
271         // e.g. it will hold
272         // { top_level_list_name, second_level_list_name, top_index, second_index, last processed node}
273         Map<String, Object> currentVFData = (Map) execution.getVariable("currentVFData")
274
275         if (null == currentVFData) {
276             currentVFData = new HashMap<>()
277         }
278         String resourceParameters = ResourceRequestBuilder.buildResourceRequestParameters(execution, currentResource, uuiServiceParameters, currentVFData)
279         resourceInput.setResourceParameters(resourceParameters)
280         resourceInput.setRequestsInputs(incomingRequest)
281         execution.setVariable("resourceInput", resourceInput.toString())
282         execution.setVariable("resourceModelUUID", resourceInput.getResourceModelInfo().getModelUuid())
283         execution.setVariable("currentVFData",currentVFData)
284         logger.trace("COMPLETED prepareResourceRecipeRequest Process ")
285     }
286
287      void executeResourceRecipe(DelegateExecution execution){
288         logger.trace("Start executeResourceRecipe Process ")
289
290         try {
291             String requestId = execution.getVariable("msoRequestId")
292             String serviceInstanceId = execution.getVariable("serviceInstanceId")
293             String serviceType = execution.getVariable("serviceType")
294             String resourceInput = execution.getVariable("resourceInput")
295             String resourceModelUUID = execution.getVariable("resourceModelUUID")
296
297             // requestAction is action, not opertiontype
298             //String requestAction = resourceInput.getOperationType()
299             String requestAction = "createInstance"
300             JSONObject resourceRecipe = catalogDbUtils.getResourceRecipe(execution, resourceModelUUID, requestAction)
301
302             if (resourceRecipe != null) {
303                 String recipeURL = BPMNProperties.getProperty("bpelURL", "http://so-bpmn-infra.onap:8081") + resourceRecipe.getString("orchestrationUri")
304                 int recipeTimeOut = resourceRecipe.getInt("recipeTimeout")
305                 String recipeParamXsd = resourceRecipe.get("paramXSD")
306
307                 BpmnRestClient bpmnRestClient = new BpmnRestClient()
308                 HttpResponse resp = bpmnRestClient.post(recipeURL, requestId, recipeTimeOut, requestAction, serviceInstanceId, serviceType, resourceInput, recipeParamXsd)
309
310                 def currentIndex = execution.getVariable("currentResourceIndex")
311                 List<Resource> sequencedResourceList = execution.getVariable("sequencedResourceList") as List<Resource>
312                 Resource currentResource = sequencedResourceList.get(currentIndex)
313                 if(ResourceType.VNF == currentResource.getResourceType()) {
314                     if (resp.getStatusLine().getStatusCode() > 199 && resp.getStatusLine().getStatusCode() < 300) {
315                         String responseString = EntityUtils.toString(resp.getEntity(), "UTF-8")
316                         if (responseString != null) {
317                             Gson gson = new Gson()
318                             Type type = new TypeToken<Map<String, String>>() {}.getType()
319                             Map<String, Object> map = gson.fromJson(responseString, type)
320                             Map<String, String> map1 = gson.fromJson(map.get("response"), type)
321                             execution.setVariable("vnf-id",map1.get("vnf-id"))
322                         }
323                     }
324                 }
325             } else {
326                 String exceptionMessage = "Resource receipe is not found for resource modeluuid: " + resourceModelUUID
327                 logger.trace(exceptionMessage)
328                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, exceptionMessage)
329             }
330
331             logger.trace("======== end executeResourceRecipe Process ======== ")
332         }catch(BpmnError b){
333             logger.debug("Rethrowing MSOWorkflowException")
334             throw b
335         }catch(Exception e){
336             logger.debug("Error occured within DoCreateResources executeResourceRecipe method: " + e)
337             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Internal Error - Occured during DoCreateResources executeResourceRecipe Catalog")
338         }
339     }
340
341      void postConfigRequest(DelegateExecution execution){
342         //now do noting
343         ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
344         for (VnfResource resource : serviceDecomposition.vnfResources) {
345             resource.setOrchestrationStatus("Active")
346         }
347         execution.setVariable("serviceDecomposition", serviceDecomposition)
348     }
349 }