From dd6ec30e6a0141de5a4489b1c7c058419927d689 Mon Sep 17 00:00:00 2001 From: "Cheung, Pat (kc1472)" Date: Mon, 11 Mar 2019 17:23:05 +0000 Subject: [PATCH] Dublin yang model update PNF support in Dublin Change-Id: Icb2a00b37be11e1d0ac1b13940c0c8053a2a5b64 Issue-ID: SDNC-633 Signed-off-by: Cheung, Pat (kc1472) --- .../model/src/main/yang/GENERIC-RESOURCE-API.yang | 110 +++++++++- .../northbound/GenericResourceApiProvider.java | 224 +++++++++++++++++++++ .../sdnc/northbound/GenericResourceApiUtil.java | 13 +- .../northbound/PnfTopologyOperationRPCTest.java | 208 +++++++++++++++++++ ...icResourceApiSvcLogicServiceClientMockUtil.java | 2 + .../org/onap/sdnc/northbound/util/MDSALUtil.java | 25 +++ 6 files changed, 579 insertions(+), 3 deletions(-) create mode 100644 generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/PnfTopologyOperationRPCTest.java diff --git a/generic-resource-api/model/src/main/yang/GENERIC-RESOURCE-API.yang b/generic-resource-api/model/src/main/yang/GENERIC-RESOURCE-API.yang index 62d8c7bc..ac89e023 100644 --- a/generic-resource-api/model/src/main/yang/GENERIC-RESOURCE-API.yang +++ b/generic-resource-api/model/src/main/yang/GENERIC-RESOURCE-API.yang @@ -51,6 +51,20 @@ module GENERIC-RESOURCE-API { } } } + container pnfs { + list pnf { + key "pnf-id"; + leaf pnf-id { + type string; + mandatory true; + } + container pnf-data { + uses pnf-operation-information; + uses pnf-topology; + uses pnf-level-oper-status; + } + } + } container vnfs { list vnf { key "vnf-id"; @@ -429,6 +443,79 @@ module GENERIC-RESOURCE-API { uses oper-status-data; } } + grouping pnf-operation-information { + uses sdnc-request-header; + uses request-information; + uses service-information; + uses pnf-details; + uses pnf-request-input; + } + grouping pnf-details { + container pnf-details { + leaf pnf-id { + description "pnfId*Identifier of this Pnf information element. CORRELATIONID = PNF-NAME (A&AI)"; + type string; + mandatory true; + } + leaf pnf-type { + description "pnfType (template)*Type of Resource. NEW type: PNF (pre-defined in SDC)"; + type string; + } + leaf pnf-name { + type string; + } + uses onap-model-information; + } + } + grouping pnf-request-input { + container pnf-request-input { + leaf request-version { + description "keep this? e.g. 1702"; + type string; + } + leaf pnf-name { + type string; + } + uses region-identifier; + container pnf-input-parameters { + uses param; + } + } + } + grouping pnf-topology { + container pnf-topology { + uses pnf-topology-identifier-structure; + uses region-identifier; + uses onap-model-information; + container pnf-parameters-data { + uses param; + } + leaf sdnc-generated-cloud-resources { + description "Indicate if source is sdnc generated cloud param.When true, the parameters are literal HEAT template parameter names;When false, the parameters need to be converted to HEAT format"; + type boolean; + } + } + } + grouping pnf-topology-identifier-structure { + container pnf-topology-identifier-structure { + leaf pnf-id { + type string; + } + leaf pnf-type { + description "In preload tree, this label is used for the vf-module-type"; + type string; + } + leaf pnf-name { + description "optionally comes from pnf-request-input container or is assigned by sdn-c"; + type string; + } + } + } + grouping pnf-level-oper-status { + container pnf-level-oper-status { + uses oper-status-data; + } + } grouping vnf-operation-information { uses sdnc-request-header; uses request-information; @@ -2353,6 +2440,9 @@ module GENERIC-RESOURCE-API { enum "CreateVnfInstance"; enum "ActivateVnfInstance"; enum "DeleteVnfInstance"; + enum "CreatePnfInstance"; + enum "ActivatePnfInstance"; + enum "DeletePnfInstance"; enum "CreateVfModuleInstance"; enum "ActivateVfModuleInstance"; enum "DeleteVfModuleInstance"; @@ -2580,12 +2670,15 @@ module GENERIC-RESOURCE-API { enum "CreateNetworkInstance"; enum "ActivateNetworkInstance"; enum "DeActivateNetworkInstance"; + enum "DeleteNetworkInstance"; enum "CreateServiceInstance"; enum "DeleteServiceInstance"; - enum "DeleteNetworkInstance"; enum "CreateVnfInstance"; enum "ActivateVnfInstance"; enum "DeleteVnfInstance"; + enum "CreatePnfInstance"; + enum "ActivatePnfInstance"; + enum "DeletePnfInstance"; enum "CreateVfModuleInstance"; enum "ActivateVfModuleInstance"; enum "DeleteVfModuleInstance"; @@ -2690,6 +2783,11 @@ module GENERIC-RESOURCE-API { uses instance-reference; } } + grouping pnf-response-information { + container pnf-response-information { + uses instance-reference; + } + } grouping contrail-route-response-information { container contrail-route-response-information { uses instance-reference; @@ -3135,6 +3233,16 @@ module GENERIC-RESOURCE-API { uses service-response-information; } } + rpc pnf-topology-operation { + input { + uses pnf-operation-information; + } + output { + uses topology-response-common; + uses pnf-response-information; + uses service-response-information; + } + } rpc contrail-route-topology-operation { input { uses contrail-route-operation-information; diff --git a/generic-resource-api/provider/src/main/java/org/onap/sdnc/northbound/GenericResourceApiProvider.java b/generic-resource-api/provider/src/main/java/org/onap/sdnc/northbound/GenericResourceApiProvider.java index 8c7e1a35..2a71e6d9 100644 --- a/generic-resource-api/provider/src/main/java/org/onap/sdnc/northbound/GenericResourceApiProvider.java +++ b/generic-resource-api/provider/src/main/java/org/onap/sdnc/northbound/GenericResourceApiProvider.java @@ -96,6 +96,10 @@ import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.re import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationInputBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationOutput; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationOutputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PnfTopologyOperationInput; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PnfTopologyOperationInputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PnfTopologyOperationOutput; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PnfTopologyOperationOutputBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.brg.response.information.BrgResponseInformationBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.connection.attachment.response.information.ConnectionAttachmentResponseInformationBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.contrail.route.response.information.ContrailRouteResponseInformationBuilder; @@ -123,6 +127,7 @@ import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.re import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.tunnelxconn.response.information.TunnelxconnResponseInformationBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.vf.module.response.information.VfModuleResponseInformationBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.vnf.response.information.VnfResponseInformationBuilder; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.pnf.response.information.PnfResponseInformationBuilder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; @@ -184,6 +189,7 @@ public class GenericResourceApiProvider implements AutoCloseable, GENERICRESOURC private static final String SERVICE_OBJECT_PATH_PARAM = "service-object-path"; private static final String NETWORK_OBJECT_PATH_PARAM = "network-object-path"; private static final String VNF_OBJECT_PATH_PARAM = "vnf-object-path"; + private static final String PNF_OBJECT_PATH_PARAM = "pnf-object-path"; private static final String VF_MODULE_OBJECT_PATH_PARAM = "vf-module-object-path"; private static final String UPDATING_MDSAL_ERROR_MESSAGE = "Caught Exception updating MD-SAL for {} [{}] \n"; private static final String UPDATING_MDSAL_ERROR_MESSAGE_2 = "Caught Exception updating MD-SAL for {} [{},{}] \n"; @@ -782,6 +788,224 @@ public class GenericResourceApiProvider implements AutoCloseable, GENERICRESOURC return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null; } + + @Override + public ListenableFuture> pnfTopologyOperation(PnfTopologyOperationInput input) { + + final String svcOperation = "pnf-topology-operation"; + ServiceData serviceData; + ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder(); + Properties properties = new Properties(); + + log.info(CALLED_STR, svcOperation); + // create a new response object + PnfTopologyOperationOutputBuilder responseBuilder = new PnfTopologyOperationOutputBuilder(); + + if (hasInvalidServiceId(input)) { + log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation); + responseBuilder.setResponseCode("404"); + responseBuilder.setResponseMessage(NULL_OR_EMPTY_ERROR_PARAM); + responseBuilder.setAckFinalIndicator("Y"); + RpcResult rpcResult = RpcResultBuilder.status(true) + .withResult(responseBuilder.build()).build(); + // return error + return Futures.immediateFuture(rpcResult); + } + + // Grab the service instance ID from the input buffer + String siid = input.getServiceInformation().getServiceInstanceId(); + + trySetSvcRequestId(input, responseBuilder); + + /* Comment out mandatory check for pnf id for scenario wherein for assign/create request pnf-id is generated by + SDNC itself. + if (hasInvalidPnfId(input)) { + log.debug("exiting {} because of null or empty pnf-id", svcOperation); + responseBuilder.setResponseCode("404"); + responseBuilder.setResponseMessage("invalid input, null or empty pnf-id"); + responseBuilder.setAckFinalIndicator("Y"); + + RpcResult rpcResult = RpcResultBuilder.status(true) + .withResult(responseBuilder.build()).build(); + + return Futures.immediateFuture(rpcResult); + } + */ + + String pnfId = input.getPnfDetails().getPnfId(); + ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder(); + getServiceData(siid, serviceDataBuilder); + + ServiceDataBuilder operDataBuilder = new ServiceDataBuilder(); + getServiceData(siid, operDataBuilder, LogicalDatastoreType.OPERATIONAL); + + // Set the serviceStatus based on input + setServiceStatus(serviceStatusBuilder, input.getSdncRequestHeader()); + setServiceStatus(serviceStatusBuilder, input.getRequestInformation()); + + // + // setup a service-data object builder + // ACTION pnf-topology-operation + // INPUT: + // USES sdnc-request-header; + // USES request-information; + // USES service-information; + // USES pnf-details + // OUTPUT: + // USES pnf-topology-response-body; + // USES pnf-details + // USES service-information + // + // uses oper-status; + + log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input); + PnfTopologyOperationInputBuilder inputBuilder = new PnfTopologyOperationInputBuilder(input); + GenericResourceApiUtil.toProperties(properties, inputBuilder.build()); + + log.info(ADDING_OPERATIONAL_DATA_LOG, svcOperation, siid, operDataBuilder.build()); + GenericResourceApiUtil.toProperties(properties, OPERATIONAL_DATA_PARAM, operDataBuilder); + + // Call SLI sync method + + ResponseObject responseObject = new ResponseObject("200", ""); + String ackFinal = "Y"; + String serviceObjectPath = null; + String pnfObjectPath = null; + Properties respProps = tryGetProperties(svcOperation, properties, serviceDataBuilder, responseObject); + + if (respProps != null) { + responseObject.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM)); + responseObject.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM)); + ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y"); + if (pnfId == null) { + pnfId = respProps.getProperty("pnfId"); + } + serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM); + pnfObjectPath = respProps.getProperty(PNF_OBJECT_PATH_PARAM); + } + + setServiceStatus(serviceStatusBuilder, responseObject.getStatusCode(), responseObject.getMessage(), ackFinal); + serviceStatusBuilder.setRequestStatus(RequestStatus.Synccomplete); + serviceStatusBuilder.setRpcName(svcOperation); + + if (failed(responseObject)) { + responseBuilder.setResponseCode(responseObject.getStatusCode()); + responseBuilder.setResponseMessage(responseObject.getMessage()); + responseBuilder.setAckFinalIndicator(ackFinal); + + ServiceBuilder serviceBuilder = new ServiceBuilder(); + serviceBuilder.setServiceInstanceId(siid); + serviceBuilder.setServiceStatus(serviceStatusBuilder.build()); + try { + saveService(serviceBuilder.build(), true, LogicalDatastoreType.CONFIGURATION); + trySaveService(input, serviceBuilder); + } catch (Exception e) { + log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e); + } + log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build()); + + RpcResult rpcResult = RpcResultBuilder.status(true) + .withResult(responseBuilder.build()).build(); + + // return error + return Futures.immediateFuture(rpcResult); + } + + // Got success from SLI + try { + serviceData = serviceDataBuilder.build(); + log.info(UPDATING_MDSAL_INFO_MESSAGE, svcOperation, siid, serviceData); + + // service object + ServiceBuilder serviceBuilder = new ServiceBuilder(); + serviceBuilder.setServiceData(serviceData); + serviceBuilder.setServiceInstanceId(siid); + serviceBuilder.setServiceStatus(serviceStatusBuilder.build()); + saveService(serviceBuilder.build(), false, LogicalDatastoreType.CONFIGURATION); + + if (isValidRequest(input) && input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate)) { + // Only update operational tree on Assign + log.info(UPDATING_TREE_INFO_MESSAGE); + saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL); + } + + ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder(); + serviceResponseInformationBuilder.setInstanceId(siid); + serviceResponseInformationBuilder.setObjectPath(serviceObjectPath); + responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build()); + + PnfResponseInformationBuilder pnfResponseInformationBuilder = new PnfResponseInformationBuilder(); + pnfResponseInformationBuilder.setInstanceId(pnfId); + pnfResponseInformationBuilder.setObjectPath(pnfObjectPath); + responseBuilder.setPnfResponseInformation(pnfResponseInformationBuilder.build()); + + } catch (Exception e) { + log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e); + responseBuilder.setResponseCode("500"); + responseBuilder.setResponseMessage(e.getMessage()); + responseBuilder.setAckFinalIndicator("Y"); + log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build()); + + RpcResult rpcResult = RpcResultBuilder.status(true) + .withResult(responseBuilder.build()).build(); + + return Futures.immediateFuture(rpcResult); + } + + // Update succeeded + responseBuilder.setResponseCode(responseObject.getStatusCode()); + responseBuilder.setAckFinalIndicator(ackFinal); + trySetResponseMessage(responseBuilder, responseObject); + log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid); + log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build()); + + RpcResult rpcResult = RpcResultBuilder.status(true) + .withResult(responseBuilder.build()).build(); + + // return success + return Futures.immediateFuture(rpcResult); + } + + private void trySetResponseMessage(PnfTopologyOperationOutputBuilder responseBuilder, + ResponseObject responseObject) { + if (responseObject.getMessage() != null) { + responseBuilder.setResponseMessage(responseObject.getMessage()); + } + } + + private void trySaveService(PnfTopologyOperationInput input, ServiceBuilder serviceBuilder) { + if (isValidRequest(input) && (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Delete) + || input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate))) { + + // Only update operational tree on activate or delete + log.info(UPDATING_TREE_INFO_MESSAGE); + saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL); + } + } + + private boolean hasInvalidPnfId(PnfTopologyOperationInput input) { + return input.getPnfDetails() == null || input.getPnfDetails().getPnfId() == null + || input.getPnfDetails().getPnfId().length() == 0; + } + + private boolean hasInvalidServiceId(PnfTopologyOperationInput input) { + return input == null || input.getServiceInformation() == null + || input.getServiceInformation().getServiceInstanceId() == null + || input.getServiceInformation().getServiceInstanceId().length() == 0; + } + + private void trySetSvcRequestId(PnfTopologyOperationInput input, + PnfTopologyOperationOutputBuilder responseBuilder) { + if (input.getSdncRequestHeader() != null) { + responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId()); + } + } + + private boolean isValidRequest(PnfTopologyOperationInput input) { + return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null; + } + + @Override public ListenableFuture> vnfTopologyOperation(VnfTopologyOperationInput input) { diff --git a/generic-resource-api/provider/src/main/java/org/onap/sdnc/northbound/GenericResourceApiUtil.java b/generic-resource-api/provider/src/main/java/org/onap/sdnc/northbound/GenericResourceApiUtil.java index 0ad9ac1c..63979833 100644 --- a/generic-resource-api/provider/src/main/java/org/onap/sdnc/northbound/GenericResourceApiUtil.java +++ b/generic-resource-api/provider/src/main/java/org/onap/sdnc/northbound/GenericResourceApiUtil.java @@ -112,7 +112,16 @@ public class GenericResourceApiUtil extends MdsalHelper { org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.vnf.resource.assignments.vnf.resource.assignments.vnf.networks.VnfNetworkBuilder u105 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.vnf.resource.assignments.vnf.resource.assignments.vnf.networks.VnfNetworkBuilder(); org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.vnf.response.information.VnfResponseInformationBuilder u106 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.vnf.response.information.VnfResponseInformationBuilder(); org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.vnf.topology.identifier.structure.VnfTopologyIdentifierStructureBuilder u107 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.vnf.topology.identifier.structure.VnfTopologyIdentifierStructureBuilder(); - org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationInputBuilder u110 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationInputBuilder(); - org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationOutputBuilder u111 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationOutputBuilder(); + org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationInputBuilder u108 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationInputBuilder(); + org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationOutputBuilder u109 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationOutputBuilder(); + org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.data.service.data.PnfsBuilder u110 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.data.service.data.PnfsBuilder(); + org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.data.service.data.pnfs.PnfBuilder u111 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.data.service.data.pnfs.PnfBuilder(); + org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.data.service.data.pnfs.pnf.PnfDataBuilder u112 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.data.service.data.pnfs.pnf.PnfDataBuilder(); + org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.pnf.request.input.PnfRequestInputBuilder u113 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.pnf.request.input.PnfRequestInputBuilder(); + org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.pnf.request.input.pnf.request.input.PnfInputParametersBuilder u114 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.pnf.request.input.pnf.request.input.PnfInputParametersBuilder(); + org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.pnf.response.information.PnfResponseInformationBuilder u115 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.pnf.response.information.PnfResponseInformationBuilder(); + org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.pnf.topology.identifier.structure.PnfTopologyIdentifierStructureBuilder u116 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.pnf.topology.identifier.structure.PnfTopologyIdentifierStructureBuilder(); + org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PnfTopologyOperationInputBuilder u117 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PnfTopologyOperationInputBuilder(); + org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PnfTopologyOperationOutputBuilder u118 = new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PnfTopologyOperationOutputBuilder(); } } diff --git a/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/PnfTopologyOperationRPCTest.java b/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/PnfTopologyOperationRPCTest.java new file mode 100644 index 00000000..60a0e1fc --- /dev/null +++ b/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/PnfTopologyOperationRPCTest.java @@ -0,0 +1,208 @@ +package org.onap.sdnc.northbound; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.onap.sdnc.northbound.GenericResourceApiProvider.APP_NAME; +import static org.onap.sdnc.northbound.GenericResourceApiProvider.NO_SERVICE_LOGIC_ACTIVE; +import static org.onap.sdnc.northbound.GenericResourceApiProvider.NULL_OR_EMPTY_ERROR_PARAM; +import static org.onap.sdnc.northbound.util.MDSALUtil.build; +import static org.onap.sdnc.northbound.util.MDSALUtil.exec; +import static org.onap.sdnc.northbound.util.MDSALUtil.requestInformation; +import static org.onap.sdnc.northbound.util.MDSALUtil.sdncRequestHeader; +import static org.onap.sdnc.northbound.util.MDSALUtil.serviceInformationBuilder; +import static org.onap.sdnc.northbound.util.MDSALUtil.serviceResponseInformation; +import static org.onap.sdnc.northbound.util.MDSALUtil.pnfDetailsBuilder; +import static org.onap.sdnc.northbound.util.MDSALUtil.pnfResponseInformation; +import static org.onap.sdnc.northbound.util.MDSALUtil.pnfTopologyOperationInput; +import static org.onap.sdnc.northbound.util.MDSALUtil.pnfTopologyOperationOutput; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.onap.sdnc.northbound.util.PropBuilder; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.TransactionChainClosedException; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PnfTopologyOperationInput; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PnfTopologyOperationOutput; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.request.information.RequestInformation; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader.SvcAction; +import org.opendaylight.yangtools.yang.common.RpcResult; + +@RunWith(MockitoJUnitRunner.class) +public class PnfTopologyOperationRPCTest extends GenericResourceApiProviderTest { + + private static final String SVC_OPERATION = "pnf-topology-operation"; + + @Before + public void setUp() throws Exception { + super.setUp(); + svcClient.setScvOperation(SVC_OPERATION); + } + + @Test + public void should_fail_when_service_info_not_present() throws Exception { + + PnfTopologyOperationInput input = build(pnfTopologyOperationInput()); + + PnfTopologyOperationOutput output = + exec(genericResourceApiProvider::pnfTopologyOperation, input, RpcResult::getResult); + + assertEquals("404", output.getResponseCode()); + assertEquals(NULL_OR_EMPTY_ERROR_PARAM, output.getResponseMessage()); + assertEquals("Y", output.getAckFinalIndicator()); + } + + + /* + @Test + public void should_fail_when_invalid_pnf_id() throws Exception { + + PnfTopologyOperationInput input = build(pnfTopologyOperationInput() + .setServiceInformation(build(serviceInformationBuilder(). + setServiceInstanceId("test-service-instance-id") + )) + ); + + PnfTopologyOperationOutput output = + exec(genericResourceApiProvider::pnfTopologyOperation, input, RpcResult::getResult); + + assertEquals("404", output.getResponseCode()); + assertEquals("invalid input, null or empty pnf-id", output.getResponseMessage()); + assertEquals("Y", output.getAckFinalIndicator()); + }*/ + + + @Test + public void should_fail_when_client_execution_failed() throws Exception { + + svcClient.mockHasGraph(true); + svcClient.mockExecute(new RuntimeException("test exception")); + + PnfTopologyOperationInput input = build(pnfTopologyOperationInput() + .setServiceInformation(build(serviceInformationBuilder() + .setServiceInstanceId("test-service-instance-id") + )) + .setPnfDetails(build(pnfDetailsBuilder() + .setPnfId("test-pnf-id") + )) + ); + + PnfTopologyOperationOutput output = + exec(genericResourceApiProvider::pnfTopologyOperation, input, RpcResult::getResult); + + assertEquals("500", output.getResponseCode()); + assertEquals("test exception", output.getResponseMessage()); + assertEquals("Y", output.getAckFinalIndicator()); + } + + @Test + public void should_fail_when_client_has_no_graph() throws Exception { + + svcClient.mockHasGraph(false); + + PnfTopologyOperationInput input = build(pnfTopologyOperationInput() + .setServiceInformation(build(serviceInformationBuilder() + .setServiceInstanceId("test-service-instance-id") + )) + .setPnfDetails(build(pnfDetailsBuilder() + .setPnfId("test-pnf-id") + )) + ); + + PnfTopologyOperationOutput output = + exec(genericResourceApiProvider::pnfTopologyOperation, input, RpcResult::getResult); + + assertEquals("503", output.getResponseCode()); + assertEquals(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + SVC_OPERATION + "'", output.getResponseMessage()); + assertEquals("Y", output.getAckFinalIndicator()); + } + + @Test + public void should_fail_when_failed_to_update_mdsal() throws Exception { + + PropBuilder svcResultProp = svcClient.createExecuteOKResult(); + svcClient.mockExecute(svcResultProp); + svcClient.mockHasGraph(true); + WriteTransaction mockWriteTransaction = mock(WriteTransaction.class); + when(mockWriteTransaction.submit()).thenThrow(new TransactionChainClosedException("test exception")); + + DataBroker spyDataBroker = Mockito.spy(dataBroker); + when(spyDataBroker.newWriteOnlyTransaction()).thenReturn(mockWriteTransaction); + genericResourceApiProvider.setDataBroker(spyDataBroker); + + PnfTopologyOperationInput input = build(pnfTopologyOperationInput() + .setServiceInformation(build(serviceInformationBuilder() + .setServiceInstanceId("test-service-instance-id") + )) + .setPnfDetails(build(pnfDetailsBuilder() + .setPnfId("test-pnf-id") + )) + ); + + PnfTopologyOperationOutput output = + exec(genericResourceApiProvider::pnfTopologyOperation, input, RpcResult::getResult); + + assertEquals("500", output.getResponseCode()); + assertEquals("test exception", output.getResponseMessage()); + assertEquals("Y", output.getAckFinalIndicator()); + } + + @Test + public void should_complete_with_success_when_no_errors() throws Exception { + + svcClient.mockHasGraph(true); + PropBuilder svcResultProp = svcClient.createExecuteOKResult(); + svcClient.mockExecute(svcResultProp); + + PnfTopologyOperationInput input = build(pnfTopologyOperationInput() + .setSdncRequestHeader(build(sdncRequestHeader() + .setSvcRequestId("test-svc-request-id") + .setSvcAction(SvcAction.Assign) + )) + .setRequestInformation(build(requestInformation() + .setRequestId("test-request-id") + .setRequestAction(RequestInformation.RequestAction.CreateServiceInstance) + )) + .setServiceInformation(build(serviceInformationBuilder() + .setServiceInstanceId("test-service-instance-id") + )) + .setPnfDetails(build(pnfDetailsBuilder() + .setPnfId("test-pnf-id") + )) + ); + + PnfTopologyOperationOutput output = + exec(genericResourceApiProvider::pnfTopologyOperation, input, RpcResult::getResult); + + assertEquals("200", output.getResponseCode()); + assertEquals("OK", output.getResponseMessage()); + assertEquals("Y", output.getAckFinalIndicator()); + + PnfTopologyOperationOutput expectedPnfTopologyOperationOutput = createExpectedOutput(svcResultProp, + input); + assertEquals(expectedPnfTopologyOperationOutput, output); + } + + private PnfTopologyOperationOutput createExpectedOutput(PropBuilder svcResultProp, + PnfTopologyOperationInput pnfTopologyOperationInput) { + return build( + pnfTopologyOperationOutput() + .setSvcRequestId(pnfTopologyOperationInput.getSdncRequestHeader().getSvcRequestId()) + .setResponseCode(svcResultProp.get(svcClient.errorCode)) + .setAckFinalIndicator(svcResultProp.get(svcClient.ackFinal)) + .setResponseMessage(svcResultProp.get(svcClient.errorMessage)) + .setServiceResponseInformation(build(serviceResponseInformation() + .setInstanceId(pnfTopologyOperationInput.getServiceInformation().getServiceInstanceId()) + .setObjectPath(svcResultProp.get(svcClient.serviceObjectPath)) + )) + .setPnfResponseInformation(build(pnfResponseInformation() + .setInstanceId(pnfTopologyOperationInput.getPnfDetails().getPnfId()) + .setObjectPath(svcResultProp.get(svcClient.pnfObjectPath)) + )) + ); + } +} diff --git a/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/util/GenericResourceApiSvcLogicServiceClientMockUtil.java b/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/util/GenericResourceApiSvcLogicServiceClientMockUtil.java index 36c6c7ff..b0cd627e 100644 --- a/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/util/GenericResourceApiSvcLogicServiceClientMockUtil.java +++ b/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/util/GenericResourceApiSvcLogicServiceClientMockUtil.java @@ -50,6 +50,7 @@ public class GenericResourceApiSvcLogicServiceClientMockUtil { public final String ackFinal = "ack-final"; public final String serviceObjectPath = "service-object-path"; public final String networkObjectPath = "network-object-path"; + public final String pnfObjectPath = "pnf-object-path"; public final String vnfObjectPath = "vnf-object-path"; public final String vfModuleObjectPath = "vf-module-object-path"; public final String networkId = "networkId"; @@ -98,6 +99,7 @@ public class GenericResourceApiSvcLogicServiceClientMockUtil { .set(ackFinal, "Y") .set(serviceObjectPath, "serviceObjectPath: XYZ") .set(networkObjectPath, "networkObjectPath: XYZ") + .set(pnfObjectPath, "pnfObjectPath: XYZ") .set(vnfObjectPath, "vnfObjectPath: XYZ") .set(vfModuleObjectPath, "vfModuleObjectPath: XYZ") .set(networkId, "networkId: XYZ"); diff --git a/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/util/MDSALUtil.java b/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/util/MDSALUtil.java index 9ed690ca..d959b9f2 100644 --- a/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/util/MDSALUtil.java +++ b/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/util/MDSALUtil.java @@ -46,6 +46,8 @@ import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.re import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VfModuleTopologyOperationOutputBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationInputBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationOutputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PnfTopologyOperationInputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PnfTopologyOperationOutputBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.brg.response.information.BrgResponseInformationBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.connection.attachment.response.information.ConnectionAttachmentResponseInformationBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.contrail.route.response.information.ContrailRouteResponseInformationBuilder; @@ -71,6 +73,9 @@ import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.re import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.vnf.information.VnfInformationBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.vnf.response.information.VnfResponseInformationBuilder; import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.vnf.topology.identifier.structure.VnfTopologyIdentifierStructureBuilder; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.pnf.details.PnfDetailsBuilder; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.pnf.response.information.PnfResponseInformationBuilder; +import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.pnf.topology.identifier.structure.PnfTopologyIdentifierStructureBuilder; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.common.RpcResult; @@ -158,6 +163,14 @@ public class MDSALUtil { return new VfModuleTopologyOperationOutputBuilder(); } + public static PnfTopologyOperationInputBuilder pnfTopologyOperationInput() { + return new PnfTopologyOperationInputBuilder(); + } + + public static PnfTopologyOperationOutputBuilder pnfTopologyOperationOutput() { + return new PnfTopologyOperationOutputBuilder(); + } + public static VnfTopologyOperationInputBuilder vnfTopologyOperationInput() { return new VnfTopologyOperationInputBuilder(); } @@ -204,6 +217,10 @@ public class MDSALUtil { return new ContrailRouteResponseInformationBuilder(); } + public static PnfResponseInformationBuilder pnfResponseInformation() { + return new PnfResponseInformationBuilder(); + } + public static VnfResponseInformationBuilder vnfResponseInformation() { return new VnfResponseInformationBuilder(); } @@ -224,6 +241,10 @@ public class MDSALUtil { return new NetworkTopologyIdentifierStructureBuilder(); } + public static PnfDetailsBuilder pnfDetailsBuilder() { + return new PnfDetailsBuilder(); + } + public static VnfInformationBuilder vnfInformationBuilder() { return new VnfInformationBuilder(); } @@ -256,6 +277,10 @@ public class MDSALUtil { return new NetworkTopologyOperationOutputBuilder(); } + public static PnfTopologyIdentifierStructureBuilder pnfTopologyIdentifierStructureBuilder() { + return new PnfTopologyIdentifierStructureBuilder(); + } + public static VnfTopologyIdentifierStructureBuilder vnfTopologyIdentifierStructureBuilder() { return new VnfTopologyIdentifierStructureBuilder(); } -- 2.16.6