Merge "Fixed the lock times and populated error variable"
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DoDeallocateNSSI.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  # Copyright (c) 2019, CMCC Technologies Co., Ltd.
6  #
7  # Licensed under the Apache License, Version 2.0 (the "License")
8  # you may not use this file except in compliance with the License.
9  # You may obtain a copy of the License at
10  #
11  #       http://www.apache.org/licenses/LICENSE-2.0
12  #
13  # Unless required by applicable law or agreed to in writing, software
14  # distributed under the License is distributed on an "AS IS" BASIS,
15  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  # See the License for the specific language governing permissions and
17  # limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.onap.so.bpmn.infrastructure.scripts
21
22 import com.fasterxml.jackson.databind.ObjectMapper
23 import org.camunda.bpm.engine.delegate.DelegateExecution
24 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
25 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
26 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
27 import org.onap.so.beans.nsmf.DeAllocateNssi
28 import org.onap.so.beans.nsmf.EsrInfo
29 import org.onap.so.beans.nsmf.NetworkType
30 import org.onap.so.beans.nsmf.NssiResponse
31 import org.onap.so.beans.nsmf.ServiceInfo
32 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
33 import org.onap.so.bpmn.common.scripts.ExceptionUtil
34 import org.onap.so.bpmn.common.scripts.NssmfAdapterUtils
35 import org.onap.so.bpmn.common.scripts.RequestDBUtil
36 import org.onap.so.bpmn.core.domain.ServiceArtifact
37 import org.onap.so.bpmn.core.domain.ServiceDecomposition
38 import org.onap.so.bpmn.core.json.JsonUtils
39 import org.onap.so.db.request.beans.OperationStatus
40 import org.slf4j.Logger
41 import org.slf4j.LoggerFactory
42
43
44 class DoDeallocateNSSI extends AbstractServiceTaskProcessor
45 {
46     private final String PREFIX ="DoDeallocateNSSI"
47
48     private ExceptionUtil exceptionUtil = new ExceptionUtil()
49     private JsonUtils jsonUtil = new JsonUtils()
50     ObjectMapper objectMapper = new ObjectMapper()
51     private RequestDBUtil requestDBUtil = new RequestDBUtil()
52     private NssmfAdapterUtils nssmfAdapterUtils = new NssmfAdapterUtils(httpClientFactory, jsonUtil)
53
54     private static final Logger LOGGER = LoggerFactory.getLogger( DoDeallocateNSSI.class)
55
56     @Override
57     void preProcessRequest(DelegateExecution execution) {
58         LOGGER.trace(" ***** ${PREFIX} Start preProcessRequest *****")
59
60         def currentNSSI = execution.getVariable("currentNSSI")
61         if (!currentNSSI) {
62             String msg = "currentNSSI is null"
63             LOGGER.error(msg)
64             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
65         }
66
67         LOGGER.trace("***** ${PREFIX} Exit preProcessRequest *****")
68     }
69
70     /**
71      *
72      * @param execution
73      */
74     void prepareDecomposeService(DelegateExecution execution)
75     {
76         LOGGER.trace(" *****${PREFIX} Start prepareDecomposeService *****")
77         try
78         {
79             def currentNSSI = execution.getVariable("currentNSSI")
80             String modelInvariantUuid = currentNSSI['modelInvariantId']
81             String modelVersionId = currentNSSI['modelVersionId']
82             String serviceModelInfo = """{
83             "modelInvariantUuid":"${modelInvariantUuid}",
84             "modelUuid":"${modelVersionId}",
85             "modelVersion":""
86              }"""
87             execution.setVariable("serviceModelInfo", serviceModelInfo)
88         }
89         catch (any)
90         {
91             String exceptionMessage = "Bpmn error encountered in deallocate nssi. Unexpected Error from method prepareDecomposeService() - " + any.getMessage()
92             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
93         }
94         LOGGER.debug(" ***** ${PREFIX} Exit prepareDecomposeService *****")
95     }
96
97     /**
98      * get vendor Info
99      * @param execution
100      */
101     void processDecomposition(DelegateExecution execution) {
102         LOGGER.debug("*****${PREFIX} start processDecomposition *****")
103
104         try {
105             ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition") as ServiceDecomposition
106             ServiceArtifact serviceArtifact = serviceDecomposition ?.getServiceInfo()?.getServiceArtifact()?.get(0)
107             String content = serviceArtifact.getContent()
108             String vendor = jsonUtil.getJsonValue(content, "metadata.vendor")
109             String domainType  = jsonUtil.getJsonValue(content, "metadata.domainType")
110
111             def currentNSSI = execution.getVariable("currentNSSI")
112             currentNSSI['vendor'] = vendor
113             currentNSSI['domainType'] = domainType
114             LOGGER.info("processDecomposition, current vendor-domainType:" +String.join("-", vendor, domainType))
115
116         } catch (any) {
117             String exceptionMessage = "Bpmn error encountered in deallocate nssi. processDecomposition() - " + any.getMessage()
118             LOGGER.debug(exceptionMessage)
119             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
120         }
121         LOGGER.debug("*****${PREFIX} Exit processDecomposition *****")
122     }
123     
124     /**
125      * send deallocate request to nssmf
126      * @param execution
127      */
128     void sendRequestToNSSMF(DelegateExecution execution)
129     {
130         LOGGER.debug("*****${PREFIX} start sendRequestToNSSMF *****")
131         def currentNSSI = execution.getVariable("currentNSSI")
132         String snssai= currentNSSI['snssai']
133         String profileId = currentNSSI['profileId']
134         String nssiId = currentNSSI['nssiServiceInstanceId']
135         String nsiId = currentNSSI['nsiServiceInstanceId']
136         String scriptName = execution.getVariable("scriptName")
137
138         String serviceInvariantUuid = currentNSSI['modelInvariantId']
139         String serviceUuid = currentNSSI['modelId']
140         String globalSubscriberId = currentNSSI['globalSubscriberId']
141         String subscriptionServiceType = execution.getVariable("serviceType")
142         
143         DeAllocateNssi deAllocateNssi = new DeAllocateNssi()
144         deAllocateNssi.setNsiId(nsiId)
145         deAllocateNssi.setNssiId(nssiId)
146         deAllocateNssi.setTerminateNssiOption(0)
147         deAllocateNssi.setSnssaiList(Arrays.asList(snssai))
148         deAllocateNssi.setScriptName(scriptName)
149         
150         ServiceInfo serviceInfo = new ServiceInfo()
151         serviceInfo.setServiceInvariantUuid(serviceInvariantUuid)
152         serviceInfo.setServiceUuid(serviceUuid)
153         serviceInfo.setNsiId(nsiId)
154         serviceInfo.setNssiId(nssiId)
155         serviceInfo.setGlobalSubscriberId(globalSubscriberId)
156         serviceInfo.setSubscriptionServiceType(subscriptionServiceType)
157         String serviceInfoString = objectMapper.writeValueAsString(serviceInfo)
158         
159         EsrInfo esrInfo = getEsrInfo(currentNSSI)
160         String esrInfoString = objectMapper.writeValueAsString(esrInfo)
161         
162         execution.setVariable("deAllocateNssi",deAllocateNssi)
163         execution.setVariable("esrInfo", esrInfoString)
164         execution.setVariable("serviceInfo", serviceInfoString)
165         String nssmfRequest = """
166                 {
167                   "deAllocateNssi": ${objectMapper.writeValueAsString(deAllocateNssi)},
168                   "esrInfo":  ${esrInfoString},
169                   "serviceInfo": ${serviceInfoString}
170                 }
171               """
172
173         String urlStr = String.format("/api/rest/provMns/v1/NSS/SliceProfiles/%s", profileId)
174
175         NssiResponse nssmfResponse = nssmfAdapterUtils.sendPostRequestNSSMF(execution, urlStr, nssmfRequest, NssiResponse.class)
176         if (nssmfResponse != null) {
177             currentNSSI['jobId']= nssmfResponse.getJobId() ?: "" 
178             currentNSSI['jobProgress'] = 0            
179             execution.setVariable("currentNSSI", currentNSSI)    
180         } else {
181             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a Bad Response from NSSMF.")
182         }
183         LOGGER.debug("*****${PREFIX} Exit sendRequestToNSSMF *****")
184     }
185
186 /**
187      * send to nssmf query progress
188      * @param execution
189      */
190     void prepareJobStatusRequest(DelegateExecution execution)
191     {
192         def currentNSSI = execution.getVariable("currentNSSI")
193         String jobId = currentNSSI['jobId']
194
195         execution.setVariable("responseId", "3")
196         execution.setVariable("jobId", jobId)
197     }
198
199     
200     /**
201      * send to nssmf query progress
202      * @param execution
203      */
204     void handleJobStatus(DelegateExecution execution)
205     {
206         try 
207         {
208         String jobStatusResponse = execution.getVariable("responseDescriptor")
209         String status = jsonUtil.getJsonValue(jobStatusResponse,"status")
210         def statusDescription = jsonUtil.getJsonValue(jobStatusResponse,"statusDescription")
211         def progress = jsonUtil.getJsonValue(jobStatusResponse,"progress")
212         if(!status.equalsIgnoreCase("failed"))
213         {
214             if(!progress)
215             {
216                 LOGGER.error("job progress is null or empty!")
217                 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a Bad Job progress from NSSMF.")
218             }
219             def currentNSSI = execution.getVariable("currentNSSI")
220             int oldProgress = currentNSSI['jobProgress']
221             int currentProgress = Integer.parseInt(progress)
222
223             execution.setVariable("isNSSIDeAllocated", (currentProgress == 100))
224             execution.setVariable("isNeedUpdateDB", (oldProgress != currentProgress))
225             currentNSSI['jobProgress'] = currentProgress
226             currentNSSI['status'] = status
227             currentNSSI['statusDescription'] = statusDescription
228
229             String nssiId = currentNSSI['nssiServiceInstanceId']
230             String nsiId = currentNSSI['nsiServiceInstanceId']
231             LOGGER.debug("job status result: nsiId = ${nsiId}, nssiId=${nssiId}, oldProgress=${oldProgress}, progress = ${currentProgress}" )
232         }
233           else {
234             execution.setVariable("isNeedUpdateDB", "true")
235             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a Bad Response from NSSMF.")
236         }
237         }
238         catch (any)
239         {
240             String msg = "Received a Bad Response from NSSMF. cause-"+any.getCause()
241             LOGGER.error(any.printStackTrace())
242             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
243         }
244     }
245
246     private EsrInfo getEsrInfo(def currentNSSI)
247     {
248         String domaintype = currentNSSI['domainType']
249         String vendor = currentNSSI['vendor']
250         
251         EsrInfo info = new EsrInfo()
252         info.setNetworkType(NetworkType.fromString(domaintype))
253         info.setVendor(vendor)
254         return info
255     }
256
257  /**
258      * handle job status
259      * prepare update requestdb
260      * @param execution
261      */
262     void prepareUpdateOperationStatus(DelegateExecution execution)
263     {
264         def currentNSSI = execution.getVariable("currentNSSI")
265         int currentProgress = currentNSSI["jobProgress"]
266         def proportion = currentNSSI['proportion']
267         def statusDes = currentNSSI["statusDescription"]
268         int progress = (currentProgress as int) == 0 ? 0 : (currentProgress as int) / 100 * (proportion as int)
269         def status = currentNSSI['status']
270         
271         OperationStatus operationStatus = new OperationStatus()
272         operationStatus.setServiceId(currentNSSI['e2eServiceInstanceId'] as String)
273         operationStatus.setOperationId(currentNSSI['operationId'] as String)
274         operationStatus.setOperation("DELETE")
275         operationStatus.setResult(status as String)
276         operationStatus.setProgress(progress as String)
277         operationStatus.setOperationContent(statusDes as String)
278         requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
279         LOGGER.debug("update operation, currentProgress=${currentProgress}, proportion=${proportion}, progress = ${progress}" )
280     }
281     
282     /**
283      * delete slice profile from aai
284      * @param execution
285      */
286     void delSliceProfileFromAAI(DelegateExecution execution)
287     {
288         LOGGER.debug("*****${PREFIX} start delSliceProfileFromAAI *****")
289         def currentNSSI = execution.getVariable("currentNSSI")
290         String nssiServiceInstanceId = currentNSSI['nssiServiceInstanceId']
291         String profileId = currentNSSI['profileId']
292         String globalSubscriberId = currentNSSI["globalSubscriberId"]
293         String serviceType = execution.getVariable("serviceType")
294
295         try
296         {
297             LOGGER.debug("delete nssiServiceInstanceId:${nssiServiceInstanceId}, profileId:${profileId}")
298             AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(
299                 AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(nssiServiceInstanceId).sliceProfile(profileId))
300             if (!getAAIClient().exists(resourceUri)) {
301                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai")
302             }
303             getAAIClient().delete(resourceUri)
304         }
305         catch (any)
306         {
307             String msg = "delete slice profile from aai failed! cause-"+any.getCause()
308             LOGGER.error(any.printStackTrace())
309             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
310         }
311         LOGGER.debug("*****${PREFIX} Exist delSliceProfileFromAAI *****")
312     }
313 }