diff options
5 files changed, 441 insertions, 369 deletions
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java index 90a578d3b4..7d30c87101 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java @@ -466,7 +466,7 @@ public class HeatBridgeImpl implements HeatBridgeApi { resourcesClient.createIfNotExists(uri, Optional.of(pInterface)); } - private void updateLInterfaceVlan(final Port port, final LInterface lIf, final String hostName) + protected void updateLInterfaceVlan(final Port port, final LInterface lIf, final String hostName) throws HeatBridgeException { // add back all vlan logic Vlan vlan = new Vlan(); @@ -486,11 +486,13 @@ public class HeatBridgeImpl implements HeatBridgeApi { Optional.of(vlan)); } - if (nodeType == NodeType.GREENFIELD) { - validatePhysicalNetwork(port, network); - processOVS(lIf, hostName, NodeType.GREENFIELD.getInterfaceName()); - } else { - processOVS(lIf, hostName, NodeType.BROWNFIELD.getInterfaceName()); + if (!lIf.getInterfaceType().equals(SRIOV)) { + if (nodeType == NodeType.GREENFIELD) { + validatePhysicalNetwork(port, network); + processOVS(lIf, hostName, NodeType.GREENFIELD.getInterfaceName()); + } else { + processOVS(lIf, hostName, NodeType.BROWNFIELD.getInterfaceName()); + } } List<String> privateVlans = (ArrayList<String>) port.getProfile().get(PRIVATE_VLANS); @@ -597,33 +599,29 @@ public class HeatBridgeImpl implements HeatBridgeApi { lIf.setInterfaceDescription( "Attached to SR-IOV port: " + pserverHostName + "::" + matchingPifName.get()); try { - Optional<PInterface> matchingPIf = resourcesClient.get(PInterface.class, + AAIResourceUri pInterfaceUri = AAIUriFactory .createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() .pserver(pserverHostName).pInterface(matchingPifName.get())) - .depth(Depth.ONE)); - if (matchingPIf.isPresent()) { - SriovPfs pIfSriovPfs = matchingPIf.get().getSriovPfs(); - if (pIfSriovPfs == null) { - pIfSriovPfs = new SriovPfs(); - } - // Extract PCI-ID from OS port object + .depth(Depth.ONE); + if (resourcesClient.exists(pInterfaceUri)) { + PInterface matchingPIf = resourcesClient.get(PInterface.class, pInterfaceUri).get(); + String pfPciId = port.getProfile().get(HeatBridgeConstants.OS_PCI_SLOT_KEY).toString(); - List<SriovPf> existingSriovPfs = pIfSriovPfs.getSriovPf(); - if (CollectionUtils.isEmpty(existingSriovPfs) || existingSriovPfs.stream() - .noneMatch(existingSriovPf -> existingSriovPf.getPfPciId().equals(pfPciId))) { - // Add sriov-pf object with PCI-ID to AAI + if (matchingPIf.getSriovPfs() == null + || CollectionUtils.isEmpty(matchingPIf.getSriovPfs().getSriovPf()) + || matchingPIf.getSriovPfs().getSriovPf().stream() + .noneMatch(existingSriovPf -> existingSriovPf.getPfPciId().equals(pfPciId))) { + SriovPf sriovPf = new SriovPf(); sriovPf.setPfPciId(pfPciId); - logger.debug("Queuing AAI command to update sriov-pf object to pserver: " + pserverHostName - + "/" + matchingPifName.get()); AAIResourceUri sriovPfUri = AAIUriFactory.createResourceUri( AAIFluentTypeBuilder.cloudInfrastructure().pserver(pserverHostName) .pInterface(matchingPifName.get()).sriovPf(sriovPf.getPfPciId())); - + // TODO if it does exist, should check if relationship is there, if not then create? if (!resourcesClient.exists(sriovPfUri)) { transaction.create(sriovPfUri, sriovPf); @@ -634,6 +632,10 @@ public class HeatBridgeImpl implements HeatBridgeApi { transaction.connect(sriovPfUri, sriovVfUri); } } + } else { + logger.warn( + "PInterface {} does not exist in AAI. Unable to build sriov-vf to sriov-pf relationship.", + matchingPifName.get()); } } catch (WebApplicationException e) { // Silently log that we failed to update the Pserver p-interface with PCI-ID diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/utils/HeatBridgeUtils.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/utils/HeatBridgeUtils.java index 1667f980e1..c281dbd9e5 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/utils/HeatBridgeUtils.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/utils/HeatBridgeUtils.java @@ -59,7 +59,7 @@ public final class HeatBridgeUtils { public static Optional<String> getMatchingPserverPifName(@Nonnull final String physicalNetworkName) { Preconditions.checkState(!Strings.isNullOrEmpty(physicalNetworkName), - "Physical network name is null or " + "empty!"); + "Physical network name is null or empty!"); if (physicalNetworkName.contains(OS_SIDE_DEDICATED_SRIOV_PREFIX)) { return Optional.of( physicalNetworkName.replace(OS_SIDE_DEDICATED_SRIOV_PREFIX, COMPUTE_SIDE_DEDICATED_SRIOV_PREFIX)); @@ -67,7 +67,7 @@ public final class HeatBridgeUtils { return Optional .of(physicalNetworkName.replace(OS_SIDE_SHARED_SRIOV_PREFIX, COMPUTE_SIDE_SHARED_SRIOV_PREFIX)); } - return Optional.empty(); + return Optional.of(physicalNetworkName); } public static List<String> extractPciIdsFromVServer(Vserver vserver) { diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java index 110faaf8ab..a9c31128ad 100644 --- a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java +++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java @@ -41,6 +41,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -65,6 +66,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; import org.onap.aai.domain.yang.L3InterfaceIpv6AddressList; import org.onap.aai.domain.yang.LInterface; @@ -131,6 +133,7 @@ public class HeatBridgeImplTest { @Mock private Server server; + @Spy @InjectMocks private HeatBridgeImpl heatbridge = new HeatBridgeImpl(resourcesClient, cloudIdentity, CLOUD_OWNER, REGION_ID, REGION_ID, TENANT_ID, NodeType.GREENFIELD); @@ -463,6 +466,63 @@ public class HeatBridgeImplTest { } @Test + public void testUpdateLInterfaceVlan() throws HeatBridgeException { + // Arrange + List<Resource> stackResources = (List<Resource>) extractTestStackResources(); + Port port = mock(Port.class); + when(port.getId()).thenReturn("test-port-id"); + when(port.getName()).thenReturn("test-port-name"); + when(port.getvNicType()).thenReturn(HeatBridgeConstants.OS_SRIOV_PORT_TYPE); + when(port.getMacAddress()).thenReturn("78:4f:43:68:e2:78"); + when(port.getNetworkId()).thenReturn("890a203a-23gg-56jh-df67-731656a8f13a"); + when(port.getDeviceId()).thenReturn("test-device-id"); + + LInterface lIf = new LInterface(); + lIf.setInterfaceId("test-port-id"); + lIf.setInterfaceType("SRIOV"); + lIf.setInterfaceName("name"); + + String pfPciId = "0000:08:00.0"; + when(port.getProfile()).thenReturn(ImmutableMap.of(HeatBridgeConstants.OS_PCI_SLOT_KEY, pfPciId, + HeatBridgeConstants.OS_PHYSICAL_NETWORK_KEY, "physical_network_id")); + + IP ip = mock(IP.class); + + Set<IP> ipSet = new HashSet<>(); + ipSet.add(ip); + when(ip.getIpAddress()).thenReturn("2606:ae00:2e60:100::226"); + when(ip.getSubnetId()).thenReturn("testSubnetId"); + when(port.getFixedIps()).thenAnswer(x -> ipSet); + + Subnet subnet = mock(Subnet.class); + when(subnet.getCidr()).thenReturn("169.254.100.0/24"); + when(osClient.getSubnetById("testSubnetId")).thenReturn(subnet); + + Network network = mock(Network.class); + when(network.getId()).thenReturn("test-network-id"); + when(network.getNetworkType()).thenReturn(NetworkType.VLAN); + when(network.getProviderSegID()).thenReturn("2345"); + when(network.getProviderPhyNet()).thenReturn("ovsnet"); + doNothing().when(heatbridge).processOVS(any(), any(), any()); + + when(osClient.getNetworkById(anyString())).thenReturn(network); + + SriovPf sriovPf = new SriovPf(); + sriovPf.setPfPciId(pfPciId); + PInterface pIf = mock(PInterface.class); + when(pIf.getInterfaceName()).thenReturn("test-port-id"); + when(resourcesClient.get(eq(PInterface.class), any(AAIResourceUri.class))).thenReturn(Optional.of(pIf)); + + // Act + heatbridge.updateLInterfaceVlan(port, lIf, "hostname"); + + // Assert + verify(transaction, times(2)).createIfNotExists(any(AAIResourceUri.class), any(Optional.class)); + verify(osClient, times(1)).getNetworkById(anyString()); + verify(heatbridge, times(0)).processOVS(any(), any(), any()); + } + + @Test public void testUpdateLInterfaceIps() throws HeatBridgeException, JsonParseException, JsonMappingException, IOException { diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/utils/HeatBridgeUtilsTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/utils/HeatBridgeUtilsTest.java index bbc99bd258..13a8cb21e7 100644 --- a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/utils/HeatBridgeUtilsTest.java +++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/utils/HeatBridgeUtilsTest.java @@ -26,6 +26,6 @@ public class HeatBridgeUtilsTest { @Test public void matchServerName_unknown() { Optional<String> serverName = HeatBridgeUtils.getMatchingPserverPifName("differentServerName"); - assertThat(serverName).isEmpty(); + assertThat(serverName).isNotEmpty().hasValue("differentServerName"); } } diff --git a/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/SDNCAdapterRestV1.groovy b/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/SDNCAdapterRestV1.groovy index 55f1187d69..669441c320 100644 --- a/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/SDNCAdapterRestV1.groovy +++ b/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/SDNCAdapterRestV1.groovy @@ -56,349 +56,359 @@ class SDNCAdapterRestV1 extends AbstractServiceTaskProcessor { private static final Logger logger = LoggerFactory.getLogger( SDNCAdapterRestV1.class) - ExceptionUtil exceptionUtil = new ExceptionUtil() - JsonUtils jsonUtil = new JsonUtils() - - /** - * Processes the incoming request. - */ - public void preProcessRequest (DelegateExecution execution) { - def method = getClass().getSimpleName() + '.preProcessRequest(' + - 'execution=' + execution.getId() + - ')' - logger.trace('Entered ' + method) - - def prefix="SDNCREST_" - execution.setVariable("prefix", prefix) - setSuccessIndicator(execution, false) - - try { - // Determine the request type and log the request - - String request = validateRequest(execution, "mso-request-id") - String requestType = jsonUtil.getJsonRootProperty(request) - execution.setVariable(prefix + 'requestType', requestType) - logger.debug(getProcessKey(execution) + ': ' + prefix + 'requestType = ' + requestType) - - // Determine the SDNCAdapter endpoint - - String sdncAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.sdnc.rest.endpoint", execution) - - if (sdncAdapterEndpoint == null || sdncAdapterEndpoint.isEmpty()) { - String msg = getProcessKey(execution) + ': mso:adapters:sdnc:rest:endpoint URN mapping is not defined' - logger.debug(msg) - logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", - ErrorCode.UnknownError.getValue()) - exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) - } - - while (sdncAdapterEndpoint.endsWith('/')) { - sdncAdapterEndpoint = sdncAdapterEndpoint.substring(0, sdncAdapterEndpoint.length()-1) - } - - String sdncAdapterMethod = null - String sdncAdapterUrl = null - String sdncAdapterRequest = request - - if ('SDNCServiceRequest'.equals(requestType)) { - // Get the sdncRequestId from the request - - String sdncRequestId = jsonUtil.getJsonValue(request, requestType + ".sdncRequestId") - - if (sdncRequestId == null || sdncRequestId.isEmpty()) { - String msg = getProcessKey(execution) + ': no sdncRequestId in ' + requestType - logger.debug(msg) - logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", - ErrorCode.UnknownError.getValue()) - exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) - } - - execution.setVariable('SDNCAResponse_CORRELATOR', sdncRequestId) - logger.debug(getProcessKey(execution) + ': SDNCAResponse_CORRELATOR = ' + sdncRequestId) - - // Get the bpNotificationUrl from the request (just to make sure it's there) - - String bpNotificationUrl = jsonUtil.getJsonValue(request, requestType + ".bpNotificationUrl") - - if (bpNotificationUrl == null || bpNotificationUrl.isEmpty()) { - String msg = getProcessKey(execution) + ': no bpNotificationUrl in ' + requestType - logger.debug(msg) - logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", - ErrorCode.UnknownError.getValue()) - exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) - } - - sdncAdapterMethod = 'POST' - sdncAdapterUrl = sdncAdapterEndpoint - - RollbackData rollbackData = new RollbackData() - rollbackData.setRequestId(sdncRequestId) - rollbackData.getAdditionalData().put("service", jsonUtil.getJsonValue(request, requestType + ".sdncService")) - rollbackData.getAdditionalData().put("operation", jsonUtil.getJsonValue(request, requestType + ".sdncOperation")) - execution.setVariable("RollbackData", rollbackData) - - } else { - String msg = getProcessKey(execution) + ': Unsupported request type: ' + requestType - logger.debug(msg) - logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", - ErrorCode.UnknownError.getValue()) - exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) - } - - execution.setVariable(prefix + 'sdncAdapterMethod', sdncAdapterMethod) - execution.setVariable(prefix + 'sdncAdapterUrl', sdncAdapterUrl) - execution.setVariable(prefix + 'sdncAdapterRequest', sdncAdapterRequest) - - // Get the Basic Auth credentials for the SDNCAdapter (yes... we ARE using the PO adapters credentials) - - String basicAuthValue = UrnPropertiesReader.getVariable("mso.adapters.po.auth", execution) - - if (basicAuthValue == null || basicAuthValue.isEmpty()) { - logger.debug(getProcessKey(execution) + ": mso:adapters:po:auth URN mapping is not defined") - logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), - getProcessKey(execution) + ": mso:adapters:po:auth URN mapping is not defined", "BPMN", - ErrorCode.UnknownError.getValue()) - } else { - try { - def encodedString = utils.getBasicAuth(basicAuthValue, UrnPropertiesReader.getVariable("mso.msoKey", execution)) - execution.setVariable(prefix + 'basicAuthHeaderValue', encodedString) - } catch (IOException ex) { - logger.debug(getProcessKey(execution) + ": Unable to encode BasicAuth credentials for SDNCAdapter") - logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), - getProcessKey(execution) + ": Unable to encode BasicAuth credentials for SDNCAdapter", - "BPMN", ErrorCode.UnknownError.getValue(), ex) - } - } - - // Set the timeout value, e.g. PT5M. It may be specified in the request as the - // bpTimeout value. If it's not in the request, use the URN mapping value. - - String timeout = jsonUtil.getJsonValue(request, requestType + ".bpTimeout") - - // in addition to null/empty, also need to verify that the timer value is a valid duration "P[n]T[n]H|M|S" - String timerRegex = "PT[0-9]+[HMS]" - if (timeout == null || timeout.isEmpty() || !timeout.matches(timerRegex)) { - logger.debug(getProcessKey(execution) + ': preProcessRequest(): null/empty/invalid bpTimeout value. Using "mso.adapters.sdnc.timeout"') - timeout = UrnPropertiesReader.getVariable("mso.adapters.sdnc.timeout", execution) - } - - // the timeout could still be null at this point if the config parm is missing/undefined - // forced to log (so OPs can fix the config) and temporarily use a hard coded value of 10 seconds - if (timeout == null) { - msoLogger.warnSimple('preProcessRequest()', 'property "mso.adapters.sdnc.timeout" is missing/undefined. Using "PT10S"') - timeout = "PT10S" - } - - execution.setVariable(prefix + 'timeout', timeout) - logger.debug(getProcessKey(execution) + ': ' + prefix + 'timeout = ' + timeout) - } catch (BpmnError e) { - throw e - } catch (Exception e) { - String msg = 'Caught exception in ' + method + ": " + e - logger.debug(msg) - logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", - ErrorCode.UnknownError.getValue()) - exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) - } - } - - /** - * Sends the request to the SDNC adapter. - */ - public void sendRequestToSDNCAdapter(DelegateExecution execution) { - def method = getClass().getSimpleName() + '.sendRequestToSDNCAdapter(' + - 'execution=' + execution.getId() + - ')' - logger.trace('Entered ' + method) - - String prefix = execution.getVariable('prefix') - - try { - String sdncAdapterMethod = execution.getVariable(prefix + 'sdncAdapterMethod') - logger.debug("SDNC Method is: " + sdncAdapterMethod) - String sdncAdapterUrl = execution.getVariable(prefix + 'sdncAdapterUrl') - logger.debug("SDNC Url is: " + sdncAdapterUrl) - String sdncAdapterRequest = execution.getVariable(prefix + 'sdncAdapterRequest') - logger.debug("SDNC Rest Request is: " + sdncAdapterRequest) - - URL url = new URL(sdncAdapterUrl) - - HttpClient httpClient = new HttpClientFactory().newJsonClient(url, ONAPComponents.SDNC_ADAPTER) - httpClient.addAdditionalHeader("mso-request-id", execution.getVariable("mso-request-id")) - httpClient.addAdditionalHeader("mso-service-instance-id", execution.getVariable("mso-service-instance-id")) - httpClient.addAdditionalHeader("Authorization", execution.getVariable(prefix + "basicAuthHeaderValue")) - - Response response - - if ("GET".equals(sdncAdapterMethod)) { - response = httpClient.get() - } else if ("PUT".equals(sdncAdapterMethod)) { - response = httpClient.put(sdncAdapterRequest) - } else if ("POST".equals(sdncAdapterMethod)) { - response = httpClient.post(sdncAdapterRequest) - } else if ("DELETE".equals(sdncAdapterMethod)) { - response = httpClient.delete(sdncAdapterRequest) - } else { - String msg = 'Unsupported HTTP method "' + sdncAdapterMethod + '" in ' + method + ": " + e - logger.debug(msg) - logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", - ErrorCode.UnknownError.getValue()) - exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) - } - - execution.setVariable(prefix + "sdncAdapterStatusCode", response.getStatus()) - if(response.hasEntity()){ - execution.setVariable(prefix + "sdncAdapterResponse", response.readEntity(String.class)) - } - } catch (BpmnError e) { - throw e - } catch (Exception e) { - String msg = 'Caught exception in ' + method + ": " + e - logger.debug(msg, e) - logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", - ErrorCode.UnknownError.getValue()) - exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) - } - } - - /** - * Processes a callback. - */ - public void processCallback(DelegateExecution execution){ - def method = getClass().getSimpleName() + '.processCallback(' + - 'execution=' + execution.getId() + - ')' - logger.trace('Entered ' + method) - - String prefix = execution.getVariable('prefix') - String callback = execution.getVariable('SDNCAResponse_MESSAGE') - logger.debug("Incoming SDNC Rest Callback is: " + callback) - - try { - int callbackNumber = 1 - while (execution.getVariable(prefix + 'callback' + callbackNumber) != null) { - ++callbackNumber - } - - execution.setVariable(prefix + 'callback' + callbackNumber, callback) - execution.removeVariable('SDNCAResponse_MESSAGE') - - String responseType = jsonUtil.getJsonRootProperty(callback) - - // Get the ackFinalIndicator and make sure it's either Y or N. Default to Y. - String ackFinalIndicator = jsonUtil.getJsonValue(callback, responseType + ".ackFinalIndicator") - - if (!'N'.equals(ackFinalIndicator)) { - ackFinalIndicator = 'Y' - } - - execution.setVariable(prefix + "ackFinalIndicator", ackFinalIndicator) - - if (responseType.endsWith('Error')) { - sdncAdapterBuildWorkflowException(execution, callback) - } - } catch (Exception e) { - callback = callback == null || String.valueOf(callback).isEmpty() ? "NONE" : callback - String msg = "Received error from SDNCAdapter: " + callback - logger.debug(getProcessKey(execution) + ': ' + msg) - exceptionUtil.buildWorkflowException(execution, 5300, msg) - } - } - - /** - * Tries to parse the response as XML to extract the information to create - * a WorkflowException. If the response cannot be parsed, a more generic - * WorkflowException is created. - */ - public void sdncAdapterBuildWorkflowException(DelegateExecution execution, String response) { - try { - String responseType = jsonUtil.getJsonRootProperty(response) - String responseCode = jsonUtil.getJsonValue(response, responseType + ".responseCode") - String responseMessage = jsonUtil.getJsonValue(response, responseType + ".responseMessage") - - String info = "" - - if (responseCode != null && !responseCode.isEmpty()) { - info += " responseCode='" + responseCode + "'" - } - - if (responseMessage != null && !responseMessage.isEmpty()) { - info += " responseMessage='" + responseMessage + "'" - } - - // Note: the mapping function handles a null or empty responseCode - int mappedResponseCode = Integer.parseInt(exceptionUtil.MapSDNCResponseCodeToErrorCode(responseCode)) - exceptionUtil.buildWorkflowException(execution, mappedResponseCode, "Received " + responseType + - " from SDNCAdapter:" + info) - } catch (Exception e) { - response = response == null || String.valueOf(response).isEmpty() ? "NONE" : response - exceptionUtil.buildWorkflowException(execution, 5300, "Received error from SDNCAdapter: " + response) - } - } - - /** - * Gets the last callback request from the execution, or null if there was no callback. - */ - public String getLastCallback(DelegateExecution execution) { - def method = getClass().getSimpleName() + '.getLastCallback(' + - 'execution=' + execution.getId() + - ')' - logger.trace('Entered ' + method) - - String prefix = execution.getVariable('prefix') - - try { - int callbackNumber = 1 - String callback = null - - while (true) { - String thisCallback = (String) execution.getVariable(prefix + 'callback' + callbackNumber) - - if (thisCallback == null) { - break - } - - callback = thisCallback - ++callbackNumber - } - - return callback - } catch (Exception e) { - String msg = 'Caught exception in ' + method + ": " + e - logger.debug(msg) - logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", - ErrorCode.UnknownError.getValue()) - exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) - } - } - - /** - * Sets the timeout value to wait for the next notification. - */ - public void setTimeoutValue(DelegateExecution execution) { - def method = getClass().getSimpleName() + '.setTimeoutValue(' + - 'execution=' + execution.getId() + - ')' - logger.trace('Entered ' + method) - - String prefix = execution.getVariable('prefix') - - try { - def timeoutValue = UrnPropertiesReader.getVariable("mso.adapters.sdnc.timeout", execution) - - if (execution.getVariable(prefix + 'callback1') != null) { - // Waiting for subsequent notifications - } - } catch (Exception e) { - String msg = 'Caught exception in ' + method + ": " + e - logger.debug(msg) - logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", - ErrorCode.UnknownError.getValue()) - exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) - } - } - - public Logger getLogger() { - return logger - } + ExceptionUtil exceptionUtil = new ExceptionUtil() + JsonUtils jsonUtil = new JsonUtils() + + /** + * Processes the incoming request. + */ + public void preProcessRequest (DelegateExecution execution) { + def method = getClass().getSimpleName() + '.preProcessRequest(' + + 'execution=' + execution.getId() + + ')' + logger.trace('Entered ' + method) + + def prefix="SDNCREST_" + execution.setVariable("prefix", prefix) + setSuccessIndicator(execution, false) + + try { + // Determine the request type and log the request + + String request = validateRequest(execution, "mso-request-id") + String requestType = jsonUtil.getJsonRootProperty(request) + execution.setVariable(prefix + 'requestType', requestType) + logger.debug(getProcessKey(execution) + ': ' + prefix + 'requestType = ' + requestType) + + // Determine the SDNCAdapter endpoint + + String sdncAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.sdnc.rest.endpoint", execution) + + if (sdncAdapterEndpoint == null || sdncAdapterEndpoint.isEmpty()) { + String msg = getProcessKey(execution) + ': mso:adapters:sdnc:rest:endpoint URN mapping is not defined' + logger.debug(msg) + logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", + ErrorCode.UnknownError.getValue()) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + + while (sdncAdapterEndpoint.endsWith('/')) { + sdncAdapterEndpoint = sdncAdapterEndpoint.substring(0, sdncAdapterEndpoint.length()-1) + } + + String sdncAdapterMethod = null + String sdncAdapterUrl = null + String sdncAdapterRequest = request + + if ('SDNCServiceRequest'.equals(requestType)) { + // Get the sdncRequestId from the request + + String sdncRequestId = jsonUtil.getJsonValue(request, requestType + ".sdncRequestId") + + if (sdncRequestId == null || sdncRequestId.isEmpty()) { + String msg = getProcessKey(execution) + ': no sdncRequestId in ' + requestType + logger.debug(msg) + logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", + ErrorCode.UnknownError.getValue()) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + + execution.setVariable('SDNCAResponse_CORRELATOR', sdncRequestId) + logger.debug(getProcessKey(execution) + ': SDNCAResponse_CORRELATOR = ' + sdncRequestId) + + // Get the bpNotificationUrl from the request (just to make sure it's there) + + String bpNotificationUrl = jsonUtil.getJsonValue(request, requestType + ".bpNotificationUrl") + + if (bpNotificationUrl == null || bpNotificationUrl.isEmpty()) { + String msg = getProcessKey(execution) + ': no bpNotificationUrl in ' + requestType + logger.debug(msg) + logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", + ErrorCode.UnknownError.getValue()) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + + sdncAdapterMethod = 'POST' + sdncAdapterUrl = sdncAdapterEndpoint + + RollbackData rollbackData = new RollbackData() + rollbackData.setRequestId(sdncRequestId) + rollbackData.getAdditionalData().put("service", jsonUtil.getJsonValue(request, requestType + ".sdncService")) + rollbackData.getAdditionalData().put("operation", jsonUtil.getJsonValue(request, requestType + ".sdncOperation")) + execution.setVariable("RollbackData", rollbackData) + + } else { + String msg = getProcessKey(execution) + ': Unsupported request type: ' + requestType + logger.debug(msg) + logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", + ErrorCode.UnknownError.getValue()) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + + execution.setVariable(prefix + 'sdncAdapterMethod', sdncAdapterMethod) + execution.setVariable(prefix + 'sdncAdapterUrl', sdncAdapterUrl) + execution.setVariable(prefix + 'sdncAdapterRequest', sdncAdapterRequest) + + // Get the Basic Auth credentials for the SDNCAdapter (yes... we ARE using the PO adapters credentials) + + String basicAuthValue = UrnPropertiesReader.getVariable("mso.adapters.po.auth", execution) + + if (basicAuthValue == null || basicAuthValue.isEmpty()) { + logger.debug(getProcessKey(execution) + ": mso:adapters:po:auth URN mapping is not defined") + logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), + getProcessKey(execution) + ": mso:adapters:po:auth URN mapping is not defined", "BPMN", + ErrorCode.UnknownError.getValue()) + } else { + try { + def encodedString = utils.getBasicAuth(basicAuthValue, UrnPropertiesReader.getVariable("mso.msoKey", execution)) + execution.setVariable(prefix + 'basicAuthHeaderValue', encodedString) + } catch (IOException ex) { + logger.debug(getProcessKey(execution) + ": Unable to encode BasicAuth credentials for SDNCAdapter") + logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), + getProcessKey(execution) + ": Unable to encode BasicAuth credentials for SDNCAdapter", + "BPMN", ErrorCode.UnknownError.getValue(), ex) + } + } + + // Set the timeout value, e.g. PT5M. It may be specified in the request as the + // bpTimeout value. If it's not in the request, use the URN mapping value. + + String timeout = jsonUtil.getJsonValue(request, requestType + ".bpTimeout") + + // in addition to null/empty, also need to verify that the timer value is a valid duration "P[n]T[n]H|M|S" + String timerRegex = "PT[0-9]+[HMS]" + if (timeout == null || timeout.isEmpty() || !timeout.matches(timerRegex)) { + logger.debug(getProcessKey(execution) + ': preProcessRequest(): null/empty/invalid bpTimeout value. Using "mso.adapters.sdnc.timeout"') + timeout = UrnPropertiesReader.getVariable("mso.adapters.sdnc.timeout", execution) + } + + // the timeout could still be null at this point if the config parm is missing/undefined + // forced to log (so OPs can fix the config) and temporarily use a hard coded value of 10 seconds + if (timeout == null) { + msoLogger.warnSimple('preProcessRequest()', 'property "mso.adapters.sdnc.timeout" is missing/undefined. Using "PT10S"') + timeout = "PT10S" + } + + execution.setVariable(prefix + 'timeout', timeout) + + Boolean failOnCallbackError = execution.getVariable("failOnCallbackError") + if(failOnCallbackError == null) { + execution.setVariable("failOnCallbackError", true) + } + + logger.debug(getProcessKey(execution) + ': ' + prefix + 'timeout = ' + timeout) + } catch (BpmnError e) { + throw e + } catch (Exception e) { + String msg = 'Caught exception in ' + method + ": " + e + logger.debug(msg) + logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", + ErrorCode.UnknownError.getValue()) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + } + + /** + * Sends the request to the SDNC adapter. + */ + public void sendRequestToSDNCAdapter(DelegateExecution execution) { + def method = getClass().getSimpleName() + '.sendRequestToSDNCAdapter(' + + 'execution=' + execution.getId() + + ')' + logger.trace('Entered ' + method) + + String prefix = execution.getVariable('prefix') + + try { + String sdncAdapterMethod = execution.getVariable(prefix + 'sdncAdapterMethod') + logger.debug("SDNC Method is: " + sdncAdapterMethod) + String sdncAdapterUrl = execution.getVariable(prefix + 'sdncAdapterUrl') + logger.debug("SDNC Url is: " + sdncAdapterUrl) + String sdncAdapterRequest = execution.getVariable(prefix + 'sdncAdapterRequest') + logger.debug("SDNC Rest Request is: " + sdncAdapterRequest) + + URL url = new URL(sdncAdapterUrl) + + HttpClient httpClient = new HttpClientFactory().newJsonClient(url, ONAPComponents.SDNC_ADAPTER) + httpClient.addAdditionalHeader("mso-request-id", execution.getVariable("mso-request-id")) + httpClient.addAdditionalHeader("mso-service-instance-id", execution.getVariable("mso-service-instance-id")) + httpClient.addAdditionalHeader("Authorization", execution.getVariable(prefix + "basicAuthHeaderValue")) + + Response response + + if ("GET".equals(sdncAdapterMethod)) { + response = httpClient.get() + } else if ("PUT".equals(sdncAdapterMethod)) { + response = httpClient.put(sdncAdapterRequest) + } else if ("POST".equals(sdncAdapterMethod)) { + response = httpClient.post(sdncAdapterRequest) + } else if ("DELETE".equals(sdncAdapterMethod)) { + response = httpClient.delete(sdncAdapterRequest) + } else { + String msg = 'Unsupported HTTP method "' + sdncAdapterMethod + '" in ' + method + ": " + e + logger.debug(msg) + logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", + ErrorCode.UnknownError.getValue()) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + + execution.setVariable(prefix + "sdncAdapterStatusCode", response.getStatus()) + if(response.hasEntity()){ + execution.setVariable(prefix + "sdncAdapterResponse", response.readEntity(String.class)) + } + } catch (BpmnError e) { + throw e + } catch (Exception e) { + String msg = 'Caught exception in ' + method + ": " + e + logger.debug(msg, e) + logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", + ErrorCode.UnknownError.getValue()) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + } + + /** + * Processes a callback. + */ + public void processCallback(DelegateExecution execution){ + def method = getClass().getSimpleName() + '.processCallback(' + + 'execution=' + execution.getId() + + ')' + logger.trace('Entered ' + method) + + String prefix = execution.getVariable('prefix') + String callback = execution.getVariable('SDNCAResponse_MESSAGE') + logger.debug("Incoming SDNC Rest Callback is: " + callback) + + try { + int callbackNumber = 1 + while (execution.getVariable(prefix + 'callback' + callbackNumber) != null) { + ++callbackNumber + } + + execution.setVariable(prefix + 'callback' + callbackNumber, callback) + execution.removeVariable('SDNCAResponse_MESSAGE') + + String responseType = jsonUtil.getJsonRootProperty(callback) + + // Get the ackFinalIndicator and make sure it's either Y or N. Default to Y. + String ackFinalIndicator = jsonUtil.getJsonValue(callback, responseType + ".ackFinalIndicator") + + if (!'N'.equals(ackFinalIndicator)) { + ackFinalIndicator = 'Y' + } + + execution.setVariable(prefix + "ackFinalIndicator", ackFinalIndicator) + + if (responseType.endsWith('Error')) { + Boolean failOnCallbackError = execution.getVariable("failOnCallbackError") + if(failOnCallbackError) { + sdncAdapterBuildWorkflowException(execution, callback) + } + } + + } catch (Exception e) { + callback = callback == null || String.valueOf(callback).isEmpty() ? "NONE" : callback + String msg = "Received error from SDNCAdapter: " + callback + logger.debug(getProcessKey(execution) + ': ' + msg) + exceptionUtil.buildWorkflowException(execution, 5300, msg) + } + } + + /** + * Tries to parse the response as XML to extract the information to create + * a WorkflowException. If the response cannot be parsed, a more generic + * WorkflowException is created. + */ + public void sdncAdapterBuildWorkflowException(DelegateExecution execution, String response) { + try { + String responseType = jsonUtil.getJsonRootProperty(response) + String responseCode = jsonUtil.getJsonValue(response, responseType + ".responseCode") + String responseMessage = jsonUtil.getJsonValue(response, responseType + ".responseMessage") + + String info = "" + + if (responseCode != null && !responseCode.isEmpty()) { + info += " responseCode='" + responseCode + "'" + } + + if (responseMessage != null && !responseMessage.isEmpty()) { + info += " responseMessage='" + responseMessage + "'" + } + + // Note: the mapping function handles a null or empty responseCode + int mappedResponseCode = Integer.parseInt(exceptionUtil.MapSDNCResponseCodeToErrorCode(responseCode)) + exceptionUtil.buildWorkflowException(execution, mappedResponseCode, "Received " + responseType + + " from SDNCAdapter:" + info) + } catch (Exception e) { + response = response == null || String.valueOf(response).isEmpty() ? "NONE" : response + exceptionUtil.buildWorkflowException(execution, 5300, "Received error from SDNCAdapter: " + response) + } + } + + /** + * Gets the last callback request from the execution, or null if there was no callback. + */ + public String getLastCallback(DelegateExecution execution) { + def method = getClass().getSimpleName() + '.getLastCallback(' + + 'execution=' + execution.getId() + + ')' + logger.trace('Entered ' + method) + + String prefix = execution.getVariable('prefix') + + try { + int callbackNumber = 1 + String callback = null + + while (true) { + String thisCallback = (String) execution.getVariable(prefix + 'callback' + callbackNumber) + + if (thisCallback == null) { + break + } + + callback = thisCallback + ++callbackNumber + } + + return callback + } catch (Exception e) { + String msg = 'Caught exception in ' + method + ": " + e + logger.debug(msg) + logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", + ErrorCode.UnknownError.getValue()) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + } + + /** + * Sets the timeout value to wait for the next notification. + */ + public void setTimeoutValue(DelegateExecution execution) { + def method = getClass().getSimpleName() + '.setTimeoutValue(' + + 'execution=' + execution.getId() + + ')' + logger.trace('Entered ' + method) + + String prefix = execution.getVariable('prefix') + + try { + def timeoutValue = UrnPropertiesReader.getVariable("mso.adapters.sdnc.timeout", execution) + + if (execution.getVariable(prefix + 'callback1') != null) { + // Waiting for subsequent notifications + } + } catch (Exception e) { + String msg = 'Caught exception in ' + method + ": " + e + logger.debug(msg) + logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN", + ErrorCode.UnknownError.getValue()) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + } + + public Logger getLogger() { + return logger + } } |