2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 Telecom Italia
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.so.bpmn.infrastructure.scripts
23 import com.fasterxml.jackson.databind.ObjectMapper
24 import com.google.gson.JsonObject
25 import org.camunda.bpm.engine.delegate.DelegateExecution
26 import org.onap.aai.domain.yang.v19.AllottedResource
27 import org.onap.aai.domain.yang.v19.GenericVnf
28 import org.onap.aai.domain.yang.v19.ServiceInstance
29 import org.onap.aai.domain.yang.v19.SliceProfile
30 import org.onap.aai.domain.yang.v19.SliceProfiles
31 import org.onap.aaiclient.client.aai.AAIResourcesClient
32 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
33 import org.onap.aaiclient.client.aai.entities.Relationships
34 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
35 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
36 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
37 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
38 import org.onap.logging.filter.base.ONAPComponents
39 import org.onap.so.bpmn.common.scripts.ExceptionUtil
40 import org.onap.so.bpmn.common.scripts.MsoUtils
41 import org.onap.so.bpmn.common.scripts.OofUtils
42 import org.onap.so.bpmn.common.scripts.RequestDBUtil
43 import org.onap.so.bpmn.core.UrnPropertiesReader
44 import org.onap.so.bpmn.core.json.JsonUtils
45 import org.onap.so.client.HttpClient
46 import org.onap.so.client.HttpClientFactory
47 import org.onap.so.client.oof.adapter.beans.payload.OofRequest
48 import org.slf4j.Logger
49 import org.slf4j.LoggerFactory
51 import javax.ws.rs.core.Response
53 import static org.apache.commons.lang3.StringUtils.isBlank
54 import static org.apache.commons.lang3.StringUtils.isBlank
55 import static org.onap.so.bpmn.common.scripts.GenericUtils.isBlank
56 import static org.onap.so.bpmn.common.scripts.GenericUtils.isBlank
58 class DoDeallocateCoreNSSI extends DoCommonCoreNSSI {
59 private final String PREFIX ="DoDeallocateCoreNSSI"
60 private final String ACTION = "Deallocate"
62 private ExceptionUtil exceptionUtil = new ExceptionUtil()
63 private RequestDBUtil requestDBUtil = new RequestDBUtil()
64 private MsoUtils utils = new MsoUtils()
65 private JsonUtils jsonUtil = new JsonUtils()
67 private static final Logger LOGGER = LoggerFactory.getLogger( DoDeallocateCoreNSSI.class)
71 void preProcessRequest(DelegateExecution execution) {
72 LOGGER.debug("${getPrefix()} Start preProcessRequest")
74 super.preProcessRequest(execution)
76 execution.setVariable("operationType", "DEALLOCATE")
78 LOGGER.debug("${getPrefix()} Exit preProcessRequest")
84 * Queries OOF for NSSI termination
87 void executeTerminateNSSIQuery(DelegateExecution execution) {
88 LOGGER.debug("${PREFIX} Start executeTerminateNSSIQuery")
90 String urlString = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
91 // String urlString = UrnPropertiesReader.getVariable("mso.adapters.oof.endpoint", execution)
94 String apiPath = "/api/oof/terminate/nxi/v1"
95 LOGGER.debug("API path for DoAllocateCoreNSSI: "+apiPath)
97 urlString = urlString + apiPath
99 //Prepare auth for OOF
101 String basicAuth = UrnPropertiesReader.getVariable("mso.oof.auth", execution)
102 String msokey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
104 String basicAuthValue = utils.encrypt(basicAuth, msokey)
105 /* if (basicAuthValue != null) {
106 LOGGER.debug( "Obtained BasicAuth username and password for OOF Adapter: " + basicAuthValue)
108 authHeader = utils.getBasicAuth(basicAuthValue, msokey)
109 execution.setVariable("BasicAuthHeaderValue", authHeader)
110 } catch (Exception ex) {
111 LOGGER.error( "Unable to encode username and password string: " + ex)
112 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to encode username and password string")
115 LOGGER.error( "Unable to obtain BasicAuth - BasicAuth value null")
116 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - BasicAuth value null")
121 authHeader = utils.getBasicAuth(basicAuthValue, msokey)
122 execution.setVariable("BasicAuthHeaderValue", authHeader)
123 } catch (Exception ex) {
124 LOGGER.error( "Unable to encode username and password string: " + ex)
125 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to encode username and password string")
128 //Prepare send request to OOF
129 String oofRequest = buildOOFRequest(execution)
131 String callOOFResponse = callOOF(urlString, authHeader, oofRequest)
132 LOGGER.debug("callOOFResponse=" + callOOFResponse)
134 String errorCode = jsonUtil.getJsonValue(callOOFResponse, "errorCode")
135 if(errorCode == null || errorCode.isEmpty()) { // No error
136 String terminateNSSI = jsonUtil.getJsonValue(callOOFResponse, "terminateResponse")
137 LOGGER.debug("isTerminateNSSI=" + terminateNSSI)
139 execution.setVariable("isTerminateNSSI", terminateNSSI)
142 LOGGER.error(jsonUtil.getJsonValue(callOOFResponse, "errorMessage"))
143 exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(errorCode), jsonUtil.getJsonValue(callOOFResponse, "errorMessage"))
146 LOGGER.debug("${PREFIX} Exit executeTerminateNSSIQuery")
151 * Executes sync call to OOF
152 * @return OOF response
154 String callOOF(String urlString, String authHeader, String oofRequest) {
155 LOGGER.debug("${PREFIX} Start callOOF")
157 String errorCode = ""
158 String errorMessage = ""
162 URL url = new URL(urlString)
163 HttpClient httpClient = getHttpClientFactory().newJsonClient(url, ONAPComponents.OOF)
164 httpClient.addAdditionalHeader("Authorization", authHeader)
165 httpClient.addAdditionalHeader("Content-Type", "application/json")
167 Response httpResponse = httpClient.post(oofRequest)
169 int responseCode = httpResponse.getStatus()
170 LOGGER.debug("OOF sync response code is: " + responseCode)
172 if(responseCode < 200 || responseCode >= 300) { // Wrong code
173 errorCode = responseCode
174 errorMessage = "Received a Bad Sync Response from OOF."
177 " \"errorCode\": \"${errorCode}\",\n" +
178 " \"errorMessage\": \"${errorMessage}\"\n" +
180 //exceptionUtil.buildAndThrowWorkflowException(execution, responseCode, "Received a Bad Sync Response from OOF.")
183 if (httpResponse.hasEntity()) {
184 response = httpResponse.readEntity(String.class)
188 errorMessage = "No response received from OOF."
191 " \"errorCode\": \"${errorCode}\",\n" +
192 " \"errorMessage\": \"${errorMessage}\"\n" +
198 errorMessage = e.getMessage()
201 " \"errorCode\": \"${errorCode}\",\n" +
202 " \"errorMessage\": \"${errorMessage}\"\n" +
206 LOGGER.debug("${PREFIX} Exit callOOF")
217 private String buildOOFRequest(DelegateExecution execution) {
218 LOGGER.debug("${PREFIX} Start buildOOFRequest")
220 def currentNSSI = execution.getVariable("currentNSSI")
222 String nssiId = currentNSSI['nssiId']
224 ServiceInstance nssi = null
226 AAIResourcesClient client = getAAIClient()
229 AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nssiId))
230 Optional<ServiceInstance> nssiOpt = client.get(ServiceInstance.class, nssiUri)
232 if (nssiOpt.isPresent()) {
236 String msg = "NSSI service instance not found in AAI for nssi id " + nssiId
238 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
243 String nsiId = currentNSSI['nsiId']
244 ServiceInstance nsi = null
245 AAIResourceUri nsiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nsiId))
246 Optional<ServiceInstance> nsiOpt = client.get(ServiceInstance.class, nsiUri)
247 if (nsiOpt.isPresent()) {
251 String msg = "NSI service instance not found in AAI for nsi id " + nsiId
253 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
257 //Setting correlator as requestId
258 String requestId = execution.getVariable("msoRequestId")
259 execution.setVariable("NSSI_correlator", requestId)
261 //Setting messageType for all Core slice as cn
262 String messageType = "cn"
263 execution.setVariable("NSSI_messageType", messageType)
266 String timeout = execution.getVariable("timeout")
267 if (isBlank(timeout)) {
268 timeout = UrnPropertiesReader.getVariable("mso.oof.timeout", execution);
269 if (isBlank(timeout)) {
274 String nxlId = nssi.getServiceInstanceId()
275 String nxlType = "NSSI"
276 String oofRequest = getOofUtils().buildTerminateNxiRequest(requestId, nxlId, nxlType, messageType, nsi.getServiceInstanceId())
277 LOGGER.debug("**** Terminate Nxi Request: "+oofRequest)
279 LOGGER.debug("${PREFIX} Exit buildOOFRequest")
287 * Invokes deleteServiceOrder external API
290 void deleteServiceOrder(DelegateExecution execution) {
291 LOGGER.debug("${PREFIX} Start deleteServiceOrder")
293 def currentNSSI = execution.getVariable("currentNSSI")
296 //url:/nbi/api/v4/serviceOrder/"
297 def nsmfЕndPoint = UrnPropertiesReader.getVariable("mso.infra.endpoint.url", execution)
299 ServiceInstance networkServiceInstance = (ServiceInstance)currentNSSI['networkServiceInstance']
301 //String url = String.format("${nbiEndpointUrl}/api/v4/serviceOrder/%s", networkServiceInstance.getServiceInstanceId())
303 GenericVnf constituteVnf = (GenericVnf)currentNSSI['constituteVnf']
305 // http://so.onap:8080/onap/so/infra/serviceInstantiation/v7/serviceInstances/de6a0aa2-19f2-41fe-b313-a5a9f159acd7/vnfs/3abbb373-8d33-4977-aa4b-2bfee496b6d5
306 String url = String.format("${nsmfЕndPoint}/serviceInstantiation/v7/serviceInstances/%s/vnfs/%s", networkServiceInstance.getServiceInstanceId(), constituteVnf.getVnfId())
308 LOGGER.debug("url = " + url)
310 currentNSSI['deleteServiceOrderURL'] = url
312 String msoKey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
313 String basicAuth = UrnPropertiesReader.getVariable("mso.adapters.po.auth", execution)
315 def authHeader = utils.getBasicAuth(basicAuth, msoKey)
317 def requestDetails = ""
319 String prepareRequestDetailsResponse = prepareRequestDetails(execution)
320 LOGGER.debug("deleteServiceOrder: prepareRequestDetailsResponse=" + prepareRequestDetailsResponse)
322 String errorCode = jsonUtil.getJsonValue(prepareRequestDetailsResponse, "errorCode")
323 LOGGER.debug("deleteServiceOrder: errorCode=" + errorCode)
324 if(errorCode == null || errorCode.isEmpty()) { // No error
325 requestDetails = prepareRequestDetailsResponse
328 exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(errorCode), jsonUtil.getJsonValue(prepareRequestDetailsResponse, "errorMessage"))
331 String callDeleteServiceOrderResponse = callDeleteServiceOrder(url, authHeader, requestDetails)
332 errorCode = jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "errorCode")
334 if(errorCode == null || errorCode.isEmpty()) { // No error
335 String macroOperationId = jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "requestReferences.requestId")
336 String requestSelfLink = jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "requestReferences.requestSelfLink")
338 execution.setVariable("macroOperationId", macroOperationId)
339 execution.setVariable("requestSelfLink", requestSelfLink)
341 currentNSSI['requestSelfLink'] = requestSelfLink
344 LOGGER.error(jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "errorMessage"))
345 exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(errorCode), jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "errorMessage"))
348 String msg = "Exception in DoDeallocateCoreNSSI.deleteServiceOrder. " + any.getCause()
350 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
353 LOGGER.debug("${PREFIX} Exit deleteServiceOrder")
357 String callDeleteServiceOrder(String url, String authHeader, String requestDetailsStr) {
358 LOGGER.debug("${PREFIX} Start callDeleteServiceOrder")
360 String errorCode = ""
361 String errorMessage = ""
364 LOGGER.debug("callDeleteServiceOrder: url = " + url)
365 LOGGER.debug("callDeleteServiceOrder: authHeader = " + authHeader)
368 HttpClient httpClient = getHttpClientFactory().newJsonClient(new URL(url), ONAPComponents.SO)
369 httpClient.addAdditionalHeader("Authorization", authHeader)
370 httpClient.addAdditionalHeader("Accept", "application/json")
371 Response httpResponse = httpClient.delete(requestDetailsStr)
373 int soResponseCode = httpResponse.getStatus()
374 LOGGER.debug("callDeleteServiceOrder: soResponseCode = " + soResponseCode)
376 if (soResponseCode >= 200 && soResponseCode < 204 && httpResponse.hasEntity()) {
377 response = httpResponse.readEntity(String.class)
379 LOGGER.debug("callDeleteServiceInstance: response = " + response)
383 errorMessage = "Response code is " + soResponseCode
386 " \"errorCode\": \"${errorCode}\",\n" +
387 " \"errorMessage\": \"${errorMessage}\"\n" +
392 String msg = "Exception in DoDeallocateCoreNSSI.callDeleteServiceOrder. " + any.getCause()
395 " \"errorCode\": \"7000\",\n" +
396 " \"errorMessage\": \"${msg}\"\n" +
400 LOGGER.debug("${PREFIX} Exit callDeleteServiceOrder")
407 * Removes NSSI association with NSI
410 void removeNSSIAssociationWithNSI(DelegateExecution execution) {
411 LOGGER.debug("${PREFIX} Start removeNSSIAssociationWithNSI")
413 AAIResourcesClient client = getAAIClient()
415 def currentNSSI = execution.getVariable("currentNSSI")
417 String nssiId = currentNSSI['nssiId']
418 String nsiId = currentNSSI['nsiId']
419 String globalSubscriberId = execution.getVariable("globalSubscriberId")
420 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
423 AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nssiId))
426 String allottedResourceId = null
429 AAIResultWrapper nssiWrapper = client.get(nssiUri)
430 Optional<Relationships> nssiRelationships = nssiWrapper.getRelationships()
432 if (nssiRelationships.isPresent()) {
434 for (AAIResourceUri allottedResourceUri : nssiRelationships.get().getRelatedUris(Types.ALLOTTED_RESOURCE)) {
435 AAIResultWrapper arWrapper = client.get(allottedResourceUri)
436 Optional<Relationships> arRelationships = arWrapper.getRelationships()
438 if(arRelationships.isPresent()) {
440 for (AAIResourceUri nsiUri : arRelationships.get().getRelatedUris(Types.SERVICE_INSTANCE)) {
441 Optional<ServiceInstance> nsiOpt = client.get(ServiceInstance.class, nsiUri)
443 if (nsiOpt.isPresent()) {
444 ServiceInstance nsi = nsiOpt.get()
445 if(nsi.getServiceRole().equals("nsi")) { // Service instance as NSI
446 // Removes NSSI association with NSI
448 client.disconnect(nssiUri, nsiUri)
450 catch (Exception e) {
451 exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occured while NSSI association with NSI dosconnect call: " + e.getMessage())
456 LOGGER.warn("No NSI found for NSSI id " + nssiId)
461 LOGGER.warn("No relationships found for Allotted Resource for NSSI id " + nssiId)
467 LOGGER.warn("No relationships found for nssi id = " + nssiId)
471 LOGGER.debug("${PREFIX} Exit removeNSSIAssociationWithNSI")
476 * Delets NSSI Service Instance
479 void deleteNSSIServiceInstance(DelegateExecution execution) {
480 LOGGER.debug("${PREFIX} Start deleteNSSIServiceInstance")
482 AAIResourcesClient client = getAAIClient()
484 def currentNSSI = execution.getVariable("currentNSSI")
486 String nssiId = currentNSSI['nssiId']
487 AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nssiId))
490 client.delete(nssiUri)
492 exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occurred while NSSI Service Instance delete call: " + e.getMessage())
495 LOGGER.debug("${PREFIX} Exit deleteNSSIServiceInstance")
500 * Gets Delete Service Order progress
503 void getDeleteServiceOrderProgress(DelegateExecution execution) {
504 LOGGER.debug("${getPrefix()} Start getDeleteServiceOrderProgress")
506 def currentNSSI = execution.getVariable("currentNSSI")
508 String url = currentNSSI['requestSelfLink']
510 String msoKey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
512 String basicAuth = UrnPropertiesReader.getVariable("mso.adapters.po.auth", execution)
515 String basicAuthValue = utils.getBasicAuth(basicAuth, msoKey)
517 getProgress(execution, url, basicAuthValue, "deleteStatus")
519 LOGGER.debug("${getPrefix()} Exit getDeleteServiceOrderProgress")
524 * Calculates a final list of S-NSSAI
527 void calculateSNSSAI(DelegateExecution execution) {
528 LOGGER.debug("${getPrefix()} Start calculateSNSSAI")
530 def currentNSSI = execution.getVariable("currentNSSI")
532 List<SliceProfile> associatedProfiles = (List<SliceProfile>)currentNSSI['associatedProfiles']
534 String givenSliceProfileId = currentNSSI['sliceProfileId']
536 List<String> snssais = new ArrayList<>()
538 String isTerminateNSSIVar = execution.getVariable("isTerminateNSSI" )
540 boolean isTerminateNSSI = Boolean.parseBoolean(isTerminateNSSIVar)
542 if(!isTerminateNSSI) { // NSSI should not be terminated
543 LOGGER.debug("calculateSNSSAI: associatedProfiles.size()" + associatedProfiles.size())
544 for (SliceProfile associatedProfile : associatedProfiles) {
545 if (!associatedProfile.getProfileId().equals(givenSliceProfileId)) { // not given profile id
546 LOGGER.debug("calculateSNSSAI: associatedProfile.getSNssai()" + associatedProfile.getSNssai())
547 snssais.add(associatedProfile.getSNssai())
549 currentNSSI['sliceProfileS-NSSAI'] = associatedProfile
554 currentNSSI['S-NSSAIs'] = snssais
556 LOGGER.debug("${getPrefix()} Exit calculateSNSSAI")
562 * @return new OofUtils()
564 OofUtils getOofUtils() {
565 return new OofUtils()
569 private String getPrefix() {