Merge "Use a dependency-injected RestTemplateBuilder to create RestTemplates"
[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.aai.domain.yang.SliceProfiles
25 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
26 import org.onap.aaiclient.client.aai.entities.uri.AAIPluralResourceUri
27 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
28 import org.onap.aaiclient.client.aai.entities.uri.AAISimpleUri
29 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
30 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
31 import org.onap.so.beans.nsmf.*
32 import org.onap.so.beans.nsmf.oof.SubnetType
33 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
34 import org.onap.so.bpmn.common.scripts.ExceptionUtil
35 import org.onap.so.bpmn.common.scripts.NssmfAdapterUtils
36 import org.onap.so.bpmn.common.scripts.RequestDBUtil
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 import javax.ws.rs.NotFoundException
44
45 class DoDeallocateNSSI extends AbstractServiceTaskProcessor {
46     private static final Logger LOGGER = LoggerFactory.getLogger( DoDeallocateNSSI.class)
47     private static final ObjectMapper mapper = new ObjectMapper()
48     private final String PREFIX ="DoDeallocateNSSI"
49
50     private ExceptionUtil exceptionUtil = new ExceptionUtil()
51     private JsonUtils jsonUtil = new JsonUtils()
52     private RequestDBUtil requestDBUtil = new RequestDBUtil()
53     private NssmfAdapterUtils nssmfAdapterUtils = new NssmfAdapterUtils(httpClientFactory, jsonUtil)
54
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             String vendor = serviceDecomposition.getServiceRole()
107             NetworkType domainType = convertServiceCategory(serviceDecomposition.getServiceCategory())
108
109             def currentNSSI = execution.getVariable("currentNSSI")
110             currentNSSI['vendor'] = vendor
111             currentNSSI['domainType'] = domainType
112             LOGGER.info("processDecomposition, current vendor-domainType:" +String.join("-", vendor, domainType.toString()))
113
114         } catch (any) {
115             String exceptionMessage = "Bpmn error encountered in deallocate nssi. processDecomposition() - " + any.getMessage()
116             LOGGER.debug(exceptionMessage)
117             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
118         }
119         LOGGER.debug("*****${PREFIX} Exit processDecomposition *****")
120     }
121
122
123     /**
124      * get subnetType from serviceCategory
125      * @return
126      */
127     private NetworkType convertServiceCategory(String serviceCategory){
128         if(serviceCategory ==~ /CN.*/){
129             return SubnetType.CN.getNetworkType()
130         }
131         if (serviceCategory ==~ /AN.*/){
132             return SubnetType.AN.getNetworkType()
133         }
134         if (serviceCategory ==~ /TN.*BH.*/){
135             return SubnetType.TN_BH.getNetworkType()
136         }
137         if(serviceCategory ==~ /TN.*MH.*/){
138             return SubnetType.TN_MH.getNetworkType()
139         }
140         if(serviceCategory ==~ /TN.*FH.*/){
141             return SubnetType.TN_FH.getNetworkType()
142         }
143         return null
144     }
145
146     /**
147      * send deallocate request to nssmf
148      * @param execution
149      */
150     void sendRequestToNSSMF(DelegateExecution execution)
151     {
152         LOGGER.debug("*****${PREFIX} start sendRequestToNSSMF *****")
153         def currentNSSI = execution.getVariable("currentNSSI")
154         String snssai= currentNSSI['snssai']
155         String profileId = currentNSSI['profileId']
156         String nssiId = currentNSSI['nssiServiceInstanceId']
157         String nsiId = currentNSSI['nsiServiceInstanceId']
158         String scriptName = execution.getVariable("scriptName")
159
160         String serviceInvariantUuid = currentNSSI['modelInvariantId']
161         String serviceUuid = currentNSSI['modelVersionId']
162         String globalSubscriberId = currentNSSI['globalSubscriberId']
163         String subscriptionServiceType = currentNSSI['serviceType']
164
165         DeAllocateNssi deAllocateNssi = new DeAllocateNssi()
166         deAllocateNssi.setNsiId(nsiId)
167         deAllocateNssi.setNssiId(nssiId)
168         deAllocateNssi.setTerminateNssiOption(0)
169         deAllocateNssi.setSnssaiList(Arrays.asList(snssai))
170         deAllocateNssi.setScriptName(scriptName)
171         deAllocateNssi.setSliceProfileId(profileId)
172
173         ServiceInfo serviceInfo = new ServiceInfo()
174         serviceInfo.setServiceInvariantUuid(serviceInvariantUuid)
175         serviceInfo.setServiceUuid(serviceUuid)
176         serviceInfo.setNsiId(nsiId)
177         serviceInfo.setNssiId(nssiId)
178         serviceInfo.setGlobalSubscriberId(globalSubscriberId)
179         serviceInfo.setSubscriptionServiceType(subscriptionServiceType)
180         String serviceInfoString = mapper.writeValueAsString(serviceInfo)
181
182         EsrInfo esrInfo = getEsrInfo(currentNSSI)
183         String esrInfoString = mapper.writeValueAsString(esrInfo)
184
185         execution.setVariable("deAllocateNssi",deAllocateNssi)
186         execution.setVariable("esrInfo", esrInfoString)
187         execution.setVariable("serviceInfo", serviceInfoString)
188         String nssmfRequest = """
189                 {
190                   "deAllocateNssi": ${mapper.writeValueAsString(deAllocateNssi)},
191                   "esrInfo":  ${esrInfoString},
192                   "serviceInfo": ${serviceInfoString}
193                 }
194               """
195
196         String urlStr = String.format("/api/rest/provMns/v1/NSS/SliceProfiles/%s", profileId)
197
198         NssiResponse nssmfResponse = nssmfAdapterUtils.sendPostRequestNSSMF(execution, urlStr, nssmfRequest, NssiResponse.class)
199         if (nssmfResponse != null) {
200             currentNSSI['jobId']= nssmfResponse.getJobId() ?: ""
201             currentNSSI['jobProgress'] = 0
202             execution.setVariable("currentNSSI", currentNSSI)
203         } else {
204             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a Bad Response from NSSMF.")
205         }
206         LOGGER.debug("*****${PREFIX} Exit sendRequestToNSSMF *****")
207     }
208
209 /**
210      * send to nssmf query progress
211      * @param execution
212      */
213     void prepareJobStatusRequest(DelegateExecution execution)
214     {
215         def currentNSSI = execution.getVariable("currentNSSI")
216         String jobId = currentNSSI['jobId']
217         execution.setVariable("jobId", jobId)
218     }
219
220
221     /**
222      * send to nssmf query progress
223      * @param execution
224      */
225     void handleJobStatus(DelegateExecution execution)
226     {
227         try
228         {
229         String jobStatusResponse = execution.getVariable("responseDescriptor")
230         String status = jsonUtil.getJsonValue(jobStatusResponse,"status")
231         def statusDescription = jsonUtil.getJsonValue(jobStatusResponse,"statusDescription")
232         def progress = jsonUtil.getJsonValue(jobStatusResponse,"progress")
233         if(!status.equalsIgnoreCase("failed"))
234         {
235             if(!progress)
236             {
237                 LOGGER.error("job progress is null or empty!")
238                 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a Bad Job progress from NSSMF.")
239             }
240             def currentNSSI = execution.getVariable("currentNSSI")
241             int oldProgress = currentNSSI['jobProgress']
242             int currentProgress = Integer.parseInt(progress)
243
244             execution.setVariable("isNSSIDeAllocated", (currentProgress == 100))
245             execution.setVariable("isNeedUpdateDB", (oldProgress != currentProgress))
246             currentNSSI['jobProgress'] = currentProgress
247             currentNSSI['status'] = status
248             currentNSSI['statusDescription'] = statusDescription
249
250             String nssiId = currentNSSI['nssiServiceInstanceId']
251             String nsiId = currentNSSI['nsiServiceInstanceId']
252             LOGGER.debug("job status result: nsiId = ${nsiId}, nssiId=${nssiId}, oldProgress=${oldProgress}, progress = ${currentProgress}" )
253         }
254           else {
255             execution.setVariable("isNeedUpdateDB", "true")
256             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a Bad Response from NSSMF.")
257         }
258         }
259         catch (any)
260         {
261             String msg = "Received a Bad Response from NSSMF. cause-"+any.getCause()
262             LOGGER.error(any.printStackTrace())
263             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
264         }
265     }
266
267     private EsrInfo getEsrInfo(def currentNSSI)
268     {
269         NetworkType domainType = currentNSSI['domainType']
270         String vendor = currentNSSI['vendor']
271
272         EsrInfo info = new EsrInfo()
273         info.setNetworkType(domainType)
274         info.setVendor(vendor)
275         return info
276     }
277
278  /**
279      * handle job status
280      * prepare update requestdb
281      * @param execution
282      */
283     void prepareUpdateOperationStatus(DelegateExecution execution)
284     {
285         def currentNSSI = execution.getVariable("currentNSSI")
286         int currentProgress = currentNSSI["jobProgress"]
287         def proportion = currentNSSI['proportion']
288         int progress = (currentProgress as int) == 0 ? 0 : (currentProgress as int) / 100 * (proportion as int)
289         def status = currentNSSI['status']
290
291
292         OperationStatus operationStatus = new OperationStatus()
293         operationStatus.setServiceId(currentNSSI['e2eServiceInstanceId'] as String)
294         operationStatus.setOperationId(currentNSSI['operationId'] as String)
295         operationStatus.setOperation("DELETE")
296         operationStatus.setResult("processing")
297         operationStatus.setProgress(progress as String)
298         operationStatus.setOperationContent(currentNSSI['domainType'].toString() + " " + status.toString())
299         requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
300         LOGGER.debug("update operation, currentProgress=${currentProgress}, proportion=${proportion}, progress = ${progress}" )
301     }
302
303     /**
304      * delete slice profile from aai
305      * @param execution
306      */
307     void delSliceProfileServiceFromAAI(DelegateExecution execution)
308     {
309         LOGGER.debug("*****${PREFIX} start delSliceProfileFromAAI *****")
310         def currentNSSI = execution.getVariable("currentNSSI")
311         String nssiServiceInstanceId = currentNSSI['nssiServiceInstanceId']
312         String profileId = currentNSSI['profileId']
313         String globalSubscriberId = currentNSSI["globalSubscriberId"]
314         String serviceType = currentNSSI['serviceType']
315
316         try
317         {
318             LOGGER.debug("delete nssiServiceInstanceId:${nssiServiceInstanceId}, profileId:${profileId}")
319             AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(
320                 AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(profileId))
321             if (!getAAIClient().exists(resourceUri)) {
322                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai")
323             }
324             getAAIClient().delete(resourceUri)
325         }
326         catch (any)
327         {
328             String msg = "delete slice profile from aai failed! cause-"+any.getCause()
329             LOGGER.error(any.printStackTrace())
330             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
331         }
332         LOGGER.debug("*****${PREFIX} Exist delSliceProfileFromAAI *****")
333     }
334
335     void delSliceProfileFromAAI(DelegateExecution execution){
336
337         LOGGER.debug("*****${PREFIX} start delSliceProfileFromAAI *****")
338         def currentNSSI = execution.getVariable("currentNSSI")
339         String globalSubscriberId = currentNSSI["globalSubscriberId"]
340         String serviceType = currentNSSI['serviceType']
341         String sliceProfileInstId = currentNSSI['profileId']
342
343         try
344         {
345             AAIPluralResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(sliceProfileInstId).sliceProfiles())
346             AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
347             Optional<SliceProfiles> sliceProfilesOpt =wrapper.asBean(SliceProfiles.class)
348             SliceProfiles sliceProfiles
349             String profileId
350             if(sliceProfilesOpt.isPresent()){
351                 sliceProfiles = sliceProfilesOpt.get()
352                 org.onap.aai.domain.yang.SliceProfile sliceProfile = sliceProfiles.getSliceProfile().get(0)
353                 profileId = sliceProfile ? sliceProfile.getProfileId() : ""
354             }
355             if (profileId){
356                 AAISimpleUri profileUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(sliceProfileInstId).sliceProfile(profileId))
357                 if (!getAAIClient().exists(profileUri)) {
358                     exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai")
359                 }
360                 getAAIClient().delete(profileUri)
361             }
362
363         }
364         catch (any)
365         {
366             String msg = "delete service profile from aai failed! cause-"+any.getCause()
367             LOGGER.error(any.printStackTrace())
368             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
369         }
370     }
371 }