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