From fb4518248d42b89992a227c94fde2fe9d6fe4df5 Mon Sep 17 00:00:00 2001 From: Javier Errea Date: Wed, 3 Feb 2021 12:17:21 +0100 Subject: [PATCH] Initial OR-TAPI mapping: Topology - Creation of T0 - Full Multi-layer topology - Mapping OR topology to Full TAPI topology on feature install - Store Full TAPI Topology in T-API context - ConvertORTopoToTapiFullTopo.java used by the new mapping - Modification of TAPI node creation: added E_ODU and I_ODU - Mapping logic from Figure 6-9 of tapi-reference guide - Added "mandatory" fields to tapi nodes and topology - Removed CheckTP for OTN nodes. As it was forcing to do the OR-TAPI mapping only to the OTN nodes associated with XPDR links JIRA: TRNSPRTPCE-384 Change-Id: I0d69242cc586c01d4a55c936be60a372176885be Signed-off-by: errea --- .../transportpce/tapi/impl/TapiProvider.java | 10 +- .../topology/ConvertORTopoToTapiFullTopo.java | 1479 +++++++++++++++++ .../tapi/topology/TapiTopologyImpl.java | 83 +- .../tapi/topology/TopologyUtils.java | 260 ++- .../transportpce/tapi/utils/TapiContext.java | 44 + .../tapi/utils/TapiInitialORMapping.java | 46 + .../TapiTopologyImplExceptionTest.java | 33 +- .../tapi/topology/TapiTopologyImplTest.java | 21 +- .../tapi/utils/TapiTopologyDataUtils.java | 1 + tapi/src/test/resources/openroadm-network.xml | 76 + 10 files changed, 2012 insertions(+), 41 deletions(-) create mode 100644 tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/ConvertORTopoToTapiFullTopo.java create mode 100644 tapi/src/main/java/org/opendaylight/transportpce/tapi/utils/TapiInitialORMapping.java create mode 100644 tapi/src/test/resources/openroadm-network.xml 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 6bde010fd..e8c0bcadc 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 @@ -15,7 +15,9 @@ import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.transportpce.common.network.NetworkTransactionService; import org.opendaylight.transportpce.tapi.connectivity.TapiConnectivityImpl; import org.opendaylight.transportpce.tapi.topology.TapiTopologyImpl; +import org.opendaylight.transportpce.tapi.topology.TopologyUtils; import org.opendaylight.transportpce.tapi.utils.TapiContext; +import org.opendaylight.transportpce.tapi.utils.TapiInitialORMapping; import org.opendaylight.transportpce.tapi.utils.TapiListener; 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; @@ -60,8 +62,13 @@ public class TapiProvider { LOG.info("TapiProvider Session Initiated"); TapiContext tapiContext = new TapiContext(this.networkTransactionService); LOG.info("Empty TAPI context created: {}", tapiContext.getTapiContext()); + + TopologyUtils topologyUtils = new TopologyUtils(this.networkTransactionService, this.dataBroker); + TapiInitialORMapping tapiInitialORMapping = new TapiInitialORMapping(topologyUtils, tapiContext); + tapiInitialORMapping.performTopoInitialMapping(); + TapiConnectivityImpl tapi = new TapiConnectivityImpl(this.serviceHandler); - TapiTopologyImpl topo = new TapiTopologyImpl(this.dataBroker); + TapiTopologyImpl topo = new TapiTopologyImpl(this.dataBroker, tapiContext, topologyUtils); rpcRegistration = rpcProviderService.registerRpcImplementation(TapiConnectivityService.class, tapi); rpcProviderService.registerRpcImplementation(TapiTopologyService.class, topo); @NonNull @@ -77,5 +84,4 @@ public class TapiProvider { LOG.info("TapiProvider Session Closed"); rpcRegistration.close(); } - } diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/ConvertORTopoToTapiFullTopo.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/ConvertORTopoToTapiFullTopo.java new file mode 100644 index 000000000..eb6b0b9b4 --- /dev/null +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/ConvertORTopoToTapiFullTopo.java @@ -0,0 +1,1479 @@ +/* + * Copyright © 2021 Nokia. 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 java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.TerminationPoint1; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State; +import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.OduSwitchingPools; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.OduSwitchingPoolsBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingList; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingListBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingListKey; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmNodeType; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmTpType; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.xpdr.tp.supported.interfaces.SupportedInterfaceCapability; +import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.Link1; +import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.Node1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint; +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.ForwardingDirection; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LAYERPROTOCOLQUALIFIER; +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.PortDirection; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.PortRole; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.TerminationDirection; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.TerminationState; +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.common.rev181210.global._class.NameKey; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePoint; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePointBuilder; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePointKey; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPE100GigE; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPE10GigELAN; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU2; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU2E; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU4; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev181210.PHOTONICLAYERQUALIFIEROMS; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev181210.PHOTONICLAYERQUALIFIEROTSi; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.ForwardingRule; +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.RuleType; +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.NodeRuleGroup; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.NodeRuleGroupBuilder; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.NodeRuleGroupKey; +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.OwnedNodeEdgePointBuilder; +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.node.edge.point.MappedServiceInterfacePoint; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.edge.point.MappedServiceInterfacePointBuilder; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.edge.point.MappedServiceInterfacePointKey; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.Rule; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.RuleBuilder; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.RuleKey; +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.NodeBuilder; +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.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.common.Uint16; +import org.opendaylight.yangtools.yang.common.Uint64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class ConvertORTopoToTapiFullTopo { + + private static final String DSR = "DSR"; + private static final String I_ODU = "iODU"; + private static final String E_ODU = "eODU"; + private static final String OTSI = "OTSi"; + private static final String E_OTSI = "eOTSi"; + private static final String I_OTSI = "iOTSi"; + private static final String PHTNC_MEDIA = "PHOTONIC_MEDIA"; + private static final String MC = "MEDIA_CHANNEL"; + private static final String OTSI_MC = "OTSi_MEDIA_CHANNEL"; + private static final Logger LOG = LoggerFactory.getLogger(ConvertORTopoToTapiFullTopo.class); + private String ietfNodeId; + private OpenroadmNodeType ietfNodeType; + private AdminStates ietfNodeAdminState; + private State ietfNodeOperState; + private List oorClientPortList; + private List oorNetworkPortList; + private OduSwitchingPools oorOduSwitchingPool; + private Uuid tapiTopoUuid; + private Map + tapiNodes; + private Map tapiLinks; + private Map tapiSips; + private Map uuidMap; + + + public ConvertORTopoToTapiFullTopo(Uuid tapiTopoUuid) { + this.tapiTopoUuid = tapiTopoUuid; + this.tapiNodes = new HashMap<>(); + this.tapiLinks = new HashMap<>(); + this.uuidMap = new HashMap<>(); + this.tapiSips = new HashMap<>(); + } + + public void convertNode(Node ietfNode, List networkPorts) { + this.ietfNodeId = ietfNode.getNodeId().getValue(); + if (ietfNode.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1.class) + == null) { + return; + } + this.ietfNodeType = ietfNode.augmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1.class).getNodeType(); + this.ietfNodeAdminState = ietfNode.augmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1.class) + .getAdministrativeState(); + this.ietfNodeOperState = ietfNode.augmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1.class) + .getOperationalState(); + this.oorNetworkPortList = ietfNode.augmentation( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class) + .getTerminationPoint().values().stream() + .filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue() + == OpenroadmTpType.XPONDERNETWORK.getIntValue() + && networkPorts.contains(tp.getTpId().getValue())) + .sorted((tp1, tp2) -> tp1.getTpId().getValue().compareTo(tp2.getTpId().getValue())) + .collect(Collectors.toList()); + if (!OpenroadmNodeType.TPDR.equals(this.ietfNodeType)) { + this.oorOduSwitchingPool = ietfNode.augmentation(Node1.class).getSwitchingPools().getOduSwitchingPools() + .values().stream().findFirst().get(); + this.oorClientPortList = ietfNode.augmentation( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class) + .getTerminationPoint().values().stream() + .filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue() + == OpenroadmTpType.XPONDERCLIENT.getIntValue()) + .sorted((tp1, tp2) -> tp1.getTpId().getValue().compareTo(tp2.getTpId().getValue())) + .collect(Collectors.toList()); + } else { + this.oorOduSwitchingPool = createOduSwitchingPoolForTp100G(); + List tpList = this.oorOduSwitchingPool.getNonBlockingList().values().stream() + .flatMap(nbl -> nbl.getTpList().stream()) + .collect(Collectors.toList()); + this.oorClientPortList = ietfNode.augmentation( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class) + .getTerminationPoint().values().stream() + .filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue() + == OpenroadmTpType.XPONDERCLIENT.getIntValue() && tpList.contains(tp.getTpId())) + .sorted((tp1, tp2) -> tp1.getTpId().getValue().compareTo(tp2.getTpId().getValue())) + .collect(Collectors.toList()); + this.oorClientPortList.forEach(tp -> LOG.info("tp = {}", tp.getTpId())); + } + + // node creation [DSR/ODU] + LOG.info("creation of a DSR/ODU node for {}", this.ietfNodeId); + Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", this.ietfNodeId, DSR)) + .getBytes(Charset.forName("UTF-8"))).toString()); + this.uuidMap.put(String.join("+", this.ietfNodeId, DSR), nodeUuid); + Name nameDsr = new NameBuilder().setValueName("dsr/odu node name").setValue( + String.join("+", this.ietfNodeId, DSR)).build(); + List dsrLayerProtocols = Arrays.asList(LayerProtocolName.DSR, LayerProtocolName.ODU); + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology + .Node dsrNode = createTapiNode(Map.of(nameDsr.key(), nameDsr), dsrLayerProtocols); + LOG.info("DSR Node {} should have {} NEPs and {} SIPs", this.ietfNodeId, + this.oorClientPortList.size() + 2 * this.oorNetworkPortList.size(), + this.oorClientPortList.size() + this.oorNetworkPortList.size()); + LOG.info("DSR Node {} has {} NEPs and {} SIPs", this.ietfNodeId, + dsrNode.getOwnedNodeEdgePoint().values().size(), dsrNode.getOwnedNodeEdgePoint().values().stream() + .filter(nep -> nep.getMappedServiceInterfacePoint() != null).count()); + tapiNodes.put(dsrNode.key(), dsrNode); + + // node creation [otsi] + LOG.info("creation of an OTSi node for {}", this.ietfNodeId); + nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", this.ietfNodeId, OTSI)) + .getBytes(Charset.forName("UTF-8"))).toString()); + this.uuidMap.put(String.join("+", this.ietfNodeId, OTSI), nodeUuid); + Name nameOtsi = new NameBuilder().setValueName("otsi node name").setValue( + String.join("+", this.ietfNodeId, OTSI)).build(); + List otsiLayerProtocols = Arrays.asList(LayerProtocolName.PHOTONICMEDIA); + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology + .Node otsiNode = createTapiNode(Map.of(nameOtsi.key(), nameOtsi), otsiLayerProtocols); + LOG.info("OTSi Node {} should have {} NEPs and {} SIPs", this.ietfNodeId, 3 * this.oorNetworkPortList.size(), + this.oorNetworkPortList.size()); + LOG.info("OTSi Node {} has {} NEPs and {} SIPs", this.ietfNodeId, + otsiNode.getOwnedNodeEdgePoint().values().size(), otsiNode.getOwnedNodeEdgePoint().values().stream() + .filter(nep -> nep.getMappedServiceInterfacePoint() != null).count()); + tapiNodes.put(otsiNode.key(), otsiNode); + + // transitional link cration between network nep of DSR/ODU node and iNep of otsi node + LOG.info("creation of transitional links between DSR/ODU and OTSi nodes"); + createTapiTransitionalLinks(); + } + + public void convertLinks( + Map otnLinkMap) { + List otnLinkList = new ArrayList<>(otnLinkMap.values()); + Collections.sort(otnLinkList, (l1, l2) -> l1.getLinkId().getValue() + .compareTo(l2.getLinkId().getValue())); + List linksToNotConvert = new ArrayList<>(); + LOG.info("creation of {} otn links", otnLinkMap.size() / 2); + for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network + .Link otnlink : otnLinkList) { + if (!linksToNotConvert.contains(otnlink.getLinkId().getValue())) { + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks + .network.Link oppositeLink = otnLinkMap.get(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns + .yang.ietf.network.topology.rev180226.networks.network.LinkKey(otnlink.augmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class) + .getOppositeLink())); + Link tapiLink = createTapiLink(otnlink, oppositeLink); + linksToNotConvert.add(oppositeLink.getLinkId().getValue()); + tapiLinks.put(tapiLink.key(), tapiLink); + } + } + } + + public void convertRdmToRdmLinks(List rdmTordmLinkList) { + List linksToNotConvert = new ArrayList<>(); + LOG.info("creation of {} roadm to roadm links", rdmTordmLinkList.size() / 2); + for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network + .Link link : rdmTordmLinkList) { + if (!linksToNotConvert.contains(link.getLinkId().getValue())) { + Link tapiLink = createTapiOmsLink(link); + linksToNotConvert.add(link + .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class) + .getOppositeLink().getValue()); + tapiLinks.put(tapiLink.key(), tapiLink); + } + } + } + + public void convertRoadmNode(Node roadm, Network openroadmTopo) { + Map oneplist = new HashMap<>(); + // 1. Get degree and srg nodes to map TPs into NEPs + if (openroadmTopo.getNode() == null) { + LOG.warn("Openroadm-topology is null."); + return; + } + int numNeps = 0; + int numSips = 0; + List nodeList = new ArrayList(openroadmTopo.getNode().values()); + for (Node node:nodeList) { + if (node.getSupportingNode().values().stream().noneMatch(sp -> sp.getNodeRef().getValue() + .equals(roadm.getNodeId().getValue()))) { + LOG.warn("Abstracted node {} is not part of {}", + node.getNodeId().getValue(), roadm.getNodeId().getValue()); + continue; + } + if (node.augmentation(Node1.class) == null + && node.augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.network.topology.rev180226.Node1.class) == null) { + LOG.warn("Abstracted node {} doesnt have type of node or is not disaggregated", + node.getNodeId().getValue()); + continue; + } + OpenroadmNodeType nodeType = node.augmentation(org.opendaylight.yang.gen.v1.http + .org.openroadm.common.network.rev200529.Node1.class).getNodeType(); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1 node1 = + node.augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.network.topology.rev180226.Node1.class); + LOG.info("TPs of node: {}", node1.getTerminationPoint().values()); + switch (nodeType.getIntValue()) { + case 11: + LOG.info("Degree node"); + // Get only external TPs of the degree + List degPortList = node1.getTerminationPoint().values().stream() + .filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue() + == OpenroadmTpType.DEGREETXRXTTP.getIntValue() + || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue() + == OpenroadmTpType.DEGREERXTTP.getIntValue() + || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue() + == OpenroadmTpType.DEGREETXTTP.getIntValue()) + .collect(Collectors.toList()); + // Convert TP List in NEPs and put it in onepl + LOG.info("Degree port List: {}", degPortList); + // TODO: deg port could be sip. e.g. MDONS + oneplist.putAll(populateNepsForRdmNode(roadm.getNodeId().getValue(), degPortList, false)); + // oneplist.putAll(populateNepsForRdmNode(node.getNodeId().getValue(), degPortList, false)); + numNeps += degPortList.size() * 3; + break; + case 12: + LOG.info("SRG node"); + // Get only external TPs of the srg + List srgPortList = node1.getTerminationPoint().values().stream() + .filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue() + == OpenroadmTpType.SRGTXRXPP.getIntValue() + || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue() + == OpenroadmTpType.SRGRXPP.getIntValue() + || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue() + == OpenroadmTpType.SRGTXPP.getIntValue()) + .collect(Collectors.toList()); + // Convert TP List in NEPs and put it in onepl + LOG.info("Srg port List: {}", srgPortList); + oneplist.putAll(populateNepsForRdmNode(roadm.getNodeId().getValue(), srgPortList, true)); + // oneplist.putAll(populateNepsForRdmNode(node.getNodeId().getValue(), srgPortList, true)); + numNeps += srgPortList.size() * 3; + numSips += srgPortList.size(); + break; + default: + LOG.error("Node {} tyoe not supported", nodeType.getName()); + } + } + // create tapi Node + // UUID + LOG.info("Creation of PHOTONIC node for {}", roadm.getNodeId().getValue()); + Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", roadm.getNodeId().getValue(), + PHTNC_MEDIA)).getBytes(Charset.forName("UTF-8"))).toString()); + // Names + Name nodeNames = new NameBuilder().setValueName("roadm node name") + .setValue(String.join("+", roadm.getNodeId().getValue(), PHTNC_MEDIA)).build(); + // Protocol Layer + List layerProtocols = Arrays.asList(LayerProtocolName.PHOTONICMEDIA); + // Build tapi node + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology + .Node roadmNode = createRoadmTapiNode(nodeUuid, nodeNames, layerProtocols, oneplist); + // TODO add states corresponding to device config + LOG.info("ROADM node {} should have {} NEPs and {} SIPs", roadm.getNodeId().getValue(), numNeps, numSips); + LOG.info("ROADM node {} has {} NEPs and {} SIPs", roadm.getNodeId().getValue(), + roadmNode.getOwnedNodeEdgePoint().values().size(), + roadmNode.getOwnedNodeEdgePoint().values().stream() + .filter(nep -> nep.getMappedServiceInterfacePoint() != null).count()); + + tapiNodes.put(roadmNode.key(), roadmNode); + } + + private OduSwitchingPools createOduSwitchingPoolForTp100G() { + Map nblMap = new HashMap<>(); + int count = 1; + for (TerminationPoint tp : this.oorNetworkPortList) { + TpId tpid1 = tp.getTpId(); + TpId tpid2 = new TpId(tp.augmentation( + org.opendaylight.yang.gen.v1.http.transportpce.topology.rev201019.TerminationPoint1.class) + .getAssociatedConnectionMapPort()); + List tpList = new ArrayList<>(); + tpList.add(tpid1); + tpList.add(tpid2); + NonBlockingList nbl = new NonBlockingListBuilder() + .setNblNumber(Uint16.valueOf(count)) + .setTpList(tpList) + .build(); + nblMap.put(nbl.key(), nbl); + count++; + } + return new OduSwitchingPoolsBuilder() + .setNonBlockingList(nblMap) + .setSwitchingPoolNumber(Uint16.valueOf(1)) + .build(); + } + + private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node + createTapiNode(Map nodeNames, List layerProtocols) { + Uuid nodeUuid = null; + Map onepl = new HashMap<>(); + Map nodeRuleGroupList = new HashMap<>(); + Map ruleList = new HashMap<>(); + Rule rule = new RuleBuilder() + .setLocalId("forward") + .setForwardingRule(ForwardingRule.MAYFORWARDACROSSGROUP) + .setRuleType(RuleType.FORWARDING) + .build(); + ruleList.put(rule.key(), rule); + if (layerProtocols.contains(LayerProtocolName.DSR)) { + nodeUuid = getNodeUuid4Dsr(onepl, nodeRuleGroupList, ruleList); + } else if (layerProtocols.contains(LayerProtocolName.PHOTONICMEDIA)) { + nodeUuid = getNodeUuid4Photonic(onepl, nodeRuleGroupList, ruleList); + } else { + LOG.error("Undefined LayerProtocolName for {} node {}", nodeNames.get(nodeNames.keySet().iterator().next()) + .getValueName(), nodeNames.get(nodeNames.keySet().iterator().next()).getValue()); + } + // Empty random creation of mandatory fields for avoiding errors.... + 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(); + return new NodeBuilder() + .setUuid(nodeUuid) + .setName(nodeNames) + .setLayerProtocolName(layerProtocols) + .setAdministrativeState(setTapiAdminState(this.ietfNodeAdminState)) + .setOperationalState(setTapiOperationalState(this.ietfNodeOperState)) + .setLifecycleState(LifecycleState.INSTALLED) + .setOwnedNodeEdgePoint(onepl) + .setNodeRuleGroup(nodeRuleGroupList) + .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic)) + .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic)) + .setErrorCharacteristic("error") + .setLossCharacteristic("loss") + .setRepeatDeliveryCharacteristic("repeat delivery") + .setDeliveryOrderCharacteristic("delivery order") + .setUnavailableTimeCharacteristic("unavailable time") + .setServerIntegrityProcessCharacteristic("server integrity process") + .build(); + } + + private AdministrativeState setTapiAdminState(AdminStates adminState) { + if (adminState == null) { + return null; + } + return adminState.equals(AdminStates.InService) + ? AdministrativeState.UNLOCKED : AdministrativeState.LOCKED; + } + + private AdministrativeState setTapiAdminState(AdminStates adminState1, AdminStates adminState2) { + if (adminState1 == null || adminState2 == null) { + return null; + } + LOG.info("Admin state 1 = {}, andmin state 2 = {}", adminState1.getName(), adminState2.getName()); + if (AdminStates.InService.equals(adminState1) && AdminStates.InService.equals(adminState2)) { + return AdministrativeState.UNLOCKED; + } else { + return AdministrativeState.LOCKED; + } + } + + private OperationalState setTapiOperationalState(State operState) { + if (operState == null) { + return null; + } + return operState.getName().equals("inService") ? OperationalState.ENABLED : OperationalState.DISABLED; + } + + private OperationalState setTapiOperationalState(State operState1, State operState2) { + if (operState1 == null || operState2 == null) { + return null; + } + LOG.info("Oper state 1 = {}, Oper state 2 = {}", operState1.getName(), operState2.getName()); + if (State.InService.equals(operState1) && State.InService.equals(operState2)) { + return OperationalState.ENABLED; + } else { + return OperationalState.DISABLED; + } + } + + private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node + createRoadmTapiNode(Uuid nodeUuid, Name nodeNames, List layerProtocols, + Map oneplist) { + // Empty random creation of mandatory fields for avoiding errors.... + 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(); + return new NodeBuilder() + .setUuid(nodeUuid) + .setName(Map.of(nodeNames.key(), nodeNames)) + .setLayerProtocolName(layerProtocols) + .setAdministrativeState(AdministrativeState.UNLOCKED) + .setOperationalState(OperationalState.ENABLED) + .setLifecycleState(LifecycleState.INSTALLED) + .setOwnedNodeEdgePoint(oneplist) + .setNodeRuleGroup(createNodeRuleGroupForRdmNode(nodeUuid, oneplist.values())) + .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic)) + .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic)) + .setErrorCharacteristic("error") + .setLossCharacteristic("loss") + .setRepeatDeliveryCharacteristic("repeat delivery") + .setDeliveryOrderCharacteristic("delivery order") + .setUnavailableTimeCharacteristic("unavailable time") + .setServerIntegrityProcessCharacteristic("server integrity process") + .build(); + } + + private Uuid getNodeUuid4Photonic(Map onepl, + Map nodeRuleGroupList, + Map ruleList) { + Uuid nodeUuid; + nodeUuid = this.uuidMap.get(String.join("+", this.ietfNodeId, OTSI)); + // iNep creation on otsi node + for (int i = 0; i < oorNetworkPortList.size(); i++) { + LOG.info("NEP = {}", String.join("+", this.ietfNodeId, I_OTSI, + oorNetworkPortList.get(i).getTpId().getValue())); + Uuid nepUuid1 = new Uuid(UUID.nameUUIDFromBytes( + (String.join("+", this.ietfNodeId, I_OTSI, oorNetworkPortList.get(i).getTpId().getValue())) + .getBytes(Charset.forName("UTF-8"))) + .toString()); + this.uuidMap.put(String.join("+", this.ietfNodeId, I_OTSI, + oorNetworkPortList.get(i).getTpId().getValue()), nepUuid1); + Name onedName = new NameBuilder() + .setValueName("iNodeEdgePoint") + .setValue(String.join("+", this.ietfNodeId, I_OTSI, oorNetworkPortList.get(i).getTpId().getValue())) + .build(); + + OwnedNodeEdgePoint onep = createNep(oorNetworkPortList.get(i), Map.of(onedName.key(), onedName), + LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.PHOTONICMEDIA, true, + String.join("+", this.ietfNodeId, I_OTSI)); + onepl.put(onep.key(), onep); + } + // eNep creation on otsi node + for (int i = 0; i < oorNetworkPortList.size(); i++) { + LOG.info("NEP = {}", String.join("+", this.ietfNodeId, E_OTSI, + oorNetworkPortList.get(i).getTpId().getValue())); + Uuid nepUuid2 = new Uuid(UUID.nameUUIDFromBytes( + (String.join("+", this.ietfNodeId, E_OTSI, oorNetworkPortList.get(i).getTpId().getValue())) + .getBytes(Charset.forName("UTF-8"))) + .toString()); + this.uuidMap.put(String.join("+", this.ietfNodeId, E_OTSI, + oorNetworkPortList.get(i).getTpId().getValue()), nepUuid2); + Name onedName = new NameBuilder() + .setValueName("eNodeEdgePoint") + .setValue(String.join("+", this.ietfNodeId, E_OTSI, oorNetworkPortList.get(i).getTpId().getValue())) + .build(); + + OwnedNodeEdgePoint onep = createNep(oorNetworkPortList.get(i), Map.of(onedName.key(), onedName), + LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.PHOTONICMEDIA, false, + String.join("+", this.ietfNodeId, E_OTSI)); + onepl.put(onep.key(), onep); + } + // Photonic Media Nep creation on otsi node + for (int i = 0; i < oorNetworkPortList.size(); i++) { + LOG.info("NEP = {}", String.join("+", this.ietfNodeId, PHTNC_MEDIA, + oorNetworkPortList.get(i).getTpId().getValue())); + Uuid nepUuid3 = new Uuid(UUID.nameUUIDFromBytes( + (String.join("+", this.ietfNodeId, PHTNC_MEDIA, + oorNetworkPortList.get(i).getTpId().getValue())).getBytes(Charset.forName("UTF-8"))) + .toString()); + this.uuidMap.put(String.join("+", this.ietfNodeId, PHTNC_MEDIA, + oorNetworkPortList.get(i).getTpId().getValue()), nepUuid3); + Name onedName = new NameBuilder() + .setValueName("PhotMedNodeEdgePoint") + .setValue(String.join("+", this.ietfNodeId, PHTNC_MEDIA, + oorNetworkPortList.get(i).getTpId().getValue())) + .build(); + + OwnedNodeEdgePoint onep = createNep(oorNetworkPortList.get(i), Map.of(onedName.key(), onedName), + LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.PHOTONICMEDIA, false, + String.join("+", this.ietfNodeId, PHTNC_MEDIA)); + onepl.put(onep.key(), onep); + } + // create NodeRuleGroup + int count = 1; + LOG.info("OTSi switching pool = {}", this.oorOduSwitchingPool.nonnullNonBlockingList().values()); + for (TerminationPoint tp : this.oorNetworkPortList) { + Map + nepList = new HashMap<>(); + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group + .NodeEdgePoint inep = new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210 + .node.rule.group.NodeEdgePointBuilder() + .setTopologyUuid(tapiTopoUuid) + .setNodeUuid(this.uuidMap.get(String.join("+", this.ietfNodeId, OTSI))) + .setNodeEdgePointUuid( + this.uuidMap.get(String.join("+", this.ietfNodeId, I_OTSI, tp.getTpId().getValue()))) + .build(); + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group + .NodeEdgePoint enep = new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210 + .node.rule.group.NodeEdgePointBuilder() + .setTopologyUuid(tapiTopoUuid) + .setNodeUuid(this.uuidMap.get(String.join("+", this.ietfNodeId, OTSI))) + .setNodeEdgePointUuid( + this.uuidMap.get(String.join("+", this.ietfNodeId, E_OTSI, tp.getTpId().getValue()))) + .build(); + nepList.put(inep.key(), inep); + nepList.put(enep.key(), enep); + // Empty random creation of mandatory fields for avoiding errors.... + 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(); + NodeRuleGroup nodeRuleGroup = new NodeRuleGroupBuilder() + .setUuid(new Uuid( + UUID.nameUUIDFromBytes(("otsi node rule group " + count).getBytes(Charset.forName("UTF-8"))) + .toString())) + .setRule(ruleList) + .setNodeEdgePoint(nepList) + .setRiskCharacteristic(Map.of(riskCharacteristic.key(), riskCharacteristic)) + .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic)) + .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic)) + .build(); + nodeRuleGroupList.put(nodeRuleGroup.key(), nodeRuleGroup); + count++; + } + return nodeUuid; + } + + private Uuid getNodeUuid4Dsr(Map onepl, + Map nodeRuleGroupList, Map ruleList) { + Uuid nodeUuid; + nodeUuid = this.uuidMap.get(String.join("+", this.ietfNodeId, DSR)); + // client nep creation on DSR node + for (int i = 0; i < oorClientPortList.size(); i++) { + LOG.info("NEP = {}", String.join("+", this.ietfNodeId, DSR, + oorClientPortList.get(i).getTpId().getValue())); + Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes( + (String.join("+", this.ietfNodeId, DSR, oorClientPortList.get(i).getTpId().getValue())) + .getBytes(Charset.forName("UTF-8"))).toString()); + this.uuidMap.put(String.join("+", this.ietfNodeId, DSR, oorClientPortList.get(i).getTpId().getValue()), + nepUuid); + NameBuilder nameBldr = new NameBuilder().setValue( + String.join("+", this.ietfNodeId, DSR, oorClientPortList.get(i).getTpId().getValue())); + Name name; + if (OpenroadmNodeType.TPDR.equals(this.ietfNodeType)) { + name = nameBldr.setValueName("100G-tpdr").build(); + } else { + name = nameBldr.setValueName("NodeEdgePoint_C").build(); + } + + OwnedNodeEdgePoint onep = createNep(oorClientPortList.get(i), Map.of(name.key(), name), + LayerProtocolName.DSR, LayerProtocolName.DSR, true, String.join("+", this.ietfNodeId, DSR)); + onepl.put(onep.key(), onep); + } + // network nep creation on I_ODU node + for (int i = 0; i < oorNetworkPortList.size(); i++) { + LOG.info("NEP = {}", String.join("+", this.ietfNodeId, I_ODU, + oorNetworkPortList.get(i).getTpId().getValue())); + Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes( + (String.join("+", this.ietfNodeId, I_ODU, oorNetworkPortList.get(i).getTpId().getValue())) + .getBytes(Charset.forName("UTF-8"))).toString()); + this.uuidMap.put(String.join("+", this.ietfNodeId, I_ODU, oorNetworkPortList.get(i).getTpId().getValue()), + nepUuid); + Name onedName = new NameBuilder() + .setValueName("iNodeEdgePoint_N") + .setValue(String.join("+", this.ietfNodeId, I_ODU, oorNetworkPortList.get(i).getTpId().getValue())) + .build(); + + OwnedNodeEdgePoint onep = createNep(oorNetworkPortList.get(i), Map.of(onedName.key(), onedName), + LayerProtocolName.ODU, LayerProtocolName.DSR, false, String.join("+", this.ietfNodeId, I_ODU)); + onepl.put(onep.key(), onep); + } + // network nep creation on E_ODU node + for (int i = 0; i < oorNetworkPortList.size(); i++) { + LOG.info("NEP = {}", String.join("+", this.ietfNodeId, E_ODU, + oorNetworkPortList.get(i).getTpId().getValue())); + Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes( + (String.join("+", this.ietfNodeId, E_ODU, oorNetworkPortList.get(i).getTpId().getValue())) + .getBytes(Charset.forName("UTF-8"))).toString()); + this.uuidMap.put(String.join("+", this.ietfNodeId, E_ODU, oorNetworkPortList.get(i).getTpId().getValue()), + nepUuid); + Name onedName = new NameBuilder() + .setValueName("eNodeEdgePoint_N") + .setValue(String.join("+", this.ietfNodeId, E_ODU, oorNetworkPortList.get(i).getTpId().getValue())) + .build(); + + OwnedNodeEdgePoint onep = createNep(oorNetworkPortList.get(i), Map.of(onedName.key(), onedName), + LayerProtocolName.ODU, LayerProtocolName.DSR, true, String.join("+", this.ietfNodeId, E_ODU)); + onepl.put(onep.key(), onep); + } + // create NodeRuleGroup + int count = 1; + LOG.info("ODU switching pool = {}", this.oorOduSwitchingPool.nonnullNonBlockingList().values()); + for (NonBlockingList nbl : this.oorOduSwitchingPool.nonnullNonBlockingList().values()) { + Map + nepList = new HashMap<>(); + LOG.info("UUidMap={}", this.uuidMap.keySet()); + LOG.info("TP list = {}", nbl.getTpList()); + for (TpId tp : nbl.getTpList()) { + LOG.info("TP={}", tp.getValue()); + LOG.info("UuidKey={}", String.join("+", this.ietfNodeId, E_ODU, tp.getValue())); + if (this.uuidMap.containsKey(String.join("+", this.ietfNodeId, E_ODU, tp.getValue())) + || this.uuidMap.containsKey(String.join("+", this.ietfNodeId, DSR, tp.getValue()))) { + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint + nep = new org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePointBuilder() + .setTopologyUuid(tapiTopoUuid) + .setNodeUuid(this.uuidMap.get(String.join("+", this.ietfNodeId, DSR))) + .setNodeEdgePointUuid((tp.getValue().contains("CLIENT")) ? this.uuidMap.get(String.join( + "+", this.ietfNodeId, DSR, tp.getValue())) : this.uuidMap.get(String.join( + "+", this.ietfNodeId, E_ODU, tp.getValue()))) + .build(); + nepList.put(nep.key(), nep); + } + } + // Empty random creation of mandatory fields for avoiding errors.... + 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(); + NodeRuleGroup nodeRuleGroup = new NodeRuleGroupBuilder() + .setUuid(new Uuid(UUID.nameUUIDFromBytes(("dsr node rule group " + count) + .getBytes(Charset.forName("UTF-8"))).toString())) + .setRule(ruleList) + .setNodeEdgePoint(nepList) + .setRiskCharacteristic(Map.of(riskCharacteristic.key(), riskCharacteristic)) + .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic)) + .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic)) + .build(); + nodeRuleGroupList.put(nodeRuleGroup.key(), nodeRuleGroup); + count++; + } + return nodeUuid; + } + + private OwnedNodeEdgePoint createNep(TerminationPoint oorTp, Map nepNames, + LayerProtocolName nepProtocol, LayerProtocolName nodeProtocol, boolean withSip, + String keyword) { + String key = String.join("+", keyword, oorTp.getTpId().getValue()); + OwnedNodeEdgePointBuilder onepBldr = new OwnedNodeEdgePointBuilder() + .setUuid(this.uuidMap.get(key)) + .setLayerProtocolName(nepProtocol) + .setName(nepNames); + if (withSip) { + onepBldr.setMappedServiceInterfacePoint(createMSIP(1, nepProtocol, oorTp, keyword)); + } + onepBldr.setSupportedCepLayerProtocolQualifier(createSupportedLayerProtocolQualifier(oorTp, nodeProtocol)) + .setLinkPortDirection(PortDirection.BIDIRECTIONAL) + .setLinkPortRole(PortRole.SYMMETRIC) + .setAdministrativeState(setTapiAdminState( + oorTp.augmentation(TerminationPoint1.class).getAdministrativeState())) + .setOperationalState(setTapiOperationalState( + oorTp.augmentation(TerminationPoint1.class).getOperationalState())) + .setLifecycleState(LifecycleState.INSTALLED) + .setTerminationDirection(TerminationDirection.BIDIRECTIONAL) + .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL); + return onepBldr.build(); + } + + private Map populateNepsForRdmNode(String nodeId, + List tpList, + boolean withSip) { + // create neps for MC and OTSiMC and Photonic Media + Map onepMap = new HashMap<>(); + for (int i = 0; i < tpList.size(); i++) { + // PHOTONIC MEDIA nep + LOG.info("NEP = {}", String.join("+", nodeId, PHTNC_MEDIA, tpList.get(i).getTpId().getValue())); + Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", nodeId, PHTNC_MEDIA, + tpList.get(i).getTpId().getValue())) + .getBytes(Charset.forName("UTF-8"))) + .toString()); + Name nepName = new NameBuilder() + .setValueName("NodeEdgePoint name") + .setValue(String.join("+", nodeId, PHTNC_MEDIA, tpList.get(i).getTpId().getValue())) + .build(); + OwnedNodeEdgePointBuilder onepBldr = new OwnedNodeEdgePointBuilder() + .setUuid(nepUuid) + .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA) + .setName(Map.of(nepName.key(), nepName)) + .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class)) + .setLinkPortDirection(PortDirection.BIDIRECTIONAL) + .setLinkPortRole(PortRole.SYMMETRIC) + .setAdministrativeState(AdministrativeState.UNLOCKED) + .setOperationalState(OperationalState.ENABLED) + .setLifecycleState(LifecycleState.INSTALLED) + .setTerminationDirection(TerminationDirection.BIDIRECTIONAL) + .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL); + OwnedNodeEdgePoint onep = onepBldr.build(); + onepMap.put(onep.key(), onep); + } + for (int i = 0; i < tpList.size(); i++) { + // MC nep + LOG.info("NEP = {}", String.join("+", nodeId, MC, tpList.get(i).getTpId().getValue())); + Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", nodeId, MC, + tpList.get(i).getTpId().getValue())) + .getBytes(Charset.forName("UTF-8"))) + .toString()); + Name nepName = new NameBuilder() + .setValueName("NodeEdgePoint name") + .setValue(String.join("+", nodeId, MC, tpList.get(i).getTpId().getValue())) + .build(); + OwnedNodeEdgePointBuilder onepBldr = new OwnedNodeEdgePointBuilder() + .setUuid(nepUuid) + .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA) + .setName(Map.of(nepName.key(), nepName)) + .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class)) + .setLinkPortDirection(PortDirection.BIDIRECTIONAL) + .setLinkPortRole(PortRole.SYMMETRIC) + .setAdministrativeState(AdministrativeState.UNLOCKED) + .setOperationalState(OperationalState.ENABLED) + .setLifecycleState(LifecycleState.INSTALLED) + .setTerminationDirection(TerminationDirection.BIDIRECTIONAL) + .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL); + if (withSip) { + onepBldr.setMappedServiceInterfacePoint(createMSIP(1, LayerProtocolName.PHOTONICMEDIA, + tpList.get(i), String.join("+", nodeId, MC))); + } + OwnedNodeEdgePoint onep = onepBldr.build(); + onepMap.put(onep.key(), onep); + } + for (int i = 0; i < tpList.size(); i++) { + // OTSiMC nep + LOG.info("NEP = {}", String.join("+", nodeId, OTSI_MC, tpList.get(i).getTpId().getValue())); + Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", nodeId, OTSI_MC, + tpList.get(i).getTpId().getValue())) + .getBytes(Charset.forName("UTF-8"))) + .toString()); + Name nepName = new NameBuilder() + .setValueName("NodeEdgePoint name") + .setValue(String.join("+", nodeId, OTSI_MC, tpList.get(i).getTpId().getValue())) + .build(); + OwnedNodeEdgePointBuilder onepBldr = new OwnedNodeEdgePointBuilder() + .setUuid(nepUuid) + .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA) + .setName(Map.of(nepName.key(), nepName)) + .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class)) + .setLinkPortDirection(PortDirection.BIDIRECTIONAL) + .setLinkPortRole(PortRole.SYMMETRIC) + .setAdministrativeState(AdministrativeState.UNLOCKED) + .setOperationalState(OperationalState.ENABLED) + .setLifecycleState(LifecycleState.INSTALLED) + .setTerminationDirection(TerminationDirection.BIDIRECTIONAL) + .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL); + OwnedNodeEdgePoint onep = onepBldr.build(); + onepMap.put(onep.key(), onep); + } + return onepMap; + } + + private Map createNodeRuleGroupForRdmNode(Uuid nodeUuid, + Collection onepl) { + Map + nepMap = new HashMap<>(); + for (OwnedNodeEdgePoint onep : onepl) { + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint + nep = new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group + .NodeEdgePointBuilder() + .setTopologyUuid(tapiTopoUuid) + .setNodeUuid(nodeUuid) + .setNodeEdgePointUuid(onep.key().getUuid()) + .build(); + nepMap.put(nep.key(), nep); + } + Map nodeRuleGroupMap = new HashMap<>(); + Map ruleList = new HashMap<>(); + Rule rule = new RuleBuilder() + .setLocalId("forward") + .setForwardingRule(ForwardingRule.MAYFORWARDACROSSGROUP) + .setRuleType(RuleType.FORWARDING) + .build(); + ruleList.put(rule.key(), rule); + NodeRuleGroup nodeRuleGroup = new NodeRuleGroupBuilder() + .setUuid(new Uuid(UUID.nameUUIDFromBytes(("rdm infra node rule group").getBytes(Charset.forName("UTF-8"))) + .toString())) + .setRule(ruleList) + .setNodeEdgePoint(nepMap) + .build(); + nodeRuleGroupMap.put(nodeRuleGroup.key(), nodeRuleGroup); + return nodeRuleGroupMap; + } + + private Map createMSIP(int nb, + LayerProtocolName layerProtocol, + TerminationPoint tp, + String nodeid) { + // add them to SIP context + Map msipl = new HashMap<>(); + for (int i = 0; i < nb; i++) { + LOG.info("SIP = {}", String.join("+", "SIP", nodeid, tp.getTpId().getValue())); + Uuid sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", nodeid, + tp.getTpId().getValue())).getBytes(Charset.forName("UTF-8"))).toString()); + MappedServiceInterfacePoint msip = new MappedServiceInterfacePointBuilder() + .setServiceInterfacePointUuid(sipUuid).build(); + ServiceInterfacePoint sip = createSIP(sipUuid, layerProtocol, tp, nodeid); + this.tapiSips.put(sip.key(), sip); + msipl.put(msip.key(), msip); + } + return msipl; + } + + private ServiceInterfacePoint createSIP(Uuid sipUuid, LayerProtocolName layerProtocol, TerminationPoint tp, + String nodeid) { + // TODO: what value should be set in total capacity and available capacity?? + // LOG.info("SIP name = {}", String.join("+", nodeid, tp.getTpId().getValue())); + Name sipName = new NameBuilder() + .setValueName("SIP name") + .setValue(String.join("+", nodeid, tp.getTpId().getValue())) + .build(); + return new ServiceInterfacePointBuilder() + .setUuid(sipUuid) + .setName(Map.of(sipName.key(), sipName)) + .setLayerProtocolName(layerProtocol) + .setAdministrativeState(AdministrativeState.UNLOCKED) + .setOperationalState(OperationalState.ENABLED) + .setLifecycleState(LifecycleState.INSTALLED) + .setAvailableCapacity(new AvailableCapacityBuilder().build()) + .setTotalPotentialCapacity(new TotalPotentialCapacityBuilder().build()) + .setSupportedLayerProtocolQualifier(createSupportedLayerProtocolQualifier(tp, layerProtocol)) + .build(); + } + + private List> createSupportedLayerProtocolQualifier(TerminationPoint tp, + LayerProtocolName lpn) { + Set> sclpqSet = new HashSet<>(); + List sicList; + org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.TerminationPoint1 tp1 = + tp.augmentation(org.opendaylight.yang.gen.v1.http + .org.openroadm.otn.network.topology.rev200529.TerminationPoint1.class); + if (tp1 == null) { + return new ArrayList<>(sclpqSet); + } + if (tp1.getTpSupportedInterfaces() == null) { + LOG.warn("Tp supported interface doesnt exist on TP {}", tp.getTpId().getValue()); + return new ArrayList<>(sclpqSet); + } + sicList = new ArrayList<>(tp1.getTpSupportedInterfaces().getSupportedInterfaceCapability().values()); + for (SupportedInterfaceCapability sic : sicList) { + switch (lpn.getName()) { + case "DSR": + switch (sic.getIfCapType().getSimpleName()) { + case "If10GEODU2e": + sclpqSet.add(ODUTYPEODU2E.class); + sclpqSet.add(DIGITALSIGNALTYPE10GigELAN.class); + break; + case "If10GEODU2": + sclpqSet.add(ODUTYPEODU2.class); + sclpqSet.add(DIGITALSIGNALTYPE10GigELAN.class); + break; + case "If10GE": + sclpqSet.add(DIGITALSIGNALTYPE10GigELAN.class); + break; + case "If100GEODU4": + sclpqSet.add(DIGITALSIGNALTYPE100GigE.class); + sclpqSet.add(ODUTYPEODU4.class); + break; + case "If100GE": + sclpqSet.add(DIGITALSIGNALTYPE100GigE.class); + break; + case "IfOCHOTU4ODU4": + case "IfOCH": + sclpqSet.add(ODUTYPEODU4.class); + break; + default: + LOG.error("IfCapability type not managed"); + break; + } + break; + case "PHOTONIC_MEDIA": + if (sic.getIfCapType().getSimpleName().equals("IfOCHOTU4ODU4") + || sic.getIfCapType().getSimpleName().equals("IfOCH")) { + sclpqSet.add(PHOTONICLAYERQUALIFIEROTSi.class); + sclpqSet.add(PHOTONICLAYERQUALIFIEROMS.class); + } + break; + default: + LOG.error("Layer Protocol Name is unknown"); + break; + } + } + return new ArrayList<>(sclpqSet); + } + + private void createTapiTransitionalLinks() { + for (TerminationPoint tp : this.oorNetworkPortList) { + Map nepList = new HashMap<>(); + String sourceKey = String.join("+", this.ietfNodeId, I_ODU, tp.getTpId().getValue()); + Uuid sourceUuidTp = this.uuidMap.get(sourceKey); + String destKey = String.join("+", this.ietfNodeId, I_OTSI, tp.getTpId().getValue()); + Uuid destUuidTp = this.uuidMap.get(destKey); + NodeEdgePoint sourceNep = new NodeEdgePointBuilder() + .setTopologyUuid(this.tapiTopoUuid) + .setNodeUuid(this.uuidMap.get(String.join("+", this.ietfNodeId, DSR))) + .setNodeEdgePointUuid(sourceUuidTp) + .build(); + nepList.put(sourceNep.key(), sourceNep); + NodeEdgePoint destNep = new NodeEdgePointBuilder() + .setTopologyUuid(this.tapiTopoUuid) + .setNodeUuid(this.uuidMap.get(String.join("+", this.ietfNodeId, OTSI))) + .setNodeEdgePointUuid(destUuidTp) + .build(); + nepList.put(destNep.key(), destNep); + Name linkName = new NameBuilder().setValueName("transitional link name") + .setValue(String.join("--", this.ietfNodeId, sourceKey, destKey)) + .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(); + Link transiLink = new LinkBuilder() + .setUuid(new Uuid( + UUID.nameUUIDFromBytes((String.join("--", this.ietfNodeId, sourceKey, destKey)) + .getBytes(Charset.forName("UTF-8"))) + .toString())) + .setName(Map.of(linkName.key(), linkName)) + .setTransitionedLayerProtocolName(Arrays.asList(LayerProtocolName.ODU.getName(), + LayerProtocolName.PHOTONICMEDIA.getName())) + .setLayerProtocolName(Arrays.asList(LayerProtocolName.ODU, LayerProtocolName.PHOTONICMEDIA)) + .setNodeEdgePoint(nepList) + .setDirection(ForwardingDirection.BIDIRECTIONAL) + .setAvailableCapacity(new AvailableCapacityBuilder().setTotalSize( + new TotalSizeBuilder().setUnit(CapacityUnit.GBPS).setValue(Uint64.valueOf(100)).build()) + .build()) + .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()) + .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(); + this.tapiLinks.put(transiLink.key(), transiLink); + } + } + + private Link createTapiLink(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.network.topology.rev180226.networks.network.Link link, + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.network.topology.rev180226.networks.network.Link oppositeLink) { + String prefix = link.getLinkId().getValue().split("-")[0]; + String sourceNode = link.getSource().getSourceNode().getValue(); + String sourceTp = link.getSource().getSourceTp().toString(); + String destNode = link.getDestination().getDestNode().getValue(); + String destTp = link.getDestination().getDestTp().toString(); + LOG.info("prefix = {}, sourceNode = {}, sourceTp = {}, destNode = {}, destTp = {}", + prefix, sourceNode, sourceTp, destNode, destTp); + Map nepList = new HashMap<>(); + Uuid sourceUuidTp; + Uuid sourceUuidNode; + Uuid destUuidTp; + Uuid destUuidNode; + Name linkName; + AdminStates oppositeLinkAdminState = null; + State oppositeLinkOperState = null; + if (oppositeLink != null) { + oppositeLinkAdminState = oppositeLink.augmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class) + .getAdministrativeState(); + oppositeLinkOperState = oppositeLink.augmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class) + .getOperationalState(); + } + 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(); + switch (prefix) { + case "OTU4": + sourceUuidTp = this.uuidMap.get(String.join("+", sourceNode, I_OTSI, sourceTp)); + sourceUuidNode = this.uuidMap.get(String.join("+", sourceNode, OTSI)); + NodeEdgePoint sourceNep = new NodeEdgePointBuilder() + .setTopologyUuid(this.tapiTopoUuid) + .setNodeUuid(sourceUuidNode) + .setNodeEdgePointUuid(sourceUuidTp) + .build(); + nepList.put(sourceNep.key(), sourceNep); + destUuidTp = this.uuidMap.get(String.join("+", destNode, I_OTSI, destTp)); + destUuidNode = this.uuidMap.get(String.join("+", destNode, OTSI)); + NodeEdgePoint destNep = new NodeEdgePointBuilder() + .setTopologyUuid(this.tapiTopoUuid) + .setNodeUuid(destUuidNode) + .setNodeEdgePointUuid(destUuidTp) + .build(); + nepList.put(destNep.key(), destNep); + linkName = new NameBuilder().setValueName("otn link name") + .setValue(link.getLinkId().getValue()) + .build(); + return new LinkBuilder() + .setUuid(new Uuid(UUID.nameUUIDFromBytes((link.getLinkId().getValue()) + .getBytes(Charset.forName("UTF-8"))).toString())) + .setName(Map.of(linkName.key(), linkName)) + .setLayerProtocolName(Arrays.asList(LayerProtocolName.PHOTONICMEDIA)) + .setTransitionedLayerProtocolName(new ArrayList<>()) + .setAdministrativeState(setTapiAdminState(link + .augmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class) + .getAdministrativeState(), oppositeLinkAdminState)) + .setOperationalState(setTapiOperationalState(link + .augmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class) + .getOperationalState(), oppositeLinkOperState)) + .setDirection(ForwardingDirection.BIDIRECTIONAL) + .setNodeEdgePoint(nepList) + .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(link.augmentation(Link1.class).getAvailableBandwidth())).build()) + .build()) + .setResilienceType(new ResilienceTypeBuilder().setProtectionType(ProtectionType.NOPROTECTON) + .setRestorationPolicy(RestorationPolicy.NA) + .build()) + .setAdministrativeState(AdministrativeState.UNLOCKED) + .setOperationalState(OperationalState.ENABLED) + .setLifecycleState(LifecycleState.INSTALLED) + .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(); + case "ODU4": + sourceUuidTp = this.uuidMap.get(String.join("+", sourceNode, E_ODU, sourceTp)); + sourceUuidNode = this.uuidMap.get(String.join("+", sourceNode, DSR)); + NodeEdgePoint sourceNep2 = new NodeEdgePointBuilder() + .setTopologyUuid(this.tapiTopoUuid) + .setNodeUuid(sourceUuidNode) + .setNodeEdgePointUuid(sourceUuidTp) + .build(); + nepList.put(sourceNep2.key(), sourceNep2); + destUuidTp = this.uuidMap.get(String.join("+", destNode, E_ODU, destTp)); + destUuidNode = this.uuidMap.get(String.join("+", destNode, DSR)); + NodeEdgePoint destNep2 = new NodeEdgePointBuilder() + .setTopologyUuid(this.tapiTopoUuid) + .setNodeUuid(destUuidNode) + .setNodeEdgePointUuid(destUuidTp) + .build(); + nepList.put(destNep2.key(), destNep2); + linkName = new NameBuilder().setValueName("otn link name") + .setValue(link.getLinkId().getValue()) + .build(); + return new LinkBuilder() + .setUuid(new Uuid(UUID.nameUUIDFromBytes((link.getLinkId().getValue()) + .getBytes(Charset.forName("UTF-8"))).toString())) + .setName(Map.of(linkName.key(), linkName)) + .setLayerProtocolName(Arrays.asList(LayerProtocolName.ODU)) + .setTransitionedLayerProtocolName(new ArrayList<>()) + .setAdministrativeState(setTapiAdminState(link + .augmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class) + .getAdministrativeState(), oppositeLinkAdminState)) + .setOperationalState(setTapiOperationalState(link + .augmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class) + .getOperationalState(), oppositeLinkOperState)) + .setDirection(ForwardingDirection.BIDIRECTIONAL) + .setNodeEdgePoint(nepList) + .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(link.augmentation(Link1.class).getAvailableBandwidth())).build()) + .build()) + .setResilienceType(new ResilienceTypeBuilder().setProtectionType(ProtectionType.NOPROTECTON) + .setRestorationPolicy(RestorationPolicy.NA) + .build()) + .setAdministrativeState(AdministrativeState.UNLOCKED) + .setOperationalState(OperationalState.ENABLED) + .setLifecycleState(LifecycleState.INSTALLED) + .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(); + default: + LOG.error("OTN link of type {} not managed yet", prefix); + return null; + } + } + + private Link createTapiOmsLink(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.network.topology.rev180226.networks.network.Link link) { + String sourceNode = getIdBasedOnModelVersion(link.getSource().getSourceNode().getValue()); + String sourceTp = link.getSource().getSourceTp().toString(); + String destNode = getIdBasedOnModelVersion(link.getDestination().getDestNode().getValue()); + String destTp = link.getDestination().getDestTp().toString(); + Map nepList = new HashMap<>(); + Uuid sourceUuidNode = new Uuid(UUID.nameUUIDFromBytes((String.join("+", sourceNode, + PHTNC_MEDIA)).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()); + 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("OMS link name") + .setValue(link.getLinkId().getValue()) + .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((link.getLinkId().getValue()).getBytes(Charset.forName("UTF-8"))) + .toString())) + .setName(Map.of(linkName.key(), linkName)) + .setLayerProtocolName(List.of(LayerProtocolName.PHOTONICMEDIA)) + .setTransitionedLayerProtocolName(new ArrayList<>()) + .setNodeEdgePoint(nepList) + .setDirection(ForwardingDirection.BIDIRECTIONAL) + .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(); + } + + public void convertXpdrToRdmLinks(List xpdrRdmLinkList) { + List linksToNotConvert = new ArrayList<>(); + LOG.info("creation of {} xpdr to roadm links", xpdrRdmLinkList.size() / 2); + // LOG.info("Link list = {}", xpdrRdmLinkList.toString()); + for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.network.topology.rev180226.networks.network.Link link:xpdrRdmLinkList) { + if (!linksToNotConvert.contains(link.getLinkId().getValue())) { + String sourceNode = (link.getSource().getSourceNode().getValue().contains("ROADM")) + ? getIdBasedOnModelVersion(link.getSource().getSourceNode().getValue()) + : link.getSource().getSourceNode().getValue(); + String sourceTp = link.getSource().getSourceTp().toString(); + String destNode = (link.getDestination().getDestNode().getValue().contains("ROADM")) + ? getIdBasedOnModelVersion(link.getDestination().getDestNode().getValue()) + : link.getDestination().getDestNode().getValue(); + String destTp = link.getDestination().getDestTp().toString(); + Map nepList = new HashMap<>(); + Uuid sourceUuidNode = (sourceNode.contains("ROADM")) ? new Uuid(UUID.nameUUIDFromBytes(( + String.join("+", sourceNode, PHTNC_MEDIA)).getBytes(Charset.forName("UTF-8"))).toString()) + : new Uuid(UUID.nameUUIDFromBytes((String.join("+", sourceNode, OTSI)) + .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 = (destNode.contains("ROADM")) ? new Uuid(UUID.nameUUIDFromBytes(( + String.join("+", destNode, PHTNC_MEDIA)).getBytes(Charset.forName("UTF-8"))).toString()) + : new Uuid(UUID.nameUUIDFromBytes((String.join("+", destNode, OTSI)) + .getBytes(Charset.forName("UTF-8"))).toString()); + Uuid destUuidTp = new Uuid(UUID.nameUUIDFromBytes((String.join("+", destNode, + PHTNC_MEDIA, destTp)).getBytes(Charset.forName("UTF-8"))).toString()); + 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("XPDR-RDM link name") + .setValue(link.getLinkId().getValue()) + .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(); + Link tapiLink = new LinkBuilder() + .setUuid(new Uuid( + UUID.nameUUIDFromBytes((link.getLinkId().getValue()).getBytes(Charset.forName("UTF-8"))) + .toString())) + .setName(Map.of(linkName.key(), linkName)) + .setLayerProtocolName(List.of(LayerProtocolName.PHOTONICMEDIA)) + .setTransitionedLayerProtocolName(new ArrayList<>()) + .setNodeEdgePoint(nepList) + .setDirection(ForwardingDirection.BIDIRECTIONAL) + .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(); + linksToNotConvert.add(link + .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class) + .getOppositeLink().getValue()); + this.tapiLinks.put(tapiLink.key(), tapiLink); + } + } + } + + private String getIdBasedOnModelVersion(String linknodeid) { + if (linknodeid.matches("[A-Z]{5}-[A-Z0-9]{2}-.*")) { + LOG.info("OpenROADM version > 1.2.1 {}", linknodeid); + return String.join("-", linknodeid.split("-")[0], linknodeid.split("-")[1]); + } else { + LOG.info("OpenROADM version <= 1.2.1 {}", linknodeid); + return linknodeid.split("-")[0]; + } + } + + public Map + getTapiNodes() { + return tapiNodes; + } + + public Map getTapiLinks() { + return tapiLinks; + } + + public Map getTapiSips() { + return tapiSips; + } +} diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImpl.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImpl.java index fc146e5f7..46e618d67 100644 --- a/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImpl.java +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImpl.java @@ -27,6 +27,7 @@ import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.transportpce.common.InstanceIdentifiers; import org.opendaylight.transportpce.common.NetworkUtils; +import org.opendaylight.transportpce.tapi.utils.TapiContext; import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.mapping.Mapping; import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.mapping.MappingKey; import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.network.Nodes; @@ -44,6 +45,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.top import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint; 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.Context; 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; @@ -51,6 +53,7 @@ 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.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.common.rev181210.global._class.NameKey; +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.ForwardingRule; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetLinkDetailsInput; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetLinkDetailsOutput; @@ -78,6 +81,7 @@ import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.no 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.NodeBuilder; 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.TopologyKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; @@ -89,9 +93,13 @@ public class TapiTopologyImpl implements TapiTopologyService { private static final Logger LOG = LoggerFactory.getLogger(TapiTopologyImpl.class); private final DataBroker dataBroker; + private final TapiContext tapiContext; + private final TopologyUtils topologyUtils; - public TapiTopologyImpl(DataBroker dataBroker) { + public TapiTopologyImpl(DataBroker dataBroker, TapiContext tapiContext, TopologyUtils topologyUtils) { this.dataBroker = dataBroker; + this.tapiContext = tapiContext; + this.topologyUtils = topologyUtils; } @Override @@ -102,8 +110,27 @@ public class TapiTopologyImpl implements TapiTopologyService { @Override public ListenableFuture> getTopologyDetails(GetTopologyDetailsInput input) { + // TODO -> Add check for Full T0 Multilayer if (!TopologyUtils.T0_MULTILAYER.equals(input.getTopologyIdOrName()) - && !TopologyUtils.TPDR_100G.equals(input.getTopologyIdOrName())) { + && !TopologyUtils.TPDR_100G.equals(input.getTopologyIdOrName())) { + if (TopologyUtils.T0_FULL_MULTILAYER.equals(input.getTopologyIdOrName())) { + Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(input.getTopologyIdOrName() + .getBytes(Charset.forName("UTF-8"))).toString()); + Context context = this.tapiContext.getTapiContext(); + Map + topologyMap = context.augmentation(Context1.class).getTopologyContext().getTopology(); + if (!(topologyMap != null && topologyMap.containsKey(new TopologyKey(topoUuid)))) { + LOG.error("Topology {} not found in datastore", input.getTopologyIdOrName()); + return RpcResultBuilder.success(new GetTopologyDetailsOutputBuilder().build()).buildFuture(); + } + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology + topology = topologyMap.get(new TopologyKey(topoUuid)); + return RpcResultBuilder.success(new GetTopologyDetailsOutputBuilder() + .setTopology(this.topologyUtils.transformTopology(topology)) + .build()) + .buildFuture(); + } LOG.error("Invalid TAPI topology name"); return RpcResultBuilder.success(new GetTopologyDetailsOutputBuilder().build()).buildFuture(); } @@ -122,12 +149,12 @@ public class TapiTopologyImpl implements TapiTopologyService { } private Topology createAbstracted100GTpdrTopology(Topology topology) { - List dsrNodes - = topology.nonnullNode().values().stream() + List dsrNodes = + topology.nonnullNode().values().stream() .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.DSR)) .collect(Collectors.toList()); List nep100GTpdrList = new ArrayList<>(); - for (org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node2 : dsrNodes) { + for (org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node2: dsrNodes) { List nepList = node2.getOwnedNodeEdgePoint().values().stream() .filter(nep -> nep.getName().containsKey(new NameKey("100G-tpdr"))).collect(Collectors.toList()); nep100GTpdrList.addAll(nepList); @@ -135,8 +162,8 @@ public class TapiTopologyImpl implements TapiTopologyService { Name topoName = new NameBuilder().setValue(TopologyUtils.TPDR_100G).setValueName("TAPI Topology Name").build(); Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.TPDR_100G.getBytes(Charset.forName("UTF-8"))) .toString()); - org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node - = createTapiNode(nep100GTpdrList, topoUuid); + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node = + createTapiNode(nep100GTpdrList, topoUuid); return new TopologyBuilder() .setName(Map.of(topoName.key(), topoName)) .setUuid(topoUuid) @@ -189,10 +216,10 @@ public class TapiTopologyImpl implements TapiTopologyService { .findFirst() .get().getNodeRef().getValue(); List networkPortList = new ArrayList<>(); - for (TerminationPoint tp : entry.getValue().augmentation(Node1.class).getTerminationPoint().values()) { + for (TerminationPoint tp: entry.getValue().augmentation(Node1.class).getTerminationPoint().values()) { if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK) - && - checkTp(entry.getKey().getValue(), portMappingNodeId, tp, xponderOutLinkList, xponderInLinkList)) { + && checkTp(entry.getKey().getValue(), portMappingNodeId, tp, xponderOutLinkList, + xponderInLinkList)) { networkPortList.add(tp.getTpId().getValue()); } } @@ -224,8 +251,9 @@ public class TapiTopologyImpl implements TapiTopologyService { LOG.warn("Unable to abstract an ROADM infrasctructure from openroadm-topology"); } if (otnTopo.augmentation(Network1.class) != null) { - Map otnLinkMap = otnTopo.augmentation(Network1.class).getLink(); + Map otnLinkMap = + otnTopo.augmentation(Network1.class).getLink(); tapiFactory.convertLinks(otnLinkMap); tapiLinkList.putAll(tapiFactory.getTapiLinks()); } @@ -260,7 +288,7 @@ public class TapiTopologyImpl implements TapiTopologyService { createTapiNode(List nepList, Uuid topoUuid) { Name name = new NameBuilder().setValueName("Tpdr100g node name").setValue("Tpdr100g over WDM node").build(); Map onepMap = new HashMap<>(); - for (OwnedNodeEdgePoint ownedNodeEdgePoint : nepList) { + for (OwnedNodeEdgePoint ownedNodeEdgePoint: nepList) { onepMap.put(ownedNodeEdgePoint.key(), ownedNodeEdgePoint); } Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(name.getValue().getBytes(Charset.forName("UTF-8"))).toString()); @@ -276,8 +304,8 @@ public class TapiTopologyImpl implements TapiTopologyService { .build(); } - private boolean checkTp(String nodeIdTopo, String nodeIdPortMap, TerminationPoint tp, List xpdOut, List< - Link> xpdIn) { + private boolean checkTp(String nodeIdTopo, String nodeIdPortMap, TerminationPoint tp, List xpdOut, + List xpdIn) { String networkLcp; if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERCLIENT)) { networkLcp = tp.augmentation( @@ -298,7 +326,7 @@ public class TapiTopologyImpl implements TapiTopologyService { try { mapping = mappingOpt.get().get(); } catch (InterruptedException | ExecutionException e) { - LOG.error("Error getting mapping for {}", networkLcp,e); + LOG.error("Error getting mapping for {}", networkLcp, e); return false; } } else { @@ -310,8 +338,8 @@ public class TapiTopologyImpl implements TapiTopologyService { long count = 0; switch (networkPortDirection) { case "bidirectional": - count += xpdOut.stream().filter(lk -> lk.getSource().getSourceNode().getValue().equals(nodeIdTopo) && lk - .getSource().getSourceTp().equals(networkLcp)).count(); + count += xpdOut.stream().filter(lk -> lk.getSource().getSourceNode().getValue().equals(nodeIdTopo) + && lk.getSource().getSourceTp().equals(networkLcp)).count(); count += xpdIn.stream().filter(lk -> lk.getDestination().getDestNode().getValue().equals(nodeIdTopo) && lk.getDestination().getDestTp().equals(networkLcp)).count(); return (count == 2); @@ -338,19 +366,20 @@ public class TapiTopologyImpl implements TapiTopologyService { } } - private Map createNodeRuleGroupFor100gTpdrNode(Uuid topoUuid, Uuid nodeUuid, - Collection onepl) { + private Map createNodeRuleGroupFor100gTpdrNode( + Uuid topoUuid, Uuid nodeUuid, Collection onepl) { + Map nepMap = new HashMap<>(); - for (OwnedNodeEdgePoint onep : onepl) { - org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint - nep = new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group + for (OwnedNodeEdgePoint onep: onepl) { + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint nep = + new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group .NodeEdgePointBuilder() - .setTopologyUuid(topoUuid) - .setNodeUuid(nodeUuid) - .setNodeEdgePointUuid(onep.key().getUuid()) - .build(); + .setTopologyUuid(topoUuid) + .setNodeUuid(nodeUuid) + .setNodeEdgePointUuid(onep.key().getUuid()) + .build(); nepMap.put(nep.key(), nep); } Map nodeRuleGroupMap = new HashMap<>(); diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TopologyUtils.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TopologyUtils.java index 457f1b91d..846d533a9 100644 --- a/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TopologyUtils.java +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TopologyUtils.java @@ -1,5 +1,5 @@ /* - * Copyright © 2019 Orange, Inc. and others. All rights reserved. + * 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, @@ -7,12 +7,264 @@ */ package org.opendaylight.transportpce.tapi.topology; -public final class TopologyUtils { +import com.google.common.util.concurrent.FluentFuture; +import com.google.common.util.concurrent.ListenableFuture; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.transportpce.common.InstanceIdentifiers; +import org.opendaylight.transportpce.common.NetworkUtils; +import org.opendaylight.transportpce.common.network.NetworkTransactionService; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.mapping.Mapping; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.mapping.MappingKey; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.network.Nodes; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.network.NodesKey; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.TerminationPoint1; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmLinkType; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmNodeType; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmTpType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint; +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.Uuid; +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.common.rev181210.tapi.context.ServiceInterfacePoint; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePointKey; +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.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.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; - private TopologyUtils() { - } +public final class TopologyUtils { + private final NetworkTransactionService networkTransactionService; + private final DataBroker dataBroker; + private static final Logger LOG = LoggerFactory.getLogger(TopologyUtils.class); public static final String T0_MULTILAYER = "T0 - Multi-layer topology"; + public static final String T0_FULL_MULTILAYER = "T0 - Full Multi-layer topology"; public static final String TPDR_100G = "Transponder 100GE"; + private Map tapiSips; + + public TopologyUtils(NetworkTransactionService networkTransactionService, DataBroker dataBroker) { + this.networkTransactionService = networkTransactionService; + this.dataBroker = dataBroker; + this.tapiSips = new HashMap<>(); + } + + public Network readTopology(InstanceIdentifier networkIID) throws TapiTopologyException { + Network topology = null; + ListenableFuture> topologyFuture = + this.networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, networkIID); + try { + topology = topologyFuture.get().get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new TapiTopologyException("Unable to get from mdsal topology: " + networkIID + .firstKeyOf(Network.class).getNetworkId().getValue(), e); + } catch (ExecutionException e) { + throw new TapiTopologyException("Unable to get from mdsal topology: " + networkIID + .firstKeyOf(Network.class).getNetworkId().getValue(), e); + } catch (NoSuchElementException e) { + return null; + } + return topology; + } + + public Topology createFullOtnTopology() throws TapiTopologyException { + // read openroadm-topology + Network openroadmTopo = readTopology(InstanceIdentifiers.OVERLAY_NETWORK_II); + List linkList = new ArrayList<>(); + if (openroadmTopo.augmentation(Network1.class) != null) { + linkList.addAll(openroadmTopo.augmentation(Network1.class).getLink().values()); + } + List xponderOutLinkList = linkList.stream() + .filter(lk -> lk.augmentation(Link1.class).getLinkType().equals(OpenroadmLinkType.XPONDEROUTPUT)) + .collect(Collectors.toList()); + List xponderInLinkList = linkList.stream() + .filter(lk -> lk.augmentation(Link1.class).getLinkType().equals(OpenroadmLinkType.XPONDERINPUT)) + .collect(Collectors.toList()); + // read otn-topology + Network otnTopo = readTopology(InstanceIdentifiers.OTN_NETWORK_II); + Map otnNodeMap = otnTopo.nonnullNode() + .values().stream().collect(Collectors.toMap(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.network.rev180226.networks.network.Node::getNodeId, node -> node)); + + Map> networkPortMap = new HashMap<>(); + Iterator> itOtnNodeMap = otnNodeMap + .entrySet().iterator(); + while (itOtnNodeMap.hasNext()) { + Map.Entry entry = itOtnNodeMap.next(); + String portMappingNodeId = entry.getValue().getSupportingNode().values().stream() + .filter(sn -> sn.getNetworkRef().getValue().equals(NetworkUtils.UNDERLAY_NETWORK_ID)) + .findFirst() + .get().getNodeRef().getValue(); + List networkPortList = new ArrayList<>(); + for (TerminationPoint tp: entry.getValue().augmentation(Node1.class).getTerminationPoint().values()) { + // TODO -> why are we checking with respect to XPDR links?? Is there a real purpose on doing that? + if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK) + && checkTp(entry.getKey().getValue(), portMappingNodeId, tp, xponderOutLinkList, + xponderInLinkList)) { + networkPortList.add(tp.getTpId().getValue()); + } + } + if (!networkPortList.isEmpty()) { + networkPortMap.put(entry.getKey().getValue(), networkPortList); + } + } + Map + tapiNodeList = new HashMap<>(); + Map + tapiLinkList = new HashMap<>(); + Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER + .getBytes(Charset.forName("UTF-8"))).toString()); + ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topoUuid); + Iterator>> it = networkPortMap.entrySet().iterator(); + while (it.hasNext()) { + String nodeId = it.next().getKey(); + tapiFactory.convertNode(otnNodeMap.get(new NodeId(nodeId)), networkPortMap.get(nodeId)); + tapiNodeList.putAll(tapiFactory.getTapiNodes()); + tapiLinkList.putAll(tapiFactory.getTapiLinks()); + } + // roadm infrastructure not abstracted + // read openroadm-network + Network openroadmNet = readTopology(InstanceIdentifiers.UNDERLAY_NETWORK_II); + if (openroadmNet != null && openroadmNet.nonnullNode().values().stream().filter(nt -> + nt.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1.class) + .getNodeType().equals(OpenroadmNodeType.ROADM)).count() > 0) { + // map roadm nodes + for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node + roadm:openroadmNet.nonnullNode().values().stream().filter( + nt -> nt.augmentation(org.opendaylight.yang.gen.v1.http + .org.openroadm.common.network.rev200529.Node1.class) + .getNodeType().equals(OpenroadmNodeType.ROADM)) + .collect(Collectors.toList())) { + tapiFactory.convertRoadmNode(roadm, openroadmTopo); + tapiNodeList.putAll(tapiFactory.getTapiNodes()); + } + } else { + LOG.warn("No roadm nodes exist in the network"); + } + // map roadm to roadm link + List rdmTordmLinkList = linkList.stream() + .filter(lk -> lk.augmentation(Link1.class).getLinkType().equals(OpenroadmLinkType.ROADMTOROADM)) + .collect(Collectors.toList()); + tapiFactory.convertRdmToRdmLinks(rdmTordmLinkList); + tapiLinkList.putAll(tapiFactory.getTapiLinks()); + // map xpdr_input to roadm and xpdr_output to roadm links. + xponderInLinkList.addAll(xponderOutLinkList); + tapiFactory.convertXpdrToRdmLinks(xponderInLinkList); + tapiLinkList.putAll(tapiFactory.getTapiLinks()); + + if (otnTopo.augmentation(Network1.class) != null) { + Map otnLinkMap = otnTopo.augmentation(Network1.class).getLink(); + tapiFactory.convertLinks(otnLinkMap); + tapiLinkList.putAll(tapiFactory.getTapiLinks()); + } + Name name = new NameBuilder().setValue(TopologyUtils.T0_FULL_MULTILAYER).setValueName("TAPI Topology Name") + .build(); + // Retrieve created sips map in TapiFactory when mapping all the nodes + this.tapiSips = tapiFactory.getTapiSips(); + return new TopologyBuilder() + .setName(Map.of(name.key(), name)) + .setUuid(topoUuid) + .setNode(tapiNodeList) + .setLayerProtocolName(List.of(LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.ODU, + LayerProtocolName.DSR)) + .setLink(tapiLinkList).build(); + } + + public Map getSipMap() { + return tapiSips; + } + + public boolean checkTp(String nodeIdTopo, String nodeIdPortMap, TerminationPoint tp, List xpdOut, + List xpdIn) { + LOG.info("Inside Checktp for node {}-{}", nodeIdTopo, nodeIdPortMap); + String networkLcp; + if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERCLIENT)) { + networkLcp = tp.augmentation( + org.opendaylight.yang.gen.v1.http.transportpce.topology.rev201019.TerminationPoint1.class) + .getAssociatedConnectionMapPort(); + } else { + networkLcp = tp.getTpId().getValue(); + } + LOG.info("Network LCP associated = {}", networkLcp); + @NonNull + KeyedInstanceIdentifier pmIID = InstanceIdentifier.create( + org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.Network.class) + .child(Nodes.class, new NodesKey(nodeIdPortMap)).child(Mapping.class, new MappingKey(networkLcp)); + @NonNull + FluentFuture> mappingOpt = this.dataBroker.newReadOnlyTransaction().read( + LogicalDatastoreType.CONFIGURATION, pmIID); + Mapping mapping = null; + if (mappingOpt.isDone()) { + try { + mapping = mappingOpt.get().get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error getting mapping for {}", networkLcp,e); + return false; + } + } else { + LOG.error("Impossible to get mapping of associated network port {} of tp {}", networkLcp, tp.getTpId() + .getValue()); + return false; + } + LOG.info("Mapping found = {}", mapping); + String networkPortDirection = mapping.getPortDirection(); + // long count = 0; + switch (networkPortDirection) { + // TODO -> remove the part of counting only if the Network LCP is part of a Link. + // We want to have all OTN nodes in the TAPI topology + case "bidirectional": + return true; + case "tx": + case "rx": + @Nullable + String partnerLcp = mapping.getPartnerLcp(); + LOG.info("PartnerLCP = {}", partnerLcp); + return true; + default: + LOG.error("Invalid port direction for {}", networkLcp); + return false; + } + } + + public org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.get.topology.details.output.Topology + transformTopology(Topology topology) { + return new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210 + .get.topology.details.output.TopologyBuilder() + .setUuid(topology.getUuid()) + .setName(topology.getName()) + .setLayerProtocolName(topology.getLayerProtocolName()) + .setNode(topology.getNode()) + .setLink(topology.getLink()) + .build(); + } } diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/utils/TapiContext.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/utils/TapiContext.java index 5c195f044..b84b5b0ff 100644 --- a/tapi/src/main/java/org/opendaylight/transportpce/tapi/utils/TapiContext.java +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/utils/TapiContext.java @@ -20,11 +20,15 @@ import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Cont 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.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.common.rev181210.tapi.context.ServiceInterfacePoint; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePointKey; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1Builder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContextBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContextBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.NwTopologyServiceBuilder; +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.TopologyKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -116,4 +120,44 @@ public class TapiContext { } + public void updateTopologyContext(Map topologyMap) { + // TODO: solve error when merging: Topology is not a valid child of topology context? + // TODO: verify this is correct. Should we identify the context IID with the context UUID?? + try { + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext + topologyContext = new TopologyContextBuilder() + //.setNwTopologyService(new NwTopologyServiceBuilder().build()) + .setTopology(topologyMap) + .build(); + InstanceIdentifier topologycontextIID = + InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.topology.rev181210.Context1.class) + .child(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext.class) + .build(); + // merge in datastore + this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, topologycontextIID, + topologyContext); + this.networkTransactionService.commit().get(); + LOG.info("TAPI topology merged successfully."); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Failed to merge TAPI topology", e); + } + } + + public void updateSIPContext(Map sipMap) { + // TODO: verify this is correct. Should we identify the context IID with the context UUID?? + try { + ContextBuilder contextBuilder = new ContextBuilder().setServiceInterfacePoint(sipMap); + InstanceIdentifier contextIID = InstanceIdentifier.builder(Context.class).build(); + // merge in datastore + this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, contextIID, + contextBuilder.build()); + this.networkTransactionService.commit().get(); + LOG.info("TAPI SIPs merged successfully."); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Failed to merge TAPI SIPs", e); + } + } } diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/utils/TapiInitialORMapping.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/utils/TapiInitialORMapping.java new file mode 100644 index 000000000..337c4eba9 --- /dev/null +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/utils/TapiInitialORMapping.java @@ -0,0 +1,46 @@ +/* + * 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.utils; + +import java.util.HashMap; +import java.util.Map; +import org.opendaylight.transportpce.tapi.topology.TapiTopologyException; +import org.opendaylight.transportpce.tapi.topology.TopologyUtils; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePoint; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePointKey; +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.TopologyKey; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TapiInitialORMapping { + + private static final Logger LOG = LoggerFactory.getLogger(TapiInitialORMapping.class); + private final TapiContext tapiContext; + private final TopologyUtils topologyUtils; + + public TapiInitialORMapping(TopologyUtils topologyUtils, TapiContext tapiContext) { + this.topologyUtils = topologyUtils; + this.tapiContext = tapiContext; + } + + public void performTopoInitialMapping() { + // creation of both topologies but with the fully roadm infrastructure. + try { + LOG.info("Performing initial mapping between OR and TAPI models."); + Topology t0FullMultiLayer = this.topologyUtils.createFullOtnTopology(); + Map topologyMap = new HashMap<>(); + topologyMap.put(t0FullMultiLayer.key(), t0FullMultiLayer); + this.tapiContext.updateTopologyContext(topologyMap); + Map sipMap = this.topologyUtils.getSipMap(); + this.tapiContext.updateSIPContext(sipMap); + } catch (TapiTopologyException e) { + LOG.error("error building TAPI topology", e); + } + } +} diff --git a/tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImplExceptionTest.java b/tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImplExceptionTest.java index 4801ac6a3..a130d44c6 100644 --- a/tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImplExceptionTest.java +++ b/tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImplExceptionTest.java @@ -8,6 +8,7 @@ package org.opendaylight.transportpce.tapi.topology; import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import com.google.common.util.concurrent.FluentFuture; @@ -17,10 +18,15 @@ import java.util.Optional; import java.util.concurrent.ExecutionException; import org.eclipse.jdt.annotation.NonNull; import org.junit.Test; -import org.mockito.Mockito; +import org.mockito.Mock; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.binding.api.ReadTransaction; +import org.opendaylight.mdsal.common.api.CommitInfo; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.transportpce.common.network.NetworkTransactionService; +import org.opendaylight.transportpce.tapi.utils.TapiContext; import org.opendaylight.transportpce.tapi.utils.TapiTopologyDataUtils; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetTopologyDetailsInput; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetTopologyDetailsOutput; @@ -30,15 +36,30 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; public class TapiTopologyImplExceptionTest { + @Mock + TapiContext tapiContext; + @Mock + TopologyUtils topologyUtils; @Test public void getTopologyDetailsWithExceptionTest() throws InterruptedException, ExecutionException { - DataBroker dataBroker = Mockito.mock(DataBroker.class); + DataBroker dataBroker = mock(DataBroker.class); when(dataBroker.newReadOnlyTransaction()) - .thenReturn(new ReadTransactionMock()); + .thenReturn(new ReadTransactionMock()); + NetworkTransactionService networkTransactionService = mock(NetworkTransactionService.class); + Answer> answer = new Answer>() { + + @Override + public FluentFuture answer(InvocationOnMock invocation) throws Throwable { + return CommitInfo.emptyFluentFuture(); + } + + }; + when(networkTransactionService.commit()).then(answer); + tapiContext = new TapiContext(networkTransactionService); GetTopologyDetailsInput input = TapiTopologyDataUtils.buildGetTopologyDetailsInput(TopologyUtils.T0_MULTILAYER); - TapiTopologyImpl tapiTopoImpl = new TapiTopologyImpl(dataBroker); + TapiTopologyImpl tapiTopoImpl = new TapiTopologyImpl(dataBroker, tapiContext, topologyUtils); ListenableFuture> result = tapiTopoImpl.getTopologyDetails(input); RpcResult rpcResult = result.get(); Topology topology = rpcResult.getResult().getTopology(); @@ -55,13 +76,13 @@ public class TapiTopologyImplExceptionTest { @Override public @NonNull FluentFuture> read(@NonNull LogicalDatastoreType store, - @NonNull InstanceIdentifier path) { + @NonNull InstanceIdentifier path) { return FluentFuture.from(Futures.immediateFailedFuture(new InterruptedException())); } @Override public @NonNull FluentFuture exists(@NonNull LogicalDatastoreType store, - @NonNull InstanceIdentifier path) { + @NonNull InstanceIdentifier path) { // TODO Auto-generated method stub return null; } diff --git a/tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImplTest.java b/tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImplTest.java index be1cdf348..41685f05e 100644 --- a/tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImplTest.java +++ b/tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImplTest.java @@ -28,6 +28,11 @@ import org.eclipse.jdt.annotation.Nullable; import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.transportpce.common.InstanceIdentifiers; +import org.opendaylight.transportpce.common.network.NetworkTransactionImpl; +import org.opendaylight.transportpce.common.network.NetworkTransactionService; +import org.opendaylight.transportpce.common.network.RequestProcessor; +import org.opendaylight.transportpce.tapi.utils.TapiContext; +import org.opendaylight.transportpce.tapi.utils.TapiInitialORMapping; import org.opendaylight.transportpce.tapi.utils.TapiTopologyDataUtils; import org.opendaylight.transportpce.test.AbstractTest; import org.opendaylight.transportpce.test.utils.TopologyDataUtils; @@ -59,6 +64,10 @@ public class TapiTopologyImplTest extends AbstractTest { private static ListeningExecutorService executorService; private static CountDownLatch endSignal; private static final int NUM_THREADS = 3; + public static NetworkTransactionService networkTransactionService; + public static TapiContext tapiContext; + public static TopologyUtils topologyUtils; + public static TapiInitialORMapping tapiInitialORMapping; @BeforeClass public static void setUp() throws InterruptedException, ExecutionException { @@ -66,10 +75,18 @@ public class TapiTopologyImplTest extends AbstractTest { endSignal = new CountDownLatch(1); TopologyDataUtils.writeTopologyFromFileToDatastore(getDataStoreContextUtil(), TapiTopologyDataUtils.OPENROADM_TOPOLOGY_FILE, InstanceIdentifiers.OVERLAY_NETWORK_II); + TopologyDataUtils.writeTopologyFromFileToDatastore(getDataStoreContextUtil(), + TapiTopologyDataUtils.OPENROADM_NETWORK_FILE, InstanceIdentifiers.UNDERLAY_NETWORK_II); TopologyDataUtils.writeTopologyFromFileToDatastore(getDataStoreContextUtil(), TapiTopologyDataUtils.OTN_TOPOLOGY_FILE, InstanceIdentifiers.OTN_NETWORK_II); TopologyDataUtils.writePortmappingFromFileToDatastore(getDataStoreContextUtil(), TapiTopologyDataUtils.PORTMAPPING_FILE); + networkTransactionService = new NetworkTransactionImpl( + new RequestProcessor(getDataStoreContextUtil().getDataBroker())); + tapiContext = new TapiContext(networkTransactionService); + topologyUtils = new TopologyUtils(networkTransactionService, getDataStoreContextUtil().getDataBroker()); + tapiInitialORMapping = new TapiInitialORMapping(topologyUtils, tapiContext); + tapiInitialORMapping.performTopoInitialMapping(); LOG.info("setup done"); } @@ -77,7 +94,7 @@ public class TapiTopologyImplTest extends AbstractTest { public void getTopologyDetailsForTransponder100GTopologyWhenSuccessful() throws ExecutionException, InterruptedException { GetTopologyDetailsInput input = TapiTopologyDataUtils.buildGetTopologyDetailsInput(TopologyUtils.TPDR_100G); - TapiTopologyImpl tapiTopoImpl = new TapiTopologyImpl(getDataBroker()); + TapiTopologyImpl tapiTopoImpl = new TapiTopologyImpl(getDataBroker(), tapiContext, topologyUtils); ListenableFuture> result = tapiTopoImpl.getTopologyDetails(input); result.addListener(new Runnable() { @Override @@ -122,7 +139,7 @@ public class TapiTopologyImplTest extends AbstractTest { public void getTopologyDetailsForOtnTopologyWithOtnLinksWhenSuccessful() throws ExecutionException, InterruptedException { GetTopologyDetailsInput input = TapiTopologyDataUtils.buildGetTopologyDetailsInput(TopologyUtils.T0_MULTILAYER); - TapiTopologyImpl tapiTopoImpl = new TapiTopologyImpl(getDataBroker()); + TapiTopologyImpl tapiTopoImpl = new TapiTopologyImpl(getDataBroker(), tapiContext, topologyUtils); ListenableFuture> result = tapiTopoImpl.getTopologyDetails(input); result.addListener(new Runnable() { @Override diff --git a/tapi/src/test/java/org/opendaylight/transportpce/tapi/utils/TapiTopologyDataUtils.java b/tapi/src/test/java/org/opendaylight/transportpce/tapi/utils/TapiTopologyDataUtils.java index 2973185fb..7448329d3 100644 --- a/tapi/src/test/java/org/opendaylight/transportpce/tapi/utils/TapiTopologyDataUtils.java +++ b/tapi/src/test/java/org/opendaylight/transportpce/tapi/utils/TapiTopologyDataUtils.java @@ -13,6 +13,7 @@ import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Ge public final class TapiTopologyDataUtils { public static final String OPENROADM_TOPOLOGY_FILE = "src/test/resources/openroadm-topology.xml"; + public static final String OPENROADM_NETWORK_FILE = "src/test/resources/openroadm-network.xml"; public static final String OTN_TOPOLOGY_FILE = "src/test/resources/otn-topology.xml"; public static final String PORTMAPPING_FILE = "src/test/resources/portmapping.xml"; diff --git a/tapi/src/test/resources/openroadm-network.xml b/tapi/src/test/resources/openroadm-network.xml new file mode 100644 index 000000000..5cc83a82a --- /dev/null +++ b/tapi/src/test/resources/openroadm-network.xml @@ -0,0 +1,76 @@ + + + + openroadm-network + + + + + ROADM-C1 + ROADM + + clli-network + NodeC + + 127.0.0.11 + vendorA + model2 + + + XPDR-C1 + XPONDER + + clli-network + NodeC + + 1.2.3.4 + vendorA + model2 + + + XPDR-A1 + XPONDER + + clli-network + NodeA + + 1.2.3.4 + vendorA + model2 + + + ROADM-A1 + ROADM + + clli-network + NodeA + + 127.0.0.11 + vendorA + model2 + + + SPDR-SA1 + SWITCH + + clli-network + NodeSA + + 1.2.3.4 + vendorA + universal-switchponder + + + SPDR-SC1 + SWITCH + + clli-network + NodeSC + + 1.2.3.4 + vendorA + universal-switchponder + + + + \ No newline at end of file -- 2.36.6