Committed by
Gerrit Code Review
[ONOS-2476]: Circuit intent support for ODU Multiplexing
Change-Id: I37229e7107e38baf8416102598f27004ef319665
Showing
4 changed files
with
319 additions
and
25 deletions
... | @@ -27,6 +27,8 @@ import org.onosproject.net.intent.IntentService; | ... | @@ -27,6 +27,8 @@ import org.onosproject.net.intent.IntentService; |
27 | import org.onosproject.net.intent.IntentState; | 27 | import org.onosproject.net.intent.IntentState; |
28 | import org.onosproject.net.intent.LinkCollectionIntent; | 28 | import org.onosproject.net.intent.LinkCollectionIntent; |
29 | import org.onosproject.net.intent.MultiPointToSinglePointIntent; | 29 | import org.onosproject.net.intent.MultiPointToSinglePointIntent; |
30 | +import org.onosproject.net.intent.OpticalCircuitIntent; | ||
31 | +import org.onosproject.net.intent.OpticalConnectivityIntent; | ||
30 | import org.onosproject.net.intent.PathIntent; | 32 | import org.onosproject.net.intent.PathIntent; |
31 | import org.onosproject.net.intent.PointToPointIntent; | 33 | import org.onosproject.net.intent.PointToPointIntent; |
32 | import org.onosproject.net.intent.SinglePointToMultiPointIntent; | 34 | import org.onosproject.net.intent.SinglePointToMultiPointIntent; |
... | @@ -114,6 +116,8 @@ public class IntentsListCommand extends AbstractShellCommand { | ... | @@ -114,6 +116,8 @@ public class IntentsListCommand extends AbstractShellCommand { |
114 | private IntentSummary summarySinglePointToMultiPoint; | 116 | private IntentSummary summarySinglePointToMultiPoint; |
115 | private IntentSummary summaryPath; | 117 | private IntentSummary summaryPath; |
116 | private IntentSummary summaryLinkCollection; | 118 | private IntentSummary summaryLinkCollection; |
119 | + private IntentSummary summaryOpticalCircuit; | ||
120 | + private IntentSummary summaryOpticalConnectivity; | ||
117 | private IntentSummary summaryUnknownType; | 121 | private IntentSummary summaryUnknownType; |
118 | 122 | ||
119 | /** | 123 | /** |
... | @@ -130,6 +134,8 @@ public class IntentsListCommand extends AbstractShellCommand { | ... | @@ -130,6 +134,8 @@ public class IntentsListCommand extends AbstractShellCommand { |
130 | new IntentSummary("SinglePointToMultiPoint"); | 134 | new IntentSummary("SinglePointToMultiPoint"); |
131 | summaryPath = new IntentSummary("Path"); | 135 | summaryPath = new IntentSummary("Path"); |
132 | summaryLinkCollection = new IntentSummary("LinkCollection"); | 136 | summaryLinkCollection = new IntentSummary("LinkCollection"); |
137 | + summaryOpticalCircuit = new IntentSummary("OpticalCircuit"); | ||
138 | + summaryOpticalConnectivity = new IntentSummary("OpticalConnectivity"); | ||
133 | summaryUnknownType = new IntentSummary("UnknownType"); | 139 | summaryUnknownType = new IntentSummary("UnknownType"); |
134 | } | 140 | } |
135 | 141 | ||
... | @@ -182,7 +188,14 @@ public class IntentsListCommand extends AbstractShellCommand { | ... | @@ -182,7 +188,14 @@ public class IntentsListCommand extends AbstractShellCommand { |
182 | summaryLinkCollection.update(intentState); | 188 | summaryLinkCollection.update(intentState); |
183 | continue; | 189 | continue; |
184 | } | 190 | } |
185 | - | 191 | + if (intent instanceof OpticalCircuitIntent) { |
192 | + summaryOpticalCircuit.update(intentState); | ||
193 | + continue; | ||
194 | + } | ||
195 | + if (intent instanceof OpticalConnectivityIntent) { | ||
196 | + summaryOpticalConnectivity.update(intentState); | ||
197 | + continue; | ||
198 | + } | ||
186 | summaryUnknownType.update(intentState); | 199 | summaryUnknownType.update(intentState); |
187 | } | 200 | } |
188 | } | 201 | } |
... | @@ -204,6 +217,8 @@ public class IntentsListCommand extends AbstractShellCommand { | ... | @@ -204,6 +217,8 @@ public class IntentsListCommand extends AbstractShellCommand { |
204 | summarySinglePointToMultiPoint.json(mapper)); | 217 | summarySinglePointToMultiPoint.json(mapper)); |
205 | result.set("path", summaryPath.json(mapper)); | 218 | result.set("path", summaryPath.json(mapper)); |
206 | result.set("linkCollection", summaryLinkCollection.json(mapper)); | 219 | result.set("linkCollection", summaryLinkCollection.json(mapper)); |
220 | + result.set("opticalCircuit", summaryOpticalCircuit.json(mapper)); | ||
221 | + result.set("opticalConnectivity", summaryOpticalConnectivity.json(mapper)); | ||
207 | result.set("unknownType", summaryUnknownType.json(mapper)); | 222 | result.set("unknownType", summaryUnknownType.json(mapper)); |
208 | result.set("all", summaryAll.json(mapper)); | 223 | result.set("all", summaryAll.json(mapper)); |
209 | return result; | 224 | return result; |
... | @@ -220,6 +235,8 @@ public class IntentsListCommand extends AbstractShellCommand { | ... | @@ -220,6 +235,8 @@ public class IntentsListCommand extends AbstractShellCommand { |
220 | summarySinglePointToMultiPoint.printState(); | 235 | summarySinglePointToMultiPoint.printState(); |
221 | summaryPath.printState(); | 236 | summaryPath.printState(); |
222 | summaryLinkCollection.printState(); | 237 | summaryLinkCollection.printState(); |
238 | + summaryOpticalCircuit.printState(); | ||
239 | + summaryOpticalConnectivity.printState(); | ||
223 | summaryUnknownType.printState(); | 240 | summaryUnknownType.printState(); |
224 | summaryAll.printState(); | 241 | summaryAll.printState(); |
225 | } | 242 | } |
... | @@ -378,6 +395,12 @@ public class IntentsListCommand extends AbstractShellCommand { | ... | @@ -378,6 +395,12 @@ public class IntentsListCommand extends AbstractShellCommand { |
378 | LinkCollectionIntent li = (LinkCollectionIntent) intent; | 395 | LinkCollectionIntent li = (LinkCollectionIntent) intent; |
379 | print(" links=%s", li.links()); | 396 | print(" links=%s", li.links()); |
380 | print(" egress=%s", li.egressPoints()); | 397 | print(" egress=%s", li.egressPoints()); |
398 | + } else if (intent instanceof OpticalCircuitIntent) { | ||
399 | + OpticalCircuitIntent ci = (OpticalCircuitIntent) intent; | ||
400 | + print(" src=%s, dst=%s", ci.getSrc(), ci.getDst()); | ||
401 | + } else if (intent instanceof OpticalConnectivityIntent) { | ||
402 | + OpticalConnectivityIntent ci = (OpticalConnectivityIntent) intent; | ||
403 | + print(" src=%s, dst=%s", ci.getSrc(), ci.getDst()); | ||
381 | } | 404 | } |
382 | 405 | ||
383 | List<Intent> installable = service.getInstallableIntents(intent.key()); | 406 | List<Intent> installable = service.getInstallableIntents(intent.key()); | ... | ... |
... | @@ -45,4 +45,14 @@ public enum OduSignalType { | ... | @@ -45,4 +45,14 @@ public enum OduSignalType { |
45 | public long bitRate() { | 45 | public long bitRate() { |
46 | return this.bitRate; | 46 | return this.bitRate; |
47 | } | 47 | } |
48 | + | ||
49 | + /** | ||
50 | + * Returns the number of tributary slots of the OduSignalType. | ||
51 | + * Each TributarySlot is 1.25Gbps. | ||
52 | + * @return number of tributary slots | ||
53 | + */ | ||
54 | + public int tributarySlots() { | ||
55 | + return (int) (this.bitRate() / OduSignalType.ODU0.bitRate()); | ||
56 | + } | ||
57 | + | ||
48 | } | 58 | } | ... | ... |
... | @@ -28,18 +28,27 @@ import org.onosproject.cfg.ComponentConfigService; | ... | @@ -28,18 +28,27 @@ import org.onosproject.cfg.ComponentConfigService; |
28 | import org.onosproject.core.ApplicationId; | 28 | import org.onosproject.core.ApplicationId; |
29 | import org.onosproject.core.CoreService; | 29 | import org.onosproject.core.CoreService; |
30 | import org.onosproject.net.AnnotationKeys; | 30 | import org.onosproject.net.AnnotationKeys; |
31 | +import org.onosproject.net.CltSignalType; | ||
31 | import org.onosproject.net.ConnectPoint; | 32 | import org.onosproject.net.ConnectPoint; |
33 | +import org.onosproject.net.DeviceId; | ||
32 | import org.onosproject.net.OchPort; | 34 | import org.onosproject.net.OchPort; |
33 | import org.onosproject.net.OduCltPort; | 35 | import org.onosproject.net.OduCltPort; |
36 | +import org.onosproject.net.OduSignalId; | ||
34 | import org.onosproject.net.OduSignalType; | 37 | import org.onosproject.net.OduSignalType; |
35 | import org.onosproject.net.Port; | 38 | import org.onosproject.net.Port; |
39 | +import org.onosproject.net.TributarySlot; | ||
40 | +import org.onosproject.net.behaviour.TributarySlotQuery; | ||
36 | import org.onosproject.net.device.DeviceService; | 41 | import org.onosproject.net.device.DeviceService; |
42 | +import org.onosproject.net.driver.Driver; | ||
43 | +import org.onosproject.net.driver.DriverService; | ||
37 | import org.onosproject.net.flow.DefaultFlowRule; | 44 | import org.onosproject.net.flow.DefaultFlowRule; |
38 | import org.onosproject.net.flow.DefaultTrafficSelector; | 45 | import org.onosproject.net.flow.DefaultTrafficSelector; |
39 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 46 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
40 | import org.onosproject.net.flow.FlowRule; | 47 | import org.onosproject.net.flow.FlowRule; |
41 | import org.onosproject.net.flow.TrafficSelector; | 48 | import org.onosproject.net.flow.TrafficSelector; |
42 | import org.onosproject.net.flow.TrafficTreatment; | 49 | import org.onosproject.net.flow.TrafficTreatment; |
50 | +import org.onosproject.net.flow.criteria.Criteria; | ||
51 | +import org.onosproject.net.flow.instructions.Instructions; | ||
43 | import org.onosproject.net.intent.FlowRuleIntent; | 52 | import org.onosproject.net.intent.FlowRuleIntent; |
44 | import org.onosproject.net.intent.Intent; | 53 | import org.onosproject.net.intent.Intent; |
45 | import org.onosproject.net.intent.IntentCompiler; | 54 | import org.onosproject.net.intent.IntentCompiler; |
... | @@ -59,19 +68,22 @@ import org.osgi.service.component.ComponentContext; | ... | @@ -59,19 +68,22 @@ import org.osgi.service.component.ComponentContext; |
59 | import org.slf4j.Logger; | 68 | import org.slf4j.Logger; |
60 | import org.slf4j.LoggerFactory; | 69 | import org.slf4j.LoggerFactory; |
61 | 70 | ||
71 | +import com.google.common.collect.ImmutableList; | ||
72 | +import com.google.common.collect.Sets; | ||
73 | + | ||
62 | import java.util.Collections; | 74 | import java.util.Collections; |
63 | import java.util.Dictionary; | 75 | import java.util.Dictionary; |
64 | import java.util.LinkedList; | 76 | import java.util.LinkedList; |
65 | import java.util.List; | 77 | import java.util.List; |
66 | import java.util.Optional; | 78 | import java.util.Optional; |
67 | import java.util.Set; | 79 | import java.util.Set; |
80 | +import java.util.stream.Collectors; | ||
68 | 81 | ||
69 | import static com.google.common.base.Preconditions.checkArgument; | 82 | import static com.google.common.base.Preconditions.checkArgument; |
70 | 83 | ||
71 | /** | 84 | /** |
72 | * An intent compiler for {@link org.onosproject.net.intent.OpticalCircuitIntent}. | 85 | * An intent compiler for {@link org.onosproject.net.intent.OpticalCircuitIntent}. |
73 | */ | 86 | */ |
74 | -// For now, remove component designation until dependency on the new resource manager is available. | ||
75 | @Component(immediate = true) | 87 | @Component(immediate = true) |
76 | public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircuitIntent> { | 88 | public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircuitIntent> { |
77 | 89 | ||
... | @@ -105,6 +117,9 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -105,6 +117,9 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
105 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 117 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
106 | protected IntentService intentService; | 118 | protected IntentService intentService; |
107 | 119 | ||
120 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
121 | + protected DriverService driverService; | ||
122 | + | ||
108 | private ApplicationId appId; | 123 | private ApplicationId appId; |
109 | 124 | ||
110 | @Modified | 125 | @Modified |
... | @@ -160,6 +175,11 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -160,6 +175,11 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
160 | 175 | ||
161 | log.debug("Compiling optical circuit intent between {} and {}", src, dst); | 176 | log.debug("Compiling optical circuit intent between {} and {}", src, dst); |
162 | 177 | ||
178 | + // Release of intent resources here is only a temporary solution for handling the | ||
179 | + // case of recompiling due to intent restoration (when intent state is FAILED). | ||
180 | + // TODO: try to release intent resources in IntentManager. | ||
181 | + resourceService.release(intent.id()); | ||
182 | + | ||
163 | // Reserve OduClt ports | 183 | // Reserve OduClt ports |
164 | Resource srcPortResource = Resources.discrete(src.deviceId(), src.port()).resource(); | 184 | Resource srcPortResource = Resources.discrete(src.deviceId(), src.port()).resource(); |
165 | Resource dstPortResource = Resources.discrete(dst.deviceId(), dst.port()).resource(); | 185 | Resource dstPortResource = Resources.discrete(dst.deviceId(), dst.port()).resource(); |
... | @@ -168,29 +188,50 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -168,29 +188,50 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
168 | throw new IntentCompilationException("Unable to reserve ports for intent " + intent); | 188 | throw new IntentCompilationException("Unable to reserve ports for intent " + intent); |
169 | } | 189 | } |
170 | 190 | ||
191 | + // Check if both devices support multiplexing (usage of TributarySlots) | ||
192 | + boolean multiplexingSupported = isMultiplexingSupported(intent); | ||
193 | + | ||
171 | LinkedList<Intent> intents = new LinkedList<>(); | 194 | LinkedList<Intent> intents = new LinkedList<>(); |
195 | + // slots are used only for devices supporting multiplexing | ||
196 | + Set<TributarySlot> slots = Collections.emptySet(); | ||
172 | 197 | ||
173 | - FlowRuleIntent circuitIntent; | 198 | + OpticalConnectivityIntent connIntent = findOpticalConnectivityIntent(intent, multiplexingSupported); |
174 | - OpticalConnectivityIntent connIntent = findOpticalConnectivityIntent(intent); | 199 | + if ((connIntent != null) && multiplexingSupported) { |
200 | + // Allocate TributarySlots on existing OCH ports | ||
201 | + slots = assignTributarySlots(intent, Pair.of(connIntent.getSrc(), connIntent.getDst())); | ||
202 | + } | ||
175 | 203 | ||
176 | - // Create optical connectivity intent if needed | 204 | + // Create optical connectivity intent if needed - no optical intent or not enough slots available |
177 | - if (connIntent == null) { | 205 | + if (connIntent == null || (multiplexingSupported && slots.isEmpty())) { |
178 | // Find OCh ports with available resources | 206 | // Find OCh ports with available resources |
179 | Pair<OchPort, OchPort> ochPorts = findPorts(intent); | 207 | Pair<OchPort, OchPort> ochPorts = findPorts(intent); |
180 | 208 | ||
181 | if (ochPorts == null) { | 209 | if (ochPorts == null) { |
182 | - return Collections.emptyList(); | 210 | + // Release port allocations if unsuccessful |
211 | + resourceService.release(intent.id()); | ||
212 | + throw new IntentCompilationException("Unable to find suitable OCH ports for intent " + intent); | ||
183 | } | 213 | } |
184 | 214 | ||
185 | - // Create optical connectivity intent | ||
186 | ConnectPoint srcCP = new ConnectPoint(src.elementId(), ochPorts.getLeft().number()); | 215 | ConnectPoint srcCP = new ConnectPoint(src.elementId(), ochPorts.getLeft().number()); |
187 | ConnectPoint dstCP = new ConnectPoint(dst.elementId(), ochPorts.getRight().number()); | 216 | ConnectPoint dstCP = new ConnectPoint(dst.elementId(), ochPorts.getRight().number()); |
188 | - // FIXME: hardcoded ODU signal type | 217 | + |
218 | + if (multiplexingSupported) { | ||
219 | + // Allocate TributarySlots on OCH ports | ||
220 | + slots = assignTributarySlots(intent, Pair.of(srcCP, dstCP)); | ||
221 | + if (slots.isEmpty()) { | ||
222 | + // Release port allocations if unsuccessful | ||
223 | + resourceService.release(intent.id()); | ||
224 | + throw new IntentCompilationException("Unable to find Tributary Slots for intent " + intent); | ||
225 | + } | ||
226 | + } | ||
227 | + | ||
228 | + // Create optical connectivity intent | ||
229 | + OduSignalType signalType = ochPorts.getLeft().signalType(); | ||
189 | connIntent = OpticalConnectivityIntent.builder() | 230 | connIntent = OpticalConnectivityIntent.builder() |
190 | .appId(appId) | 231 | .appId(appId) |
191 | .src(srcCP) | 232 | .src(srcCP) |
192 | .dst(dstCP) | 233 | .dst(dstCP) |
193 | - .signalType(OduSignalType.ODU4) | 234 | + .signalType(signalType) |
194 | .bidirectional(intent.isBidirectional()) | 235 | .bidirectional(intent.isBidirectional()) |
195 | .build(); | 236 | .build(); |
196 | intentService.submit(connIntent); | 237 | intentService.submit(connIntent); |
... | @@ -198,16 +239,20 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -198,16 +239,20 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
198 | 239 | ||
199 | // Create optical circuit intent | 240 | // Create optical circuit intent |
200 | List<FlowRule> rules = new LinkedList<>(); | 241 | List<FlowRule> rules = new LinkedList<>(); |
201 | - rules.add(connectPorts(src, connIntent.getSrc(), intent.priority())); | 242 | + // at the source: ODUCLT port mapping to OCH port |
202 | - rules.add(connectPorts(connIntent.getDst(), dst, intent.priority())); | 243 | + rules.add(connectPorts(src, connIntent.getSrc(), intent.priority(), slots)); |
244 | + // at the destination: OCH port mapping to ODUCLT port | ||
245 | + rules.add(connectPorts(connIntent.getDst(), dst, intent.priority(), slots)); | ||
203 | 246 | ||
204 | // Create flow rules for reverse path | 247 | // Create flow rules for reverse path |
205 | if (intent.isBidirectional()) { | 248 | if (intent.isBidirectional()) { |
206 | - rules.add(connectPorts(connIntent.getSrc(), src, intent.priority())); | 249 | + // at the destination: OCH port mapping to ODUCLT port |
207 | - rules.add(connectPorts(dst, connIntent.getDst(), intent.priority())); | 250 | + rules.add(connectPorts(connIntent.getSrc(), src, intent.priority(), slots)); |
251 | + // at the source: ODUCLT port mapping to OCH port | ||
252 | + rules.add(connectPorts(dst, connIntent.getDst(), intent.priority(), slots)); | ||
208 | } | 253 | } |
209 | 254 | ||
210 | - circuitIntent = new FlowRuleIntent(appId, rules, intent.resources()); | 255 | + FlowRuleIntent circuitIntent = new FlowRuleIntent(appId, rules, intent.resources()); |
211 | 256 | ||
212 | // Save circuit to connectivity intent mapping | 257 | // Save circuit to connectivity intent mapping |
213 | intentSetMultimap.allocateMapping(connIntent.id(), intent.id()); | 258 | intentSetMultimap.allocateMapping(connIntent.id(), intent.id()); |
... | @@ -259,9 +304,14 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -259,9 +304,14 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
259 | * Returns existing and available optical connectivity intent that matches the given circuit intent. | 304 | * Returns existing and available optical connectivity intent that matches the given circuit intent. |
260 | * | 305 | * |
261 | * @param circuitIntent optical circuit intent | 306 | * @param circuitIntent optical circuit intent |
307 | + * @param multiplexingSupported indicates whether ODU multiplexing is supported | ||
262 | * @return existing optical connectivity intent, null otherwise. | 308 | * @return existing optical connectivity intent, null otherwise. |
263 | */ | 309 | */ |
264 | - private OpticalConnectivityIntent findOpticalConnectivityIntent(OpticalCircuitIntent circuitIntent) { | 310 | + private OpticalConnectivityIntent findOpticalConnectivityIntent(OpticalCircuitIntent circuitIntent, |
311 | + boolean multiplexingSupported) { | ||
312 | + | ||
313 | + OduSignalType oduSignalType = mappingCltSignalTypeToOduSignalType(circuitIntent.getSignalType()); | ||
314 | + | ||
265 | for (Intent intent : intentService.getIntents()) { | 315 | for (Intent intent : intentService.getIntents()) { |
266 | if (!(intent instanceof OpticalConnectivityIntent)) { | 316 | if (!(intent instanceof OpticalConnectivityIntent)) { |
267 | continue; | 317 | continue; |
... | @@ -272,7 +322,7 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -272,7 +322,7 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
272 | ConnectPoint src = circuitIntent.getSrc(); | 322 | ConnectPoint src = circuitIntent.getSrc(); |
273 | ConnectPoint dst = circuitIntent.getDst(); | 323 | ConnectPoint dst = circuitIntent.getDst(); |
274 | // Ignore if the intents don't have identical src and dst devices | 324 | // Ignore if the intents don't have identical src and dst devices |
275 | - if (!src.deviceId().equals(connIntent.getSrc().deviceId()) && | 325 | + if (!src.deviceId().equals(connIntent.getSrc().deviceId()) || |
276 | !dst.deviceId().equals(connIntent.getDst().deviceId())) { | 326 | !dst.deviceId().equals(connIntent.getDst().deviceId())) { |
277 | continue; | 327 | continue; |
278 | } | 328 | } |
... | @@ -281,14 +331,68 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -281,14 +331,68 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
281 | continue; | 331 | continue; |
282 | } | 332 | } |
283 | 333 | ||
284 | - if (isAvailable(connIntent.id())) { | 334 | + if (!isAvailable(connIntent.id())) { |
285 | - return connIntent; | 335 | + continue; |
336 | + } | ||
337 | + | ||
338 | + if (multiplexingSupported) { | ||
339 | + if (!isAvailableTributarySlots(connIntent, oduSignalType.tributarySlots())) { | ||
340 | + continue; | ||
341 | + } | ||
286 | } | 342 | } |
343 | + | ||
344 | + return connIntent; | ||
287 | } | 345 | } |
288 | 346 | ||
289 | return null; | 347 | return null; |
290 | } | 348 | } |
291 | 349 | ||
350 | + private boolean isAvailableTributarySlots(OpticalConnectivityIntent connIntent, int requestedTsNum) { | ||
351 | + Set<TributarySlot> common = findCommonTributarySlotsOnCps(connIntent.getSrc(), connIntent.getDst()); | ||
352 | + if (common.isEmpty()) { | ||
353 | + log.debug("No available TributarySlots"); | ||
354 | + return false; | ||
355 | + } | ||
356 | + if (common.size() < requestedTsNum) { | ||
357 | + log.debug("Not enough available TributarySlots={} < requestedTsNum={}", common.size(), requestedTsNum); | ||
358 | + return false; | ||
359 | + } | ||
360 | + return true; | ||
361 | + } | ||
362 | + | ||
363 | + private Set<TributarySlot> assignTributarySlots(OpticalCircuitIntent intent, | ||
364 | + Pair<ConnectPoint, ConnectPoint> ports) { | ||
365 | + | ||
366 | + OduSignalType oduSignalType = mappingCltSignalTypeToOduSignalType(intent.getSignalType()); | ||
367 | + int requestedTsNum = oduSignalType.tributarySlots(); | ||
368 | + Set<TributarySlot> commonTributarySlots = findCommonTributarySlotsOnCps(ports.getLeft(), ports.getRight()); | ||
369 | + if (commonTributarySlots.isEmpty()) { | ||
370 | + return Collections.emptySet(); | ||
371 | + } | ||
372 | + if (commonTributarySlots.size() < requestedTsNum) { | ||
373 | + return Collections.emptySet(); | ||
374 | + } | ||
375 | + | ||
376 | + Set<TributarySlot> tributarySlots = commonTributarySlots.stream() | ||
377 | + .limit(requestedTsNum) | ||
378 | + .collect(Collectors.toSet()); | ||
379 | + | ||
380 | + final List<ConnectPoint> portsList = ImmutableList.of(ports.getLeft(), ports.getRight()); | ||
381 | + List<Resource> tributarySlotResources = portsList.stream() | ||
382 | + .flatMap(cp -> tributarySlots | ||
383 | + .stream() | ||
384 | + .map(ts-> Resources.discrete(cp.deviceId(), cp.port()).resource().child(ts))) | ||
385 | + .collect(Collectors.toList()); | ||
386 | + | ||
387 | + List<ResourceAllocation> allocations = resourceService.allocate(intent.id(), tributarySlotResources); | ||
388 | + if (allocations.isEmpty()) { | ||
389 | + log.debug("Resource allocation for {} failed (resource request: {})", | ||
390 | + intent, tributarySlotResources); | ||
391 | + return Collections.emptySet(); | ||
392 | + } | ||
393 | + return tributarySlots; | ||
394 | + } | ||
395 | + | ||
292 | private ConnectPoint staticPort(ConnectPoint connectPoint) { | 396 | private ConnectPoint staticPort(ConnectPoint connectPoint) { |
293 | Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port()); | 397 | Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port()); |
294 | 398 | ||
... | @@ -306,7 +410,7 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -306,7 +410,7 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
306 | return null; | 410 | return null; |
307 | } | 411 | } |
308 | 412 | ||
309 | - private OchPort findAvailableOchPort(ConnectPoint oduPort) { | 413 | + private OchPort findAvailableOchPort(ConnectPoint oduPort, OduSignalType ochPortSignalType) { |
310 | // First see if the port mappings are constrained | 414 | // First see if the port mappings are constrained |
311 | ConnectPoint ochCP = staticPort(oduPort); | 415 | ConnectPoint ochCP = staticPort(oduPort); |
312 | 416 | ||
... | @@ -323,6 +427,7 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -323,6 +427,7 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
323 | if (isAvailable(intentId.orElse(null))) { | 427 | if (isAvailable(intentId.orElse(null))) { |
324 | return ochPort; | 428 | return ochPort; |
325 | } | 429 | } |
430 | + return null; | ||
326 | } | 431 | } |
327 | 432 | ||
328 | // No port constraints, so find any port that works | 433 | // No port constraints, so find any port that works |
... | @@ -332,6 +437,14 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -332,6 +437,14 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
332 | if (!(port instanceof OchPort)) { | 437 | if (!(port instanceof OchPort)) { |
333 | continue; | 438 | continue; |
334 | } | 439 | } |
440 | + // This should be the first allocation on the OCH port | ||
441 | + if (!resourceService.isAvailable(Resources.discrete(oduPort.deviceId(), port.number()).resource())) { | ||
442 | + continue; | ||
443 | + } | ||
444 | + // OchPort is required to have the requested oduSignalType | ||
445 | + if (((OchPort) port).signalType() != ochPortSignalType) { | ||
446 | + continue; | ||
447 | + } | ||
335 | 448 | ||
336 | Optional<IntentId> intentId = | 449 | Optional<IntentId> intentId = |
337 | resourceService.getResourceAllocations(Resources.discrete(oduPort.deviceId(), port.number()).id()) | 450 | resourceService.getResourceAllocations(Resources.discrete(oduPort.deviceId(), port.number()).id()) |
... | @@ -350,13 +463,34 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -350,13 +463,34 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
350 | } | 463 | } |
351 | 464 | ||
352 | private Pair<OchPort, OchPort> findPorts(OpticalCircuitIntent intent) { | 465 | private Pair<OchPort, OchPort> findPorts(OpticalCircuitIntent intent) { |
466 | + Pair<OchPort, OchPort> ochPorts = null; | ||
467 | + // According to the OpticalCircuitIntent's signalType find OCH ports with available TributarySlots resources | ||
468 | + switch (intent.getSignalType()) { | ||
469 | + case CLT_1GBE: | ||
470 | + case CLT_10GBE: | ||
471 | + // First search for OCH ports with OduSignalType of ODU2. If not found - search for those with ODU4 | ||
472 | + ochPorts = findPorts(intent, OduSignalType.ODU2); | ||
473 | + if (ochPorts == null) { | ||
474 | + ochPorts = findPorts(intent, OduSignalType.ODU4); | ||
475 | + } | ||
476 | + break; | ||
477 | + case CLT_100GBE: | ||
478 | + ochPorts = findPorts(intent, OduSignalType.ODU4); | ||
479 | + break; | ||
480 | + case CLT_40GBE: | ||
481 | + default: | ||
482 | + break; | ||
483 | + } | ||
484 | + return ochPorts; | ||
485 | + } | ||
353 | 486 | ||
354 | - OchPort srcPort = findAvailableOchPort(intent.getSrc()); | 487 | + private Pair<OchPort, OchPort> findPorts(OpticalCircuitIntent intent, OduSignalType ochPortSignalType) { |
488 | + OchPort srcPort = findAvailableOchPort(intent.getSrc(), ochPortSignalType); | ||
355 | if (srcPort == null) { | 489 | if (srcPort == null) { |
356 | return null; | 490 | return null; |
357 | } | 491 | } |
358 | 492 | ||
359 | - OchPort dstPort = findAvailableOchPort(intent.getDst()); | 493 | + OchPort dstPort = findAvailableOchPort(intent.getDst(), ochPortSignalType); |
360 | if (dstPort == null) { | 494 | if (dstPort == null) { |
361 | return null; | 495 | return null; |
362 | } | 496 | } |
... | @@ -369,18 +503,46 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -369,18 +503,46 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
369 | * | 503 | * |
370 | * @param src source port | 504 | * @param src source port |
371 | * @param dst destination port | 505 | * @param dst destination port |
506 | + * @param priority | ||
507 | + * @param slots Set of TributarySlots | ||
372 | * @return flow rules | 508 | * @return flow rules |
373 | */ | 509 | */ |
374 | - private FlowRule connectPorts(ConnectPoint src, ConnectPoint dst, int priority) { | 510 | + private FlowRule connectPorts(ConnectPoint src, ConnectPoint dst, int priority, Set<TributarySlot> slots) { |
375 | checkArgument(src.deviceId().equals(dst.deviceId())); | 511 | checkArgument(src.deviceId().equals(dst.deviceId())); |
376 | 512 | ||
377 | TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); | 513 | TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); |
378 | TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder(); | 514 | TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder(); |
379 | 515 | ||
380 | selectorBuilder.matchInPort(src.port()); | 516 | selectorBuilder.matchInPort(src.port()); |
381 | - //selectorBuilder.add(Criteria.matchCltSignalType) | 517 | + if (!slots.isEmpty()) { |
518 | + Port srcPort = deviceService.getPort(src.deviceId(), src.port()); | ||
519 | + Port dstPort = deviceService.getPort(dst.deviceId(), dst.port()); | ||
520 | + OduSignalType oduCltPortOduSignalType; | ||
521 | + OduSignalType ochPortOduSignalType; | ||
522 | + | ||
523 | + if (srcPort instanceof OduCltPort) { | ||
524 | + oduCltPortOduSignalType = mappingCltSignalTypeToOduSignalType(((OduCltPort) srcPort).signalType()); | ||
525 | + ochPortOduSignalType = ((OchPort) dstPort).signalType(); | ||
526 | + | ||
527 | + selectorBuilder.add(Criteria.matchOduSignalType(oduCltPortOduSignalType)); | ||
528 | + // use Instruction of OduSignalId only in case of ODU Multiplexing | ||
529 | + if (oduCltPortOduSignalType != ochPortOduSignalType) { | ||
530 | + OduSignalId oduSignalId = buildOduSignalId(ochPortOduSignalType, slots); | ||
531 | + treatmentBuilder.add(Instructions.modL1OduSignalId(oduSignalId)); | ||
532 | + } | ||
533 | + } else { // srcPort is OchPort | ||
534 | + oduCltPortOduSignalType = mappingCltSignalTypeToOduSignalType(((OduCltPort) dstPort).signalType()); | ||
535 | + ochPortOduSignalType = ((OchPort) srcPort).signalType(); | ||
536 | + | ||
537 | + selectorBuilder.add(Criteria.matchOduSignalType(oduCltPortOduSignalType)); | ||
538 | + // use Criteria of OduSignalId only in case of ODU Multiplexing | ||
539 | + if (oduCltPortOduSignalType != ochPortOduSignalType) { | ||
540 | + OduSignalId oduSignalId = buildOduSignalId(ochPortOduSignalType, slots); | ||
541 | + selectorBuilder.add(Criteria.matchOduSignalId(oduSignalId)); | ||
542 | + } | ||
543 | + } | ||
544 | + } | ||
382 | treatmentBuilder.setOutput(dst.port()); | 545 | treatmentBuilder.setOutput(dst.port()); |
383 | - //treatmentBuilder.add(Instructions.modL1OduSignalType) | ||
384 | 546 | ||
385 | FlowRule flowRule = DefaultFlowRule.builder() | 547 | FlowRule flowRule = DefaultFlowRule.builder() |
386 | .forDevice(src.deviceId()) | 548 | .forDevice(src.deviceId()) |
... | @@ -393,4 +555,98 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -393,4 +555,98 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
393 | 555 | ||
394 | return flowRule; | 556 | return flowRule; |
395 | } | 557 | } |
558 | + | ||
559 | + private OduSignalId buildOduSignalId(OduSignalType ochPortSignalType, Set<TributarySlot> slots) { | ||
560 | + int tributaryPortNumber = findFirstTributarySlotIndex(slots); | ||
561 | + int tributarySlotLen = ochPortSignalType.tributarySlots(); | ||
562 | + byte[] tributarySlotBitmap = new byte[OduSignalId.TRIBUTARY_SLOT_BITMAP_SIZE]; | ||
563 | + | ||
564 | + slots.forEach(ts -> tributarySlotBitmap[(byte) (ts.index() - 1) / 8] |= 0x1 << ((ts.index() - 1) % 8)); | ||
565 | + return OduSignalId.oduSignalId(tributaryPortNumber, tributarySlotLen, tributarySlotBitmap); | ||
566 | + } | ||
567 | + | ||
568 | + private int findFirstTributarySlotIndex(Set<TributarySlot> tributarySlots) { | ||
569 | + return (int) tributarySlots.stream().findFirst().get().index(); | ||
570 | + } | ||
571 | + | ||
572 | + private boolean isTributarySlotBehaviourSupported(DeviceId deviceId) { | ||
573 | + Driver driver = driverService.getDriver(deviceId); | ||
574 | + return (driver != null && driver.hasBehaviour(TributarySlotQuery.class)); | ||
575 | + } | ||
576 | + | ||
577 | + private boolean isMultiplexingSupported(OpticalCircuitIntent intent) { | ||
578 | + ConnectPoint src = intent.getSrc(); | ||
579 | + ConnectPoint dst = intent.getDst(); | ||
580 | + | ||
581 | + if (!isTributarySlotBehaviourSupported(src.deviceId()) || | ||
582 | + !isTributarySlotBehaviourSupported(dst.deviceId())) { | ||
583 | + return false; | ||
584 | + } | ||
585 | + | ||
586 | + ConnectPoint srcStaticPort = staticPort(src); | ||
587 | + if (srcStaticPort != null) { | ||
588 | + return false; | ||
589 | + } | ||
590 | + ConnectPoint dstStaticPort = staticPort(dst); | ||
591 | + if (dstStaticPort != null) { | ||
592 | + return false; | ||
593 | + } | ||
594 | + | ||
595 | + return true; | ||
596 | + } | ||
597 | + | ||
598 | + /** | ||
599 | + * Maps from Intent's OduClt SignalType to OduSignalType. | ||
600 | + * | ||
601 | + * @param cltSignalType OduClt port signal type | ||
602 | + * @return OduSignalType the result of mapping CltSignalType to OduSignalType | ||
603 | + */ | ||
604 | + OduSignalType mappingCltSignalTypeToOduSignalType(CltSignalType cltSignalType) { | ||
605 | + OduSignalType oduSignalType = OduSignalType.ODU0; | ||
606 | + switch (cltSignalType) { | ||
607 | + case CLT_1GBE: | ||
608 | + oduSignalType = OduSignalType.ODU0; | ||
609 | + break; | ||
610 | + case CLT_10GBE: | ||
611 | + oduSignalType = OduSignalType.ODU2; | ||
612 | + break; | ||
613 | + case CLT_40GBE: | ||
614 | + oduSignalType = OduSignalType.ODU3; | ||
615 | + break; | ||
616 | + case CLT_100GBE: | ||
617 | + oduSignalType = OduSignalType.ODU4; | ||
618 | + break; | ||
619 | + default: | ||
620 | + log.error("Unsupported CltSignalType {}", cltSignalType); | ||
621 | + break; | ||
622 | + } | ||
623 | + return oduSignalType; | ||
624 | + } | ||
625 | + | ||
626 | + /** | ||
627 | + * Finds the common TributarySlots available on the two connect points. | ||
628 | + * | ||
629 | + * @param srcCp source connect point | ||
630 | + * @param dstCp dest connect point | ||
631 | + * @return set of common TributarySlots on both connect points | ||
632 | + */ | ||
633 | + Set<TributarySlot> findCommonTributarySlotsOnCps(ConnectPoint srcCp, ConnectPoint dstCp) { | ||
634 | + Set<TributarySlot> forward = findTributarySlotsOnCp(srcCp); | ||
635 | + Set<TributarySlot> backward = findTributarySlotsOnCp(dstCp); | ||
636 | + return Sets.intersection(forward, backward); | ||
637 | + } | ||
638 | + | ||
639 | + /** | ||
640 | + * Finds the TributarySlots available on the connect point. | ||
641 | + * | ||
642 | + * @param cp connect point | ||
643 | + * @return set of TributarySlots available on the connect point | ||
644 | + */ | ||
645 | + Set<TributarySlot> findTributarySlotsOnCp(ConnectPoint cp) { | ||
646 | + return resourceService.getAvailableResources(Resources.discrete(cp.deviceId(), cp.port()).id()) | ||
647 | + .stream() | ||
648 | + .filter(x -> x.last() instanceof TributarySlot) | ||
649 | + .map(x -> (TributarySlot) x.last()) | ||
650 | + .collect(Collectors.toSet()); | ||
651 | + } | ||
396 | } | 652 | } | ... | ... |
... | @@ -108,6 +108,11 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical | ... | @@ -108,6 +108,11 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical |
108 | 108 | ||
109 | log.debug("Compiling optical connectivity intent between {} and {}", src, dst); | 109 | log.debug("Compiling optical connectivity intent between {} and {}", src, dst); |
110 | 110 | ||
111 | + // Release of intent resources here is only a temporary solution for handling the | ||
112 | + // case of recompiling due to intent restoration (when intent state is FAILED). | ||
113 | + // TODO: try to release intent resources in IntentManager. | ||
114 | + resourceService.release(intent.id()); | ||
115 | + | ||
111 | // Reserve OCh ports | 116 | // Reserve OCh ports |
112 | Resource srcPortResource = Resources.discrete(src.deviceId(), src.port()).resource(); | 117 | Resource srcPortResource = Resources.discrete(src.deviceId(), src.port()).resource(); |
113 | Resource dstPortResource = Resources.discrete(dst.deviceId(), dst.port()).resource(); | 118 | Resource dstPortResource = Resources.discrete(dst.deviceId(), dst.port()).resource(); | ... | ... |
-
Please register or login to post a comment