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