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=a817bec4aaed44050e6d259f0b4288c60f09a309;hb=refs%2Fchanges%2F46%2F100646%2F27;hp=6fb58fcdd56e204fa5734d8ad669c18192374fe7;hpb=e82fbaf8294be8b3bc2df5ef1649a401fa636912;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 6fb58fcdd..a817bec4a 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,14 +8,13 @@ package org.opendaylight.transportpce.pce.networkanalyzer; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; 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; @@ -27,14 +26,21 @@ 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.common.service.ServiceTypes; +import org.opendaylight.transportpce.pce.PceComplianceCheck; 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.opendaylight.transportpce.portmapping.rev201012.network.nodes.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.opendaylight.transportpce.pce.rev220615.PathComputationRequestInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.mc.capabilities.McCapabilities; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Link1; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1; +//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.http.org.openroadm.device.types.rev191129.NodeTypes; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmLinkType; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmNodeType; +//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; @@ -45,6 +51,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.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.Uint32; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,14 +67,14 @@ public class PceCalculation { private String serviceFormatA = ""; private String serviceFormatZ = ""; private String serviceType = ""; - private Long serviceRate = 0L; + private Uint32 serviceRate = Uint32.valueOf(0); private PceConstraints pceHardConstraints; ///////////// Intermediate data///////////////// private List addLinks = new ArrayList<>(); private List dropLinks = new ArrayList<>(); - private HashSet azSrgs = new HashSet<>(); + private List azSrgs = new ArrayList<>(); private PceNode aendPceNode = null; private PceNode zendPceNode = null; @@ -80,7 +87,7 @@ public class PceCalculation { // this List serves calculation of ZtoA path description // TODO maybe better solution is possible private Map allPceLinks = new HashMap<>(); - private Set linksToExclude = new HashSet<>(); + private List linksToExclude = new ArrayList<>(); private PceResult returnStructure; private PortMapping portMapping; @@ -124,116 +131,113 @@ public class PceCalculation { } private boolean parseInput() { - if (input.getServiceAEnd().getServiceFormat() == null || input.getServiceZEnd().getServiceFormat() == null - || input.getServiceAEnd().getServiceRate() == null) { + if (!PceComplianceCheck.checkString(input.getServiceAEnd().getServiceFormat().getName()) + || !PceComplianceCheck.checkString(input.getServiceZEnd().getServiceFormat().getName()) + || !PceComplianceCheck.checkString(input.getServiceAEnd().getServiceRate().toString())) { LOG.error("Service Format and Service Rate are required for a path calculation"); return false; } serviceFormatA = input.getServiceAEnd().getServiceFormat().getName(); serviceFormatZ = input.getServiceZEnd().getServiceFormat().getName(); - serviceRate = input.getServiceAEnd().getServiceRate().toJava(); + serviceRate = input.getServiceAEnd().getServiceRate(); + serviceType = ServiceTypes.getServiceType( + serviceFormatA, + serviceRate, + NodeTypes.Xpdr.equals(portMapping.getNode(input.getServiceAEnd().getNodeId()).getNodeInfo().getNodeType()) + && checkAendInputTxPortName() + ? portMapping.getMapping( + input.getServiceAEnd().getNodeId(), + input.getServiceAEnd().getTxDirection().getPort().getPortName()) + : null); LOG.info("parseInput: A and Z :[{}] and [{}]", anodeId, znodeId); - if (!(serviceFormatA.equals(serviceFormatZ))) { - LOG.info("parseInput: different service format for A and Z not handled, will use service format from Aend"); - } else if (serviceRate == 100L) { - switch (serviceFormatA) { - case "Ethernet": - case "OC": - serviceType = StringConstants.SERVICE_TYPE_100GE; - break; - case "OTU": - serviceType = StringConstants.SERVICE_TYPE_OTU4; - break; - case "ODU": - serviceType = StringConstants.SERVICE_TYPE_ODU4; - break; - default: - LOG.debug("parseInput: unsupported service type: Format {} Rate 100L", serviceFormatA); - break; - } - //switch(serviceRate) may seem a better option at first glance. - //But switching on Long or long is not directly possible in Java. - //And casting to int bumps the limit here. - //Passing by ENUM or String are possible alternatives. - //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 == 400L) { - serviceType = StringConstants.SERVICE_TYPE_400GE; - } else if (serviceRate == 10L) { - serviceType = StringConstants.SERVICE_TYPE_10GE; - } else if (serviceRate == 1L) { - serviceType = StringConstants.SERVICE_TYPE_1GE; - } else { - LOG.debug("parseInput: unsupported service type: Format Ethernet Rate {}", serviceRate); - } - } else { - 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(); - } + + getAZnodeId(); returnStructure.setRate(input.getServiceAEnd().getServiceRate().toJava()); returnStructure.setServiceFormat(input.getServiceAEnd().getServiceFormat()); return true; } + private boolean checkAendInputTxPortName() { + return checkAendInputTxPort() + && input.getServiceAEnd().getTxDirection().getPort().getPortName() != null; + } + + private boolean checkAendInputTxPortDeviceName() { + return checkAendInputTxPort() + && input.getServiceAEnd().getTxDirection().getPort().getPortDeviceName() != null; + } + + private boolean checkAendInputTxPort() { + return input.getServiceAEnd() != null + && input.getServiceAEnd().getTxDirection() != null + && input.getServiceAEnd().getTxDirection().getPort() != null; + } + + private boolean checkZendInputTxPortDeviceName() { + return input.getServiceZEnd() != null + && input.getServiceZEnd().getTxDirection() != null + && input.getServiceZEnd().getTxDirection().getPort() != null + && input.getServiceZEnd().getTxDirection().getPort().getPortDeviceName() != null; + } + + private void getAZnodeId() { + anodeId = + checkAendInputTxPortDeviceName() + ? input.getServiceAEnd().getTxDirection().getPort().getPortDeviceName() + : input.getServiceAEnd().getNodeId(); + znodeId = + checkZendInputTxPortDeviceName() + ? input.getServiceZEnd().getTxDirection().getPort().getPortDeviceName() + : input.getServiceZEnd().getNodeId(); + } + private boolean readMdSal() { InstanceIdentifier nwInstanceIdentifier = null; - Network nw = null; - 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) || (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(); - } else { - LOG.info("readMdSal: service-rate {} / service-format not handled {}", serviceRate, serviceFormatA); - return false; - } - - try { - Optional nwOptional = - networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, nwInstanceIdentifier).get(); - if (nwOptional.isPresent()) { - nw = nwOptional.get(); - LOG.debug("readMdSal: network nodes: nwOptional.isPresent = true {}", nw); - } - } catch (InterruptedException | ExecutionException e) { - LOG.error("readMdSal: Error reading topology {}", nwInstanceIdentifier); - networkTransactionService.close(); - returnStructure.setRC(ResponseCodes.RESPONSE_FAILED); - throw new RuntimeException( - "readMdSal: Error reading from operational store, topology : " + nwInstanceIdentifier + " :" + e); + switch (serviceType) { + case StringConstants.SERVICE_TYPE_100GE_T: + case StringConstants.SERVICE_TYPE_400GE: + case StringConstants.SERVICE_TYPE_OTU4: + case StringConstants.SERVICE_TYPE_OTUC2: + case StringConstants.SERVICE_TYPE_OTUC3: + case StringConstants.SERVICE_TYPE_OTUC4: + 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(); + break; + case StringConstants.SERVICE_TYPE_100GE_M: + case StringConstants.SERVICE_TYPE_100GE_S: + case StringConstants.SERVICE_TYPE_ODU4: + case StringConstants.SERVICE_TYPE_ODUC2: + case StringConstants.SERVICE_TYPE_ODUC3: + case StringConstants.SERVICE_TYPE_ODUC4: + case StringConstants.SERVICE_TYPE_10GE: + case StringConstants.SERVICE_TYPE_1GE: + 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(); + break; + default: + LOG.warn("readMdSal: unknown service-type for service-rate {} and service-format {}", serviceRate, + serviceFormatA); + break; } - networkTransactionService.close(); - if (nw == null) { + if (readTopology(nwInstanceIdentifier) == null) { LOG.error("readMdSal: network is null: {}", nwInstanceIdentifier); return false; } - allNodes = nw.nonnullNode().values().stream().sorted((n1, n2) + + allNodes = readTopology(nwInstanceIdentifier).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) { + Network1 nw1 = readTopology(nwInstanceIdentifier).augmentation(Network1.class); + if (nw1 == null) { + LOG.warn("no otn links in otn-topology"); + } else { allLinks = nw1.nonnullLink().values().stream().sorted((l1, l2) - -> l1.getSource().getSourceTp().toString().compareTo(l2.getSource().getSourceTp().toString())) + -> l1.getSource().getSourceTp().getValue().compareTo(l2.getSource().getSourceTp().getValue())) .collect(Collectors.toList()); - } else { - LOG.warn("no otn links in otn-topology"); } if (allNodes == null || allNodes.isEmpty()) { LOG.error("readMdSal: no nodes "); @@ -252,58 +256,83 @@ public class PceCalculation { return true; } + private Network readTopology(InstanceIdentifier nwInstanceIdentifier) { + Network nw = null; + try { + Optional nwOptional = + networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, nwInstanceIdentifier).get(); + if (nwOptional.isPresent()) { + nw = nwOptional.get(); + LOG.debug("readMdSal: network nodes: nwOptional.isPresent = true {}", nw); + networkTransactionService.close(); + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("readMdSal: Error reading topology {}", nwInstanceIdentifier); + networkTransactionService.close(); + returnStructure.setRC(ResponseCodes.RESPONSE_FAILED); + throw new RuntimeException( + "readMdSal: Error reading from operational store, topology : " + nwInstanceIdentifier + " :" + e); + } + return nw; + } + private boolean analyzeNw() { LOG.debug("analyzeNw: allNodes size {}, allLinks size {}", allNodes.size(), allLinks.size()); + switch (serviceType) { + case StringConstants.SERVICE_TYPE_100GE_T: + case StringConstants.SERVICE_TYPE_OTU4: + case StringConstants.SERVICE_TYPE_400GE: + case StringConstants.SERVICE_TYPE_OTUC2: + case StringConstants.SERVICE_TYPE_OTUC3: + case StringConstants.SERVICE_TYPE_OTUC4: + // 100GE service and OTU4 service are handled at the openroadm-topology layer + for (Node node : allNodes) { + validateNode(node); + } - 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); - } - - LOG.debug("analyzeNw: allPceNodes size {}", allPceNodes.size()); + LOG.debug("analyzeNw: allPceNodes size {}", allPceNodes.size()); - if (aendPceNode == null || zendPceNode == null) { - LOG.error("analyzeNw: Error in reading nodes: A or Z do not present in the network"); - return false; - } - for (Link link : allLinks) { - validateLink(link); - } - // debug prints - LOG.debug("analyzeNw: addLinks size {}, dropLinks size {}", addLinks.size(), dropLinks.size()); - // debug prints - LOG.debug("analyzeNw: azSrgs size = {}", azSrgs.size()); - for (NodeId srg : azSrgs) { - LOG.debug("analyzeNw: A/Z Srgs SRG = {}", srg.getValue()); - } - // debug prints - for (PceLink link : addLinks) { - filteraddLinks(link); - } - for (PceLink link : dropLinks) { - filterdropLinks(link); - } + if (aendPceNode == null || zendPceNode == null) { + LOG.error("analyzeNw: Error in reading nodes: A or Z do not present in the network"); + return false; + } + for (Link link : allLinks) { + validateLink(link); + } + // debug prints + LOG.debug("analyzeNw: addLinks size {}, dropLinks size {}", addLinks.size(), dropLinks.size()); + // debug prints + LOG.debug("analyzeNw: azSrgs size = {}", azSrgs.size()); + for (NodeId srg : azSrgs) { + LOG.debug("analyzeNw: A/Z Srgs SRG = {}", srg.getValue()); + } + // debug prints + for (PceLink link : addLinks) { + filteraddLinks(link); + } + for (PceLink link : dropLinks) { + filterdropLinks(link); + } + break; - } else { - // ODU4, 10GE/ODU2e or 1GE/ODU0 services are handled at openroadm-otn layer + default: + // ODU4, 10GE/ODU2e or 1GE/ODU0 services are handled at openroadm-otn layer - for (Node node : allNodes) { - validateOtnNode(node); - } + for (Node node : allNodes) { + validateOtnNode(node); + } - LOG.info("analyzeNw: allPceNodes {}", allPceNodes); + LOG.info("analyzeNw: allPceNodes {}", allPceNodes); - if (aendPceNode == null || zendPceNode == null) { - LOG.error("analyzeNw: Error in reading nodes: A or Z do not present in the network"); - return false; - } - for (Link link : allLinks) { - validateLink(link); - } + if (aendPceNode == null || zendPceNode == null) { + LOG.error("analyzeNw: Error in reading nodes: A or Z do not present in the network"); + return false; + } + for (Link link : allLinks) { + validateLink(link); + } + break; } LOG.info("analyzeNw: allPceNodes size {}, allPceLinks size {}", allPceNodes.size(), allPceLinks.size()); @@ -380,121 +409,31 @@ public class PceCalculation { 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); - LOG.error(" validateLink: Link is ignored due errors in network data or in opposite link"); - return false; - } - LinkId linkId = pcelink.getLinkId(); - if (validateLinkConstraints(pcelink).equals(ConstraintTypes.HARD_EXCLUDE)) { - dropOppositeLink(link); - LOG.debug("validateLink: constraints : link is ignored == {}", linkId.getValue()); - return false; - } - switch (pcelink.getlinkType()) { - case ROADMTOROADM: - case EXPRESSLINK: - allPceLinks.put(linkId, pcelink); - source.addOutgoingLink(pcelink); - LOG.debug("validateLink: {}-LINK added to allPceLinks {}", - pcelink.getlinkType(), pcelink); - break; - case ADDLINK: - pcelink.setClient(source.getRdmSrgClient(pcelink.getSourceTP().toString())); - addLinks.add(pcelink); - LOG.debug("validateLink: ADD-LINK saved {}", pcelink); - break; - case DROPLINK: - pcelink.setClient(dest.getRdmSrgClient(pcelink.getDestTP().toString())); - dropLinks.add(pcelink); - LOG.debug("validateLink: DROP-LINK saved {}", pcelink); - break; - case XPONDERINPUT: - // store separately all SRG links directly - azSrgs.add(sourceId); - // connected to A/Z - if (!dest.checkTP(pcelink.getDestTP().toString())) { - LOG.debug( - "validateLink: XPONDER-INPUT is rejected as NW port is busy - {} ", pcelink); - return false; - } - if (dest.getXpdrClient(pcelink.getDestTP().toString()) != null) { - pcelink.setClient(dest.getXpdrClient(pcelink.getDestTP().toString())); - } - allPceLinks.put(linkId, pcelink); - source.addOutgoingLink(pcelink); - LOG.debug("validateLink: XPONDER-INPUT link added to allPceLinks {}", pcelink); - break; - // does it mean XPONDER==>>SRG ? - case XPONDEROUTPUT: - // store separately all SRG links directly - azSrgs.add(destId); - // connected to A/Z - if (!source.checkTP(pcelink.getSourceTP().toString())) { - LOG.debug( - "validateLink: XPONDER-OUTPUT is rejected as NW port is busy - {} ", pcelink); - return false; - } - if (source.getXpdrClient(pcelink.getSourceTP().toString()) != null) { - pcelink.setClient(source.getXpdrClient(pcelink.getSourceTP().toString())); - } - allPceLinks.put(linkId, pcelink); - source.addOutgoingLink(pcelink); - LOG.debug("validateLink: XPONDER-OUTPUT link added to allPceLinks {}", pcelink); - break; - default: - LOG.warn("validateLink: link type is not supported {}", pcelink); - } - return true; - - } 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); - - if (!pceOtnLink.isOtnValid(link, serviceType)) { - dropOppositeLink(link); - LOG.error(" validateLink: Link is ignored due errors in network data or in opposite link"); - return false; - } - - LinkId linkId = pceOtnLink.getLinkId(); - if (validateLinkConstraints(pceOtnLink).equals(ConstraintTypes.HARD_EXCLUDE)) { - dropOppositeLink(link); - LOG.debug("validateLink: constraints : link is ignored == {}", linkId.getValue()); + switch (serviceType) { + case StringConstants.SERVICE_TYPE_100GE_T: + case StringConstants.SERVICE_TYPE_OTU4: + case StringConstants.SERVICE_TYPE_OTUC2: + case StringConstants.SERVICE_TYPE_OTUC3: + case StringConstants.SERVICE_TYPE_OTUC4: + case StringConstants.SERVICE_TYPE_400GE: + return processPceLink(link, sourceId, destId, source, dest); + case StringConstants.SERVICE_TYPE_ODU4: + case StringConstants.SERVICE_TYPE_10GE: + case StringConstants.SERVICE_TYPE_100GE_M: + case StringConstants.SERVICE_TYPE_100GE_S: + case StringConstants.SERVICE_TYPE_ODUC2: + case StringConstants.SERVICE_TYPE_ODUC3: + case StringConstants.SERVICE_TYPE_ODUC4: + case StringConstants.SERVICE_TYPE_1GE: + return processPceOtnLink(link, source, dest); + default: + LOG.error(" validateLink: Unmanaged service type {}", serviceType); return false; - } - - switch (pceOtnLink.getlinkType()) { - case OTNLINK: - if (dest.getXpdrClient(pceOtnLink.getDestTP().toString()) != null) { - pceOtnLink.setClient(dest.getXpdrClient(pceOtnLink.getDestTP().toString())); - } - - allPceLinks.put(linkId, pceOtnLink); - source.addOutgoingLink(pceOtnLink); - LOG.info("validateLink: OTN-LINK added to allPceLinks {}", pceOtnLink); - break; - default: - LOG.warn("validateLink: link type is not supported {}", pceOtnLink); - } - return true; - - } else { - LOG.error(" validateLink: Unmanaged service type {}", serviceType); - return false; } - } private void validateNode(Node node) { - LOG.debug("validateNode: node {} ", node); + LOG.info("validateNode: node {} ", node); // PceNode will be used in Graph algorithm Node1 node1 = node.augmentation(Node1.class); if (node1 == null) { @@ -516,7 +455,8 @@ public class PceCalculation { 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())); + mappingUtils.getOpenRoadmVersion(deviceNodeId), getSlotWidthGranularity(deviceNodeId, node.getNodeId()), + getCentralFreqGranularity(deviceNodeId, node.getNodeId())); pceNode.validateAZxponder(anodeId, znodeId, input.getServiceAEnd().getServiceFormat()); pceNode.initFrequenciesBitSet(); @@ -527,13 +467,26 @@ public class PceCalculation { if (validateNodeConstraints(pceNode).equals(ConstraintTypes.HARD_EXCLUDE)) { return; } - if (endPceNode(nodeType, pceNode.getNodeId(), pceNode) && this.aendPceNode == null - && isAZendPceNode(this.serviceFormatA, pceNode, anodeId, "A")) { - this.aendPceNode = pceNode; - } - if (endPceNode(nodeType, pceNode.getNodeId(), pceNode) && this.zendPceNode == null - && isAZendPceNode(this.serviceFormatZ, pceNode, znodeId, "Z")) { - this.zendPceNode = pceNode; + + if (endPceNode(nodeType, pceNode.getNodeId(), pceNode)) { + if (this.aendPceNode == null && isAZendPceNode(this.serviceFormatA, pceNode, anodeId, "A")) { + // Added to ensure A-node has a addlink in the topology + List links = this.allLinks.stream() + .filter(x -> x.getSource().getSourceNode().getValue().contains(pceNode.getNodeId().getValue())) + .collect(Collectors.toList()); + if (links.size() > 0) { + this.aendPceNode = pceNode; + } + } + if (this.zendPceNode == null && isAZendPceNode(this.serviceFormatZ, pceNode, znodeId, "Z")) { + // Added to ensure Z-node has a droplink in the topology + List links = this.allLinks.stream() + .filter(x -> x.getDestination().getDestNode().getValue().contains(pceNode.getNodeId().getValue())) + .collect(Collectors.toList()); + if (links.size() > 0) { + this.zendPceNode = pceNode; + } + } } allPceNodes.put(pceNode.getNodeId(), pceNode); @@ -541,6 +494,10 @@ public class PceCalculation { return; } + @SuppressWarnings("fallthrough") + @SuppressFBWarnings( + value = "SF_SWITCH_FALLTHROUGH", + justification = "intentional fallthrough") private boolean isAZendPceNode(String serviceFormat, PceOpticalNode pceNode, String azNodeId, String azEndPoint) { switch (serviceFormat) { case "Ethernet": @@ -548,17 +505,20 @@ public class PceCalculation { if (pceNode.getSupNetworkNodeId().equals(azNodeId)) { return true; } - return false; + //fallthrough 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; + switch (azEndPoint) { + case "A": + return checkAendInputTxPortDeviceName() + && pceNode.getNodeId().getValue() + .equals(this.input.getServiceAEnd().getTxDirection().getPort().getPortDeviceName()); + case "Z": + return checkZendInputTxPortDeviceName() + && pceNode.getNodeId().getValue() + .equals(this.input.getServiceZEnd().getTxDirection().getPort().getPortDeviceName()); + default: + return false; } - return false; default: LOG.debug("Unsupported service Format {} for node {}", serviceFormat, pceNode.getNodeId().getValue()); return false; @@ -568,32 +528,48 @@ public class PceCalculation { private void validateOtnNode(Node node) { LOG.info("validateOtnNode: {} ", node.getNodeId().getValue()); // PceOtnNode will be used in Graph algorithm - if (node.augmentation(Node1.class) != null) { - OpenroadmNodeType nodeType = node.augmentation(Node1.class).getNodeType(); - - PceOtnNode pceOtnNode = new PceOtnNode(node, nodeType, node.getNodeId(), "otn", serviceType); - pceOtnNode.validateXponder(anodeId, znodeId); + if (node.augmentation(Node1.class) == null) { + LOG.error("ValidateOtnNode: no node-type augmentation. Node {} is ignored", node.getNodeId().getValue()); + return; + } - if (!pceOtnNode.isValid()) { - LOG.warn(" validateOtnNode: Node {} is ignored", node.getNodeId().getValue()); - return; - } - if (validateNodeConstraints(pceOtnNode).equals(ConstraintTypes.HARD_EXCLUDE)) { - return; - } - if (pceOtnNode.getNodeId().getValue().equals(anodeId) && this.aendPceNode == null) { - this.aendPceNode = pceOtnNode; - } - if (pceOtnNode.getNodeId().getValue().equals(znodeId) && this.zendPceNode == null) { - this.zendPceNode = pceOtnNode; - } - allPceNodes.put(pceOtnNode.getNodeId(), pceOtnNode); - LOG.info("validateOtnNode: node {} is saved", node.getNodeId().getValue()); + OpenroadmNodeType nodeType = node.augmentation(Node1.class).getNodeType(); + String clientPort = null; + if (node.getNodeId().getValue().equals(anodeId) + && this.aendPceNode == null + && input.getServiceAEnd() != null + && input.getServiceAEnd().getRxDirection() != null + && input.getServiceAEnd().getRxDirection().getPort() != null + && input.getServiceAEnd().getRxDirection().getPort().getPortName() != null) { + clientPort = input.getServiceAEnd().getRxDirection().getPort().getPortName(); + } else if (node.getNodeId().getValue().equals(znodeId) + && this.zendPceNode == null + && input.getServiceZEnd() != null + && input.getServiceZEnd().getRxDirection() != null + && input.getServiceZEnd().getRxDirection().getPort() != null + && input.getServiceZEnd().getRxDirection().getPort().getPortName() != null) { + clientPort = input.getServiceZEnd().getRxDirection().getPort().getPortName(); + } + + PceOtnNode pceOtnNode = new PceOtnNode(node, nodeType, node.getNodeId(), "otn", serviceType, clientPort); + pceOtnNode.validateXponder(anodeId, znodeId); + + if (!pceOtnNode.isValid()) { + LOG.warn(" validateOtnNode: Node {} is ignored", node.getNodeId().getValue()); return; - } else { - LOG.error("ValidateOtnNode: no node-type augmentation. Node {} is ignored", node.getNodeId().getValue()); + } + if (validateNodeConstraints(pceOtnNode).equals(ConstraintTypes.HARD_EXCLUDE)) { return; } + if (pceOtnNode.getNodeId().getValue().equals(anodeId) && this.aendPceNode == null) { + this.aendPceNode = pceOtnNode; + } + if (pceOtnNode.getNodeId().getValue().equals(znodeId) && this.zendPceNode == null) { + this.zendPceNode = pceOtnNode; + } + allPceNodes.put(pceOtnNode.getNodeId(), pceOtnNode); + LOG.info("validateOtnNode: node {} is saved", node.getNodeId().getValue()); + return; } private ConstraintTypes validateNodeConstraints(PceNode pcenode) { @@ -662,6 +638,112 @@ public class PceCalculation { return true; } + private boolean processPceLink(Link link, NodeId sourceId, NodeId destId, PceNode source, PceNode dest) { + PceLink pcelink = new PceLink(link, source, dest); + if (!pcelink.isValid()) { + dropOppositeLink(link); + LOG.error(" validateLink: Link is ignored due errors in network data or in opposite link"); + return false; + } + LinkId linkId = pcelink.getLinkId(); + if (validateLinkConstraints(pcelink).equals(ConstraintTypes.HARD_EXCLUDE)) { + dropOppositeLink(link); + LOG.debug("validateLink: constraints : link is ignored == {}", linkId.getValue()); + return false; + } + switch (pcelink.getlinkType()) { + case ROADMTOROADM: + case EXPRESSLINK: + allPceLinks.put(linkId, pcelink); + source.addOutgoingLink(pcelink); + LOG.debug("validateLink: {}-LINK added to allPceLinks {}", + pcelink.getlinkType(), pcelink); + break; + case ADDLINK: + pcelink.setClient( + source.getRdmSrgClient(pcelink.getSourceTP().getValue(), StringConstants.SERVICE_DIRECTION_AZ)); + addLinks.add(pcelink); + LOG.debug("validateLink: ADD-LINK saved {}", pcelink); + break; + case DROPLINK: + pcelink.setClient( + dest.getRdmSrgClient(pcelink.getDestTP().getValue(), StringConstants.SERVICE_DIRECTION_ZA)); + dropLinks.add(pcelink); + LOG.debug("validateLink: DROP-LINK saved {}", pcelink); + break; + case XPONDERINPUT: + // store separately all SRG links directly + azSrgs.add(sourceId); + // connected to A/Z + if (!dest.checkTP(pcelink.getDestTP().getValue())) { + LOG.debug( + "validateLink: XPONDER-INPUT is rejected as NW port is busy - {} ", pcelink); + return false; + } + if (dest.getXpdrClient(pcelink.getDestTP().getValue()) != null) { + pcelink.setClient(dest.getXpdrClient(pcelink.getDestTP().getValue())); + } + allPceLinks.put(linkId, pcelink); + source.addOutgoingLink(pcelink); + LOG.debug("validateLink: XPONDER-INPUT link added to allPceLinks {}", pcelink); + break; + // does it mean XPONDER==>>SRG ? + case XPONDEROUTPUT: + // store separately all SRG links directly + azSrgs.add(destId); + // connected to A/Z + if (!source.checkTP(pcelink.getSourceTP().getValue())) { + LOG.debug( + "validateLink: XPONDER-OUTPUT is rejected as NW port is busy - {} ", pcelink); + return false; + } + if (source.getXpdrClient(pcelink.getSourceTP().getValue()) != null) { + pcelink.setClient(source.getXpdrClient(pcelink.getSourceTP().getValue())); + } + allPceLinks.put(linkId, pcelink); + source.addOutgoingLink(pcelink); + LOG.debug("validateLink: XPONDER-OUTPUT link added to allPceLinks {}", pcelink); + break; + default: + LOG.warn("validateLink: link type is not supported {}", pcelink); + } + return true; + } + + private boolean processPceOtnLink(Link link, PceNode source, PceNode dest) { + PceLink pceOtnLink = new PceLink(link, source, dest); + + if (!pceOtnLink.isOtnValid(link, serviceType)) { + dropOppositeLink(link); + LOG.error(" validateLink: Link is ignored due errors in network data or in opposite link"); + return false; + } + + LinkId linkId = pceOtnLink.getLinkId(); + if (validateLinkConstraints(pceOtnLink).equals(ConstraintTypes.HARD_EXCLUDE)) { + dropOppositeLink(link); + LOG.debug("validateLink: constraints : link is ignored == {}", linkId.getValue()); + return false; + } + + switch (pceOtnLink.getlinkType()) { + case OTNLINK: + if (source.getXpdrClient(pceOtnLink.getSourceTP().getValue()) != null) { + pceOtnLink.setClient(source.getXpdrClient(pceOtnLink.getSourceTP().getValue())); + } + if (dest.getXpdrClient(pceOtnLink.getDestTP().getValue()) != null) { + pceOtnLink.setClient(dest.getXpdrClient(pceOtnLink.getDestTP().getValue())); + } + allPceLinks.put(linkId, pceOtnLink); + source.addOutgoingLink(pceOtnLink); + LOG.info("validateLink: OTN-LINK added to allPceLinks {}", pceOtnLink); + break; + default: + LOG.warn("validateLink: link type is not supported {}", pceOtnLink); + } + return true; + } + public PceNode getaendPceNode() { return aendPceNode; } @@ -704,12 +786,42 @@ public class PceCalculation { // deviceNodeId: openroadm-network level node List mcCapabilities = mappingUtils.getMcCapabilitiesForNode(deviceNodeId); String[] params = nodeId.getValue().split("-"); - // DEGX or SRGX - String rdmModuleName = params[params.length - 1]; + // DEGx or SRGx or XPDRx + String moduleName = params[params.length - 1]; for (McCapabilities mcCapabitility : mcCapabilities) { - if (mcCapabitility.getMcNodeName().contains(rdmModuleName) + if (mcCapabitility.getMcNodeName().contains("XPDR") && mcCapabitility.getSlotWidthGranularity() != null) { - return mcCapabitility.getSlotWidthGranularity().getValue(); + return mcCapabitility.getSlotWidthGranularity().getValue().decimalValue(); + } + if (mcCapabitility.getMcNodeName().contains(moduleName) + && mcCapabitility.getSlotWidthGranularity() != null) { + return mcCapabitility.getSlotWidthGranularity().getValue().decimalValue(); + } + } + return GridConstant.SLOT_WIDTH_50; + } + + /** + * Get mc capability central-width granularity for device. + * @param deviceNodeId String + * @param nodeId NodeId + * @return center-freq granularity + */ + private BigDecimal getCentralFreqGranularity(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 or XPDRx + String moduleName = params[params.length - 1]; + for (McCapabilities mcCapabitility : mcCapabilities) { + if (mcCapabitility.getMcNodeName().contains("XPDR") + && mcCapabitility.getCenterFreqGranularity() != null) { + return mcCapabitility.getCenterFreqGranularity().getValue().decimalValue(); + } + if (mcCapabitility.getMcNodeName().contains(moduleName) + && mcCapabitility.getCenterFreqGranularity() != null) { + return mcCapabitility.getCenterFreqGranularity().getValue().decimalValue(); } } return GridConstant.SLOT_WIDTH_50;