Committed by
Gerrit Code Review
Deprecate IndexedLambda and remove from optical intent compiler.
Allow drivers to report any spectral grid. Bugfixes. ONOS-3495 Change-Id: Ied946660d48e482c1746d1e87735498b1637bb4b
Showing
10 changed files
with
153 additions
and
56 deletions
| ... | @@ -15,11 +15,6 @@ | ... | @@ -15,11 +15,6 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.optical.testapp; | 16 | package org.onosproject.optical.testapp; |
| 17 | 17 | ||
| 18 | -import static org.slf4j.LoggerFactory.getLogger; | ||
| 19 | - | ||
| 20 | -import java.util.HashMap; | ||
| 21 | -import java.util.Map; | ||
| 22 | - | ||
| 23 | import org.apache.felix.scr.annotations.Activate; | 18 | import org.apache.felix.scr.annotations.Activate; |
| 24 | import org.apache.felix.scr.annotations.Deactivate; | 19 | import org.apache.felix.scr.annotations.Deactivate; |
| 25 | import org.apache.felix.scr.annotations.Reference; | 20 | import org.apache.felix.scr.annotations.Reference; |
| ... | @@ -44,9 +39,17 @@ import org.onosproject.net.flow.criteria.Criteria; | ... | @@ -44,9 +39,17 @@ import org.onosproject.net.flow.criteria.Criteria; |
| 44 | import org.onosproject.net.flow.instructions.Instructions; | 39 | import org.onosproject.net.flow.instructions.Instructions; |
| 45 | import org.slf4j.Logger; | 40 | import org.slf4j.Logger; |
| 46 | 41 | ||
| 42 | +import java.util.HashMap; | ||
| 43 | +import java.util.Map; | ||
| 44 | + | ||
| 45 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 46 | + | ||
| 47 | /** | 47 | /** |
| 48 | * Sample reactive forwarding application. | 48 | * Sample reactive forwarding application. |
| 49 | + * | ||
| 50 | + * @deprecated in Emu (ONOS 1.4). | ||
| 49 | */ | 51 | */ |
| 52 | +@Deprecated | ||
| 50 | //@Component(immediate = true) | 53 | //@Component(immediate = true) |
| 51 | public class LambdaForwarding { | 54 | public class LambdaForwarding { |
| 52 | 55 | ... | ... |
| ... | @@ -25,7 +25,7 @@ public enum ChannelSpacing { | ... | @@ -25,7 +25,7 @@ public enum ChannelSpacing { |
| 25 | CHL_50GHZ(50), // 50 GHz | 25 | CHL_50GHZ(50), // 50 GHz |
| 26 | CHL_25GHZ(25), // 25 GHz | 26 | CHL_25GHZ(25), // 25 GHz |
| 27 | CHL_12P5GHZ(12.5), // 12.5 GHz | 27 | CHL_12P5GHZ(12.5), // 12.5 GHz |
| 28 | - CHL_6P25GHZ(6.5); // 6.25 GHz | 28 | + CHL_6P25GHZ(6.25); // 6.25 GHz |
| 29 | 29 | ||
| 30 | private final Frequency frequency; | 30 | private final Frequency frequency; |
| 31 | 31 | ... | ... |
| ... | @@ -19,7 +19,10 @@ import com.google.common.base.MoreObjects; | ... | @@ -19,7 +19,10 @@ import com.google.common.base.MoreObjects; |
| 19 | 19 | ||
| 20 | /** | 20 | /** |
| 21 | * Implementation of Lambda simply designated by an index number of wavelength. | 21 | * Implementation of Lambda simply designated by an index number of wavelength. |
| 22 | + * | ||
| 23 | + * @deprecated in Emu (ONOS 1.4). | ||
| 22 | */ | 24 | */ |
| 25 | +@Deprecated | ||
| 23 | public class IndexedLambda implements Lambda { | 26 | public class IndexedLambda implements Lambda { |
| 24 | 27 | ||
| 25 | private final long index; | 28 | private final long index; | ... | ... |
| ... | @@ -16,10 +16,18 @@ | ... | @@ -16,10 +16,18 @@ |
| 16 | package org.onosproject.net; | 16 | package org.onosproject.net; |
| 17 | 17 | ||
| 18 | import com.google.common.base.MoreObjects; | 18 | import com.google.common.base.MoreObjects; |
| 19 | +import com.google.common.collect.ImmutableSet; | ||
| 19 | import org.onlab.util.Frequency; | 20 | import org.onlab.util.Frequency; |
| 20 | import org.onlab.util.Spectrum; | 21 | import org.onlab.util.Spectrum; |
| 21 | 22 | ||
| 23 | +import java.util.List; | ||
| 22 | import java.util.Objects; | 24 | import java.util.Objects; |
| 25 | +import java.util.Set; | ||
| 26 | +import java.util.SortedSet; | ||
| 27 | +import java.util.TreeSet; | ||
| 28 | +import java.util.function.Supplier; | ||
| 29 | +import java.util.stream.Collectors; | ||
| 30 | +import java.util.stream.IntStream; | ||
| 23 | 31 | ||
| 24 | import static com.google.common.base.Preconditions.checkArgument; | 32 | import static com.google.common.base.Preconditions.checkArgument; |
| 25 | import static com.google.common.base.Preconditions.checkNotNull; | 33 | import static com.google.common.base.Preconditions.checkNotNull; |
| ... | @@ -33,14 +41,13 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -33,14 +41,13 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 33 | */ | 41 | */ |
| 34 | public class OchSignal implements Lambda { | 42 | public class OchSignal implements Lambda { |
| 35 | 43 | ||
| 36 | - public static final Frequency FLEX_GRID_SLOT = Frequency.ofGHz(12.5); | 44 | + public static final Set<Integer> FIXED_GRID_SLOT_GRANULARITIES = ImmutableSet.of(1, 2, 4, 8); |
| 37 | private static final GridType DEFAULT_OCH_GRIDTYPE = GridType.DWDM; | 45 | private static final GridType DEFAULT_OCH_GRIDTYPE = GridType.DWDM; |
| 38 | private static final ChannelSpacing DEFAULT_CHANNEL_SPACING = ChannelSpacing.CHL_50GHZ; | 46 | private static final ChannelSpacing DEFAULT_CHANNEL_SPACING = ChannelSpacing.CHL_50GHZ; |
| 39 | 47 | ||
| 40 | - | ||
| 41 | private final GridType gridType; | 48 | private final GridType gridType; |
| 42 | private final ChannelSpacing channelSpacing; | 49 | private final ChannelSpacing channelSpacing; |
| 43 | - // Frequency = 193.1 THz + spacingMultiplier * channelSpacing | 50 | + // Nominal central frequency = 193.1 THz + spacingMultiplier * channelSpacing |
| 44 | private final int spacingMultiplier; | 51 | private final int spacingMultiplier; |
| 45 | // Slot width = slotGranularity * 12.5 GHz | 52 | // Slot width = slotGranularity * 12.5 GHz |
| 46 | private final int slotGranularity; | 53 | private final int slotGranularity; |
| ... | @@ -118,9 +125,9 @@ public class OchSignal implements Lambda { | ... | @@ -118,9 +125,9 @@ public class OchSignal implements Lambda { |
| 118 | } | 125 | } |
| 119 | 126 | ||
| 120 | /** | 127 | /** |
| 121 | - * Returns slow width granularity. | 128 | + * Returns slot width granularity. |
| 122 | * | 129 | * |
| 123 | - * @return slow width granularity | 130 | + * @return slot width granularity |
| 124 | */ | 131 | */ |
| 125 | public int slotGranularity() { | 132 | public int slotGranularity() { |
| 126 | return slotGranularity; | 133 | return slotGranularity; |
| ... | @@ -141,7 +148,56 @@ public class OchSignal implements Lambda { | ... | @@ -141,7 +148,56 @@ public class OchSignal implements Lambda { |
| 141 | * @return slot width | 148 | * @return slot width |
| 142 | */ | 149 | */ |
| 143 | public Frequency slotWidth() { | 150 | public Frequency slotWidth() { |
| 144 | - return FLEX_GRID_SLOT.multiply(slotGranularity); | 151 | + return ChannelSpacing.CHL_12P5GHZ.frequency().multiply(slotGranularity); |
| 152 | + } | ||
| 153 | + | ||
| 154 | + /** | ||
| 155 | + * Convert fixed grid OCh signal to sorted set of flex grid slots with 6.25 GHz spacing and 12.5 GHz slot width. | ||
| 156 | + * | ||
| 157 | + * @param ochSignal fixed grid lambda | ||
| 158 | + * @return sorted set of flex grid OCh lambdas | ||
| 159 | + */ | ||
| 160 | + public static SortedSet<OchSignal> toFlexGrid(OchSignal ochSignal) { | ||
| 161 | + checkArgument(ochSignal.gridType() != GridType.FLEX); | ||
| 162 | + checkArgument(ochSignal.channelSpacing() != ChannelSpacing.CHL_6P25GHZ); | ||
| 163 | + checkArgument(FIXED_GRID_SLOT_GRANULARITIES.contains(ochSignal.slotGranularity())); | ||
| 164 | + | ||
| 165 | + int startMultiplier = (int) (1 - ochSignal.slotGranularity() + | ||
| 166 | + ochSignal.spacingMultiplier() * ochSignal.channelSpacing().frequency().asHz() / | ||
| 167 | + ChannelSpacing.CHL_6P25GHZ.frequency().asHz()); | ||
| 168 | + | ||
| 169 | + Supplier<SortedSet<OchSignal>> supplier = () -> new TreeSet<>(new DefaultOchSignalComparator()); | ||
| 170 | + return IntStream.range(0, ochSignal.slotGranularity()) | ||
| 171 | + .mapToObj(i -> new OchSignal(GridType.FLEX, ChannelSpacing.CHL_6P25GHZ, startMultiplier + 2 * i, 1)) | ||
| 172 | + .collect(Collectors.toCollection(supplier)); | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + /** | ||
| 176 | + * Convert list of lambdas with flex grid 6.25 GHz spacing and 12.5 GHz width into fixed grid OCh signal. | ||
| 177 | + * | ||
| 178 | + * @param lambdas list of flex grid lambdas in sorted order | ||
| 179 | + * @param spacing desired fixed grid spacing | ||
| 180 | + * @return fixed grid lambda | ||
| 181 | + */ | ||
| 182 | + public static OchSignal toFixedGrid(List<OchSignal> lambdas, ChannelSpacing spacing) { | ||
| 183 | + // Number of slots of 12.5 GHz that fit into requested spacing | ||
| 184 | + int ratio = (int) (spacing.frequency().asHz() / ChannelSpacing.CHL_12P5GHZ.frequency().asHz()); | ||
| 185 | + checkArgument(lambdas.size() == ratio); | ||
| 186 | + lambdas.forEach(x -> checkArgument(x.gridType() == GridType.FLEX)); | ||
| 187 | + lambdas.forEach(x -> checkArgument(x.channelSpacing() == ChannelSpacing.CHL_6P25GHZ)); | ||
| 188 | + lambdas.forEach(x -> checkArgument(x.slotGranularity() == 1)); | ||
| 189 | + // Consecutive lambdas (multiplier increments by 2 because spacing is 6.25 GHz but slot width is 12.5 GHz) | ||
| 190 | + IntStream.range(1, lambdas.size()) | ||
| 191 | + .forEach(i -> checkArgument( | ||
| 192 | + lambdas.get(i).spacingMultiplier() == lambdas.get(i - 1).spacingMultiplier() + 2)); | ||
| 193 | + // Is center frequency compatible with requested spacing | ||
| 194 | + Frequency center = lambdas.get(ratio / 2).centralFrequency().subtract(ChannelSpacing.CHL_6P25GHZ.frequency()); | ||
| 195 | + checkArgument(Spectrum.CENTER_FREQUENCY.subtract(center).asHz() % spacing.frequency().asHz() == 0); | ||
| 196 | + | ||
| 197 | + // Multiplier sits in middle of given lambdas, then convert from 6.25 to requested spacing | ||
| 198 | + int spacingMultiplier = (lambdas.get(ratio / 2).spacingMultiplier() + 1) / (ratio * 2); | ||
| 199 | + | ||
| 200 | + return new OchSignal(GridType.DWDM, spacing, spacingMultiplier, lambdas.size()); | ||
| 145 | } | 201 | } |
| 146 | 202 | ||
| 147 | @Override | 203 | @Override | ... | ... |
| ... | @@ -25,6 +25,7 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -25,6 +25,7 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 25 | /** | 25 | /** |
| 26 | * Implementation of indexed lambda criterion. | 26 | * Implementation of indexed lambda criterion. |
| 27 | */ | 27 | */ |
| 28 | +@Deprecated | ||
| 28 | public class IndexedLambdaCriterion implements Criterion { | 29 | public class IndexedLambdaCriterion implements Criterion { |
| 29 | 30 | ||
| 30 | private final IndexedLambda lambda; | 31 | private final IndexedLambda lambda; | ... | ... |
| ... | @@ -26,14 +26,14 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -26,14 +26,14 @@ import org.apache.felix.scr.annotations.Reference; |
| 26 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 26 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 27 | import org.onlab.util.Frequency; | 27 | import org.onlab.util.Frequency; |
| 28 | import org.onosproject.net.AnnotationKeys; | 28 | import org.onosproject.net.AnnotationKeys; |
| 29 | +import org.onosproject.net.ChannelSpacing; | ||
| 29 | import org.onosproject.net.ConnectPoint; | 30 | import org.onosproject.net.ConnectPoint; |
| 31 | +import org.onosproject.net.DefaultOchSignalComparator; | ||
| 30 | import org.onosproject.net.DeviceId; | 32 | import org.onosproject.net.DeviceId; |
| 31 | -import org.onosproject.net.IndexedLambda; | ||
| 32 | import org.onosproject.net.Link; | 33 | import org.onosproject.net.Link; |
| 33 | import org.onosproject.net.OchPort; | 34 | import org.onosproject.net.OchPort; |
| 34 | import org.onosproject.net.OchSignal; | 35 | import org.onosproject.net.OchSignal; |
| 35 | import org.onosproject.net.OchSignalType; | 36 | import org.onosproject.net.OchSignalType; |
| 36 | -import org.onosproject.net.OmsPort; | ||
| 37 | import org.onosproject.net.Path; | 37 | import org.onosproject.net.Path; |
| 38 | import org.onosproject.net.Port; | 38 | import org.onosproject.net.Port; |
| 39 | import org.onosproject.net.device.DeviceService; | 39 | import org.onosproject.net.device.DeviceService; |
| ... | @@ -53,6 +53,7 @@ import org.onosproject.net.topology.TopologyService; | ... | @@ -53,6 +53,7 @@ import org.onosproject.net.topology.TopologyService; |
| 53 | import org.slf4j.Logger; | 53 | import org.slf4j.Logger; |
| 54 | import org.slf4j.LoggerFactory; | 54 | import org.slf4j.LoggerFactory; |
| 55 | 55 | ||
| 56 | +import java.util.ArrayList; | ||
| 56 | import java.util.Collections; | 57 | import java.util.Collections; |
| 57 | import java.util.List; | 58 | import java.util.List; |
| 58 | import java.util.Set; | 59 | import java.util.Set; |
| ... | @@ -64,11 +65,12 @@ import static com.google.common.base.Preconditions.checkArgument; | ... | @@ -64,11 +65,12 @@ import static com.google.common.base.Preconditions.checkArgument; |
| 64 | /** | 65 | /** |
| 65 | * An intent compiler for {@link org.onosproject.net.intent.OpticalConnectivityIntent}. | 66 | * An intent compiler for {@link org.onosproject.net.intent.OpticalConnectivityIntent}. |
| 66 | */ | 67 | */ |
| 67 | -// For now, remove component designation until dependency on the new resource manager is available. | ||
| 68 | @Component(immediate = true) | 68 | @Component(immediate = true) |
| 69 | public class OpticalConnectivityIntentCompiler implements IntentCompiler<OpticalConnectivityIntent> { | 69 | public class OpticalConnectivityIntentCompiler implements IntentCompiler<OpticalConnectivityIntent> { |
| 70 | 70 | ||
| 71 | protected static final Logger log = LoggerFactory.getLogger(OpticalConnectivityIntentCompiler.class); | 71 | protected static final Logger log = LoggerFactory.getLogger(OpticalConnectivityIntentCompiler.class); |
| 72 | + // By default, allocate 50 GHz lambdas (4 slots of 12.5 GHz) for each intent. | ||
| 73 | + private static final int SLOT_COUNT = 4; | ||
| 72 | 74 | ||
| 73 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 75 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 74 | protected IntentExtensionService intentManager; | 76 | protected IntentExtensionService intentManager; |
| ... | @@ -133,16 +135,15 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical | ... | @@ -133,16 +135,15 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical |
| 133 | srcOchPort.lambda().channelSpacing(), | 135 | srcOchPort.lambda().channelSpacing(), |
| 134 | srcOchPort.lambda().slotGranularity()); | 136 | srcOchPort.lambda().slotGranularity()); |
| 135 | } else if (!srcOchPort.isTunable() || !dstOchPort.isTunable()) { | 137 | } else if (!srcOchPort.isTunable() || !dstOchPort.isTunable()) { |
| 136 | - // FIXME: also check OCh port | 138 | + // FIXME: also check destination OCh port |
| 137 | ochSignal = srcOchPort.lambda(); | 139 | ochSignal = srcOchPort.lambda(); |
| 138 | } else { | 140 | } else { |
| 139 | // Request and reserve lambda on path | 141 | // Request and reserve lambda on path |
| 140 | - IndexedLambda lambda = assignWavelength(intent, path); | 142 | + List<OchSignal> lambdas = assignWavelength(intent, path); |
| 141 | - if (lambda == null) { | 143 | + if (lambdas.isEmpty()) { |
| 142 | continue; | 144 | continue; |
| 143 | } | 145 | } |
| 144 | - OmsPort omsPort = (OmsPort) deviceService.getPort(path.src().deviceId(), path.src().port()); | 146 | + ochSignal = OchSignal.toFixedGrid(lambdas, ChannelSpacing.CHL_50GHZ); |
| 145 | - ochSignal = new OchSignal((int) lambda.index(), omsPort.maxFrequency(), omsPort.grid()); | ||
| 146 | } | 147 | } |
| 147 | 148 | ||
| 148 | // Create installable optical path intent | 149 | // Create installable optical path intent |
| ... | @@ -174,48 +175,77 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical | ... | @@ -174,48 +175,77 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical |
| 174 | * @param path path in WDM topology | 175 | * @param path path in WDM topology |
| 175 | * @return first available lambda allocated | 176 | * @return first available lambda allocated |
| 176 | */ | 177 | */ |
| 177 | - private IndexedLambda assignWavelength(Intent intent, Path path) { | 178 | + private List<OchSignal> assignWavelength(Intent intent, Path path) { |
| 178 | - Set<IndexedLambda> lambdas = findCommonLambdasOverLinks(path.links()); | 179 | + Set<OchSignal> lambdas = findCommonLambdasOverLinks(path.links()); |
| 179 | if (lambdas.isEmpty()) { | 180 | if (lambdas.isEmpty()) { |
| 180 | - return null; | 181 | + return Collections.emptyList(); |
| 181 | } | 182 | } |
| 182 | 183 | ||
| 183 | - IndexedLambda minLambda = findFirstLambda(lambdas); | 184 | + List<OchSignal> minLambda = findFirstLambda(lambdas, slotCount()); |
| 184 | List<ResourcePath> lambdaResources = path.links().stream() | 185 | List<ResourcePath> lambdaResources = path.links().stream() |
| 185 | .flatMap(x -> Stream.of( | 186 | .flatMap(x -> Stream.of( |
| 186 | ResourcePath.discrete(x.src().deviceId(), x.src().port()), | 187 | ResourcePath.discrete(x.src().deviceId(), x.src().port()), |
| 187 | ResourcePath.discrete(x.dst().deviceId(), x.dst().port()) | 188 | ResourcePath.discrete(x.dst().deviceId(), x.dst().port()) |
| 188 | )) | 189 | )) |
| 189 | - .map(x -> x.child(minLambda)) | 190 | + .flatMap(x -> minLambda.stream().map(l -> x.child(l))) |
| 190 | .collect(Collectors.toList()); | 191 | .collect(Collectors.toList()); |
| 191 | 192 | ||
| 192 | List<ResourceAllocation> allocations = resourceService.allocate(intent.id(), lambdaResources); | 193 | List<ResourceAllocation> allocations = resourceService.allocate(intent.id(), lambdaResources); |
| 193 | if (allocations.isEmpty()) { | 194 | if (allocations.isEmpty()) { |
| 194 | log.info("Resource allocation for {} failed (resource request: {})", intent, lambdaResources); | 195 | log.info("Resource allocation for {} failed (resource request: {})", intent, lambdaResources); |
| 195 | - return null; | 196 | + return Collections.emptyList(); |
| 196 | } | 197 | } |
| 197 | 198 | ||
| 198 | return minLambda; | 199 | return minLambda; |
| 199 | } | 200 | } |
| 200 | 201 | ||
| 201 | - private Set<IndexedLambda> findCommonLambdasOverLinks(List<Link> links) { | 202 | + /** |
| 203 | + * Get the number of 12.5 GHz slots required for the path. | ||
| 204 | + * | ||
| 205 | + * For now this returns a constant value of 4 (i.e., fixed grid 50 GHz slot), | ||
| 206 | + * but in the future can depend on optical reach, line rate, transponder port capabilities, etc. | ||
| 207 | + * | ||
| 208 | + * @return number of slots | ||
| 209 | + */ | ||
| 210 | + private int slotCount() { | ||
| 211 | + return SLOT_COUNT; | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + private Set<OchSignal> findCommonLambdasOverLinks(List<Link> links) { | ||
| 202 | return links.stream() | 215 | return links.stream() |
| 203 | .flatMap(x -> Stream.of( | 216 | .flatMap(x -> Stream.of( |
| 204 | ResourcePath.discrete(x.src().deviceId(), x.src().port()), | 217 | ResourcePath.discrete(x.src().deviceId(), x.src().port()), |
| 205 | ResourcePath.discrete(x.dst().deviceId(), x.dst().port()) | 218 | ResourcePath.discrete(x.dst().deviceId(), x.dst().port()) |
| 206 | )) | 219 | )) |
| 207 | .map(resourceService::getAvailableResources) | 220 | .map(resourceService::getAvailableResources) |
| 208 | - .map(x -> Iterables.filter(x, r -> r.last() instanceof IndexedLambda)) | 221 | + .map(x -> Iterables.filter(x, r -> r.last() instanceof OchSignal)) |
| 209 | - .map(x -> Iterables.transform(x, r -> (IndexedLambda) r.last())) | 222 | + .map(x -> Iterables.transform(x, r -> (OchSignal) r.last())) |
| 210 | - .map(x -> (Set<IndexedLambda>) ImmutableSet.copyOf(x)) | 223 | + .map(x -> (Set<OchSignal>) ImmutableSet.copyOf(x)) |
| 211 | .reduce(Sets::intersection) | 224 | .reduce(Sets::intersection) |
| 212 | .orElse(Collections.emptySet()); | 225 | .orElse(Collections.emptySet()); |
| 213 | } | 226 | } |
| 214 | 227 | ||
| 215 | - private IndexedLambda findFirstLambda(Set<IndexedLambda> lambdas) { | 228 | + /** |
| 216 | - return lambdas.stream() | 229 | + * Returns list of consecutive resources in given set of lambdas. |
| 217 | - .findFirst() | 230 | + * |
| 218 | - .get(); | 231 | + * @param lambdas list of lambdas |
| 232 | + * @param count number of consecutive lambdas to return | ||
| 233 | + * @return list of consecutive lambdas | ||
| 234 | + */ | ||
| 235 | + private List<OchSignal> findFirstLambda(Set<OchSignal> lambdas, int count) { | ||
| 236 | + // Sort available lambdas | ||
| 237 | + List<OchSignal> lambdaList = new ArrayList<>(lambdas); | ||
| 238 | + lambdaList.sort(new DefaultOchSignalComparator()); | ||
| 239 | + | ||
| 240 | + // Look ahead by count and ensure spacing multiplier is as expected (i.e., no gaps) | ||
| 241 | + for (int i = 0; i < lambdaList.size() - count; i++) { | ||
| 242 | + if (lambdaList.get(i).spacingMultiplier() + 2 * count == | ||
| 243 | + lambdaList.get(i + count).spacingMultiplier()) { | ||
| 244 | + return lambdaList.subList(i, i + count); | ||
| 245 | + } | ||
| 246 | + } | ||
| 247 | + | ||
| 248 | + return Collections.emptyList(); | ||
| 219 | } | 249 | } |
| 220 | 250 | ||
| 221 | private ConnectPoint staticPort(ConnectPoint connectPoint) { | 251 | private ConnectPoint staticPort(ConnectPoint connectPoint) { | ... | ... |
| ... | @@ -19,6 +19,7 @@ import com.google.common.collect.Lists; | ... | @@ -19,6 +19,7 @@ import com.google.common.collect.Lists; |
| 19 | import org.onlab.packet.MplsLabel; | 19 | import org.onlab.packet.MplsLabel; |
| 20 | import org.onlab.packet.VlanId; | 20 | import org.onlab.packet.VlanId; |
| 21 | import org.onlab.util.ItemNotFoundException; | 21 | import org.onlab.util.ItemNotFoundException; |
| 22 | +import org.onosproject.net.DefaultOchSignalComparator; | ||
| 22 | import org.onosproject.net.Device; | 23 | import org.onosproject.net.Device; |
| 23 | import org.onosproject.net.DeviceId; | 24 | import org.onosproject.net.DeviceId; |
| 24 | import org.onosproject.net.Port; | 25 | import org.onosproject.net.Port; |
| ... | @@ -44,7 +45,9 @@ import org.slf4j.LoggerFactory; | ... | @@ -44,7 +45,9 @@ import org.slf4j.LoggerFactory; |
| 44 | import java.util.Collections; | 45 | import java.util.Collections; |
| 45 | import java.util.List; | 46 | import java.util.List; |
| 46 | import java.util.SortedSet; | 47 | import java.util.SortedSet; |
| 48 | +import java.util.TreeSet; | ||
| 47 | import java.util.concurrent.ExecutorService; | 49 | import java.util.concurrent.ExecutorService; |
| 50 | +import java.util.function.Supplier; | ||
| 48 | import java.util.stream.Collectors; | 51 | import java.util.stream.Collectors; |
| 49 | import java.util.stream.IntStream; | 52 | import java.util.stream.IntStream; |
| 50 | 53 | ||
| ... | @@ -199,7 +202,10 @@ final class ResourceDeviceListener implements DeviceListener { | ... | @@ -199,7 +202,10 @@ final class ResourceDeviceListener implements DeviceListener { |
| 199 | } | 202 | } |
| 200 | LambdaQuery query = handler.behaviour(LambdaQuery.class); | 203 | LambdaQuery query = handler.behaviour(LambdaQuery.class); |
| 201 | if (query != null) { | 204 | if (query != null) { |
| 202 | - return query.queryLambdas(port); | 205 | + Supplier<SortedSet<OchSignal>> supplier = () -> new TreeSet<>(new DefaultOchSignalComparator()); |
| 206 | + return query.queryLambdas(port).stream() | ||
| 207 | + .flatMap(x -> OchSignal.toFlexGrid(x).stream()) | ||
| 208 | + .collect(Collectors.toCollection(supplier)); | ||
| 203 | } else { | 209 | } else { |
| 204 | return Collections.emptySortedSet(); | 210 | return Collections.emptySortedSet(); |
| 205 | } | 211 | } | ... | ... |
| ... | @@ -51,6 +51,7 @@ import java.util.Set; | ... | @@ -51,6 +51,7 @@ import java.util.Set; |
| 51 | import java.util.SortedSet; | 51 | import java.util.SortedSet; |
| 52 | import java.util.TreeSet; | 52 | import java.util.TreeSet; |
| 53 | import java.util.concurrent.atomic.AtomicBoolean; | 53 | import java.util.concurrent.atomic.AtomicBoolean; |
| 54 | +import java.util.function.Supplier; | ||
| 54 | import java.util.stream.Collectors; | 55 | import java.util.stream.Collectors; |
| 55 | import java.util.stream.IntStream; | 56 | import java.util.stream.IntStream; |
| 56 | 57 | ||
| ... | @@ -209,13 +210,12 @@ public class CalientFiberSwitchHandshaker | ... | @@ -209,13 +210,12 @@ public class CalientFiberSwitchHandshaker |
| 209 | ChannelSpacing.CHL_12P5GHZ.frequency().asHz(); | 210 | ChannelSpacing.CHL_12P5GHZ.frequency().asHz(); |
| 210 | long stopSpacingMultiplier = Spectrum.O_BAND_MAX.subtract(Spectrum.CENTER_FREQUENCY).asHz() / | 211 | long stopSpacingMultiplier = Spectrum.O_BAND_MAX.subtract(Spectrum.CENTER_FREQUENCY).asHz() / |
| 211 | ChannelSpacing.CHL_12P5GHZ.frequency().asHz(); | 212 | ChannelSpacing.CHL_12P5GHZ.frequency().asHz(); |
| 212 | - List<OchSignal> lambdas = IntStream.rangeClosed((int) startSpacingMultiplier, (int) stopSpacingMultiplier) | 213 | + Supplier<SortedSet<OchSignal>> supplier = () -> new TreeSet<>(new DefaultOchSignalComparator()); |
| 213 | - .mapToObj(x -> new OchSignal(GridType.FLEX, ChannelSpacing.CHL_12P5GHZ, x, 1)) | ||
| 214 | - .collect(Collectors.toList()); | ||
| 215 | 214 | ||
| 216 | - SortedSet<OchSignal> result = new TreeSet<>(new DefaultOchSignalComparator()); | 215 | + // Only consider odd values for the multiplier (for easy mapping to fixed grid) |
| 217 | - result.addAll(lambdas); | 216 | + return IntStream.rangeClosed((int) startSpacingMultiplier, (int) stopSpacingMultiplier) |
| 218 | - | 217 | + .filter(i -> i % 2 == 1) |
| 219 | - return result; | 218 | + .mapToObj(i -> new OchSignal(GridType.FLEX, ChannelSpacing.CHL_6P25GHZ, i, 1)) |
| 219 | + .collect(Collectors.toCollection(supplier)); | ||
| 220 | } | 220 | } |
| 221 | } | 221 | } | ... | ... |
| ... | @@ -59,6 +59,7 @@ import java.util.Set; | ... | @@ -59,6 +59,7 @@ import java.util.Set; |
| 59 | import java.util.SortedSet; | 59 | import java.util.SortedSet; |
| 60 | import java.util.TreeSet; | 60 | import java.util.TreeSet; |
| 61 | import java.util.concurrent.atomic.AtomicBoolean; | 61 | import java.util.concurrent.atomic.AtomicBoolean; |
| 62 | +import java.util.function.Supplier; | ||
| 62 | import java.util.stream.Collectors; | 63 | import java.util.stream.Collectors; |
| 63 | import java.util.stream.IntStream; | 64 | import java.util.stream.IntStream; |
| 64 | 65 | ||
| ... | @@ -74,7 +75,7 @@ import java.util.stream.IntStream; | ... | @@ -74,7 +75,7 @@ import java.util.stream.IntStream; |
| 74 | * As LINC implements custom OF optical extensions (in contrast to the final standard as specified in | 75 | * As LINC implements custom OF optical extensions (in contrast to the final standard as specified in |
| 75 | * ONF TS-022 (March 15, 2015), we need to rewrite flow stat requests and flow mods in {@link #sendMsg(OFMessage)}. | 76 | * ONF TS-022 (March 15, 2015), we need to rewrite flow stat requests and flow mods in {@link #sendMsg(OFMessage)}. |
| 76 | * | 77 | * |
| 77 | - * LINC exposes OchSignal resources: 80 lambdas of 50 GHz around ITU-T G.694.1 center frequency 193.1 GHz. | 78 | + * LINC exposes OchSignal resources: 80 lambdas of 50 GHz (fixed grid) around ITU-T G.694.1 center frequency 193.1 GHz. |
| 78 | * | 79 | * |
| 79 | */ | 80 | */ |
| 80 | public class OfOpticalSwitchImplLinc13 | 81 | public class OfOpticalSwitchImplLinc13 |
| ... | @@ -224,8 +225,9 @@ public class OfOpticalSwitchImplLinc13 | ... | @@ -224,8 +225,9 @@ public class OfOpticalSwitchImplLinc13 |
| 224 | } | 225 | } |
| 225 | 226 | ||
| 226 | OFActionSetField sf = (OFActionSetField) action; | 227 | OFActionSetField sf = (OFActionSetField) action; |
| 227 | - if (!(sf instanceof OFOxmExpOchSigId)) { | 228 | + if (!(sf.getField() instanceof OFOxmExpOchSigId)) { |
| 228 | newActions.add(action); | 229 | newActions.add(action); |
| 230 | + continue; | ||
| 229 | } | 231 | } |
| 230 | 232 | ||
| 231 | OFOxmExpOchSigId oxm = (OFOxmExpOchSigId) sf.getField(); | 233 | OFOxmExpOchSigId oxm = (OFOxmExpOchSigId) sf.getField(); |
| ... | @@ -259,7 +261,6 @@ public class OfOpticalSwitchImplLinc13 | ... | @@ -259,7 +261,6 @@ public class OfOpticalSwitchImplLinc13 |
| 259 | OFFlowMod fm = (OFFlowMod) msg; | 261 | OFFlowMod fm = (OFFlowMod) msg; |
| 260 | newMatch = rewriteMatch(fm.getMatch()); | 262 | newMatch = rewriteMatch(fm.getMatch()); |
| 261 | List<OFAction> actions = rewriteActions(fm.getActions()); | 263 | List<OFAction> actions = rewriteActions(fm.getActions()); |
| 262 | - | ||
| 263 | newMsg = fm.createBuilder().setMatch(newMatch).setActions(actions).build(); | 264 | newMsg = fm.createBuilder().setMatch(newMatch).setActions(actions).build(); |
| 264 | } | 265 | } |
| 265 | 266 | ||
| ... | @@ -371,15 +372,10 @@ public class OfOpticalSwitchImplLinc13 | ... | @@ -371,15 +372,10 @@ public class OfOpticalSwitchImplLinc13 |
| 371 | return Collections.emptySortedSet(); | 372 | return Collections.emptySortedSet(); |
| 372 | } | 373 | } |
| 373 | 374 | ||
| 374 | - // OMS ports expose 80 lambdas of 50GHz width, centered around the ITU-T center frequency. | 375 | + // OMS ports expose 80 fixed grid lambdas of 50GHz width, centered around the ITU-T center frequency 193.1 THz. |
| 375 | - // We report these with a spacing of 12.5 GHz. | 376 | + Supplier<SortedSet<OchSignal>> supplier = () -> new TreeSet<>(new DefaultOchSignalComparator()); |
| 376 | - List<OchSignal> lambdas = IntStream.range(0, LAMBDA_COUNT) | 377 | + return IntStream.range(0, LAMBDA_COUNT) |
| 377 | - .mapToObj(x -> new OchSignal(GridType.FLEX, ChannelSpacing.CHL_12P5GHZ, x - (LAMBDA_COUNT / 2), 1)) | 378 | + .mapToObj(x -> new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, x - (LAMBDA_COUNT / 2), 4)) |
| 378 | - .collect(Collectors.toList()); | 379 | + .collect(Collectors.toCollection(supplier)); |
| 379 | - | ||
| 380 | - SortedSet<OchSignal> result = new TreeSet<>(new DefaultOchSignalComparator()); | ||
| 381 | - result.addAll(lambdas); | ||
| 382 | - | ||
| 383 | - return result; | ||
| 384 | } | 380 | } |
| 385 | } | 381 | } | ... | ... |
| ... | @@ -536,7 +536,9 @@ class LINCSwitch(OpticalSwitch): | ... | @@ -536,7 +536,9 @@ class LINCSwitch(OpticalSwitch): |
| 536 | for link in LINCSwitch.opticalJSON[ 'links' ]: | 536 | for link in LINCSwitch.opticalJSON[ 'links' ]: |
| 537 | linkDict = {} | 537 | linkDict = {} |
| 538 | linkDict[ 'type' ] = link[ 'type' ] | 538 | linkDict[ 'type' ] = link[ 'type' ] |
| 539 | - linkDict.update(link[ 'annotations' ]) | 539 | + # FIXME: Clean up unnecessary link/device attributes, then re-enable annotations |
| 540 | + linkDict['durable'] = True | ||
| 541 | + # linkDict.update(link[ 'annotations' ]) | ||
| 540 | 542 | ||
| 541 | linkSubj = link[ 'src' ] + '-' + link[ 'dst' ] | 543 | linkSubj = link[ 'src' ] + '-' + link[ 'dst' ] |
| 542 | links[ linkSubj ] = { 'basic': linkDict } | 544 | links[ linkSubj ] = { 'basic': linkDict } | ... | ... |
-
Please register or login to post a comment