Merge "Fix VNF-API yang validation issues"
authorDan Timoney <dtimoney@att.com>
Wed, 27 Sep 2017 07:50:34 +0000 (07:50 +0000)
committerGerrit Code Review <gerrit@onap.org>
Wed, 27 Sep 2017 07:50:34 +0000 (07:50 +0000)
generic-resource-api/features/src/main/resources/features.xml
generic-resource-api/model/src/main/yang/GENERIC-RESOURCE-API.yang
generic-resource-api/provider/pom.xml
generic-resource-api/provider/src/main/java/org/onap/sdnc/northbound/GenericResourceApiProvider.java
generic-resource-api/provider/src/main/java/org/onap/sdnc/northbound/GenericResourceApiUtil.java
generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/TestGenericResourceApi.java [new file with mode: 0644]
vnfapi/features/src/main/resources/features.xml
vnfapi/provider/src/main/java/org/onap/sdnc/vnfapi/VnfSdnUtil.java

index ac7a1d0..ccf6032 100644 (file)
@@ -6,7 +6,7 @@
 
     <feature name='GENERIC-RESOURCE-API' description="generic-resource-api.GENERIC-RESOURCE-API" version='${project.version}'>
         <feature version="${odl.controller.mdsal.version}">odl-mdsal-broker</feature>
-        <feature version="${sdnctl.sli.version}">sdnc-sli</feature>
+        <feature>sdnc-sli</feature>
         <!-- It is assumed that applications are installed on BVC, which installs bvc-core including MD-SAL etc.
              Do not list those features out here as that will tie your implementation to a specific version
              of MD-SAL / BVC and force updates to your application for every upgrade of BVC core platform.-->
index 233fbaf..4340ae4 100644 (file)
@@ -160,7 +160,7 @@ module GENERIC-RESOURCE-API {
    grouping service-topology {\r
       container service-topology {\r
          uses service-topology-identifier;\r
-         uses ecomp-model-information;\r
+         uses onap-model-information;\r
          uses service-assignments;\r
          uses service-parameters;\r
       }\r
@@ -225,7 +225,7 @@ module GENERIC-RESOURCE-API {
          leaf network-type {\r
             type string;\r
          }\r
-         uses ecomp-model-information;\r
+         uses onap-model-information;\r
       }\r
    }\r
    grouping network-request-input {\r
@@ -243,7 +243,7 @@ module GENERIC-RESOURCE-API {
       container network-topology {\r
          uses network-topology-identifier-structure;\r
          uses region-identifier;\r
-         uses ecomp-model-information;\r
+         uses onap-model-information;\r
          uses network-assignments;\r
          uses network-parameters;\r
       }\r
@@ -313,7 +313,7 @@ module GENERIC-RESOURCE-API {
             description "vnf-model-id in Pats model?in Pats vnf submodule, contained within vnf-instance-topology-identifier grouping (along with vnf-name and vnf-instance-id)";\r
             type string;\r
          }\r
-         uses ecomp-model-information;\r
+         uses onap-model-information;\r
       }\r
    }\r
    grouping vnf-request-input {\r
@@ -342,7 +342,7 @@ module GENERIC-RESOURCE-API {
       container vnf-topology {\r
          uses vnf-topology-identifier-structure;\r
          uses region-identifier;\r
-         uses ecomp-model-information;\r
+         uses onap-model-information;\r
          uses vnf-resource-assignments;\r
          container vnf-parameters-data {\r
             uses param;\r
@@ -458,7 +458,7 @@ module GENERIC-RESOURCE-API {
          leaf vf-module-type {\r
             type string;\r
          }\r
-         uses ecomp-model-information;\r
+         uses onap-model-information;\r
       }\r
    }\r
    grouping vf-module-request-input {\r
@@ -480,7 +480,7 @@ module GENERIC-RESOURCE-API {
       container vf-module-topology {\r
          uses vf-module-topology-identifier;\r
          uses region-identifier;\r
-         uses ecomp-model-information;\r
+         uses onap-model-information;\r
          uses vf-module-assignments;\r
          container vf-module-parameters {\r
             uses param;\r
@@ -691,7 +691,7 @@ module GENERIC-RESOURCE-API {
    grouping contrail-route-topology {\r
       container contrail-route-topology {\r
          uses allotted-resource-identifiers;\r
-         uses ecomp-model-information;\r
+         uses onap-model-information;\r
          uses contrail-route-assignments;\r
          container contrail-route-parameters {\r
             uses param;\r
@@ -762,7 +762,7 @@ module GENERIC-RESOURCE-API {
    grouping security-zone-topology {\r
       container security-zone-topology {\r
          uses allotted-resource-identifiers;\r
-         uses ecomp-model-information;\r
+         uses onap-model-information;\r
          uses security-zone-assignments;\r
          container security-zone-parameters {\r
             uses param;\r
@@ -798,6 +798,75 @@ module GENERIC-RESOURCE-API {
          }\r
       }\r
    }\r
+   grouping tunnelxconn-operation-information {\r
+       uses sdnc-request-header;\r
+       uses request-information;\r
+       uses service-information;\r
+       uses allotted-resource-information;\r
+       uses tunnelxconn-request-input;\r
+   }\r
+   grouping tunnelxconn-request-input {\r
+       leaf brg-wan-mac-address {\r
+           type string;\r
+       }\r
+   }\r
+   grouping tunnelxconn-topology {\r
+       container tunnelxconn-topology {\r
+           uses allotted-resource-identifiers;\r
+           uses onap-model-information;\r
+           uses tunnelxconn-assignments;\r
+           container tunnelxconn-parameters {\r
+               uses param;\r
+           }\r
+       }\r
+   }\r
+   grouping tunnelxconn-assignments {\r
+       leaf vni {\r
+           description "The Network Controller will assign a VNI value from the associated vGMUX VNI pool";\r
+           type string;\r
+       }\r
+       leaf vgmux-bearer-ip {\r
+           description "The Network Controller will look up the vgmux bearer ip from the vgmux vf module";\r
+           type inet:ip-address;\r
+       }\r
+       leaf vgmux-lan-up {\r
+           description "The Network Controller will look up the vgmux lan ip from the vgmux vg module";\r
+           type inet:ip-address;\r
+       }\r
+   }\r
+   grouping brg-operation-information {\r
+       uses sdnc-request-header;\r
+       uses request-information;\r
+       uses service-information;\r
+       uses allotted-resource-information;\r
+       uses brg-request-input;\r
+   }\r
+   grouping brg-request-input {\r
+       leaf vgmux-bearer-ip {\r
+           type inet:ip-address;\r
+       }\r
+       leaf vni {\r
+           type string;\r
+       }\r
+       leaf brg-wan-ip-address {\r
+           type inet:ip-address;\r
+       }\r
+   }\r
+   grouping brg-topology {\r
+       container brg-topology {\r
+           uses allotted-resource-identifiers;\r
+           uses onap-model-information;\r
+           uses brg-assignments;\r
+           container brg-parameters {\r
+               uses param;\r
+           }\r
+       }\r
+   }\r
+   grouping brg-assignments {\r
+       leaf vbrg-wan-ip {\r
+           type inet:ip-address;\r
+       }\r
+   }\r
    grouping allotted-resource-information {\r
       container allotted-resource-information {\r
          leaf allotted-resource-id {\r
@@ -811,7 +880,7 @@ module GENERIC-RESOURCE-API {
             description "Service-instance-id of the parent service to which this allotted resource belongs.";\r
             type string;\r
          }\r
-         uses ecomp-model-information;\r
+         uses onap-model-information;\r
       }\r
    }\r
    grouping allotted-resource-identifiers {\r
@@ -978,7 +1047,7 @@ module GENERIC-RESOURCE-API {
             description "used to reference a&ai subscription-service-type. For example, we show as vIPR-ATM in example.";\r
             type string;\r
          }\r
-         uses ecomp-model-information;\r
+         uses onap-model-information;\r
          leaf service-instance-id {\r
             type string;\r
          }\r
@@ -992,8 +1061,8 @@ module GENERIC-RESOURCE-API {
          }\r
       }\r
    }\r
-   grouping ecomp-model-information {\r
-      container ecomp-model-information {\r
+   grouping onap-model-information {\r
+      container onap-model-information {\r
          leaf model-invariant-uuid {\r
             description "identifies the invariant uuid for this service or resource";\r
             type string;\r
@@ -1144,6 +1213,16 @@ module GENERIC-RESOURCE-API {
          uses instance-reference;\r
       }\r
    }\r
+   grouping tunnelxconn-response-information {\r
+       container tunnelxconn-response-information {\r
+           uses instance-reference;\r
+       }\r
+   }\r
+   grouping brg-response-information {\r
+       container brg-response-information {\r
+           uses instance-reference;\r
+       }\r
+   }\r
    grouping preload-model-information {\r
       list vnf-preload-list {\r
          key "vnf-name vnf-type";\r
@@ -1229,7 +1308,7 @@ module GENERIC-RESOURCE-API {
             }\r
          }\r
          list vnf-networks {\r
-            key "";\r
+            key "network-role";\r
             uses vnf-network;\r
             uses sriov-vlan-filter-list;\r
          }\r
@@ -1253,7 +1332,7 @@ module GENERIC-RESOURCE-API {
             }\r
          }\r
          list vm-networks {\r
-            key "";\r
+            key "network-role";\r
             uses vm-network;\r
          }\r
       }\r
@@ -1584,6 +1663,46 @@ module GENERIC-RESOURCE-API {
          uses allotted-resource-status;\r
       }\r
    }\r
+   container tunnelxconn-allotted-resources {\r
+       list tunnelxconn-allotted-resource {\r
+           key "allotted-resource-id";\r
+           leaf allotted-resource-id {\r
+               type string;\r
+               mandatory true;\r
+           }\r
+           container allotted-resource-data {\r
+               container allotted-resource-operation-information {\r
+                   uses tunnelxconn-operation-information;\r
+               }\r
+               uses tunnelxconn-topology;\r
+               container tunnelxconn-parameters {\r
+                   uses param;\r
+               }\r
+               uses allotted-resource-oper-status;\r
+           }\r
+           uses allotted-resource-status;\r
+       }\r
+   }\r
+   container brg-allotted-respources {\r
+       list brg-allotted-resource {\r
+           key "allotted-resource-id";\r
+           leaf allotted-resource-id {\r
+               type string;\r
+               mandatory true;\r
+           }\r
+           container allotted-resource-data {\r
+               container allotted-resource-operation-information {\r
+                   uses brg-operation-information;\r
+               }\r
+               uses brg-topology;\r
+               container brg-parameters {\r
+                   uses param;\r
+               }\r
+               uses allotted-resource-oper-status;\r
+           }\r
+           uses allotted-resource-status;\r
+       }\r
+   }\r
    rpc service-topology-operation {\r
       input {\r
          uses service-operation-information;\r
@@ -1644,6 +1763,26 @@ module GENERIC-RESOURCE-API {
          uses service-response-information;\r
       }\r
    }\r
+   rpc tunnelxconn-topology-operation {\r
+       input {\r
+           uses tunnelxconn-operation-information;\r
+       }\r
+       output {\r
+           uses topology-response-common;\r
+           uses tunnelxconn-response-information;\r
+           uses service-response-information;\r
+       }\r
+   }\r
+   rpc brg-topology-operation {\r
+       input {\r
+           uses brg-operation-information;\r
+       }\r
+       output {\r
+           uses topology-response-common;\r
+           uses brg-response-information;\r
+           uses service-response-information;\r
+       }\r
+   }\r
    container preload-vnfs {\r
       uses preload-model-information;\r
    }\r
@@ -1667,4 +1806,5 @@ module GENERIC-RESOURCE-API {
          uses vnf-topology-response-body;\r
       }\r
    }\r
+\r
 } ////closes the module\r
index c3f61c9..2f4a25f 100644 (file)
@@ -37,7 +37,6 @@
                        <version>${odl.mdsal.version}</version>
                </dependency>
 
-        <!--
                <dependency>
                        <groupId>org.opendaylight.controller</groupId>
                        <artifactId>sal-test-model</artifactId>
                <dependency>
                        <groupId>org.opendaylight.controller</groupId>
                        <artifactId>sal-binding-broker-impl</artifactId>
-                       <version>${odl.mdsal.version}}</version>
+                       <version>${odl.mdsal.version}</version>
                        <type>test-jar</type>
                        <classifier>tests</classifier>
                        <scope>test</scope>
                </dependency>
-        -->
+
                <dependency>
                        <groupId>org.apache.commons</groupId>
                        <artifactId>commons-lang3</artifactId>
                <dependency>
                        <groupId>junit</groupId>
                        <artifactId>junit</artifactId>
-                       <version>3.8.1</version>
+                       <version>${junit.version}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.mockito</groupId>
+                       <artifactId>mockito-core</artifactId>
+                       <version>${mockito.version}</version>
                        <scope>test</scope>
                </dependency>
        </dependencies>
index 0176aca..a0b0862 100644 (file)
@@ -19,6 +19,10 @@ import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedEx
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.BrgTopologyOperationInput;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.BrgTopologyOperationInputBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.BrgTopologyOperationOutput;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.BrgTopologyOperationOutputBuilder;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ContrailRouteTopologyOperationInput;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ContrailRouteTopologyOperationInputBuilder;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ContrailRouteTopologyOperationOutput;
@@ -48,6 +52,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.ServiceTopologyOperationOutputBuilder;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.Services;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServicesBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.TunnelxconnTopologyOperationInput;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.TunnelxconnTopologyOperationInputBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.TunnelxconnTopologyOperationOutput;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.TunnelxconnTopologyOperationOutputBuilder;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VfModuleTopologyOperationInput;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VfModuleTopologyOperationInputBuilder;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VfModuleTopologyOperationOutput;
@@ -56,6 +64,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.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.brg.response.information.BrgResponseInformationBuilder;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.contrail.route.response.information.ContrailRouteResponseInformationBuilder;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.network.response.information.NetworkResponseInformationBuilder;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.preload.data.PreloadData;
@@ -76,6 +85,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.service.status.ServiceStatus.RequestStatus;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatus.RpcAction;
 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatusBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.tunnelxconn.response.information.TunnelxconnResponseInformationBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
@@ -1698,6 +1708,356 @@ public class GenericResourceApiProvider implements AutoCloseable, GENERICRESOURC
                return Futures.immediateFuture(rpcResult);
        }
 
+       @Override
+       public Future<RpcResult<TunnelxconnTopologyOperationOutput>> tunnelxconnTopologyOperation(
+                       TunnelxconnTopologyOperationInput input) {
+
+               final String SVC_OPERATION = "tunnelxconn-topology-operation";
+               ServiceData serviceData;
+               ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
+               Properties parms = new Properties();
+
+               log.info("{} called.", SVC_OPERATION);
+               // create a new response object
+               TunnelxconnTopologyOperationOutputBuilder responseBuilder = new TunnelxconnTopologyOperationOutputBuilder();
+
+               if(input == null ||
+            input.getServiceInformation() == null ||
+                input.getServiceInformation().getServiceInstanceId() == null ||
+                    input.getServiceInformation().getServiceInstanceId().length() == 0)
+        {
+                       log.debug("exiting {} because of null or empty service-instance-id", SVC_OPERATION);
+                       responseBuilder.setResponseCode("404");
+                       responseBuilder.setResponseMessage("invalid input, null or empty service-instance-id");
+                       responseBuilder.setAckFinalIndicator("Y");
+                       RpcResult<TunnelxconnTopologyOperationOutput> rpcResult =
+                RpcResultBuilder.<TunnelxconnTopologyOperationOutput> status(true).withResult(responseBuilder.build()).build();
+                       return Futures.immediateFuture(rpcResult);
+               }
+
+        String siid = input.getServiceInformation().getServiceInstanceId();
+
+        // Get the service-instance service data from MD-SAL
+        ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
+        getServiceData(siid,serviceDataBuilder);
+
+               if (input.getSdncRequestHeader() != null) {
+                       responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
+               }
+
+        ServiceData sd = serviceDataBuilder.build();
+        if (sd == null || sd.getServiceLevelOperStatus() == null)
+        {
+                       log.debug("exiting {} because the service-instance does not have any service data in SDNC", SVC_OPERATION);
+                       responseBuilder.setResponseCode("404");
+                       responseBuilder.setResponseMessage("invalid input: the service-instance does not have any service data in SDNC");
+                       responseBuilder.setAckFinalIndicator("Y");
+                       RpcResult<TunnelxconnTopologyOperationOutput> rpcResult =
+                RpcResultBuilder.<TunnelxconnTopologyOperationOutput> status(true).withResult(responseBuilder.build()).build();
+                       return Futures.immediateFuture(rpcResult);
+               }
+
+               log.info("Adding INPUT data for {} [{}] input: {}", SVC_OPERATION, siid, input);
+               TunnelxconnTopologyOperationInputBuilder inputBuilder = new TunnelxconnTopologyOperationInputBuilder(input);
+               GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
+
+               // Call SLI sync method
+               // Get SvcLogicService reference
+
+               GenericResourceApiSvcLogicServiceClient svcLogicClient = new GenericResourceApiSvcLogicServiceClient();
+               Properties respProps = null;
+
+               String errorCode = "200";
+               String errorMessage = null;
+               String ackFinal = "Y";
+               String allottedResourceId = "error";
+        String serviceObjectPath = null;
+        String tunnelxconnObjectPath = null;
+
+               try
+               {
+                       if (svcLogicClient.hasGraph(appName, SVC_OPERATION , null, "sync"))
+                       {
+
+                               try
+                               {
+                                       respProps = svcLogicClient.execute(appName, SVC_OPERATION, null, "sync", serviceDataBuilder, parms);
+                               }
+                               catch (Exception e)
+                               {
+                                       log.error("Caught exception executing service logic for {}", SVC_OPERATION, e);
+                                       errorMessage = e.getMessage();
+                                       errorCode = "500";
+                               }
+                       } else {
+                               errorMessage = "No service logic active for "+ appName +": '" + SVC_OPERATION + "'";
+                               errorCode = "503";
+                       }
+               }
+               catch (Exception e)
+               {
+                       errorCode = "500";
+                       errorMessage = e.getMessage();
+                       log.error("Caught exception looking for service logic", e);
+               }
+
+
+               if (respProps != null)
+               {
+                       errorCode = respProps.getProperty("error-code");
+                       errorMessage = respProps.getProperty("error-message");
+                       ackFinal = respProps.getProperty("ack-final", "Y");
+                       allottedResourceId = respProps.getProperty("allotted-resource-id");
+                       serviceObjectPath = respProps.getProperty("service-object-path");
+                       tunnelxconnObjectPath = respProps.getProperty("tunnelxconn-object-path");
+               }
+
+               if ( errorCode != null && errorCode.length() != 0 && !( errorCode.equals("0")|| errorCode.equals("200"))) {
+                       responseBuilder.setResponseCode(errorCode);
+                       responseBuilder.setResponseMessage(errorMessage);
+                       responseBuilder.setAckFinalIndicator(ackFinal);
+
+                       log.error("Returned FAILED for {} [{}] {}", SVC_OPERATION, siid, responseBuilder.build());
+
+                       RpcResult<TunnelxconnTopologyOperationOutput> rpcResult =
+                RpcResultBuilder.<TunnelxconnTopologyOperationOutput> status(true).withResult(responseBuilder.build()).build();
+                       return Futures.immediateFuture(rpcResult);
+               }
+
+               // Got success from SLI
+               try {
+
+                       serviceData = serviceDataBuilder.build();
+                       log.info("Updating MD-SAL for {} [{}] ServiceData: {}", SVC_OPERATION, 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 (input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null)
+                       {
+                               // Only update operational tree on activate or delete
+                               if (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Unassign) ||
+                                               input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate))
+                               {
+                                       log.info("Updating OPERATIONAL tree.");
+                                       saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
+                               }
+                       }
+
+                       TunnelxconnResponseInformationBuilder tunnelxconnResponseInformationBuilder = new TunnelxconnResponseInformationBuilder();
+                       tunnelxconnResponseInformationBuilder.setInstanceId(allottedResourceId);
+                       tunnelxconnResponseInformationBuilder.setObjectPath(tunnelxconnObjectPath);
+                       responseBuilder.setTunnelxconnResponseInformation(tunnelxconnResponseInformationBuilder.build());
+
+                       ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
+                       serviceResponseInformationBuilder.setInstanceId(siid);
+                       serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
+                       responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
+
+               } catch (IllegalStateException e) {
+                       log.error("Caught Exception updating MD-SAL for {} [{}] \n", SVC_OPERATION, siid, e);
+                       responseBuilder.setResponseCode("500");
+                       responseBuilder.setResponseMessage(e.toString());
+                       responseBuilder.setAckFinalIndicator("Y");
+                       log.error("Returned FAILED for {} [{}] {}", SVC_OPERATION, siid, responseBuilder.build());
+                       RpcResult<TunnelxconnTopologyOperationOutput> rpcResult =
+                RpcResultBuilder.<TunnelxconnTopologyOperationOutput> status(true).withResult(responseBuilder.build()).build();
+                       return Futures.immediateFuture(rpcResult);
+               }
+
+               // Update succeeded
+               responseBuilder.setResponseCode(errorCode);
+               responseBuilder.setAckFinalIndicator(ackFinal);
+               if (errorMessage != null)
+               {
+                       responseBuilder.setResponseMessage(errorMessage);
+               }
+               log.info("Updated MD-SAL for {} [{}]", SVC_OPERATION, siid);
+               log.info("Returned SUCCESS for {} [{}] {}", SVC_OPERATION, siid, responseBuilder.build());
+
+               RpcResult<TunnelxconnTopologyOperationOutput> rpcResult =
+            RpcResultBuilder.<TunnelxconnTopologyOperationOutput> status(true).withResult(responseBuilder.build()).build();
+               return Futures.immediateFuture(rpcResult);
+       }
+
+       @Override
+       public Future<RpcResult<BrgTopologyOperationOutput>> brgTopologyOperation(BrgTopologyOperationInput input) {
+               final String SVC_OPERATION = "brg-topology-operation";
+               ServiceData serviceData;
+               ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
+               Properties parms = new Properties();
+
+               log.info("{} called.", SVC_OPERATION);
+               // create a new response object
+               BrgTopologyOperationOutputBuilder responseBuilder = new BrgTopologyOperationOutputBuilder();
+
+               if(input == null ||
+            input.getServiceInformation() == null ||
+                input.getServiceInformation().getServiceInstanceId() == null ||
+                    input.getServiceInformation().getServiceInstanceId().length() == 0)
+        {
+                       log.debug("exiting {} because of null or empty service-instance-id", SVC_OPERATION);
+                       responseBuilder.setResponseCode("404");
+                       responseBuilder.setResponseMessage("invalid input, null or empty service-instance-id");
+                       responseBuilder.setAckFinalIndicator("Y");
+                       RpcResult<BrgTopologyOperationOutput> rpcResult =
+                RpcResultBuilder.<BrgTopologyOperationOutput> status(true).withResult(responseBuilder.build()).build();
+                       return Futures.immediateFuture(rpcResult);
+               }
+
+        String siid = input.getServiceInformation().getServiceInstanceId();
+
+        // Get the service-instance service data from MD-SAL
+        ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
+        getServiceData(siid,serviceDataBuilder);
+
+               if (input.getSdncRequestHeader() != null) {
+                       responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
+               }
+
+        ServiceData sd = serviceDataBuilder.build();
+        if (sd == null || sd.getServiceLevelOperStatus() == null)
+        {
+                       log.debug("exiting {} because the service-instance does not have any service data in SDNC", SVC_OPERATION);
+                       responseBuilder.setResponseCode("404");
+                       responseBuilder.setResponseMessage("invalid input: the service-instance does not have any service data in SDNC");
+                       responseBuilder.setAckFinalIndicator("Y");
+                       RpcResult<BrgTopologyOperationOutput> rpcResult =
+                RpcResultBuilder.<BrgTopologyOperationOutput> status(true).withResult(responseBuilder.build()).build();
+                       return Futures.immediateFuture(rpcResult);
+               }
+
+               log.info("Adding INPUT data for {} [{}] input: {}", SVC_OPERATION, siid, input);
+               BrgTopologyOperationInputBuilder inputBuilder = new BrgTopologyOperationInputBuilder(input);
+               GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
+
+               // Call SLI sync method
+               // Get SvcLogicService reference
+
+               GenericResourceApiSvcLogicServiceClient svcLogicClient = new GenericResourceApiSvcLogicServiceClient();
+               Properties respProps = null;
+
+               String errorCode = "200";
+               String errorMessage = null;
+               String ackFinal = "Y";
+               String allottedResourceId = "error";
+        String serviceObjectPath = null;
+        String brgObjectPath = null;
+
+               try
+               {
+                       if (svcLogicClient.hasGraph(appName, SVC_OPERATION , null, "sync"))
+                       {
+
+                               try
+                               {
+                                       respProps = svcLogicClient.execute(appName, SVC_OPERATION, null, "sync", serviceDataBuilder, parms);
+                               }
+                               catch (Exception e)
+                               {
+                                       log.error("Caught exception executing service logic for {}", SVC_OPERATION, e);
+                                       errorMessage = e.getMessage();
+                                       errorCode = "500";
+                               }
+                       } else {
+                               errorMessage = "No service logic active for "+ appName +": '" + SVC_OPERATION + "'";
+                               errorCode = "503";
+                       }
+               }
+               catch (Exception e)
+               {
+                       errorCode = "500";
+                       errorMessage = e.getMessage();
+                       log.error("Caught exception looking for service logic", e);
+               }
+
+
+               if (respProps != null)
+               {
+                       errorCode = respProps.getProperty("error-code");
+                       errorMessage = respProps.getProperty("error-message");
+                       ackFinal = respProps.getProperty("ack-final", "Y");
+                       allottedResourceId = respProps.getProperty("allotted-resource-id");
+                       serviceObjectPath = respProps.getProperty("service-object-path");
+                       brgObjectPath = respProps.getProperty("brg-object-path");
+               }
+
+               if ( errorCode != null && errorCode.length() != 0 && !( errorCode.equals("0")|| errorCode.equals("200"))) {
+                       responseBuilder.setResponseCode(errorCode);
+                       responseBuilder.setResponseMessage(errorMessage);
+                       responseBuilder.setAckFinalIndicator(ackFinal);
+
+                       log.error("Returned FAILED for {} [{}] {}", SVC_OPERATION, siid, responseBuilder.build());
+
+                       RpcResult<BrgTopologyOperationOutput> rpcResult =
+                RpcResultBuilder.<BrgTopologyOperationOutput> status(true).withResult(responseBuilder.build()).build();
+                       return Futures.immediateFuture(rpcResult);
+               }
+
+               // Got success from SLI
+               try {
+
+                       serviceData = serviceDataBuilder.build();
+                       log.info("Updating MD-SAL for {} [{}] ServiceData: {}", SVC_OPERATION, 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 (input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null)
+                       {
+                               // Only update operational tree on activate or delete
+                               if (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Unassign) ||
+                                               input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate))
+                               {
+                                       log.info("Updating OPERATIONAL tree.");
+                                       saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
+                               }
+                       }
+
+                       BrgResponseInformationBuilder brgResponseInformationBuilder = new BrgResponseInformationBuilder();
+                       brgResponseInformationBuilder.setInstanceId(allottedResourceId);
+                       brgResponseInformationBuilder.setObjectPath(brgObjectPath);
+                       responseBuilder.setBrgResponseInformation(brgResponseInformationBuilder.build());
+
+                       ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
+                       serviceResponseInformationBuilder.setInstanceId(siid);
+                       serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
+                       responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
+
+               } catch (IllegalStateException e) {
+                       log.error("Caught Exception updating MD-SAL for {} [{}] \n", SVC_OPERATION, siid, e);
+                       responseBuilder.setResponseCode("500");
+                       responseBuilder.setResponseMessage(e.toString());
+                       responseBuilder.setAckFinalIndicator("Y");
+                       log.error("Returned FAILED for {} [{}] {}", SVC_OPERATION, siid, responseBuilder.build());
+                       RpcResult<BrgTopologyOperationOutput> rpcResult =
+                RpcResultBuilder.<BrgTopologyOperationOutput> status(true).withResult(responseBuilder.build()).build();
+                       return Futures.immediateFuture(rpcResult);
+               }
+
+               // Update succeeded
+               responseBuilder.setResponseCode(errorCode);
+               responseBuilder.setAckFinalIndicator(ackFinal);
+               if (errorMessage != null)
+               {
+                       responseBuilder.setResponseMessage(errorMessage);
+               }
+               log.info("Updated MD-SAL for {} [{}]", SVC_OPERATION, siid);
+               log.info("Returned SUCCESS for {} [{}] {}", SVC_OPERATION, siid, responseBuilder.build());
+
+               RpcResult<BrgTopologyOperationOutput> rpcResult =
+            RpcResultBuilder.<BrgTopologyOperationOutput> status(true).withResult(responseBuilder.build()).build();
+               return Futures.immediateFuture(rpcResult);
+       }
+
     @Override
     public Future<RpcResult<PreloadVnfTopologyOperationOutput>> preloadVnfTopologyOperation(
             PreloadVnfTopologyOperationInput input) {
@@ -2074,4 +2434,6 @@ public class GenericResourceApiProvider implements AutoCloseable, GENERICRESOURC
                 RpcResultBuilder.<PreloadNetworkTopologyOperationOutput> status(true).withResult(responseBuilder.build()).build();
         return Futures.immediateFuture(rpcResult);
     }
+
+
 }
index 6e6da0e..c03bc12 100644 (file)
@@ -40,8 +40,8 @@ public class GenericResourceApiUtil extends MdsalHelper {
                // Trick class loader into loading builders. Some of
                // these will be needed later by Reflection classes, but need
                // to explicitly "new" them here to get class loader to load them.
-               org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ecomp.model.information.EcompModelInformationBuilder u1 =
-                       new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ecomp.model.information.EcompModelInformationBuilder();
+               org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.onap.model.information.OnapModelInformationBuilder u1 =
+                       new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.onap.model.information.OnapModelInformationBuilder();
                org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.network.assignments.NetworkAssignmentsBuilder u2 =
                        new org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.network.assignments.NetworkAssignmentsBuilder();
                org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.network.information.NetworkInformationBuilder u3 =
diff --git a/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/TestGenericResourceApi.java b/generic-resource-api/provider/src/test/java/org/onap/sdnc/northbound/TestGenericResourceApi.java
new file mode 100644 (file)
index 0000000..1230cd2
--- /dev/null
@@ -0,0 +1,129 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                                                     reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.sdnc.northbound;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationOutput;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServiceTopologyOperationInputBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationInputBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServiceTopologyOperationOutput;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.network.information.NetworkInformationBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.request.information.RequestInformation.RequestAction;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.request.information.RequestInformationBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader.SvcAction;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeaderBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.information.ServiceInformationBuilder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestGenericResourceApi extends AbstractConcurrentDataBrokerTest {
+
+    private GenericResourceApiProvider genericResourceApiProvider;
+    private static final Logger LOG = LoggerFactory.getLogger(GenericResourceApiProvider.class);
+
+    @Before
+    public void setUp() throws Exception {
+        if (null == genericResourceApiProvider) {
+            DataBroker dataBroker = getDataBroker();
+            NotificationPublishService mockNotification = mock(NotificationPublishService.class);
+            RpcProviderRegistry mockRpcRegistry = mock(RpcProviderRegistry.class);
+            genericResourceApiProvider = new GenericResourceApiProvider(dataBroker, mockNotification, mockRpcRegistry);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testServiceTopologyOperation() {
+
+        ServiceTopologyOperationInputBuilder inputBuilder = new ServiceTopologyOperationInputBuilder();
+
+        SdncRequestHeaderBuilder sdncRequestHeaderBuilder = new SdncRequestHeaderBuilder();
+        sdncRequestHeaderBuilder.setSvcRequestId("1111");
+        sdncRequestHeaderBuilder.setSvcAction(SvcAction.Assign);
+        inputBuilder.setSdncRequestHeader(sdncRequestHeaderBuilder.build());
+
+        RequestInformationBuilder requestInformationBuilder = new RequestInformationBuilder();
+        requestInformationBuilder.setRequestId("1111");
+        requestInformationBuilder.setRequestAction(RequestAction.CreateServiceInstance);
+        inputBuilder.setRequestInformation(requestInformationBuilder.build());
+
+        ServiceInformationBuilder serviceInformationBuilder = new ServiceInformationBuilder();
+        serviceInformationBuilder.setServiceInstanceId("1111");
+        inputBuilder.setServiceInformation(serviceInformationBuilder.build());
+
+        // TODO: currently initialize GenericResourceApiSvcLogicServiceClient is failing, need to fix
+        java.util.concurrent.Future<RpcResult<ServiceTopologyOperationOutput>> future = genericResourceApiProvider
+        .serviceTopologyOperation(inputBuilder.build());
+        RpcResult<ServiceTopologyOperationOutput> rpcResult = null;
+        try {
+            rpcResult = future.get();
+        } catch (Exception e) {
+            fail("Error : " + e);
+        }
+        LOG.info("result: {}", rpcResult);
+        assertEquals("1111", rpcResult.getResult().getSvcRequestId());
+    }
+
+    @Test
+    public void testNetworkTopologyOperation() {
+
+        NetworkTopologyOperationInputBuilder inputBuilder = new NetworkTopologyOperationInputBuilder();
+
+        SdncRequestHeaderBuilder sdncRequestHeaderBuilder = new SdncRequestHeaderBuilder();
+        sdncRequestHeaderBuilder.setSvcRequestId("1111");
+        sdncRequestHeaderBuilder.setSvcAction(SvcAction.Create);
+        inputBuilder.setSdncRequestHeader(sdncRequestHeaderBuilder.build());
+
+        RequestInformationBuilder requestInformationBuilder = new RequestInformationBuilder();
+        requestInformationBuilder.setRequestId("1111");
+        requestInformationBuilder.setRequestAction(RequestAction.CreateNetworkInstance);
+        inputBuilder.setRequestInformation(requestInformationBuilder.build());
+
+        ServiceInformationBuilder serviceInformationBuilder = new ServiceInformationBuilder();
+        serviceInformationBuilder.setServiceInstanceId("1111");
+        inputBuilder.setServiceInformation(serviceInformationBuilder.build());
+
+        NetworkInformationBuilder networkInformationBuilder = new NetworkInformationBuilder();
+        inputBuilder.setNetworkInformation(networkInformationBuilder.build());
+
+        java.util.concurrent.Future<RpcResult<NetworkTopologyOperationOutput>> future = genericResourceApiProvider
+            .networkTopologyOperation(inputBuilder.build());
+        RpcResult<NetworkTopologyOperationOutput> rpcResult = null;
+        try {
+            rpcResult = future.get();
+        } catch (Exception e) {
+            fail("Error : " + e);
+        }
+        LOG.info("result: {}", rpcResult);
+        assertEquals("1111", rpcResult.getResult().getSvcRequestId());
+    }
+}
index 5ea0700..3da86e0 100644 (file)
@@ -30,7 +30,7 @@
     <feature name='sdnc-vnfapi' description="sdnc-vnfapi" version='${project.version}'>
         <!-- Most applications will have a dependency on the ODL MD-SAL Broker -->
         <feature version="${odl.mdsal.version}">odl-mdsal-broker</feature>
-        <feature version="${sdnctl.sli.version}">sdnc-sli</feature>
+        <feature>sdnc-sli</feature>
         <bundle>mvn:org.onap.sdnc.northbound/vnfapi-model/${project.version}</bundle>
         <bundle>mvn:org.onap.sdnc.northbound/vnfapi-provider/${project.version}</bundle>
         <configfile finalname="etc/opendaylight/karaf/200-vnfapi-provider.xml">mvn:org.openecomp.sdnc.northbound/vnfapi-provider/${project.version}/xml/config</configfile>
index c4d8c52..522ee7f 100644 (file)
@@ -53,23 +53,15 @@ public class VnfSdnUtil extends MdsalHelper {
         File propFile = new File(ODLHOME.getAbsolutePath() + "/configuration/vnfapi.properties");
         String propFileName = propFile.getAbsolutePath();
         properties = new Properties();
-        InputStream input = null;
         if (propFile.isFile() && propFile.canRead()) {
-            try    {
-                input = new FileInputStream(propFile);
+            try (InputStream input = new FileInputStream(propFile)) {
                 properties.load(input);
                 LOG.info("Loaded properties from " + propFileName );
                 setYangMappingProperties(properties);
+            } catch (IOException e) {
+                LOG.error("Failed to close properties file " + propFileName +"\n",e);
             } catch (Exception e) {
                 LOG.error("Failed to load properties " + propFileName +"\n",e);
-            } finally {
-                if (input != null) {
-                    try {
-                        input.close();
-                    } catch (IOException e) {
-                        LOG.error("Failed to close properties file " + propFileName +"\n",e);
-                    }
-                }
             }
         }
     }