X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=pce%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Ftransportpce%2Fpce%2Fnetworkanalyzer%2FPceCalculation.java;h=81cc58b52f5bb57ca14544be5798304e1dd43e61;hb=67763b4d82e44c68fdbc765cdeec5496ff65b01e;hp=fd8f3a28007fea337672ec7a5ce060b3e3b82346;hpb=7ea354677f9b8ee0b160a7b636c51bb0bedfcd7b;p=transportpce.git diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceCalculation.java b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceCalculation.java index fd8f3a280..81cc58b52 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceCalculation.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceCalculation.java @@ -8,26 +8,33 @@ package org.opendaylight.transportpce.pce.networkanalyzer; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; - import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.transportpce.common.NetworkUtils; import org.opendaylight.transportpce.common.ResponseCodes; +import org.opendaylight.transportpce.common.StringConstants; +import org.opendaylight.transportpce.common.fixedflex.GridConstant; +import org.opendaylight.transportpce.common.mapping.MappingUtils; +import org.opendaylight.transportpce.common.mapping.MappingUtilsImpl; +import org.opendaylight.transportpce.common.mapping.PortMapping; import org.opendaylight.transportpce.common.network.NetworkTransactionService; import org.opendaylight.transportpce.pce.constraints.PceConstraints; import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestInput; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Node1; -import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmLinkType; -import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmNodeType; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.mc.capabilities.McCapabilities; +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.Node1; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State; +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.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId; @@ -38,7 +45,6 @@ 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.Network1; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -//import org.opendaylight.yangtools.yang.common.Decimal64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -76,18 +82,24 @@ public class PceCalculation { private Map allPceLinks = new HashMap<>(); private Set linksToExclude = new HashSet<>(); private PceResult returnStructure; + private PortMapping portMapping; private enum ConstraintTypes { NONE, HARD_EXCLUDE, HARD_INCLUDE, HARD_DIVERSITY, SOFT_EXCLUDE, SOFT_INCLUDE, SOFT_DIVERSITY; } + private MappingUtils mappingUtils; + public PceCalculation(PathComputationRequestInput input, NetworkTransactionService networkTransactionService, - PceConstraints pceHardConstraints, PceConstraints pceSoftConstraints, PceResult rc) { + PceConstraints pceHardConstraints, PceConstraints pceSoftConstraints, PceResult rc, + PortMapping portMapping) { this.input = input; this.networkTransactionService = networkTransactionService; this.returnStructure = rc; this.pceHardConstraints = pceHardConstraints; + this.mappingUtils = new MappingUtilsImpl(networkTransactionService.getDataBroker()); + this.portMapping = portMapping; parseInput(); } @@ -112,8 +124,6 @@ public class PceCalculation { } private boolean parseInput() { - anodeId = input.getServiceAEnd().getNodeId(); - znodeId = input.getServiceZEnd().getNodeId(); if (input.getServiceAEnd().getServiceFormat() == null || input.getServiceZEnd().getServiceFormat() == null || input.getServiceAEnd().getServiceRate() == null) { LOG.error("Service Format and Service Rate are required for a path calculation"); @@ -130,13 +140,13 @@ public class PceCalculation { switch (serviceFormatA) { case "Ethernet": case "OC": - serviceType = "100GE"; + serviceType = StringConstants.SERVICE_TYPE_100GE; break; case "OTU": - serviceType = "OTU4"; + serviceType = StringConstants.SERVICE_TYPE_OTU4; break; case "ODU": - serviceType = "ODU4"; + serviceType = StringConstants.SERVICE_TYPE_ODU4; break; default: LOG.debug("parseInput: unsupported service type: Format {} Rate 100L", serviceFormatA); @@ -149,10 +159,12 @@ public class PceCalculation { //Maybe HashMap and similar options should also be considered here. } else if ("Ethernet".equals(serviceFormatA)) { //only rate 100L is currently supported except in Ethernet - if (serviceRate == 10L) { - serviceType = "10GE"; + if (serviceRate == 400L) { + serviceType = StringConstants.SERVICE_TYPE_400GE; + } else if (serviceRate == 10L) { + serviceType = StringConstants.SERVICE_TYPE_10GE; } else if (serviceRate == 1L) { - serviceType = "1GE"; + serviceType = StringConstants.SERVICE_TYPE_1GE; } else { LOG.debug("parseInput: unsupported service type: Format Ethernet Rate {}", serviceRate); } @@ -160,6 +172,15 @@ public class PceCalculation { LOG.debug("parseInput: unsupported service type: Format {} Rate {}", serviceFormatA, serviceRate); } + if (StringConstants.SERVICE_TYPE_ODU4.equals(serviceType) + || StringConstants.SERVICE_TYPE_10GE.equals(serviceType) + || StringConstants.SERVICE_TYPE_1GE.equals(serviceType)) { + anodeId = input.getServiceAEnd().getTxDirection().getPort().getPortDeviceName(); + znodeId = input.getServiceZEnd().getTxDirection().getPort().getPortDeviceName(); + } else { + anodeId = input.getServiceAEnd().getNodeId(); + znodeId = input.getServiceZEnd().getNodeId(); + } returnStructure.setRate(input.getServiceAEnd().getServiceRate().toJava()); returnStructure.setServiceFormat(input.getServiceAEnd().getServiceFormat()); @@ -169,14 +190,13 @@ public class PceCalculation { private boolean readMdSal() { InstanceIdentifier nwInstanceIdentifier = null; Network nw = null; - if (("OC".equals(serviceFormatA)) || ("OTU".equals(serviceFormatA)) || (("Ethernet".equals(serviceFormatA)) - && (serviceRate == 100L))) { - + if (("OC".equals(serviceFormatA)) || ("OTU".equals(serviceFormatA)) + || ("Ethernet".equals(serviceFormatA) && ((serviceRate == 100L) || (serviceRate == 400L)))) { LOG.info("readMdSal: network {}", NetworkUtils.OVERLAY_NETWORK_ID); nwInstanceIdentifier = InstanceIdentifier.builder(Networks.class) .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))).build(); - } else if ("ODU".equals(serviceFormatA) || ("Ethernet".equals(serviceFormatA) && serviceRate == 10L) - || ("Ethernet".equals(serviceFormatA) && serviceRate == 1L)) { + } else if ("ODU".equals(serviceFormatA) + || ("Ethernet".equals(serviceFormatA) && ((serviceRate == 10L) || (serviceRate == 1L)))) { LOG.info("readMdSal: network {}", NetworkUtils.OTN_NETWORK_ID); nwInstanceIdentifier = InstanceIdentifier.builder(Networks.class) .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))).build(); @@ -205,12 +225,13 @@ public class PceCalculation { LOG.error("readMdSal: network is null: {}", nwInstanceIdentifier); return false; } - allNodes = nw.getNode().stream().sorted((n1, n2) -> n1.getNodeId().getValue().compareTo(n2.getNodeId() - .getValue())).collect(Collectors.toList()); + allNodes = nw.nonnullNode().values().stream().sorted((n1, n2) + -> n1.getNodeId().getValue().compareTo(n2.getNodeId().getValue())).collect(Collectors.toList()); Network1 nw1 = nw.augmentation(Network1.class); if (nw1 != null) { - allLinks = nw1.getLink().stream().sorted((l1, l2) -> l1.getSource().getSourceTp().toString().compareTo(l2 - .getSource().getSourceTp().toString())).collect(Collectors.toList()); + allLinks = nw1.nonnullLink().values().stream().sorted((l1, l2) + -> l1.getSource().getSourceTp().toString().compareTo(l2.getSource().getSourceTp().toString())) + .collect(Collectors.toList()); } else { LOG.warn("no otn links in otn-topology"); } @@ -235,7 +256,9 @@ public class PceCalculation { LOG.debug("analyzeNw: allNodes size {}, allLinks size {}", allNodes.size(), allLinks.size()); - if (("100GE".equals(serviceType)) || ("OTU4".equals(serviceType))) { + if (StringConstants.SERVICE_TYPE_100GE.equals(serviceType) + || StringConstants.SERVICE_TYPE_OTU4.equals(serviceType) + || StringConstants.SERVICE_TYPE_400GE.equals(serviceType)) { // 100GE service and OTU4 service are handled at the openroadm-topology layer for (Node node : allNodes) { validateNode(node); @@ -338,6 +361,7 @@ public class PceCalculation { NodeId destId = link.getDestination().getDestNode(); PceNode source = allPceNodes.get(sourceId); PceNode dest = allPceNodes.get(destId); + State state = link.augmentation(Link1.class).getOperationalState(); if (source == null) { LOG.debug("validateLink: Link is ignored due source node is rejected by node validation - {}", @@ -350,8 +374,16 @@ public class PceCalculation { return false; } - if (("100GE".equals(serviceType)) || ("OTU4".equals(serviceType))) { - // 100GE or OTU4 services are handled at WDM Layer + if (State.OutOfService.equals(state)) { + LOG.debug("validateLink: Link is ignored due operational state - {}", + state.getName()); + return false; + } + + if (StringConstants.SERVICE_TYPE_100GE.equals(serviceType) + || StringConstants.SERVICE_TYPE_OTU4.equals(serviceType) + || StringConstants.SERVICE_TYPE_400GE.equals(serviceType)) { + // 100GE or 400GE or OTU4 services are handled at WDM Layer PceLink pcelink = new PceLink(link, source, dest); if (!pcelink.isValid()) { dropOppositeLink(link); @@ -420,7 +452,9 @@ public class PceCalculation { } return true; - } else if (("ODU4".equals(serviceType)) || ("10GE".equals(serviceType)) || ("1GE".equals(serviceType))) { + } else if ((StringConstants.SERVICE_TYPE_ODU4.equals(serviceType)) + || (StringConstants.SERVICE_TYPE_10GE.equals(serviceType)) + || (StringConstants.SERVICE_TYPE_1GE.equals(serviceType))) { // ODU4, 1GE and 10GE services relying on ODU2, ODU2e or ODU0 services are handled at OTN layer PceLink pceOtnLink = new PceLink(link, source, dest); @@ -459,46 +493,79 @@ public class PceCalculation { } - private boolean validateNode(Node node) { + private void validateNode(Node node) { LOG.debug("validateNode: node {} ", node); - // PceNode will be used in Graph algorithm Node1 node1 = node.augmentation(Node1.class); if (node1 == null) { LOG.error("getNodeType: no Node1 (type) Augmentation for node: [{}]. Node is ignored", node.getNodeId()); - return false; + return; + } + if (State.OutOfService.equals(node1.getOperationalState())) { + LOG.error("getNodeType: node is ignored due to operational state - {}", node1.getOperationalState() + .getName()); + return; } OpenroadmNodeType nodeType = node1.getNodeType(); + String deviceNodeId = MapUtils.getSupNetworkNode(node); + // Should never happen but because of existing topology test files + // we have to manage this case + if (deviceNodeId == null || deviceNodeId.isBlank()) { + deviceNodeId = node.getNodeId().getValue(); + } - PceOpticalNode pceNode = new PceOpticalNode(node, nodeType, node.getNodeId(), - input.getServiceAEnd().getServiceFormat(), "optical"); - pceNode.validateAZxponder(anodeId, znodeId); - pceNode.initWLlist(); + LOG.info("Device node id {} for {}", deviceNodeId, node); + PceOpticalNode pceNode = new PceOpticalNode(deviceNodeId, this.serviceType, portMapping, node, nodeType, + mappingUtils.getOpenRoadmVersion(deviceNodeId), getSlotWidthGranularity(deviceNodeId, node.getNodeId())); + pceNode.validateAZxponder(anodeId, znodeId, input.getServiceAEnd().getServiceFormat()); + pceNode.initFrequenciesBitSet(); if (!pceNode.isValid()) { LOG.warn(" validateNode: Node is ignored"); - return false; + return; } - if (validateNodeConstraints(pceNode).equals(ConstraintTypes.HARD_EXCLUDE)) { - return false; + return; } - if ((pceNode.getSupNetworkNodeId().equals(anodeId) && (this.aendPceNode == null)) - && (Boolean.TRUE.equals(endPceNode(nodeType, pceNode.getNodeId(), pceNode)))) { + if (endPceNode(nodeType, pceNode.getNodeId(), pceNode) && this.aendPceNode == null + && isAZendPceNode(this.serviceFormatA, pceNode, anodeId, "A")) { this.aendPceNode = pceNode; } - if ((pceNode.getSupNetworkNodeId().equals(znodeId) && (this.zendPceNode == null)) - && (Boolean.TRUE.equals(endPceNode(nodeType, pceNode.getNodeId(), pceNode)))) { + if (endPceNode(nodeType, pceNode.getNodeId(), pceNode) && this.zendPceNode == null + && isAZendPceNode(this.serviceFormatZ, pceNode, znodeId, "Z")) { this.zendPceNode = pceNode; } allPceNodes.put(pceNode.getNodeId(), pceNode); LOG.debug("validateNode: node is saved {}", pceNode.getNodeId().getValue()); - return true; + return; } - private boolean validateOtnNode(Node node) { + private boolean isAZendPceNode(String serviceFormat, PceOpticalNode pceNode, String azNodeId, String azEndPoint) { + switch (serviceFormat) { + case "Ethernet": + case "OC": + if (pceNode.getSupNetworkNodeId().equals(azNodeId)) { + return true; + } + return false; + case "OTU": + if ("A".equals(azEndPoint) && pceNode.getNodeId().getValue() + .equals(this.input.getServiceAEnd().getRxDirection().getPort().getPortDeviceName())) { + return true; + } + if ("Z".equals(azEndPoint) && pceNode.getNodeId().getValue() + .equals(this.input.getServiceZEnd().getRxDirection().getPort().getPortDeviceName())) { + return true; + } + return false; + default: + LOG.debug("Unsupported service Format {} for node {}", serviceFormat, pceNode.getNodeId().getValue()); + return false; + } + } + private void validateOtnNode(Node node) { LOG.info("validateOtnNode: {} ", node.getNodeId().getValue()); // PceOtnNode will be used in Graph algorithm if (node.augmentation(Node1.class) != null) { @@ -509,10 +576,10 @@ public class PceCalculation { if (!pceOtnNode.isValid()) { LOG.warn(" validateOtnNode: Node {} is ignored", node.getNodeId().getValue()); - return false; + return; } if (validateNodeConstraints(pceOtnNode).equals(ConstraintTypes.HARD_EXCLUDE)) { - return false; + return; } if (pceOtnNode.getNodeId().getValue().equals(anodeId) && this.aendPceNode == null) { this.aendPceNode = pceOtnNode; @@ -522,20 +589,11 @@ public class PceCalculation { } allPceNodes.put(pceOtnNode.getNodeId(), pceOtnNode); LOG.info("validateOtnNode: node {} is saved", node.getNodeId().getValue()); - return true; + return; } else { LOG.error("ValidateOtnNode: no node-type augmentation. Node {} is ignored", node.getNodeId().getValue()); - return false; + return; } - -// if (mode == "AZ") { -// pceOtnNode.validateAZxponder(anodeId, znodeId); -// } else if (mode == "intermediate") { -// pceOtnNode.validateIntermediateSwitch(); -// } else { -// LOG.error("validateOtnNode: unproper mode passed to the method : {} not supported", mode); -// return null; -// } } private ConstraintTypes validateNodeConstraints(PceNode pcenode) { @@ -590,7 +648,7 @@ public class PceCalculation { this.azSrgs.add(nodeId); break; case XPONDER: - pceNode.initXndrTps(); + pceNode.initXndrTps(input.getServiceAEnd().getServiceFormat()); break; default: LOG.warn("endPceNode: Node {} is not SRG or XPONDER !", nodeId); @@ -598,7 +656,7 @@ public class PceCalculation { } if (!pceNode.isValid()) { - LOG.error("validateNode : there are no availaible wavelengths in node {}", pceNode.getNodeId().getValue()); + LOG.error("validateNode : there are no available frequencies in node {}", pceNode.getNodeId().getValue()); return false; } return true; @@ -628,12 +686,32 @@ public class PceCalculation { return returnStructure; } - private static void printNodesInfo(Map allpcenodes) { - Iterator> nodes = allpcenodes.entrySet().iterator(); - while (nodes.hasNext()) { - PceNode pcenode = nodes.next().getValue(); - List links = pcenode.getOutgoingLinks(); - LOG.info("In printNodes in node {} : outgoing links {} ", pcenode.getNodeId().getValue(), links); + private static void printNodesInfo(Map allPceNodes) { + allPceNodes.forEach(((nodeId, pceNode) -> { + LOG.info("In printNodes in node {} : outgoing links {} ", pceNode.getNodeId().getValue(), + pceNode.getOutgoingLinks()); + })); + } + + /** + * Get mc capability slot width granularity for device. + * @param deviceNodeId String + * @param nodeId NodeId + * @return slot width granularity + */ + private BigDecimal getSlotWidthGranularity(String deviceNodeId, NodeId nodeId) { + // nodeId: openroadm-topology level node + // deviceNodeId: openroadm-network level node + List mcCapabilities = mappingUtils.getMcCapabilitiesForNode(deviceNodeId); + String[] params = nodeId.getValue().split("-"); + // DEGX or SRGX + String rdmModuleName = params[params.length - 1]; + for (McCapabilities mcCapabitility : mcCapabilities) { + if (mcCapabitility.getMcNodeName().contains(rdmModuleName) + && mcCapabitility.getSlotWidthGranularity() != null) { + return mcCapabitility.getSlotWidthGranularity().getValue(); + } } + return GridConstant.SLOT_WIDTH_50; } }