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)
241 //Setting correlator as requestId
242 String requestId = execution.getVariable("msoRequestId")
243 execution.setVariable("NSSI_correlator", requestId)
245 //Setting messageType for all Core slice as cn
246 String messageType = "cn"
247 execution.setVariable("NSSI_messageType", messageType)
250 String timeout = execution.getVariable("timeout")
251 if (isBlank(timeout)) {
252 timeout = UrnPropertiesReader.getVariable("mso.oof.timeout", execution);
253 if (isBlank(timeout)) {
258 String nxlId = nssi.getServiceInstanceId()
259 String nxlType = "NSSI"
260 String oofRequest = getOofUtils().buildTerminateNxiRequest(requestId, nxlId, nxlType, messageType, nssi.getServiceInstanceId())
261 LOGGER.debug("**** Terminate Nxi Request: "+oofRequest)
263 LOGGER.debug("${PREFIX} Exit buildOOFRequest")
271 * Invokes deleteServiceOrder external API
274 void deleteServiceOrder(DelegateExecution execution) {
275 LOGGER.debug("${PREFIX} Start deleteServiceOrder")
277 def currentNSSI = execution.getVariable("currentNSSI")
280 //url:/nbi/api/v4/serviceOrder/"
281 def nsmfЕndPoint = UrnPropertiesReader.getVariable("mso.infra.endpoint.url", execution)
283 ServiceInstance networkServiceInstance = (ServiceInstance)currentNSSI['networkServiceInstance']
285 //String url = String.format("${nbiEndpointUrl}/api/v4/serviceOrder/%s", networkServiceInstance.getServiceInstanceId())
287 GenericVnf constituteVnf = (GenericVnf)currentNSSI['constituteVnf']
289 // http://so.onap:8080/onap/so/infra/serviceInstantiation/v7/serviceInstances/de6a0aa2-19f2-41fe-b313-a5a9f159acd7/vnfs/3abbb373-8d33-4977-aa4b-2bfee496b6d5
290 String url = String.format("${nsmfЕndPoint}/serviceInstantiation/v7/serviceInstances/%s/vnfs/%s", networkServiceInstance.getServiceInstanceId(), constituteVnf.getVnfId())
292 currentNSSI['deleteServiceOrderURL'] = url
294 String msoKey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
295 String basicAuth = UrnPropertiesReader.getVariable("mso.adapters.po.auth", execution)
297 /*String basicAuthValue = encryptBasicAuth(basicAuth, msoKey)
299 if (basicAuthValue != null) {
300 String responseAuthHeader = getAuthHeader(execution, basicAuthValue, msoKey)
301 String errorCode = jsonUtil.getJsonValue(responseAuthHeader, "errorCode")
302 if(errorCode == null || errorCode.isEmpty()) { // No error
303 authHeader = responseAuthHeader
306 exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(errorCode), jsonUtil.getJsonValue(responseAuthHeader, "errorMessage"))
309 LOGGER.error( "Unable to obtain BasicAuth - BasicAuth value null")
310 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - BasicAuth " +
314 def authHeader = utils.getBasicAuth(basicAuth, msoKey)
316 String callDeleteServiceOrderResponse = callDeleteServiceOrder(execution, url, authHeader)
317 String errorCode = jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "errorCode")
319 if(errorCode == null || errorCode.isEmpty()) { // No error
320 String macroOperationId = jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "requestReferences.requestId")
321 String requestSelfLink = jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "requestReferences.requestSelfLink")
323 execution.setVariable("macroOperationId", macroOperationId)
324 execution.setVariable("requestSelfLink", requestSelfLink)
326 currentNSSI['requestSelfLink'] = requestSelfLink
329 LOGGER.error(jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "errorMessage"))
330 exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(errorCode), jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "errorMessage"))
333 String msg = "Exception in DoDeallocateCoreNSSI.deleteServiceOrder. " + any.getCause()
335 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
338 LOGGER.debug("${PREFIX} Exit deleteServiceOrder")
342 String callDeleteServiceOrder(DelegateExecution execution, String url, String authHeader) {
343 LOGGER.debug("${PREFIX} Start callDeleteServiceOrder")
345 String errorCode = ""
346 String errorMessage = ""
350 HttpClient httpClient = getHttpClientFactory().newJsonClient(new URL(url), ONAPComponents.SO)
351 httpClient.addAdditionalHeader("Authorization", authHeader)
352 httpClient.addAdditionalHeader("Accept", "application/json")
353 Response httpResponse = httpClient.delete()
355 int soResponseCode = httpResponse.getStatus()
356 LOGGER.debug("callDeleteServiceInstance: soResponseCode = " + soResponseCode)
358 if (soResponseCode >= 200 && soResponseCode < 204 && httpResponse.hasEntity()) {
359 response = httpResponse.readEntity(String.class)
361 LOGGER.debug("callDeleteServiceInstance: response = " + response)
365 errorMessage = "Response code is " + soResponseCode
368 " \"errorCode\": \"${errorCode}\",\n" +
369 " \"errorMessage\": \"${errorMessage}\"\n" +
374 String msg = "Exception in DoDeallocateCoreNSSI.callDeleteServiceOrder. " + any.getCause()
377 " \"errorCode\": \"7000\",\n" +
378 " \"errorMessage\": \"${msg}\"\n" +
382 LOGGER.debug("${PREFIX} Exit callDeleteServiceOrder")
389 * Removes NSSI association with NSI
392 void removeNSSIAssociationWithNSI(DelegateExecution execution) {
393 LOGGER.debug("${PREFIX} Start removeNSSIAssociationWithNSI")
395 AAIResourcesClient client = getAAIClient()
397 def currentNSSI = execution.getVariable("currentNSSI")
399 String nssiId = currentNSSI['nssiId']
400 String nsiId = currentNSSI['nsiId']
401 String globalSubscriberId = execution.getVariable("globalSubscriberId")
402 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
405 AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nssiId))
408 String allottedResourceId = null
411 AAIResultWrapper nssiWrapper = client.get(nssiUri)
412 Optional<Relationships> nssiRelationships = nssiWrapper.getRelationships()
414 if (nssiRelationships.isPresent()) {
416 for (AAIResourceUri allottedResourceUri : nssiRelationships.get().getRelatedUris(Types.ALLOTTED_RESOURCE)) {
417 AAIResultWrapper arWrapper = client.get(allottedResourceUri)
418 Optional<Relationships> arRelationships = arWrapper.getRelationships()
420 if(arRelationships.isPresent()) {
422 for (AAIResourceUri nsiUri : arRelationships.get().getRelatedUris(Types.SERVICE_INSTANCE)) {
423 Optional<ServiceInstance> nsiOpt = client.get(ServiceInstance.class, nsiUri)
425 if (nsiOpt.isPresent()) {
426 ServiceInstance nsi = nsiOpt.get()
427 if(nsi.getServiceRole().equals("nsi")) { // Service instance as NSI
428 // Removes NSSI association with NSI
430 client.disconnect(nssiUri, nsiUri)
432 catch (Exception e) {
433 exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occured while NSSI association with NSI dosconnect call: " + e.getMessage())
438 LOGGER.warn("No NSI found for NSSI id " + nssiId)
443 LOGGER.warn("No relationships found for Allotted Resource for NSSI id " + nssiId)
449 LOGGER.warn("No relationships found for nssi id = " + nssiId)
453 LOGGER.debug("${PREFIX} Exit removeNSSIAssociationWithNSI")
458 * Delets NSSI Service Instance
461 void deleteNSSIServiceInstance(DelegateExecution execution) {
462 LOGGER.debug("${PREFIX} Start deleteNSSIServiceInstance")
464 AAIResourcesClient client = getAAIClient()
466 def currentNSSI = execution.getVariable("currentNSSI")
468 String nssiId = currentNSSI['nssiId']
469 AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nssiId))
472 client.delete(nssiUri)
474 exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occurred while NSSI Service Instance delete call: " + e.getMessage())
477 LOGGER.debug("${PREFIX} Exit deleteNSSIServiceInstance")
482 * Gets Delete Service Order progress
485 void getDeleteServiceOrderProgress(DelegateExecution execution) {
486 LOGGER.debug("${getPrefix()} Start getDeleteServiceOrderProgress")
488 def currentNSSI = execution.getVariable("currentNSSI")
490 String url = currentNSSI['requestSelfLink']
492 String msoKey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
494 String basicAuth = UrnPropertiesReader.getVariable("mso.adapters.po.auth", execution)
497 String basicAuthValue = utils.getBasicAuth(basicAuth, msoKey)
499 getProgress(execution, url, basicAuthValue, "deleteStatus")
501 LOGGER.debug("${getPrefix()} Exit getDeleteServiceOrderProgress")
506 * Calculates a final list of S-NSSAI
509 void calculateSNSSAI(DelegateExecution execution) {
510 LOGGER.debug("${getPrefix()} Start calculateSNSSAI")
512 def currentNSSI = execution.getVariable("currentNSSI")
514 List<SliceProfile> associatedProfiles = (List<SliceProfile>)currentNSSI['associatedProfiles']
516 String givenSliceProfileId = currentNSSI['sliceProfileId']
518 List<String> snssais = new ArrayList<>()
520 String isTerminateNSSIVar = execution.getVariable("isTerminateNSSI" )
522 boolean isTerminateNSSI = Boolean.parseBoolean(isTerminateNSSIVar)
524 if(!isTerminateNSSI) { // NSSI should not be terminated
525 LOGGER.debug("calculateSNSSAI: associatedProfiles.size()" + associatedProfiles.size())
526 for (SliceProfile associatedProfile : associatedProfiles) {
527 if (!associatedProfile.getProfileId().equals(givenSliceProfileId)) { // not given profile id
528 LOGGER.debug("calculateSNSSAI: associatedProfile.getSNssai()" + associatedProfile.getSNssai())
529 snssais.add(associatedProfile.getSNssai())
531 currentNSSI['sliceProfileS-NSSAI'] = associatedProfile
536 currentNSSI['S-NSSAIs'] = snssais
538 LOGGER.debug("${getPrefix()} Exit calculateSNSSAI")
544 * @return new OofUtils()
546 OofUtils getOofUtils() {
547 return new OofUtils()
551 private String getPrefix() {