import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.transportpce.common.fixedflex.GridConstant;
+import org.opendaylight.transportpce.common.fixedflex.GridUtils;
import org.opendaylight.transportpce.pce.constraints.PceConstraints;
import org.opendaylight.transportpce.pce.constraints.PceConstraints.ResourcePair;
+import org.opendaylight.transportpce.pce.gnpy.utils.AToZComparator;
+import org.opendaylight.transportpce.pce.gnpy.utils.ZToAComparator;
import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.Elements;
import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.ElementsKey;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.RouteIncludeEro;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.TeHopType;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.TeNodeId;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.TePathDisjointness;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.TeTpId;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.common.constraints_config.TeBandwidth;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.common.constraints_config.TeBandwidthBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.explicit.route.hop.Type;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.explicit.route.hop.type.NumUnnumHopBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.explicit.route.hop.type.num.unnum.hop.NumUnnumHop;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.generic.path.constraints.PathConstraints;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.generic.path.constraints.PathConstraintsBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.gnpy.specific.parameters.EffectiveFreqSlot;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.gnpy.specific.parameters.EffectiveFreqSlotBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.path.route.objects.ExplicitRouteObjects;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.path.route.objects.ExplicitRouteObjectsBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.path.route.objects.explicit.route.objects.RouteObjectIncludeExclude;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.path.route.objects.explicit.route.objects.RouteObjectIncludeExcludeBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.path.route.objects.explicit.route.objects.RouteObjectIncludeExcludeKey;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.service.PathRequest;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.service.PathRequestBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.service.PathRequestKey;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.synchronization.info.Synchronization;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.synchronization.info.SynchronizationBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.synchronization.info.synchronization.Svec;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.synchronization.info.synchronization.SvecBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestInput;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.AToZDirection;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.ZToADirection;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.atoz.direction.AToZ;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.ztoa.direction.ZToA;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.pce.resource.resource.Resource;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.RouteIncludeEro;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.TeHopType;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.TeNodeId;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.TePathDisjointness;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.TeTpId;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.common.constraints_config.TeBandwidth;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.common.constraints_config.TeBandwidthBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.Type;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type.NumUnnumHopBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type.num.unnum.hop.NumUnnumHop;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.constraints.PathConstraints;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.constraints.PathConstraintsBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.gnpy.specific.parameters.EffectiveFreqSlot;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.gnpy.specific.parameters.EffectiveFreqSlotBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.path.route.objects.ExplicitRouteObjects;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.path.route.objects.ExplicitRouteObjectsBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.path.route.objects.explicit.route.objects.RouteObjectIncludeExclude;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.path.route.objects.explicit.route.objects.RouteObjectIncludeExcludeBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequest;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequestBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequestKey;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.Synchronization;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.SynchronizationBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.synchronization.Svec;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.synchronization.SvecBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.PathComputationRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.FrequencyTHz;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.ModulationFormat;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.AToZDirection;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.ZToADirection;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.atoz.direction.AToZ;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.ztoa.direction.ZToA;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.Resource;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yangtools.yang.common.Uint32;
import org.slf4j.Logger;
public class GnpyServiceImpl {
private static final Logger LOG = LoggerFactory.getLogger(GnpyServiceImpl.class);
- //Fix-grid channel width (THz)
- private static final double FIX_CH = 0.05;
- //Number of slot in 50GHz channel (THz)
- private static final int NB_SLOT_BW = 4;
- //Nominal central frequency granularity (THz)
- private static final double SLOT_BW = 0.00625;
- //Minimum channel center frequency (openRoadm spec) (THz)
- private static final double MAX_CENTRAL_FREQ = 196.1;
- //Flex-grid reference channel frequency (THz)
- private static final double FLEX_CENTRAL_FREQ = 193.1;
- //Convert THz to Hz
- private static final double CONVERT_TH_HZ = 1e12;
+ private static final Comparator<RouteObjectIncludeExclude> ROUTE_OBJECT_COMPARATOR =
+ Comparator.comparing(RouteObjectIncludeExclude::getIndex);
private Map<PathRequestKey, PathRequest> pathRequest = new HashMap<>();
private List<Synchronization> synchronization = new ArrayList<>();
private Map<String, IpAddress> mapFiberIp = new HashMap<>();
private List<String> trxList = new ArrayList<>();
private Map<ElementsKey, Elements> elements = new HashMap<>();
- private Map<RouteObjectIncludeExcludeKey,RouteObjectIncludeExclude> routeObjectIncludeExcludes = new HashMap<>();
+ private List<RouteObjectIncludeExclude> routeObjectIncludeExcludes = new ArrayList<>();
private IpAddress currentNodeIpAddress = null;
+ private AToZComparator atoZComparator = new AToZComparator();
+ private ZToAComparator ztoAComparator = new ZToAComparator();
/*
* Construct the GnpyServiceImpl
// Create explicitRouteObjects
List<AToZ> listAtoZ = new ArrayList<>(atoz.nonnullAToZ().values());
if (!listAtoZ.isEmpty()) {
+ Collections.sort(listAtoZ, atoZComparator);
extractRouteObjectIcludeAtoZ(listAtoZ);
} else {
extractHardConstraints(pceHardConstraints);
}
+
+ Collections.sort(routeObjectIncludeExcludes, ROUTE_OBJECT_COMPARATOR);
ExplicitRouteObjects explicitRouteObjects = new ExplicitRouteObjectsBuilder()
.setRouteObjectIncludeExclude(routeObjectIncludeExcludes).build();
//Create Path Constraint
- Long atozWavelength = null;
- if (atoz.getAToZWavelengthNumber() != null) {
- atozWavelength = atoz.getAToZWavelengthNumber().toJava();
- }
- PathConstraints pathConstraints = createPathConstraints(atoz.getRate().toJava(), atozWavelength);
+ PathConstraints pathConstraints = createPathConstraints(atoz.getRate().toJava(),
+ atoz.getModulationFormat(),
+ atoz.getAToZMinFrequency(),
+ atoz.getAToZMaxFrequency());
// Create the path request
Map<PathRequestKey, PathRequest> pathRequestMap = new HashMap<>();
// Create explicitRouteObjects
@NonNull List<ZToA> listZtoA = new ArrayList<>(ztoa.nonnullZToA().values());
if (!listZtoA.isEmpty()) {
+ Collections.sort(listZtoA, ztoAComparator);
extractRouteObjectIcludeZtoA(listZtoA);
} else {
extractHardConstraints(pceHardConstraints);
}
+ Collections.sort(routeObjectIncludeExcludes, ROUTE_OBJECT_COMPARATOR);
ExplicitRouteObjects explicitRouteObjects = new ExplicitRouteObjectsBuilder()
.setRouteObjectIncludeExclude(routeObjectIncludeExcludes).build();
//Create Path Constraint
- Long ztoaWavelength = null;
- if (ztoa.getZToAWavelengthNumber() != null) {
- ztoaWavelength = ztoa.getZToAWavelengthNumber().toJava();
- }
- PathConstraints pathConstraints = createPathConstraints(ztoa.getRate().toJava(), ztoaWavelength);
+ PathConstraints pathConstraints = createPathConstraints(ztoa.getRate().toJava(),
+ ztoa.getModulationFormat(),
+ ztoa.getZToAMinFrequency(),
+ ztoa.getZToAMaxFrequency());
// Create the path request
Map<PathRequestKey, PathRequest> pathRequestMap = new HashMap<>();
.setBidirectional(false).setPathConstraints(pathConstraints)
.setExplicitRouteObjects(explicitRouteObjects).build();
pathRequestMap.put(pathRequestEl.key(),pathRequestEl);
- LOG.debug("In GnpyServiceImpl: path request ZToA is extracted");
+ LOG.debug("In GnpyServiceImpl: path request ZToA is extracted is extracted");
return pathRequestMap;
}
//Extract RouteObjectIncludeExclude list in the case of pre-computed path A-to-Z
- private void extractRouteObjectIcludeAtoZ(List<AToZ> listAtoZ) throws GnpyException {
+ private void extractRouteObjectIcludeAtoZ(Collection<AToZ> listAtoZ) throws GnpyException {
Long index = 0L;
for (AToZ entry : listAtoZ) {
index = createResource(entry.getResource().getResource(),index);
Long idx = index;
if (resource
instanceof
- org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629
+ org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210
.pce.resource.resource.resource.Node) {
- org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629
+ org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210
.pce.resource.resource.resource.Node node =
- (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629
+ (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210
.pce.resource.resource.resource.Node) resource;
if (node.getNodeId() == null) {
throw new GnpyException("In gnpyServiceImpl: nodeId is null");
if (resource
instanceof
- org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629
+ org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210
.pce.resource.resource.resource.Link) {
- org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629
+ org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210
.pce.resource.resource.resource.Link link =
- (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629
+ (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210
.pce.resource.resource.resource.Link) resource;
idx = addLinkToRouteObject(link.getLinkId(),idx);
}
}
for (Elements element : this.elements.values()) {
- if (element.getUid().contains(ipAddress.getIpv4Address().getValue())) {
+ if (element.getUid().equals(ipAddress.getIpv4Address().getValue())) {
if ((this.currentNodeIpAddress == null) || (!this.currentNodeIpAddress.equals(ipAddress))) {
this.currentNodeIpAddress = ipAddress;
- RouteObjectIncludeExclude routeObjectIncludeExclude =
- addRouteObjectIncludeExclude(ipAddress, Uint32.valueOf(1),idx);
- routeObjectIncludeExcludes.put(routeObjectIncludeExclude.key(),routeObjectIncludeExclude);
+ RouteObjectIncludeExclude routeObjectIncludeExclude = addRouteObjectIncludeExclude(ipAddress,
+ Uint32.valueOf(1), idx);
+ routeObjectIncludeExcludes.add(routeObjectIncludeExclude);
idx += 1;
}
return idx;
}
RouteObjectIncludeExclude routeObjectIncludeExclude =
addRouteObjectIncludeExclude(fiberIp, Uint32.valueOf(1),idx);
- routeObjectIncludeExcludes.put(routeObjectIncludeExclude.key(),routeObjectIncludeExclude);
+ routeObjectIncludeExcludes.add(routeObjectIncludeExclude);
idx += 1;
}
return idx;
private RouteObjectIncludeExclude addRouteObjectIncludeExclude(IpAddress ipAddress, Uint32 teTpValue, Long index) {
TeNodeId teNodeId = new TeNodeId(ipAddress);
TeTpId teTpId = new TeTpId(teTpValue);
- NumUnnumHop numUnnumHop = new org.opendaylight.yang.gen.v1.gnpy.path.rev200202.explicit.route.hop.type.num
+ NumUnnumHop numUnnumHop = new org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type.num
.unnum.hop.NumUnnumHopBuilder()
.setNodeId(teNodeId.getIpv4Address().getValue())
.setLinkTpId(teTpId.getUint32().toString())
}
//Create the path constraints
- private PathConstraints createPathConstraints(Long rate, Long wavelengthNumber) {
- // Create EffectiveFreqSlot
- int freqNdex = 0;
- if (wavelengthNumber != null) {
- double freq = (MAX_CENTRAL_FREQ - FIX_CH * (wavelengthNumber - 1));
- freqNdex = (int) Math.round((freq - FLEX_CENTRAL_FREQ) / SLOT_BW);
+ private PathConstraints createPathConstraints(Long rate, String modulationFormat, FrequencyTHz minFrequency,
+ FrequencyTHz maxFrequency) {
+ BigDecimal spacing = GridConstant.SLOT_WIDTH_50;
+ int mvalue = GridConstant.NB_SLOTS_100G;
+ int nvalue = 0;
+ if (minFrequency != null && maxFrequency != null && modulationFormat != null) {
+ LOG.info("Creating path constraints for rate {}, modulationFormat {}, min freq {}, max freq {}", rate,
+ modulationFormat, minFrequency, maxFrequency);
+ FrequencyTHz centralFrequency = GridUtils
+ .getCentralFrequency(minFrequency.getValue(), maxFrequency.getValue());
+ int centralFrequencyBitSetIndex = GridUtils.getIndexFromFrequency(centralFrequency.getValue());
+ mvalue = GridConstant.RATE_SPECTRAL_WIDTH_SLOT_NUMBER_MAP.getOrDefault(Uint32.valueOf(rate),
+ GridConstant.NB_SLOTS_100G);
+ nvalue = GridUtils.getNFromFrequencyIndex(centralFrequencyBitSetIndex);
+ ModulationFormat mformat = ModulationFormat.DpQpsk;
+ Optional<ModulationFormat> optionalModulationFormat = ModulationFormat.forName(modulationFormat);
+ if (optionalModulationFormat.isPresent()) {
+ mformat = optionalModulationFormat.get();
+ }
+ spacing = GridConstant.FREQUENCY_SLOT_WIDTH_TABLE.get(Uint32.valueOf(rate), mformat);
+
}
- EffectiveFreqSlot effectiveFreqSlot1 = new EffectiveFreqSlotBuilder().setM(NB_SLOT_BW).setN(freqNdex).build();
- // Create Te-Bandwidth
- TeBandwidth teBandwidth = new TeBandwidthBuilder().setPathBandwidth(new BigDecimal(rate))
- .setTechnology("flexi-grid").setTrxType("openroadm-beta1")
- .setTrxMode("W100G").setEffectiveFreqSlot(Map.of(effectiveFreqSlot1.key(),effectiveFreqSlot1))
- .setSpacing(BigDecimal.valueOf(FIX_CH * CONVERT_TH_HZ)).build();
+ LOG.info("Creating path constraints for rate {}, mvalue {}, nvalue {}, spacing {}", rate,
+ mvalue, nvalue, spacing);
+ EffectiveFreqSlot effectiveFreqSlot = new EffectiveFreqSlotBuilder().setM(mvalue / 2).setN(nvalue).build();
+ // TODO : TrxMode is today hardcoded to W100G.
+ TeBandwidth teBandwidth = new TeBandwidthBuilder().setPathBandwidth(BigDecimal.valueOf(rate))
+ .setTechnology("flexi-grid").setTrxType("openroadm-beta1").setTrxMode("W100G")
+ .setEffectiveFreqSlot(Map.of(effectiveFreqSlot.key(), effectiveFreqSlot))
+ .setSpacing(spacing.multiply(BigDecimal.valueOf(1e9))).build();
return new PathConstraintsBuilder().setTeBandwidth(teBandwidth).build();
}