554f7a6392e94c5c65e50a80e0aadf73ddb7312d
[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.*/){
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         deAllocateNssi.setSliceProfileId(profileId)
170         
171         ServiceInfo serviceInfo = new ServiceInfo()
172         serviceInfo.setServiceInvariantUuid(serviceInvariantUuid)
173         serviceInfo.setServiceUuid(serviceUuid)
174         serviceInfo.setNsiId(nsiId)
175         serviceInfo.setNssiId(nssiId)
176         serviceInfo.setGlobalSubscriberId(globalSubscriberId)
177         serviceInfo.setSubscriptionServiceType(subscriptionServiceType)
178         String serviceInfoString = objectMapper.writeValueAsString(serviceInfo)
179         
180         EsrInfo esrInfo = getEsrInfo(currentNSSI)
181         String esrInfoString = objectMapper.writeValueAsString(esrInfo)
182         
183         execution.setVariable("deAllocateNssi",deAllocateNssi)
184         execution.setVariable("esrInfo", esrInfoString)
185         execution.setVariable("serviceInfo", serviceInfoString)
186         String nssmfRequest = """
187                 {
188                   "deAllocateNssi": ${objectMapper.writeValueAsString(deAllocateNssi)},
189                   "esrInfo":  ${esrInfoString},
190                   "serviceInfo": ${serviceInfoString}
191                 }
192               """
193
194         String urlStr = String.format("/api/rest/provMns/v1/NSS/SliceProfiles/%s", profileId)
195
196         NssiResponse nssmfResponse = nssmfAdapterUtils.sendPostRequestNSSMF(execution, urlStr, nssmfRequest, NssiResponse.class)
197         if (nssmfResponse != null) {
198             currentNSSI['jobId']= nssmfResponse.getJobId() ?: "" 
199             currentNSSI['jobProgress'] = 0            
200             execution.setVariable("currentNSSI", currentNSSI)    
201         } else {
202             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a Bad Response from NSSMF.")
203         }
204         LOGGER.debug("*****${PREFIX} Exit sendRequestToNSSMF *****")
205     }
206
207 /**
208      * send to nssmf query progress
209      * @param execution
210      */
211     void prepareJobStatusRequest(DelegateExecution execution)
212     {
213         def currentNSSI = execution.getVariable("currentNSSI")
214         String jobId = currentNSSI['jobId']
215         execution.setVariable("jobId", jobId)
216     }
217
218     
219     /**
220      * send to nssmf query progress
221      * @param execution
222      */
223     void handleJobStatus(DelegateExecution execution)
224     {
225         try 
226         {
227         String jobStatusResponse = execution.getVariable("responseDescriptor")
228         String status = jsonUtil.getJsonValue(jobStatusResponse,"status")
229         def statusDescription = jsonUtil.getJsonValue(jobStatusResponse,"statusDescription")
230         def progress = jsonUtil.getJsonValue(jobStatusResponse,"progress")
231         if(!status.equalsIgnoreCase("failed"))
232         {
233             if(!progress)
234             {
235                 LOGGER.error("job progress is null or empty!")
236                 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a Bad Job progress from NSSMF.")
237             }
238             def currentNSSI = execution.getVariable("currentNSSI")
239             int oldProgress = currentNSSI['jobProgress']
240             int currentProgress = Integer.parseInt(progress)
241
242             execution.setVariable("isNSSIDeAllocated", (currentProgress == 100))
243             execution.setVariable("isNeedUpdateDB", (oldProgress != currentProgress))
244             currentNSSI['jobProgress'] = currentProgress
245             currentNSSI['status'] = status
246             currentNSSI['statusDescription'] = statusDescription
247
248             String nssiId = currentNSSI['nssiServiceInstanceId']
249             String nsiId = currentNSSI['nsiServiceInstanceId']
250             LOGGER.debug("job status result: nsiId = ${nsiId}, nssiId=${nssiId}, oldProgress=${oldProgress}, progress = ${currentProgress}" )
251         }
252           else {
253             execution.setVariable("isNeedUpdateDB", "true")
254             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a Bad Response from NSSMF.")
255         }
256         }
257         catch (any)
258         {
259             String msg = "Received a Bad Response from NSSMF. cause-"+any.getCause()
260             LOGGER.error(any.printStackTrace())
261             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
262         }
263     }
264
265     private EsrInfo getEsrInfo(def currentNSSI)
266     {
267         NetworkType domainType = currentNSSI['domainType']
268         String vendor = currentNSSI['vendor']
269         
270         EsrInfo info = new EsrInfo()
271         info.setNetworkType(domainType)
272         info.setVendor(vendor)
273         return info
274     }
275
276  /**
277      * handle job status
278      * prepare update requestdb
279      * @param execution
280      */
281     void prepareUpdateOperationStatus(DelegateExecution execution)
282     {
283         def currentNSSI = execution.getVariable("currentNSSI")
284         int currentProgress = currentNSSI["jobProgress"]
285         def proportion = currentNSSI['proportion']
286         int progress = (currentProgress as int) == 0 ? 0 : (currentProgress as int) / 100 * (proportion as int)
287         def status = currentNSSI['status']
288
289
290         OperationStatus operationStatus = new OperationStatus()
291         operationStatus.setServiceId(currentNSSI['e2eServiceInstanceId'] as String)
292         operationStatus.setOperationId(currentNSSI['operationId'] as String)
293         operationStatus.setOperation("DELETE")
294         operationStatus.setResult("processing")
295         operationStatus.setProgress(progress as String)
296         operationStatus.setOperationContent(currentNSSI['domainType'].toString() + " " + status.toString())
297         requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
298         LOGGER.debug("update operation, currentProgress=${currentProgress}, proportion=${proportion}, progress = ${progress}" )
299     }
300     
301     /**
302      * delete slice profile from aai
303      * @param execution
304      */
305     void delSliceProfileServiceFromAAI(DelegateExecution execution)
306     {
307         LOGGER.debug("*****${PREFIX} start delSliceProfileFromAAI *****")
308         def currentNSSI = execution.getVariable("currentNSSI")
309         String nssiServiceInstanceId = currentNSSI['nssiServiceInstanceId']
310         String profileId = currentNSSI['profileId']
311         String globalSubscriberId = currentNSSI["globalSubscriberId"]
312         String serviceType = currentNSSI['serviceType']
313
314         try
315         {
316             LOGGER.debug("delete nssiServiceInstanceId:${nssiServiceInstanceId}, profileId:${profileId}")
317             AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(
318                 AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(profileId))
319             if (!getAAIClient().exists(resourceUri)) {
320                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai")
321             }
322             getAAIClient().delete(resourceUri)
323         }
324         catch (any)
325         {
326             String msg = "delete slice profile from aai failed! cause-"+any.getCause()
327             LOGGER.error(any.printStackTrace())
328             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
329         }
330         LOGGER.debug("*****${PREFIX} Exist delSliceProfileFromAAI *****")
331     }
332
333     void delSliceProfileFromAAI(DelegateExecution execution){
334
335         LOGGER.debug("*****${PREFIX} start delSliceProfileFromAAI *****")
336         def currentNSSI = execution.getVariable("currentNSSI")
337         String globalSubscriberId = currentNSSI["globalSubscriberId"]
338         String serviceType = currentNSSI['serviceType']
339         String sliceProfileInstId = currentNSSI['profileId']
340
341         try
342         {
343             AAIPluralResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(sliceProfileInstId).sliceProfiles())
344             AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
345             Optional<SliceProfiles> sliceProfilesOpt =wrapper.asBean(SliceProfiles.class)
346             SliceProfiles sliceProfiles
347             String profileId
348             if(sliceProfilesOpt.isPresent()){
349                 sliceProfiles = sliceProfilesOpt.get()
350                 org.onap.aai.domain.yang.SliceProfile sliceProfile = sliceProfiles.getSliceProfile().get(0)
351                 profileId = sliceProfile ? sliceProfile.getProfileId() : ""
352             }
353             if (profileId){
354                 AAISimpleUri profileUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(sliceProfileInstId).sliceProfile(profileId))
355                 if (!getAAIClient().exists(profileUri)) {
356                     exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai")
357                 }
358                 getAAIClient().delete(profileUri)
359             }
360
361         }
362         catch (any)
363         {
364             String msg = "delete service profile from aai failed! cause-"+any.getCause()
365             LOGGER.error(any.printStackTrace())
366             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
367         }
368     }
369 }