From b16ead644f52fb2d797eece5d1d39c7fa56bb178 Mon Sep 17 00:00:00 2001 From: Javier Errea Date: Thu, 4 Feb 2021 13:58:03 +0100 Subject: [PATCH] TAPI network utils - 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 --- ...nsportpce-tapinetworkutils@2021-04-08.yang | 107 ++++++ .../tpce/module/TransportPCEImpl.java | 11 +- .../controllers/tpce/utils/TPCEUtils.java | 2 + .../transportpce/tapi/impl/TapiProvider.java | 13 +- .../tapi/topology/TapiNetworkUtilsImpl.java | 312 ++++++++++++++++++ .../OSGI-INF/blueprint/tapi-blueprint.xml | 5 + 6 files changed, 446 insertions(+), 4 deletions(-) create mode 100644 api/src/main/yang/transportpce-tapinetworkutils@2021-04-08.yang create mode 100644 tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiNetworkUtilsImpl.java 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 index 000000000..60481c7f9 --- /dev/null +++ b/api/src/main/yang/transportpce-tapinetworkutils@2021-04-08.yang @@ -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; + } + } + } +} diff --git a/lighty/src/main/java/io/lighty/controllers/tpce/module/TransportPCEImpl.java b/lighty/src/main/java/io/lighty/controllers/tpce/module/TransportPCEImpl.java index 179196f19..07855f03d 100644 --- a/lighty/src/main/java/io/lighty/controllers/tpce/module/TransportPCEImpl.java +++ b/lighty/src/main/java/io/lighty/controllers/tpce/module/TransportPCEImpl.java @@ -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); } /** diff --git a/lighty/src/main/java/io/lighty/controllers/tpce/utils/TPCEUtils.java b/lighty/src/main/java/io/lighty/controllers/tpce/utils/TPCEUtils.java index 0893271c6..c62aad86e 100644 --- a/lighty/src/main/java/io/lighty/controllers/tpce/utils/TPCEUtils.java +++ b/lighty/src/main/java/io/lighty/controllers/tpce/utils/TPCEUtils.java @@ -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 diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/impl/TapiProvider.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/impl/TapiProvider.java index 7beb695cb..dc30a57eb 100644 --- a/tapi/src/main/java/org/opendaylight/transportpce/tapi/impl/TapiProvider.java +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/impl/TapiProvider.java @@ -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 rpcRegistration; + private ObjectRegistration tapiNetworkutilsServiceRpcRegistration; private ListenerRegistration dataTreeChangeListenerRegistration; private ListenerRegistration 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 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 index 000000000..11f035937 --- /dev/null +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiNetworkUtilsImpl.java @@ -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> 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.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> 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.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> deleteTapiLink(DeleteTapiLinkInput input) { + // TODO: check if this IID is correct + // TODO --> need to check if the link exists in the topology + try { + InstanceIdentifier 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.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 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 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 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 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 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 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; + } +} diff --git a/tapi/src/main/resources/OSGI-INF/blueprint/tapi-blueprint.xml b/tapi/src/main/resources/OSGI-INF/blueprint/tapi-blueprint.xml index 314df38f6..70bbc9186 100644 --- a/tapi/src/main/resources/OSGI-INF/blueprint/tapi-blueprint.xml +++ b/tapi/src/main/resources/OSGI-INF/blueprint/tapi-blueprint.xml @@ -44,6 +44,10 @@ Author: Gilles Thouenon + + + + @@ -55,6 +59,7 @@ Author: Gilles Thouenon + -- 2.36.6