Committed by
Gerrit Code Review
Refactor: Reserve resources only in one place
This is a preparation task for the future Intent Framework major enhancement that aims to consolidate resource allocation invocations into the Framework side instead of the compiler side. Declaring required resources and allocating the resources need to be clearly separated. This patch tries to separate these phases. Change-Id: I7b238f24996b3f1dc97afda6d188426001052127
Showing
1 changed file
with
81 additions
and
56 deletions
... | @@ -197,58 +197,116 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -197,58 +197,116 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
197 | && isMultiplexingSupported(intent.getDst()); | 197 | && isMultiplexingSupported(intent.getDst()); |
198 | 198 | ||
199 | // slots are used only for devices supporting multiplexing | 199 | // slots are used only for devices supporting multiplexing |
200 | - Set<TributarySlot> slots = Collections.emptySet(); | 200 | + List<Resource> ports = ImmutableList.of(srcPortResource, dstPortResource); |
201 | 201 | ||
202 | OpticalConnectivityIntent connIntent = findOpticalConnectivityIntent(intent.getSrc(), intent.getDst(), | 202 | OpticalConnectivityIntent connIntent = findOpticalConnectivityIntent(intent.getSrc(), intent.getDst(), |
203 | intent.getSignalType(), multiplexingSupported); | 203 | intent.getSignalType(), multiplexingSupported); |
204 | - if ((connIntent != null) && multiplexingSupported) { | 204 | + |
205 | - // Allocate TributarySlots on existing OCH ports | 205 | + if (connIntent != null && !multiplexingSupported) { |
206 | - slots = assignTributarySlots(intent, Pair.of(connIntent.getSrc(), connIntent.getDst())); | 206 | + return compile(intent, src, dst, Optional.of(connIntent), ports, false); |
207 | } | 207 | } |
208 | 208 | ||
209 | // Create optical connectivity intent if needed - no optical intent or not enough slots available | 209 | // Create optical connectivity intent if needed - no optical intent or not enough slots available |
210 | - if (connIntent == null || (multiplexingSupported && slots.isEmpty())) { | 210 | + if (connIntent == null) { |
211 | + return compile(intent, src, dst, Optional.empty(), ports, multiplexingSupported); | ||
212 | + } | ||
213 | + | ||
214 | + List<Resource> slots = availableSlotResources(connIntent.getSrc(), connIntent.getDst(), | ||
215 | + intent.getSignalType()); | ||
216 | + if (slots.isEmpty()) { | ||
217 | + return compile(intent, src, dst, Optional.empty(), ports, true); | ||
218 | + } | ||
219 | + | ||
220 | + return compile(intent, src, dst, Optional.of(connIntent), ImmutableList.<Resource>builder() | ||
221 | + .addAll(ports).addAll(slots).build(), false); | ||
222 | + | ||
223 | + } | ||
224 | + | ||
225 | + private List<Intent> compile(OpticalCircuitIntent intent, ConnectPoint src, ConnectPoint dst, | ||
226 | + Optional<OpticalConnectivityIntent> existingConnectivity, | ||
227 | + List<Resource> resources, boolean supportsMultiplexing) { | ||
228 | + OpticalConnectivityIntent connectivityIntent; | ||
229 | + List<Resource> required; | ||
230 | + if (existingConnectivity.isPresent()) { | ||
231 | + connectivityIntent = existingConnectivity.get(); | ||
232 | + required = resources; | ||
233 | + } else { | ||
211 | // Find OCh ports with available resources | 234 | // Find OCh ports with available resources |
212 | Pair<OchPort, OchPort> ochPorts = findPorts(intent.getSrc(), intent.getDst(), intent.getSignalType()); | 235 | Pair<OchPort, OchPort> ochPorts = findPorts(intent.getSrc(), intent.getDst(), intent.getSignalType()); |
213 | 236 | ||
214 | if (ochPorts == null) { | 237 | if (ochPorts == null) { |
215 | - // Release port allocations if unsuccessful | ||
216 | - resourceService.release(intent.id()); | ||
217 | throw new IntentCompilationException("Unable to find suitable OCH ports for intent " + intent); | 238 | throw new IntentCompilationException("Unable to find suitable OCH ports for intent " + intent); |
218 | } | 239 | } |
219 | 240 | ||
220 | ConnectPoint srcCP = new ConnectPoint(src.elementId(), ochPorts.getLeft().number()); | 241 | ConnectPoint srcCP = new ConnectPoint(src.elementId(), ochPorts.getLeft().number()); |
221 | ConnectPoint dstCP = new ConnectPoint(dst.elementId(), ochPorts.getRight().number()); | 242 | ConnectPoint dstCP = new ConnectPoint(dst.elementId(), ochPorts.getRight().number()); |
222 | 243 | ||
223 | - if (multiplexingSupported) { | ||
224 | - // Allocate TributarySlots on OCH ports | ||
225 | - slots = assignTributarySlots(intent, Pair.of(srcCP, dstCP)); | ||
226 | - if (slots.isEmpty()) { | ||
227 | - // Release port allocations if unsuccessful | ||
228 | - resourceService.release(intent.id()); | ||
229 | - throw new IntentCompilationException("Unable to find Tributary Slots for intent " + intent); | ||
230 | - } | ||
231 | - } | ||
232 | - | ||
233 | // Create optical connectivity intent | 244 | // Create optical connectivity intent |
234 | - OduSignalType signalType = ochPorts.getLeft().signalType(); | 245 | + connectivityIntent = OpticalConnectivityIntent.builder() |
235 | - connIntent = OpticalConnectivityIntent.builder() | ||
236 | .appId(appId) | 246 | .appId(appId) |
237 | .src(srcCP) | 247 | .src(srcCP) |
238 | .dst(dstCP) | 248 | .dst(dstCP) |
239 | - .signalType(signalType) | 249 | + .signalType(ochPorts.getLeft().signalType()) |
240 | .bidirectional(intent.isBidirectional()) | 250 | .bidirectional(intent.isBidirectional()) |
241 | .build(); | 251 | .build(); |
242 | - intentService.submit(connIntent); | 252 | + |
253 | + if (!supportsMultiplexing) { | ||
254 | + required = resources; | ||
255 | + } else { | ||
256 | + List<Resource> slots = availableSlotResources(srcCP, dstCP, intent.getSignalType()); | ||
257 | + if (slots.isEmpty()) { | ||
258 | + throw new IntentCompilationException("Unable to find Tributary Slots for intent " + intent); | ||
259 | + } | ||
260 | + required = ImmutableList.<Resource>builder().addAll(resources).addAll(slots).build(); | ||
261 | + } | ||
262 | + } | ||
263 | + | ||
264 | + if (resourceService.allocate(intent.id(), required).isEmpty()) { | ||
265 | + throw new IntentCompilationException("Unable to allocate resources for intent " + intent | ||
266 | + + ": resources=" + required); | ||
243 | } | 267 | } |
244 | 268 | ||
269 | + intentService.submit(connectivityIntent); | ||
270 | + | ||
245 | // Save circuit to connectivity intent mapping | 271 | // Save circuit to connectivity intent mapping |
246 | - intentSetMultimap.allocateMapping(connIntent.id(), intent.id()); | 272 | + intentSetMultimap.allocateMapping(connectivityIntent.id(), intent.id()); |
247 | 273 | ||
248 | - FlowRuleIntent circuitIntent = createFlowRule(intent, connIntent, slots); | 274 | + FlowRuleIntent circuitIntent = createFlowRule(intent, connectivityIntent, required.stream(). |
275 | + flatMap(x -> Tools.stream(x.valueAs(TributarySlot.class))) | ||
276 | + .collect(Collectors.toSet())); | ||
249 | return ImmutableList.of(circuitIntent); | 277 | return ImmutableList.of(circuitIntent); |
250 | } | 278 | } |
251 | 279 | ||
280 | + private List<Resource> availableSlotResources(ConnectPoint src, ConnectPoint dst, CltSignalType signalType) { | ||
281 | + OduSignalType oduSignalType = mappingCltSignalTypeToOduSignalType(signalType); | ||
282 | + int requestedTsNum = oduSignalType.tributarySlots(); | ||
283 | + Set<TributarySlot> commonTributarySlots = findCommonTributarySlotsOnCps(src, dst); | ||
284 | + if (commonTributarySlots.isEmpty()) { | ||
285 | + return Collections.emptyList(); | ||
286 | + } | ||
287 | + if (commonTributarySlots.size() < requestedTsNum) { | ||
288 | + return Collections.emptyList(); | ||
289 | + } | ||
290 | + | ||
291 | + Set<TributarySlot> tributarySlots = commonTributarySlots.stream() | ||
292 | + .limit(requestedTsNum) | ||
293 | + .collect(Collectors.toSet()); | ||
294 | + | ||
295 | + final List<ConnectPoint> portsList = ImmutableList.of(src, dst); | ||
296 | + List<Resource> tributarySlotResources = portsList.stream() | ||
297 | + .flatMap(cp -> tributarySlots | ||
298 | + .stream() | ||
299 | + .map(ts-> Resources.discrete(cp.deviceId(), cp.port()).resource().child(ts))) | ||
300 | + .collect(Collectors.toList()); | ||
301 | + | ||
302 | + if (!tributarySlotResources.stream().allMatch(resourceService::isAvailable)) { | ||
303 | + log.debug("Resource allocation for {} on {} and {} failed (resource request: {})", | ||
304 | + signalType, src, dst, tributarySlotResources); | ||
305 | + return Collections.emptyList(); | ||
306 | + } | ||
307 | + return tributarySlotResources; | ||
308 | + } | ||
309 | + | ||
252 | private FlowRuleIntent createFlowRule(OpticalCircuitIntent higherIntent, | 310 | private FlowRuleIntent createFlowRule(OpticalCircuitIntent higherIntent, |
253 | OpticalConnectivityIntent lowerIntent, Set<TributarySlot> slots) { | 311 | OpticalConnectivityIntent lowerIntent, Set<TributarySlot> slots) { |
254 | // Create optical circuit intent | 312 | // Create optical circuit intent |
... | @@ -338,39 +396,6 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu | ... | @@ -338,39 +396,6 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu |
338 | return true; | 396 | return true; |
339 | } | 397 | } |
340 | 398 | ||
341 | - private Set<TributarySlot> assignTributarySlots(OpticalCircuitIntent intent, | ||
342 | - Pair<ConnectPoint, ConnectPoint> ports) { | ||
343 | - | ||
344 | - OduSignalType oduSignalType = mappingCltSignalTypeToOduSignalType(intent.getSignalType()); | ||
345 | - int requestedTsNum = oduSignalType.tributarySlots(); | ||
346 | - Set<TributarySlot> commonTributarySlots = findCommonTributarySlotsOnCps(ports.getLeft(), ports.getRight()); | ||
347 | - if (commonTributarySlots.isEmpty()) { | ||
348 | - return Collections.emptySet(); | ||
349 | - } | ||
350 | - if (commonTributarySlots.size() < requestedTsNum) { | ||
351 | - return Collections.emptySet(); | ||
352 | - } | ||
353 | - | ||
354 | - Set<TributarySlot> tributarySlots = commonTributarySlots.stream() | ||
355 | - .limit(requestedTsNum) | ||
356 | - .collect(Collectors.toSet()); | ||
357 | - | ||
358 | - final List<ConnectPoint> portsList = ImmutableList.of(ports.getLeft(), ports.getRight()); | ||
359 | - List<Resource> tributarySlotResources = portsList.stream() | ||
360 | - .flatMap(cp -> tributarySlots | ||
361 | - .stream() | ||
362 | - .map(ts-> Resources.discrete(cp.deviceId(), cp.port()).resource().child(ts))) | ||
363 | - .collect(Collectors.toList()); | ||
364 | - | ||
365 | - List<ResourceAllocation> allocations = resourceService.allocate(intent.id(), tributarySlotResources); | ||
366 | - if (allocations.isEmpty()) { | ||
367 | - log.debug("Resource allocation for {} failed (resource request: {})", | ||
368 | - intent, tributarySlotResources); | ||
369 | - return Collections.emptySet(); | ||
370 | - } | ||
371 | - return tributarySlots; | ||
372 | - } | ||
373 | - | ||
374 | private ConnectPoint staticPort(ConnectPoint connectPoint) { | 399 | private ConnectPoint staticPort(ConnectPoint connectPoint) { |
375 | Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port()); | 400 | Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port()); |
376 | 401 | ... | ... |
-
Please register or login to post a comment