TAPI network utils 25/95025/35
authorJavier Errea <errea@eurecom.fr>
Thu, 4 Feb 2021 12:58:03 +0000 (13:58 +0100)
committererrea <errea@eurecom.fr>
Fri, 30 Apr 2021 12:38:24 +0000 (14:38 +0200)
- Creation of links in tapi topology
- Implementation equal to transportpce-networkutils
- transportpce-tapinetworkutils.yang model -> rpcs
- Modifified tapi blueprint and lighty to support impl

JIRA: TRNSPRTPCE-426
Change-Id: Ifce60d44129bff0f7d8d1f5a24967ad0084cbb5e
Signed-off-by: errea <errea@eurecom.fr>
api/src/main/yang/transportpce-tapinetworkutils@2021-04-08.yang [new file with mode: 0644]
lighty/src/main/java/io/lighty/controllers/tpce/module/TransportPCEImpl.java
lighty/src/main/java/io/lighty/controllers/tpce/utils/TPCEUtils.java
tapi/src/main/java/org/opendaylight/transportpce/tapi/impl/TapiProvider.java
tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiNetworkUtilsImpl.java [new file with mode: 0644]
tapi/src/main/resources/OSGI-INF/blueprint/tapi-blueprint.xml

diff --git a/api/src/main/yang/transportpce-tapinetworkutils@2021-04-08.yang b/api/src/main/yang/transportpce-tapinetworkutils@2021-04-08.yang
new file mode 100644 (file)
index 0000000..60481c7
--- /dev/null
@@ -0,0 +1,107 @@
+module transportpce-tapinetworkutils {
+  yang-version 1;
+  namespace "http://org/opendaylight/transportpce/tapinetworkutils";
+  prefix "org-opendaylight-transportpce-tapinetworkutils";
+
+  import tapi-common {
+    prefix tapi-common;
+    revision-date 2018-12-10;
+  }
+
+  organization
+    "transportPCE";
+  contact
+    "transportPCE committers - ODL";
+  description
+    "YANG definitions of TAPI link creation in TAPI topology (adapted from NetworkUtils yang model)
+     Copyright ©  2021 Nokia, Inc. and others.  All rights reserved.
+
+      Redistribution and use in source and binary forms, with or without modification,
+      are permitted provided that the following conditions are met:
+
+      * Redistributions of source code must retain the above copyright notice, this
+        list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above copyright notice,
+        this list of conditions and the following disclaimer in the documentation and/or
+        other materials provided with the distribution.
+      * Neither Nokia nor the names of its contributors may be used to endorse or promote
+        products derived from this software without specific prior written permission.
+
+      THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND NOKIA AND OTHER CONTRIBUTORS ''AS IS''
+      AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+      IN NO EVENT ITS AUTHORS AND NOKIA AND OTHER CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+      INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+      NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA,
+      OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+      WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+      ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+      POSSIBILITY OF SUCH DAMAGE";
+
+  revision "2021-04-08" {
+    description
+      "Initial revision of tapi networkutils model. Used as the transportpce-networkutils model to
+      create tapi links between tapi nodes in the tapi topology. The inputs are base on OR naming but later
+      translated into tapi";
+  }
+
+  rpc init-roadm-roadm-tapi-link {
+    description "This rpc initiates a tapi roadm to roadm link";
+    input {
+      leaf rdm-a-node {
+        type string;
+      }
+      leaf deg-a-tp {
+        type string;
+      }
+      leaf rdm-z-node {
+        type string;
+      }
+      leaf deg-z-tp {
+        type string;
+      }
+    }
+    output {
+      leaf result {
+        type string;
+      }
+    }
+  }
+
+  rpc init-xpdr-rdm-tapi-link {
+    description "This rpc initiates a tapi xponder to rdm link. Bidirectional";
+    input {
+      leaf xpdr-node {
+        type string;
+      }
+      leaf network-tp {
+        type string;
+      }
+      leaf rdm-node {
+        type string;
+      }
+      leaf add-drop-tp {
+        type string;
+      }
+    }
+    output {
+      leaf result {
+        type string;
+      }
+    }
+  }
+
+  rpc delete-tapi-link {
+    description "This rpc deletes a given link in openroadm Topology layer";
+    input {
+      leaf uuid {
+        type tapi-common:uuid;
+      }
+    }
+    output {
+      leaf result {
+        type string;
+      }
+    }
+  }
+}
index 179196f19e1bb6262f0dcc40fd792e2ea0555048..07855f03daf5b7aa7b569e7bcde34ad6153b2dba 100644 (file)
@@ -80,8 +80,10 @@ import org.opendaylight.transportpce.tapi.topology.TapiNetconfTopologyListener;
 import org.opendaylight.transportpce.tapi.topology.TapiNetworkModelService;
 import org.opendaylight.transportpce.tapi.topology.TapiNetworkModelServiceImpl;
 import org.opendaylight.transportpce.tapi.topology.TapiPortMappingListener;
+import org.opendaylight.transportpce.tapi.topology.TapiNetworkUtilsImpl;
 import org.opendaylight.transportpce.tapi.utils.TapiListener;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkutils.rev170818.TransportpceNetworkutilsService;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.TransportpceTapinetworkutilsService;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.TransportpceOlmService;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.OrgOpenroadmServiceService;
 import org.slf4j.Logger;
@@ -197,6 +199,8 @@ public class TransportPCEImpl extends AbstractLightyModule implements TransportP
         LOG.info("Creating tapi beans ...");
         R2RTapiLinkDiscovery tapilinkDiscoveryImpl = new R2RTapiLinkDiscovery(lightyServices.getBindingDataBroker(),
             deviceTransactionManager);
+        TransportpceTapinetworkutilsService tapiNetworkutilsServiceImpl = new TapiNetworkUtilsImpl(
+                networkTransaction);
         TapiNetworkModelService tapiNetworkModelService = new TapiNetworkModelServiceImpl(
             tapilinkDiscoveryImpl, networkTransaction);
         TapiNetconfTopologyListener tapiNetConfTopologyListener =
@@ -204,7 +208,7 @@ public class TransportPCEImpl extends AbstractLightyModule implements TransportP
         TapiPortMappingListener tapiPortMappingListener =
             new TapiPortMappingListener(tapiNetworkModelService);
         tapiProvider = initTapi(lightyServices, servicehandler, networkTransaction, serviceDataStoreOperations,
-                tapiNetConfTopologyListener, tapiPortMappingListener);
+                tapiNetConfTopologyListener, tapiPortMappingListener, tapiNetworkutilsServiceImpl);
         if(activateNbiNotification) {
             LOG.info("Creating nbi-notifications beans ...");
             nbiNotificationsProvider = new NbiNotificationsProvider(
@@ -268,10 +272,11 @@ public class TransportPCEImpl extends AbstractLightyModule implements TransportP
                                   NetworkTransactionService networkTransaction,
                                   ServiceDataStoreOperations serviceDataStoreOperations,
                                   TapiNetconfTopologyListener tapiNetConfTopologyListener,
-                                  TapiPortMappingListener tapiPortMappingListener) {
+                                  TapiPortMappingListener tapiPortMappingListener,
+                                  TransportpceTapinetworkutilsService tapiNetworkutilsServiceImpl) {
         return new TapiProvider(lightyServices.getBindingDataBroker(), lightyServices.getRpcProviderService(),
             servicehandler, serviceDataStoreOperations, new TapiListener(), networkTransaction,
-            tapiNetConfTopologyListener, tapiPortMappingListener);
+            tapiNetConfTopologyListener, tapiPortMappingListener, tapiNetworkutilsServiceImpl);
     }
 
     /**
index 0893271c619db217dd843d6823d062dcd5e86acf..c62aad86e4a87091b7938e58c7ebc97fc1ee15fd 100644 (file)
@@ -297,6 +297,8 @@ public final class TPCEUtils {
                     .getInstance(),
             org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.$YangModuleInfoImpl
                     .getInstance(),
+            org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408
+                    .$YangModuleInfoImpl.getInstance(),
             org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev200128
                     .$YangModuleInfoImpl.getInstance(),
             org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116
index 7beb695cb3e7a2d69b6acf6e06ffd7adb0ca8b27..dc30a57ebb5462ea6bde47f981f489078bf84f27 100644 (file)
@@ -27,6 +27,7 @@ import org.opendaylight.transportpce.tapi.utils.TapiInitialORMapping;
 import org.opendaylight.transportpce.tapi.utils.TapiListener;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.Network;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.network.Nodes;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.TransportpceTapinetworkutilsService;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.OrgOpenroadmServiceService;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.TapiConnectivityService;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.TapiTopologyService;
@@ -54,6 +55,7 @@ public class TapiProvider {
     private final DataBroker dataBroker;
     private final RpcProviderService rpcProviderService;
     private ObjectRegistration<TapiConnectivityService> rpcRegistration;
+    private ObjectRegistration<TransportpceTapinetworkutilsService> tapiNetworkutilsServiceRpcRegistration;
     private ListenerRegistration<TapiNetconfTopologyListener> dataTreeChangeListenerRegistration;
     private ListenerRegistration<TapiPortMappingListener> mappingListenerListenerRegistration;
     private final OrgOpenroadmServiceService serviceHandler;
@@ -62,11 +64,13 @@ public class TapiProvider {
     private final TapiNetconfTopologyListener topologyListener;
     private TapiPortMappingListener tapiPortMappingListener;
     private final NetworkTransactionService networkTransactionService;
+    private final TransportpceTapinetworkutilsService tapiNetworkUtils;
 
     public TapiProvider(DataBroker dataBroker, RpcProviderService rpcProviderService,
             OrgOpenroadmServiceService serviceHandler, ServiceDataStoreOperations serviceDataStoreOperations,
             TapiListener tapiListener, NetworkTransactionService networkTransactionService,
-            TapiNetconfTopologyListener topologyListener, TapiPortMappingListener tapiPortMappingListener) {
+            TapiNetconfTopologyListener topologyListener, TapiPortMappingListener tapiPortMappingListener,
+            TransportpceTapinetworkutilsService tapiNetworkUtils) {
         this.dataBroker = dataBroker;
         this.rpcProviderService = rpcProviderService;
         this.serviceHandler = serviceHandler;
@@ -75,6 +79,7 @@ public class TapiProvider {
         this.networkTransactionService = networkTransactionService;
         this.topologyListener = topologyListener;
         this.tapiPortMappingListener = tapiPortMappingListener;
+        this.tapiNetworkUtils = tapiNetworkUtils;
     }
 
     /**
@@ -103,6 +108,9 @@ public class TapiProvider {
         mappingListenerListenerRegistration =
             dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION,
                 MAPPING_II), tapiPortMappingListener);
+        tapiNetworkutilsServiceRpcRegistration =
+                rpcProviderService.registerRpcImplementation(TransportpceTapinetworkutilsService.class,
+                        this.tapiNetworkUtils);
         @NonNull
         InstanceIdentifier<ServiceInterfacePoints> sipIID = InstanceIdentifier.create(ServiceInterfacePoints.class);
         dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(
@@ -120,6 +128,9 @@ public class TapiProvider {
         if (mappingListenerListenerRegistration != null) {
             mappingListenerListenerRegistration.close();
         }
+        if (tapiNetworkutilsServiceRpcRegistration != null) {
+            tapiNetworkutilsServiceRpcRegistration.close();
+        }
         rpcRegistration.close();
     }
 }
diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiNetworkUtilsImpl.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiNetworkUtilsImpl.java
new file mode 100644 (file)
index 0000000..11f0359
--- /dev/null
@@ -0,0 +1,312 @@
+/*
+ * Copyright © 2021 Nokia, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.transportpce.tapi.topology;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.transportpce.common.network.NetworkTransactionService;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.DeleteTapiLinkInput;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.DeleteTapiLinkOutput;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.DeleteTapiLinkOutputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.InitRoadmRoadmTapiLinkInput;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.InitRoadmRoadmTapiLinkOutput;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.InitRoadmRoadmTapiLinkOutputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.InitXpdrRdmTapiLinkInput;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.InitXpdrRdmTapiLinkOutput;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.InitXpdrRdmTapiLinkOutputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.TransportpceTapinetworkutilsService;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.AdministrativeState;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.CapacityUnit;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Context;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.ForwardingDirection;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LayerProtocolName;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LifecycleState;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.TotalSizeBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.pac.AvailableCapacityBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.pac.TotalPotentialCapacityBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.Name;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.ProtectionType;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.RestorationPolicy;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.NodeEdgePoint;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.NodeEdgePointBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.NodeEdgePointKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.ResilienceTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePoint;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.risk.parameter.pac.RiskCharacteristic;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.risk.parameter.pac.RiskCharacteristicBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.LinkBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.LinkKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.TopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.cost.pac.CostCharacteristic;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.cost.pac.CostCharacteristicBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.timing.pac.LatencyCharacteristic;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.timing.pac.LatencyCharacteristicBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.validation.pac.ValidationMechanism;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.validation.pac.ValidationMechanismBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TapiNetworkUtilsImpl implements TransportpceTapinetworkutilsService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(TapiNetworkUtilsImpl.class);
+    private static final String PHTNC_MEDIA = "PHOTONIC_MEDIA";
+    private static final String OTSI = "OTSi";
+    private final Uuid tapiTopoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
+            .getBytes(Charset.forName("UTF-8"))).toString());
+    private final NetworkTransactionService networkTransactionService;
+
+    public TapiNetworkUtilsImpl(NetworkTransactionService networkTransactionService) {
+        this.networkTransactionService = networkTransactionService;
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<InitRoadmRoadmTapiLinkOutput>> initRoadmRoadmTapiLink(
+            InitRoadmRoadmTapiLinkInput input) {
+        // TODO --> need to check if the nodes and neps exist in the topology
+        String sourceNode = input.getRdmANode();
+        String sourceTp = input.getDegATp();
+        String destNode = input.getRdmZNode();
+        String destTp = input.getDegZTp();
+        String linkId = String.join("-", sourceNode, sourceTp.split("-")[0], sourceTp)
+            + "to" + String.join("-", destNode, destTp.split("-")[0], destTp);
+        Link link = createTapiLink(sourceNode, sourceTp, destNode, destTp, linkId, "OMS link name", PHTNC_MEDIA);
+        InitRoadmRoadmTapiLinkOutputBuilder output = new InitRoadmRoadmTapiLinkOutputBuilder();
+        if (link == null) {
+            LOG.error("Error creating link object");
+            return RpcResultBuilder.<InitRoadmRoadmTapiLinkOutput>failed().withError(RpcError.ErrorType.RPC,
+                "Failed to create link in topology").buildFuture();
+        }
+        if (putLinkInTopology(link)) {
+            output = new InitRoadmRoadmTapiLinkOutputBuilder()
+                .setResult("Link created in tapi topology. Link-uuid = " + link.getUuid());
+        }
+        return RpcResultBuilder.success(output.build()).buildFuture();
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<InitXpdrRdmTapiLinkOutput>> initXpdrRdmTapiLink(InitXpdrRdmTapiLinkInput input) {
+        // TODO --> need to check if the nodes and neps exist in the topology
+        String destNode = input.getRdmNode();
+        String destTp = input.getAddDropTp();
+        String sourceNode = input.getXpdrNode();
+        String sourceTp = input.getNetworkTp();
+        String linkId = String.join("-", sourceNode, sourceTp)
+            + "to" + String.join("-", destNode, destTp.split("-")[0], destTp);
+        Link link = createTapiLink(sourceNode, sourceTp, destNode, destTp, linkId, "XPDR-RDM link name", OTSI);
+        InitXpdrRdmTapiLinkOutputBuilder output = new InitXpdrRdmTapiLinkOutputBuilder();
+        if (link == null) {
+            LOG.error("Error creating link object");
+            return RpcResultBuilder.<InitXpdrRdmTapiLinkOutput>failed().withError(RpcError.ErrorType.RPC,
+                "Failed to create link in topology").buildFuture();
+        }
+        if (putLinkInTopology(link)) {
+            output = new InitXpdrRdmTapiLinkOutputBuilder()
+                .setResult("Link created in tapi topology. Link-uuid = " + link.getUuid());
+        }
+        return RpcResultBuilder.success(output.build()).buildFuture();
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<DeleteTapiLinkOutput>> deleteTapiLink(DeleteTapiLinkInput input) {
+        // TODO: check if this IID is correct
+        // TODO --> need to check if the link exists in the topology
+        try {
+            InstanceIdentifier<Link> linkIID = InstanceIdentifier.builder(Context.class)
+                    .augmentation(Context1.class).child(TopologyContext.class).child(Topology.class,
+                            new TopologyKey(tapiTopoUuid)).child(Link.class, new LinkKey(input.getUuid())).build();
+            this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, linkIID);
+            this.networkTransactionService.commit().get();
+            LOG.info("TAPI link deleted successfully.");
+            return RpcResultBuilder.success(new DeleteTapiLinkOutputBuilder()
+                .setResult("Link successfully deleted from tapi topology").build()).buildFuture();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Failed to delete TAPI link", e);
+            return RpcResultBuilder.<DeleteTapiLinkOutput>failed().withError(RpcError.ErrorType.RPC,
+                "Failed to delete link from topology").buildFuture();
+        }
+    }
+
+    private Link createTapiLink(String sourceNode, String sourceTp, String destNode, String destTp, String linkId,
+                                String valueName, String sourceNodeQual) {
+        Map<NodeEdgePointKey, NodeEdgePoint> nepList = new HashMap<>();
+        Uuid sourceUuidNode = new Uuid(UUID.nameUUIDFromBytes((String.join("+", sourceNode,
+            sourceNodeQual)).getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid sourceUuidTp = new Uuid(UUID.nameUUIDFromBytes((String.join("+", sourceNode, PHTNC_MEDIA,
+            sourceTp)).getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid destUuidNode = new Uuid(UUID.nameUUIDFromBytes((String.join("+", destNode,
+            PHTNC_MEDIA)).getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid destUuidTp = new Uuid(UUID.nameUUIDFromBytes((String.join("+", destNode, PHTNC_MEDIA,
+            destTp)).getBytes(Charset.forName("UTF-8"))).toString());
+        if (!(nodeExists(sourceUuidNode) && nodeExists(destUuidNode)
+                && nepExists(sourceUuidTp, sourceUuidNode) && nepExists(destUuidTp, destUuidNode))) {
+            LOG.error("Verify the input data. No link can be created, "
+                + "as either the node or the tp doesnt exist in the TAPI topology");
+            return null;
+        }
+        NodeEdgePoint sourceNep = new NodeEdgePointBuilder()
+            .setTopologyUuid(this.tapiTopoUuid)
+            .setNodeUuid(sourceUuidNode)
+            .setNodeEdgePointUuid(sourceUuidTp)
+            .build();
+        nepList.put(sourceNep.key(), sourceNep);
+        NodeEdgePoint destNep = new NodeEdgePointBuilder()
+            .setTopologyUuid(this.tapiTopoUuid)
+            .setNodeUuid(destUuidNode)
+            .setNodeEdgePointUuid(destUuidTp)
+            .build();
+        nepList.put(destNep.key(), destNep);
+        Name linkName = new NameBuilder().setValueName(valueName)
+            .setValue(linkId)
+            .build();
+        CostCharacteristic costCharacteristic = new CostCharacteristicBuilder()
+            .setCostAlgorithm("Restricted Shortest Path - RSP")
+            .setCostName("HOP_COUNT")
+            .setCostValue("12345678")
+            .build();
+        LatencyCharacteristic latencyCharacteristic = new LatencyCharacteristicBuilder()
+            .setFixedLatencyCharacteristic("12345678")
+            .setQueingLatencyCharacteristic("12345678")
+            .setJitterCharacteristic("12345678")
+            .setWanderCharacteristic("12345678")
+            .setTrafficPropertyName("FIXED_LATENCY")
+            .build();
+        RiskCharacteristic riskCharacteristic = new RiskCharacteristicBuilder()
+            .setRiskCharacteristicName("risk characteristic")
+            .setRiskIdentifierList(List.of("risk identifier1", "risk identifier2"))
+            .build();
+        ValidationMechanism validationMechanism = new ValidationMechanismBuilder()
+            .setValidationMechanism("validation mechanism")
+            .setValidationRobustness("validation robustness")
+            .setLayerProtocolAdjacencyValidated("layer protocol adjacency")
+            .build();
+        return new LinkBuilder()
+            .setUuid(new Uuid(
+                UUID.nameUUIDFromBytes(linkId.getBytes(Charset.forName("UTF-8")))
+                    .toString()))
+            .setName(Map.of(linkName.key(), linkName))
+            .setLayerProtocolName(List.of(LayerProtocolName.PHOTONICMEDIA))
+            .setNodeEdgePoint(nepList)
+            .setDirection(ForwardingDirection.BIDIRECTIONAL)
+            .setTransitionedLayerProtocolName(new ArrayList<>())
+            .setResilienceType(new ResilienceTypeBuilder().setProtectionType(ProtectionType.NOPROTECTON)
+                .setRestorationPolicy(RestorationPolicy.NA)
+                .build())
+            .setAdministrativeState(AdministrativeState.UNLOCKED)
+            .setOperationalState(OperationalState.ENABLED)
+            .setLifecycleState(LifecycleState.INSTALLED)
+            .setTotalPotentialCapacity(new TotalPotentialCapacityBuilder().setTotalSize(
+                new TotalSizeBuilder().setUnit(CapacityUnit.GBPS)
+                    .setValue(Uint64.valueOf(100)).build()).build())
+            .setAvailableCapacity(new AvailableCapacityBuilder().setTotalSize(
+                new TotalSizeBuilder().setUnit(CapacityUnit.MBPS)
+                    .setValue(Uint64.valueOf(100)).build())
+                .build())
+            .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic))
+            .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic))
+            .setRiskCharacteristic(Map.of(riskCharacteristic.key(), riskCharacteristic))
+            .setErrorCharacteristic("error")
+            .setLossCharacteristic("loss")
+            .setRepeatDeliveryCharacteristic("repeat delivery")
+            .setDeliveryOrderCharacteristic("delivery order")
+            .setUnavailableTimeCharacteristic("unavailable time")
+            .setServerIntegrityProcessCharacteristic("server integrity process")
+            .setValidationMechanism(Map.of(validationMechanism.key(), validationMechanism))
+            .build();
+    }
+
+    private boolean nepExists(Uuid nepUuid, Uuid nodeUuid) {
+        LOG.info("Checking if nep with uuid {} existis in tapi topology", nepUuid);
+        try {
+            InstanceIdentifier<OwnedNodeEdgePoint> onepIID = InstanceIdentifier.builder(Context.class)
+                .augmentation(Context1.class).child(TopologyContext.class)
+                .child(Topology.class, new TopologyKey(tapiTopoUuid)).child(Node.class, new NodeKey(nodeUuid))
+                .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nepUuid))
+                .build();
+            Optional<OwnedNodeEdgePoint> optionalOnep = this.networkTransactionService.read(
+                LogicalDatastoreType.OPERATIONAL, onepIID).get();
+            if (!optionalOnep.isPresent()) {
+                LOG.error("ONEP is not present in datastore");
+                return false;
+            }
+            return true;
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Couldnt retrieve nep from datastore");
+            return false;
+        }
+    }
+
+    private boolean nodeExists(Uuid nodeUuid) {
+        LOG.info("Checking if node with uuid {} existis in tapi topology", nodeUuid);
+        try {
+            InstanceIdentifier<Node> nodeIID = InstanceIdentifier.builder(Context.class)
+                .augmentation(Context1.class).child(TopologyContext.class)
+                .child(Topology.class, new TopologyKey(tapiTopoUuid)).child(Node.class, new NodeKey(nodeUuid))
+                .build();
+            Optional<Node> optionalNode = this.networkTransactionService.read(
+                LogicalDatastoreType.OPERATIONAL, nodeIID).get();
+            if (!optionalNode.isPresent()) {
+                LOG.error("Node is not present in datastore");
+                return false;
+            }
+            return true;
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Couldnt retrieve nep from datastore");
+            return false;
+        }
+    }
+
+    private boolean putLinkInTopology(Link tapiLink) {
+        // TODO is this merge correct? Should we just merge topology by changing the nodes map??
+        // TODO: verify this is correct. Should we identify the context IID with the context UUID??
+        LOG.info("Creating tapi node in TAPI topology context");
+        InstanceIdentifier<Topology> topoIID = InstanceIdentifier.builder(Context.class)
+            .augmentation(Context1.class).child(TopologyContext.class)
+            .child(Topology.class, new TopologyKey(tapiTopoUuid))
+            .build();
+
+        Topology topology = new TopologyBuilder().setUuid(tapiTopoUuid)
+            .setLink(Map.of(tapiLink.key(), tapiLink)).build();
+
+        // merge in datastore
+        this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, topoIID,
+            topology);
+        try {
+            this.networkTransactionService.commit().get();
+
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Error populating TAPI topology: ", e);
+            return false;
+        }
+        LOG.info("TAPI Link added succesfully.");
+        return true;
+    }
+}
index 314df38f66cf7968bd19e29ea0c25234bcdbfbe7..70bbc9186909bee36979e081aff715f131999eef 100644 (file)
@@ -44,6 +44,10 @@ Author: Gilles Thouenon <gilles.thouenon@orange.com>
         <argument ref="tapiNetworkModelService" />
     </bean>
 
+    <bean id="tapiNetworkUtilsImpl" class="org.opendaylight.transportpce.tapi.topology.TapiNetworkUtilsImpl">
+        <argument ref="networkTransactionImpl" />
+    </bean>
+
     <bean id="tapiProvider"
           class="org.opendaylight.transportpce.tapi.impl.TapiProvider"
           init-method="init" destroy-method="close">
@@ -55,6 +59,7 @@ Author: Gilles Thouenon <gilles.thouenon@orange.com>
         <argument ref="networkTransactionImpl" />
         <argument ref="tapiNetconfTopologyListener" />
         <argument ref="tapiPortMappingListener" />
+        <argument ref="tapiNetworkUtilsImpl" />
     </bean>
 
     <bean id="tapiPortMappingListener" class="org.opendaylight.transportpce.tapi.topology.TapiPortMappingListener">