Add sub-process test for deleting slice service
[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.logging.filter.base.ONAPComponents
25 import org.onap.so.beans.nsmf.DeAllocateNssi
26 import org.onap.so.beans.nsmf.EsrInfo
27 import org.onap.so.beans.nsmf.JobStatusRequest
28 import org.onap.so.beans.nsmf.JobStatusResponse
29 import org.onap.so.beans.nsmf.NetworkType
30 import org.onap.so.beans.nsmf.NssiDeAllocateRequest
31 import org.onap.so.beans.nsmf.NssiResponse
32 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
33 import org.onap.so.bpmn.common.scripts.ExceptionUtil
34 import org.onap.so.bpmn.common.scripts.RequestDBUtil
35 import org.onap.so.bpmn.core.UrnPropertiesReader
36 import org.onap.so.bpmn.core.domain.ServiceArtifact
37 import org.onap.so.bpmn.core.domain.ServiceDecomposition
38 import org.onap.so.bpmn.core.json.JsonUtils
39 import org.onap.so.client.HttpClient
40 import org.onap.so.client.HttpClientFactory
41 import org.onap.so.client.aai.AAIObjectType
42 import org.onap.so.client.aai.AAIResourcesClient
43 import org.onap.so.client.aai.entities.uri.AAIResourceUri
44 import org.onap.so.client.aai.entities.uri.AAIUriFactory
45 import org.onap.so.db.request.beans.OperationStatus
46 import org.slf4j.Logger
47 import org.slf4j.LoggerFactory
48
49 import javax.ws.rs.core.Response
50
51
52 class DoDeallocateNSSI extends AbstractServiceTaskProcessor
53 {
54     private final String PREFIX ="DoDeallocateNSSI"
55
56     private ExceptionUtil exceptionUtil = new ExceptionUtil()
57     private JsonUtils jsonUtil = new JsonUtils()
58     private RequestDBUtil requestDBUtil = new RequestDBUtil()
59     private static final Logger LOGGER = LoggerFactory.getLogger( DoDeallocateNSSI.class)
60
61     @Override
62     void preProcessRequest(DelegateExecution execution) {
63         LOGGER.trace(" ***** ${PREFIX} Start preProcessRequest *****")
64
65         def currentNSSI = execution.getVariable("currentNSSI")
66         if (!currentNSSI) {
67             String msg = "currentNSSI is null"
68             LOGGER.error(msg)
69             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
70         }
71
72         LOGGER.trace("***** ${PREFIX} Exit preProcessRequest *****")
73     }
74
75     /**
76      *
77      * @param execution
78      */
79     void prepareDecomposeService(DelegateExecution execution)
80     {
81         LOGGER.trace(" *****${PREFIX} Start prepareDecomposeService *****")
82         try
83         {
84             def currentNSSI = execution.getVariable("currentNSSI")
85             String modelInvariantUuid = currentNSSI['modelInvariantId']
86             String modelVersionId = currentNSSI['modelVersionId']
87             String serviceModelInfo = """{
88             "modelInvariantUuid":"${modelInvariantUuid}",
89             "modelUuid":"${modelVersionId}",
90             "modelVersion":""
91              }"""
92             execution.setVariable("serviceModelInfo", serviceModelInfo)
93         }
94         catch (any)
95         {
96             String exceptionMessage = "Bpmn error encountered in deallocate nssi. Unexpected Error from method prepareDecomposeService() - " + any.getMessage()
97             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
98         }
99         LOGGER.debug(" ***** ${PREFIX} Exit prepareDecomposeService *****")
100     }
101
102     /**
103      * get vendor Info
104      * @param execution
105      */
106      void processDecomposition(DelegateExecution execution) {
107         LOGGER.debug("*****${PREFIX} start processDecomposition *****")
108
109         try {
110             ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition") as ServiceDecomposition
111             ServiceArtifact serviceArtifact = serviceDecomposition ?.getServiceInfo()?.getServiceArtifact()?.get(0)
112             String content = serviceArtifact.getContent()
113             String vendor = jsonUtil.getJsonValue(content, "metadata.vendor")
114             String domainType  = jsonUtil.getJsonValue(content, "metadata.domainType")
115
116             def currentNSSI = execution.getVariable("currentNSSI")
117             currentNSSI['vendor'] = vendor
118             currentNSSI['domainType'] = domainType
119             LOGGER.info("processDecomposition, current vendor-domainType:" +String.join("-", vendor, domainType))
120
121         } catch (any) {
122             String exceptionMessage = "Bpmn error encountered in deallocate nssi. processDecomposition() - " + any.getMessage()
123             LOGGER.debug(exceptionMessage)
124             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
125         }
126         LOGGER.debug("*****${PREFIX} Exit processDecomposition *****")
127     }
128
129     /**
130      * send deallocate request to nssmf
131      * @param execution
132      */
133     void sendRequestToNSSMF(DelegateExecution execution)
134     {
135         LOGGER.debug("*****${PREFIX} start sendRequestToNSSMF *****")
136         def currentNSSI = execution.getVariable("currentNSSI")
137         String snssai= currentNSSI['snssai']
138         String profileId = currentNSSI['profileId']
139         String nssiId = currentNSSI['nssiServiceInstanceId']
140         String nsiId = currentNSSI['nsiServiceInstanceId']
141
142         DeAllocateNssi deAllocateNssi = new DeAllocateNssi()
143         deAllocateNssi.setNsiId(nsiId)
144         deAllocateNssi.setNssiId(nssiId)
145         deAllocateNssi.setTerminateNssiOption(0)
146         deAllocateNssi.setSnssaiList(Arrays.asList(snssai))
147
148         NssiDeAllocateRequest deAllocateRequest = new NssiDeAllocateRequest()
149         deAllocateRequest.setDeAllocateNssi(deAllocateNssi)
150         deAllocateRequest.setEsrInfo(getEsrInfo(currentNSSI))
151
152         ObjectMapper mapper = new ObjectMapper()
153         String json = mapper.writeValueAsString(deAllocateRequest)
154
155         //Prepare auth for NSSMF - Begin
156         String nssmfRequest = UrnPropertiesReader.getVariable("mso.adapters.nssmf.endpoint", execution)
157         nssmfRequest = nssmfRequest + String.format("/api/rest/provMns/v1/NSS/SliceProfiles/%s",profileId)
158         //nssmfRequest = nssmfRequest + String.format(NssmfAdapterUtil.NSSMI_DEALLOCATE_URL,profileId)
159         //send request to active  NSSI TN option
160         URL url = new URL(nssmfRequest)
161         LOGGER.info("deallocate nssmfRequest:${nssmfRequest}, reqBody: ${json}")
162
163         HttpClient httpClient = getHttpClientFactory().newJsonClient(url, ONAPComponents.EXTERNAL)
164         Response httpResponse = httpClient.post(json)
165         checkNssmfResponse(httpResponse, execution)
166
167         NssiResponse nssmfResponse = httpResponse.readEntity(NssiResponse.class)
168         currentNSSI['jobId']= nssmfResponse.getJobId() ?: ""
169         currentNSSI['jobProgress'] = 0
170         execution.setVariable("currentNSSI", currentNSSI)
171
172         LOGGER.debug("*****${PREFIX} Exit sendRequestToNSSMF *****")
173     }
174
175     /**
176      * send to nssmf query progress
177      * @param execution
178      */
179     void getJobStatus(DelegateExecution execution)
180     {
181         def currentNSSI = execution.getVariable("currentNSSI")
182         String jobId = currentNSSI['jobId']
183         String nssiId = currentNSSI['nssiServiceInstanceId']
184         String nsiId = currentNSSI['nsiServiceInstanceId']
185
186         JobStatusRequest jobStatusRequest = new JobStatusRequest()
187         jobStatusRequest.setNssiId(nssiId)
188         jobStatusRequest.setNsiId(nsiId)
189         jobStatusRequest.setEsrInfo(getEsrInfo(currentNSSI))
190
191         ObjectMapper mapper = new ObjectMapper()
192         String json = mapper.writeValueAsString(jobStatusRequest)
193
194         //Prepare auth for NSSMF - Begin
195         String nssmfRequest = UrnPropertiesReader.getVariable("mso.adapters.nssmf.endpoint", execution)
196         nssmfRequest = nssmfRequest + String.format("/api/rest/provMns/v1/NSS/jobs/%s",jobId)
197         //send request to active  NSSI TN option
198         URL url = new URL(nssmfRequest)
199         LOGGER.info("get deallocate job status, nssmfRequest:${nssmfRequest}, requestBody: ${json}")
200
201         HttpClient httpClient = getHttpClientFactory().newJsonClient(url, ONAPComponents.EXTERNAL)
202         Response httpResponse = httpClient.post(json)
203         checkNssmfResponse(httpResponse, execution)
204
205         JobStatusResponse jobStatusResponse = httpResponse.readEntity(JobStatusResponse.class)
206         def progress = jobStatusResponse?.getResponseDescriptor()?.getProgress()
207         if(!progress)
208         {
209             LOGGER.error("job progress is null or empty!")
210             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a Bad Job progress from NSSMF.")
211         }
212         int oldProgress = currentNSSI['jobProgress']
213         int currentProgress = progress
214
215         execution.setVariable("isNSSIDeAllocated", (currentProgress == 100))
216         execution.setVariable("isNeedUpdateDB", (oldProgress != currentProgress))
217         currentNSSI['jobProgress'] = currentProgress
218
219         def statusDescription = jobStatusResponse?.getResponseDescriptor()?.getStatusDescription()
220         currentNSSI['statusDescription'] = statusDescription
221
222         LOGGER.debug("job status result: nsiId = ${nsiId}, nssiId=${nssiId}, oldProgress=${oldProgress}, progress = ${currentProgress}" )
223     }
224
225     private void checkNssmfResponse(Response httpResponse, DelegateExecution execution) {
226         int responseCode = httpResponse.getStatus()
227         LOGGER.debug("NSSMF response code is: " + responseCode)
228
229         if ( responseCode < 200 || responseCode > 204 || !httpResponse.hasEntity()) {
230             exceptionUtil.buildAndThrowWorkflowException(execution, responseCode, "Received a Bad Response from NSSMF.")
231         }
232     }
233
234
235     private EsrInfo getEsrInfo(def currentNSSI)
236     {
237         String domaintype = currentNSSI['domainType']
238         String vendor = currentNSSI['vendor']
239
240         EsrInfo info = new EsrInfo()
241         info.setNetworkType(NetworkType.fromString(domaintype))
242         info.setVendor(vendor)
243         return info
244     }
245
246     /**
247      * handle job status
248      * prepare update requestdb
249      * @param execution
250      */
251     void handleJobStatus(DelegateExecution execution)
252     {
253         def currentNSSI = execution.getVariable("currentNSSI")
254         int currentProgress = currentNSSI["jobProgress"]
255         def proportion = currentNSSI['proportion']
256         def statusDes = currentNSSI["statusDescription"]
257         int progress = (currentProgress as int) == 0 ? 0 : (currentProgress as int) / 100 * (proportion as int)
258
259         OperationStatus operationStatus = new OperationStatus()
260         operationStatus.setServiceId(currentNSSI['e2eServiceInstanceId'] as String)
261         operationStatus.setOperationId(currentNSSI['operationId'] as String)
262         operationStatus.setOperation("DELETE")
263         operationStatus.setResult("processing")
264         operationStatus.setProgress(progress as String)
265         operationStatus.setOperationContent(statusDes as String)
266         requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
267         LOGGER.debug("update operation, currentProgress=${currentProgress}, proportion=${proportion}, progress = ${progress}" )
268     }
269
270     void timeDelay(DelegateExecution execution) {
271         try {
272             Thread.sleep(10000);
273         } catch(InterruptedException e) {
274             LOGGER.error("Time Delay exception" + e)
275         }
276     }
277
278     /**
279      * delete slice profile from aai
280      * @param execution
281      */
282     void delSliceProfileFromAAI(DelegateExecution execution)
283     {
284         LOGGER.debug("*****${PREFIX} start delSliceProfileFromAAI *****")
285         def currentNSSI = execution.getVariable("currentNSSI")
286         String nssiServiceInstanceId = currentNSSI['nssiServiceInstanceId']
287         String profileId = currentNSSI['profileId']
288         String globalSubscriberId = currentNSSI["globalSubscriberId"]
289         String serviceType = currentNSSI["serviceType"]
290
291         try
292         {
293             LOGGER.debug("delete nssiServiceInstanceId:${nssiServiceInstanceId}, profileId:${profileId}")
294             AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIObjectType.SLICE_PROFILE, globalSubscriberId, serviceType, nssiServiceInstanceId, profileId)
295             if (!getAAIClient().exists(resourceUri)) {
296                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai")
297             }
298             getAAIClient().delete(resourceUri)
299         }
300         catch (any)
301         {
302             String msg = "delete slice profile from aai failed! cause-"+any.getCause()
303             LOGGER.error(any.printStackTrace())
304             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
305         }
306         LOGGER.debug("*****${PREFIX} Exist delSliceProfileFromAAI *****")
307     }
308 }