5fd06fd8d42db94a2a6009572718dcf7f07aa80a
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DoDeleteSliceService.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 org.camunda.bpm.engine.delegate.BpmnError
23 import org.camunda.bpm.engine.delegate.DelegateExecution
24 import org.onap.aai.domain.yang.AllottedResource
25 import org.onap.aai.domain.yang.AllottedResources
26 import org.onap.aai.domain.yang.Relationship
27 import org.onap.aai.domain.yang.ServiceInstance
28 import org.onap.aaiclient.client.aai.AAIObjectName
29 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
30 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
31 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
32 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
33 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
34 import org.onap.logging.filter.base.ONAPComponents
35 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
36 import org.onap.so.bpmn.common.scripts.ExceptionUtil
37 import org.onap.so.bpmn.common.scripts.OofUtils
38 import org.onap.so.bpmn.core.UrnPropertiesReader
39 import org.onap.so.client.HttpClient
40 import org.onap.so.client.HttpClientFactory
41 import org.slf4j.Logger
42 import org.slf4j.LoggerFactory
43
44 import javax.ws.rs.NotFoundException
45 import javax.ws.rs.core.Response
46
47 import static org.apache.commons.lang3.StringUtils.isBlank
48
49 /**
50  * This groovy class supports the <class>DoDeleteSliceService.bpmn</class> process.
51  *
52  * Inputs:
53  * @param - msoRequestId
54  * @param - globalSubscriberId - O
55  * @param - subscriptionServiceType - O
56  * @param - serviceInstanceId
57  *
58  */
59 class DoDeleteSliceService extends AbstractServiceTaskProcessor {
60     private final String PREFIX ="DoDeleteSliceService"
61     ExceptionUtil exceptionUtil = new ExceptionUtil()
62     OofUtils oofUtils = new OofUtils()
63     private static final Logger LOGGER = LoggerFactory.getLogger( DoDeleteSliceService.class)
64
65     @Override
66     void preProcessRequest(DelegateExecution execution) {
67         LOGGER.debug(" *****${PREFIX} preProcessRequest *****")
68         String msg = ""
69
70         try {
71             //String requestId = execution.getVariable("msoRequestId")
72             execution.setVariable("prefix",PREFIX)
73
74             //Inputs
75             //requestDetails.subscriberInfo. for AAI GET & PUT
76              execution.getVariable("globalSubscriberId") ?: execution.setVariable("globalSubscriberId", "")
77
78             //requestDetails.requestParameters. for AAI PUT
79             execution.getVariable("serviceType") ?: execution.setVariable("serviceType", "")
80
81             //Generated in parent for AAI PUT
82             String serviceInstanceId = execution.getVariable("serviceInstanceId")
83             if (isBlank(serviceInstanceId)){
84                 msg = "Input serviceInstanceId is null"
85                 LOGGER.info(msg)
86                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
87             }
88         } catch (BpmnError e) {
89             throw e
90         } catch (Exception ex){
91             msg = "Exception in preProcessRequest " + ex.getMessage()
92             LOGGER.error(msg)
93             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
94         }
95         LOGGER.debug("*****${PREFIX} Exit preProcessRequest *****")
96     }
97
98     /**
99      * query E2ESliceService from AAI
100      * save snssai
101      * @param execution
102      */
103     void queryServiceProfileFromAAI(DelegateExecution execution)
104     {
105         LOGGER.trace(" *****${PREFIX} Start queryE2ESliceSeriveFromAAI *****")
106         String serviceInstanceId = execution.getVariable("serviceInstanceId")
107         try
108         {
109         String errorMsg = "query e2e slice service from aai failed"
110         AAIResultWrapper wrapper = queryAAI(execution, Types.SERVICE_INSTANCE, serviceInstanceId, errorMsg)
111         Optional<ServiceInstance> si =wrapper.asBean(ServiceInstance.class)
112         if(si.isPresent())
113         {
114             String snssai = si.get()?.getEnvironmentContext()
115             execution.setVariable("snssai", snssai ?: "")
116 //            ServiceProfiles serviceProfiles = si.get()?.getServiceProfiles()
117 //            ServiceProfile serviceProfile = serviceProfiles.getServiceProfile().get(0)
118 //            String serviceProfileId = serviceProfile ? serviceProfile.getProfileId() : ""
119 //            execution.setVariable("serviceProfileId", serviceProfileId)
120             List<ServiceInstance> sliceProfileList = []
121             List<Relationship> relationshipList = si.get().getRelationshipList().getRelationship()
122             for (Relationship relationship : relationshipList) {
123                 String relatedTo = relationship.getRelatedTo()
124                 if (relatedTo.toLowerCase() == "service-instance") {
125                     String relatioshipurl = relationship.getRelatedLink()
126                     String instanceId = relatioshipurl.substring(relatioshipurl.lastIndexOf("/") + 1, relatioshipurl.length())
127                     AAIResultWrapper wrapper1 = queryAAI(execution, Types.SERVICE_INSTANCE, instanceId, errorMsg)
128                     Optional<ServiceInstance> serviceInstance = wrapper1.asBean(ServiceInstance.class)
129                     if (serviceInstance.isPresent()) {
130                         ServiceInstance instance = serviceInstance.get()
131                         if ("slice-profile".equalsIgnoreCase(instance.getServiceRole())) {
132                             sliceProfileList.add(instance)
133                         }
134                     }
135                 }
136             }
137             execution.setVariable("sliceProfileList",sliceProfileList)
138             LOGGER.info("serviceInstanceId: ${serviceInstanceId}, snssai: ${snssai}, sliceProfileList: ${sliceProfileList}")
139         }
140         LOGGER.trace(" *****${PREFIX} Exit queryE2ESliceSeriveFromAAI *****")
141         }
142         catch (any)
143         {
144             String msg = "query E2E slice service from aai failed! cause-"+any.getCause()
145             LOGGER.error(any.printStackTrace())
146             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
147         }
148     }
149
150     /**
151      * get allotted resource from AAI
152      * save nsi id
153      * @param execution
154      */
155     void getAllottedResFromAAI(DelegateExecution execution)
156     {
157         LOGGER.trace(" *****${PREFIX} Start getAllottedResFromAAI *****")
158         String serviceInstanceId = execution.getVariable("serviceInstanceId")
159         try
160         {
161             String errorMsg = "query allotted resource from aai failed."
162             AAIResultWrapper wrapper = queryAAI(execution, Types.ALLOTTED_RESOURCE, serviceInstanceId, errorMsg)
163             Optional<AllottedResources> ars = wrapper?.asBean(AllottedResources.class)
164             if(ars.isPresent() && ars.get().getAllottedResource())
165             {
166                 List<AllottedResource> allottedResourceList = ars.get().getAllottedResource()
167                 AllottedResource ar = allottedResourceList.first()
168                 String relatedLink = ar?.getRelationshipList()?.getRelationship()?.first()?.getRelatedLink()
169                 String nsiId = relatedLink ? relatedLink.substring(relatedLink.lastIndexOf("/") + 1,relatedLink.length()) : ""
170                 execution.setVariable("nsiId", nsiId)
171                 LOGGER.info("serviceInstanceId: ${serviceInstanceId}, nsiId:${nsiId}")
172             }
173         }
174         catch(BpmnError e){
175             throw e
176         }
177         catch (Exception ex){
178             String msg = "Exception in getAllottedResFromAAI " + ex.getMessage()
179             LOGGER.error(msg)
180             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
181         }
182         LOGGER.trace(" *****${PREFIX} Exit getAllottedResFromAAI *****")
183     }
184
185     /**
186      * get nsi service instance from aai
187      * save nssi id
188      * @param execution
189      */
190     void getNSIFromAAI(DelegateExecution execution)
191     {
192         LOGGER.trace(" *****${PREFIX} Start getNSIFromAAI *****")
193         String nsiId = execution.getVariable("nsiId")
194         List<String> nssiIdList = getNSSIIdList(execution, nsiId)
195         String msg = "nsiId: ${nsiId}, nssiIdList:"
196         msg+= nssiIdList.join(",")
197         LOGGER.info(msg)
198         execution.setVariable("nssiIdList", nssiIdList)
199         LOGGER.trace(" *****${PREFIX} Exit getNSIFromAAI *****")
200     }
201     /**
202      * Get NSSI Id from AAI
203      * @param execution
204      * @param nsiId
205      * @return
206      */
207     private List<String> getNSSIIdList(DelegateExecution execution, String nsiId){
208         List<String> nssiIdList = []
209
210         try
211         {
212             String errorMsg = "query nssi from aai failed."
213             AAIResultWrapper wrapper = queryAAI(execution, Types.SERVICE_INSTANCE, nsiId, errorMsg)
214             Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
215             if(si.isPresent())
216             {
217                 List<Relationship> relationshipList = si.get().getRelationshipList()?.getRelationship()
218                 for (Relationship relationship : relationshipList)
219                 {
220                     String relatedTo = relationship.getRelatedTo()
221                     if (relatedTo == "service-instance")
222                     {
223                         String relatedLink = relationship.getRelatedLink()?:""
224                         String instanceId = relatedLink ? relatedLink.substring(relatedLink.lastIndexOf("/") + 1,relatedLink.length()) : ""
225                         AAIResultWrapper wrapper1 = queryAAI(execution, Types.SERVICE_INSTANCE, instanceId, errorMsg)
226                         Optional<ServiceInstance> serviceInstance = wrapper1.asBean(ServiceInstance.class)
227                         def nssiId
228                         if (serviceInstance.isPresent()) {
229                             ServiceInstance instance = serviceInstance.get()
230                             if ("nssi".equalsIgnoreCase(instance.getServiceRole())) {
231                                 nssiId = instance.getServiceInstanceId()
232                                 nssiIdList.add(nssiId)
233                             }
234                         }
235                     }
236                 }
237             }
238         }
239         catch(BpmnError e){
240             throw e
241         }
242         catch (Exception ex){
243             String msg = "Exception in getNSIFromAAI " + ex.getMessage()
244             LOGGER.error(msg)
245             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
246         }
247         return nssiIdList
248     }
249
250     /**
251      * get nssi service from AAI
252      * prepare list
253      * @param execution
254      */
255     void getNSSIListFromAAI(DelegateExecution execution)
256     {
257         LOGGER.trace("*****${PREFIX} Start getNSSIListFromAAI *****")
258         List<String> nssiIdList = execution.getVariable("nssiIdList")
259         List<ServiceInstance> nssiInstanceList = []
260         String errorMsg = "query nssi list from aai failed"
261         for(String nssiId : nssiIdList)
262         {
263             AAIResultWrapper wrapper = queryAAI(execution, Types.SERVICE_INSTANCE, nssiId, errorMsg)
264             Optional<ServiceInstance> si =wrapper.asBean(ServiceInstance.class)
265             if(si.isPresent())
266             {
267                 nssiInstanceList.add(si.get())
268             }
269         }
270         int size = nssiInstanceList.size()
271         int proportion = size >0 ?((90/size) as int) : 90
272         execution.setVariable("nssiInstanceList", nssiInstanceList)
273         execution.setVariable("currentNSSIIndex", 0)
274         execution.setVariable("proportion", proportion)
275         String msg ="nssiInstanceList size: ${nssiInstanceList.size()}, proportion:${proportion}"
276         LOGGER.info(msg)
277         LOGGER.trace(" *****${PREFIX} Exit getNSSIListFromAAI *****")
278     }
279
280     /**
281      * get current NSSI
282      * @param execution
283      */
284     void getCurrentNSSI(DelegateExecution execution)
285     {
286         LOGGER.trace(" *****${PREFIX} Start getCurrentNSSI *****")
287         List<ServiceInstance> nssiInstanceList = execution.getVariable("nssiInstanceList")
288         List<ServiceInstance> sliceProfileList = execution.getVariable("sliceProfileList")
289         int currentIndex = execution.getVariable("currentNSSIIndex") as int
290         String profileInstId = ""
291         ServiceInstance nssi = nssiInstanceList?.get(currentIndex)
292         List<Relationship> relationshipList = nssi.getRelationshipList()?.getRelationship()
293         for(ServiceInstance sliceProfileInstance : sliceProfileList) {
294             for (Relationship relationship : relationshipList) {
295                 String relatedTo = relationship.getRelatedTo()
296                 if (relatedTo == "service-instance"){
297                     String relatedLink = relationship.getRelatedLink()?:""
298                     String instanceId = relatedLink ? relatedLink.substring(relatedLink.lastIndexOf("/") + 1,relatedLink.length()) : ""
299                     if(instanceId.equals(sliceProfileInstance.getServiceInstanceId())){
300                         profileInstId = sliceProfileInstance.getServiceInstanceId()
301                         break
302                     }
303                 }
304             }
305             if(profileInstId){
306                 break
307             }
308         }
309
310         //@TODO Temp begin*******************
311 //        AAIPluralResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("serviceType")).serviceInstance(profileInstId).sliceProfiles())
312 //        AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
313 //        Optional<SliceProfiles> sliceProfilesOpt =wrapper.asBean(SliceProfiles.class)
314 //        SliceProfiles sliceProfiles
315 //        String sliceProfileId
316 //        if(sliceProfilesOpt.isPresent()){
317 //            sliceProfiles = sliceProfilesOpt.get()
318 //            org.onap.aai.domain.yang.SliceProfile sliceProfile = sliceProfiles.getSliceProfile().get(0)
319 //            sliceProfileId = sliceProfile ? sliceProfile.getProfileId() : ""
320 //        }
321         //@TODO Temp end*******************
322
323         def currentNSSI = [:]
324         currentNSSI['nssiServiceInstanceId'] = nssi?.getServiceInstanceId()
325         currentNSSI['modelInvariantId'] = nssi?.getModelInvariantId()
326         currentNSSI['modelVersionId'] = nssi?.getModelVersionId()
327         currentNSSI['nssiName'] = nssi?.getServiceInstanceName()
328         currentNSSI['sST'] = nssi?.getServiceType()
329         currentNSSI['PLMNIdList'] = nssi?.getServiceInstanceLocationId()
330         //@TODO Temp
331
332         currentNSSI['profileId'] =  profileInstId
333 //        currentNSSI['profileId'] =  sliceProfileId
334         currentNSSI['snssai'] = execution.getVariable("snssai") ?: ""
335         currentNSSI['nsiServiceInstanceId'] = execution.getVariable("nsiId") ?: ""
336         currentNSSI['operationId'] = execution.getVariable("operationId") ?: ""
337         currentNSSI['e2eServiceInstanceId'] = execution.getVariable("serviceInstanceId") ?: ""
338         currentNSSI['msoRequestId'] = execution.getVariable("msoRequestId") ?: ""
339         currentNSSI['globalSubscriberId'] = execution.getVariable("globalSubscriberId") ?: ""
340         currentNSSI['serviceType'] = execution.getVariable("serviceType") ?: ""
341         currentNSSI['serviceModelInfo'] = execution.getVariable("serviceModelInfo") ?: ""
342         currentNSSI['proportion'] = (execution.getVariable("proportion") as int)*(currentIndex+1)
343         execution.setVariable("currentNSSI", currentNSSI)
344         String msg = "Now we deal with nssiServiceInstanceId: ${currentNSSI['nssiServiceInstanceId']}, current Index: ${currentIndex}, current proportion:${currentNSSI['proportion']}"
345         LOGGER.info(msg)
346         LOGGER.trace(" *****${PREFIX} Exit getCurrentNSSI *****")
347     }
348
349     /**
350      * parse next nssi
351      * @param execution
352      */
353     void parseNextNSSI(DelegateExecution execution)
354     {
355         LOGGER.trace(" *****${PREFIX} Start parseNextNSSI *****")
356         if(execution.getVariable("WorkflowException") != null){
357             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "current job failure!")
358         }
359         def currentIndex = execution.getVariable("currentNSSIIndex")
360         List<ServiceInstance> nssiInstanceList = execution.getVariable("nssiInstanceList")
361         def nextIndex = ++currentIndex
362         LOGGER.info("nextIndex: ${nextIndex}")
363         if(nextIndex >= nssiInstanceList.size()){
364             execution.setVariable("isAllNSSIFinished", "true")
365         }else{
366             execution.setVariable("isAllNSSIFinished", "false")
367             execution.setVariable("currentNSSIIndex", nextIndex)
368         }
369         LOGGER.trace(" *****${PREFIX} Exit parseNextNSSI *****")
370     }
371
372     /**
373      * query AAI
374      * @param execution
375      * @param aaiObjectName
376      * @param instanceId
377      * @return AAIResultWrapper
378      */
379     private AAIResultWrapper queryAAI(DelegateExecution execution, AAIObjectName aaiObjectName, String instanceId, String errorMsg)
380     {
381         LOGGER.trace(" *****${PREFIX} Start queryAAI *****")
382         String globalSubscriberId = execution.getVariable("globalSubscriberId")
383         String serviceType = execution.getVariable("serviceType")
384
385         org.onap.aaiclient.client.generated.fluentbuilders.ServiceInstance serviceInstanceType = AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(instanceId)
386         def type
387         if (aaiObjectName == Types.ALLOTTED_RESOURCE) {
388             type = serviceInstanceType.allottedResources()
389         } else if (aaiObjectName == Types.SLICE_PROFILES) {
390             type = serviceInstanceType.sliceProfiles()
391         } else {
392             type = serviceInstanceType
393         }
394         def uri = AAIUriFactory.createResourceUri(type)
395         if (!getAAIClient().exists(uri)) {
396             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, errorMsg)
397         }
398         AAIResultWrapper wrapper = getAAIClient().get(uri, NotFoundException.class)
399         LOGGER.trace(" *****${PREFIX} Exit queryAAI *****")
400         return wrapper
401     }
402
403     void terminateNSIQuery(DelegateExecution execution)
404     {
405         LOGGER.debug("Start terminateNSIQuery")
406
407         return
408
409         //To test
410         String requestId = execution.getVariable("msoRequestId")
411         String nxlId = currentNSSI['nsiServiceInstanceId']
412         String nxlType = "NSI"
413         String messageType = "nsiTerminationResponse"
414         String serviceInstanceId = execution.getVariable("serviceInstanceId")
415         
416         def authHeader = ""
417         String basicAuth = UrnPropertiesReader.getVariable("mso.oof.auth", execution)
418         String msokey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
419
420         String basicAuthValue = utils.encrypt(basicAuth, msokey)
421         if (basicAuthValue != null) {
422             LOGGER.debug( "Obtained BasicAuth username and password for OOF: " + basicAuthValue)
423             try {
424                 authHeader = utils.getBasicAuth(basicAuthValue, msokey)
425                 execution.setVariable("BasicAuthHeaderValue", authHeader)
426             } catch (Exception ex) {
427                 LOGGER.debug( "Unable to encode username and password string: " + ex)
428                 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to " +
429                         "encode username and password string")
430             }
431         } else {
432             LOGGER.debug( "Unable to obtain BasicAuth - BasicAuth value null")
433             exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - BasicAuth " +
434                     "value null")
435         }
436
437         URL requestUrl = new URL(oofUrl + "/api/oof/terminate/nxi/v1")
438         String oofRequest = oofUtils.buildTerminateNxiRequest(requestId, nxlId, nxlType, messageType, serviceInstanceId)
439         HttpClient httpClient = new HttpClientFactory().newJsonClient(requestUrl, ONAPComponents.OOF)
440         httpClient.addAdditionalHeader("Authorization", authHeader)
441         Response httpResponse = httpClient.post(oofRequest)
442
443         int responseCode = httpResponse.getStatus()
444         LOGGER.debug("OOF sync response code is: " + responseCode)
445
446         if(responseCode != 200){
447             exceptionUtil.buildAndThrowWorkflowException(execution, responseCode, "Received a Bad Sync Response from OOF.")
448         }       
449         try {
450             Map<String, String> resMap = httpResponse.readEntity(Map.class)
451             boolean terminateResponse = resMap.get("terminateResponse")
452             execution.setVariable("terminateNSI", terminateResponse)
453         } catch (Exception ex) {
454             LOGGER.debug( "Failed to get terminate Response suggested by OOF.")
455             exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Failed to get terminate Response suggested by OOF.")
456         }
457         LOGGER.debug("Finish terminateNSIQuery")
458     }
459
460
461     /**
462      * If no nssi,delete NSI from AAI
463      * @param execution
464      */
465     void deleteNSIInstance(DelegateExecution execution){
466         def currentNSSI = execution.getVariable("currentNSSI")
467         def nsiId = currentNSSI['nsiServiceInstanceId']
468         List<String> nssiIdList = getNSSIIdList(execution, nsiId)
469         try
470         {
471             if(0 == nssiIdList.size()){
472                 AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("serviceType")).serviceInstance(nsiId))
473                 getAAIClient().delete(serviceInstanceUri)
474             }
475         } catch (Exception ex) {
476             LOGGER.debug( "Failed to delete NSI instance.")
477             exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Failed to delete NSI instance.")
478         }
479
480     }
481 }