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