Committed by
Ray Milkey
In this commit:
Bug fix when optimized SR re-routing fails, do full re-route Bug fix filtering objectives should be called for new device even if there is an existing grouphandler Bug fix NPE in ofdpa driver due to null check on the wrong variable New cli command for debugging flow-objectives for pending next-objectives Flow objective cli commands now start with "obj-" Change-Id: I819f82d1d67769cb9fbbde60f099d29b8e7f7c9e
Showing
11 changed files
with
171 additions
and
33 deletions
... | @@ -16,7 +16,7 @@ | ... | @@ -16,7 +16,7 @@ |
16 | package org.onosproject.pce.util; | 16 | package org.onosproject.pce.util; |
17 | 17 | ||
18 | import java.util.List; | 18 | import java.util.List; |
19 | - | 19 | +import com.google.common.collect.ImmutableList; |
20 | import org.onosproject.net.DeviceId; | 20 | import org.onosproject.net.DeviceId; |
21 | import org.onosproject.net.flowobjective.FilteringObjective; | 21 | import org.onosproject.net.flowobjective.FilteringObjective; |
22 | import org.onosproject.net.flowobjective.FlowObjectiveService; | 22 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
... | @@ -60,6 +60,11 @@ public class FlowObjServiceAdapter implements FlowObjectiveService { | ... | @@ -60,6 +60,11 @@ public class FlowObjServiceAdapter implements FlowObjectiveService { |
60 | 60 | ||
61 | @Override | 61 | @Override |
62 | public List<String> getNextMappings() { | 62 | public List<String> getNextMappings() { |
63 | - return null; | 63 | + return ImmutableList.of(); |
64 | + } | ||
65 | + | ||
66 | + @Override | ||
67 | + public List<String> getPendingNexts() { | ||
68 | + return ImmutableList.of(); | ||
64 | } | 69 | } |
65 | } | 70 | } | ... | ... |
... | @@ -170,6 +170,7 @@ public class DefaultRoutingHandler { | ... | @@ -170,6 +170,7 @@ public class DefaultRoutingHandler { |
170 | log.trace("populateRoutingRulesForLinkStatusChange: " | 170 | log.trace("populateRoutingRulesForLinkStatusChange: " |
171 | + "populationStatus is STARTED"); | 171 | + "populationStatus is STARTED"); |
172 | populationStatus = Status.STARTED; | 172 | populationStatus = Status.STARTED; |
173 | + // optimized re-routing | ||
173 | if (linkFail == null) { | 174 | if (linkFail == null) { |
174 | // Compare all routes of existing ECMP SPG with the new ones | 175 | // Compare all routes of existing ECMP SPG with the new ones |
175 | routeChanges = computeRouteChange(); | 176 | routeChanges = computeRouteChange(); |
... | @@ -178,6 +179,11 @@ public class DefaultRoutingHandler { | ... | @@ -178,6 +179,11 @@ public class DefaultRoutingHandler { |
178 | routeChanges = computeDamagedRoutes(linkFail); | 179 | routeChanges = computeDamagedRoutes(linkFail); |
179 | } | 180 | } |
180 | 181 | ||
182 | + // null routeChanges indicates that full re-routing is required | ||
183 | + if (routeChanges == null) { | ||
184 | + return populateAllRoutingRules(); | ||
185 | + } | ||
186 | + | ||
181 | if (routeChanges.isEmpty()) { | 187 | if (routeChanges.isEmpty()) { |
182 | log.info("No route changes for the link status change"); | 188 | log.info("No route changes for the link status change"); |
183 | log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is SUCCEEDED"); | 189 | log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is SUCCEEDED"); |
... | @@ -276,6 +282,15 @@ public class DefaultRoutingHandler { | ... | @@ -276,6 +282,15 @@ public class DefaultRoutingHandler { |
276 | return true; | 282 | return true; |
277 | } | 283 | } |
278 | 284 | ||
285 | + /** | ||
286 | + * Computes set of affected ECMP routes due to failed link. Assumes | ||
287 | + * previous ecmp shortest-path graph exists for a switch in order to compute | ||
288 | + * affected routes. If such a graph does not exist, the method returns null. | ||
289 | + * | ||
290 | + * @param linkFail the failed link | ||
291 | + * @return the set of affected routes which may be empty if no routes were | ||
292 | + * affected, or null if no previous ecmp spg was found for comparison | ||
293 | + */ | ||
279 | private Set<ArrayList<DeviceId>> computeDamagedRoutes(Link linkFail) { | 294 | private Set<ArrayList<DeviceId>> computeDamagedRoutes(Link linkFail) { |
280 | 295 | ||
281 | Set<ArrayList<DeviceId>> routes = new HashSet<>(); | 296 | Set<ArrayList<DeviceId>> routes = new HashSet<>(); |
... | @@ -284,20 +299,31 @@ public class DefaultRoutingHandler { | ... | @@ -284,20 +299,31 @@ public class DefaultRoutingHandler { |
284 | log.debug("Computing the impacted routes for device {} due to link fail", | 299 | log.debug("Computing the impacted routes for device {} due to link fail", |
285 | sw.id()); | 300 | sw.id()); |
286 | if (!srManager.mastershipService.isLocalMaster(sw.id())) { | 301 | if (!srManager.mastershipService.isLocalMaster(sw.id())) { |
302 | + log.debug("No mastership for {} .. skipping route optimization", | ||
303 | + sw.id()); | ||
287 | continue; | 304 | continue; |
288 | } | 305 | } |
289 | EcmpShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); | 306 | EcmpShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); |
290 | if (ecmpSpg == null) { | 307 | if (ecmpSpg == null) { |
291 | - log.error("No existing ECMP graph for switch {}", sw.id()); | 308 | + log.warn("No existing ECMP graph for switch {}. Aborting optimized" |
292 | - continue; | 309 | + + " rerouting and opting for full-reroute", sw.id()); |
310 | + return null; | ||
293 | } | 311 | } |
294 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = | 312 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = |
295 | ecmpSpg.getAllLearnedSwitchesAndVia(); | 313 | ecmpSpg.getAllLearnedSwitchesAndVia(); |
296 | for (Integer itrIdx : switchVia.keySet()) { | 314 | for (Integer itrIdx : switchVia.keySet()) { |
315 | + log.trace("Iterindex# {}", itrIdx); | ||
297 | HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap = | 316 | HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap = |
298 | switchVia.get(itrIdx); | 317 | switchVia.get(itrIdx); |
299 | for (DeviceId targetSw : swViaMap.keySet()) { | 318 | for (DeviceId targetSw : swViaMap.keySet()) { |
300 | DeviceId destSw = sw.id(); | 319 | DeviceId destSw = sw.id(); |
320 | + if (log.isTraceEnabled()) { | ||
321 | + log.trace("TargetSwitch {} --> RootSwitch {}", targetSw, destSw); | ||
322 | + for (ArrayList<DeviceId> via : swViaMap.get(targetSw)) { | ||
323 | + log.trace(" Via:"); | ||
324 | + via.forEach(e -> { log.trace(" {}", e); }); | ||
325 | + } | ||
326 | + } | ||
301 | Set<ArrayList<DeviceId>> subLinks = | 327 | Set<ArrayList<DeviceId>> subLinks = |
302 | computeLinks(targetSw, destSw, swViaMap); | 328 | computeLinks(targetSw, destSw, swViaMap); |
303 | for (ArrayList<DeviceId> alink: subLinks) { | 329 | for (ArrayList<DeviceId> alink: subLinks) { |
... | @@ -327,20 +353,18 @@ public class DefaultRoutingHandler { | ... | @@ -327,20 +353,18 @@ public class DefaultRoutingHandler { |
327 | Set<ArrayList<DeviceId>> routes = new HashSet<>(); | 353 | Set<ArrayList<DeviceId>> routes = new HashSet<>(); |
328 | 354 | ||
329 | for (Device sw : srManager.deviceService.getDevices()) { | 355 | for (Device sw : srManager.deviceService.getDevices()) { |
330 | - log.debug("Computing the impacted routes for device {}", | 356 | + log.debug("Computing the impacted routes for device {}", sw.id()); |
331 | - sw.id()); | ||
332 | if (!srManager.mastershipService.isLocalMaster(sw.id())) { | 357 | if (!srManager.mastershipService.isLocalMaster(sw.id())) { |
333 | - log.debug("No mastership for {} and skip route optimization", | 358 | + log.debug("No mastership for {} ... skipping route optimization", |
334 | sw.id()); | 359 | sw.id()); |
335 | continue; | 360 | continue; |
336 | } | 361 | } |
337 | - | 362 | + if (log.isTraceEnabled()) { |
338 | log.trace("link of {} - ", sw.id()); | 363 | log.trace("link of {} - ", sw.id()); |
339 | for (Link link: srManager.linkService.getDeviceLinks(sw.id())) { | 364 | for (Link link: srManager.linkService.getDeviceLinks(sw.id())) { |
340 | log.trace("{} -> {} ", link.src().deviceId(), link.dst().deviceId()); | 365 | log.trace("{} -> {} ", link.src().deviceId(), link.dst().deviceId()); |
341 | } | 366 | } |
342 | - | 367 | + } |
343 | - log.debug("Checking route change for switch {}", sw.id()); | ||
344 | EcmpShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); | 368 | EcmpShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); |
345 | if (ecmpSpg == null) { | 369 | if (ecmpSpg == null) { |
346 | log.debug("No existing ECMP graph for device {}", sw.id()); | 370 | log.debug("No existing ECMP graph for device {}", sw.id()); |
... | @@ -363,7 +387,7 @@ public class DefaultRoutingHandler { | ... | @@ -363,7 +387,7 @@ public class DefaultRoutingHandler { |
363 | ArrayList<ArrayList<DeviceId>> viaUpdated = swViaMapUpdated.get(srcSw); | 387 | ArrayList<ArrayList<DeviceId>> viaUpdated = swViaMapUpdated.get(srcSw); |
364 | ArrayList<ArrayList<DeviceId>> via = getVia(switchVia, srcSw); | 388 | ArrayList<ArrayList<DeviceId>> via = getVia(switchVia, srcSw); |
365 | if ((via == null) || !viaUpdated.equals(via)) { | 389 | if ((via == null) || !viaUpdated.equals(via)) { |
366 | - log.debug("Impacted route:{}->{}", srcSw, sw.id()); | 390 | + log.debug("Impacted route:{} -> {}", srcSw, sw.id()); |
367 | ArrayList<DeviceId> route = new ArrayList<>(); | 391 | ArrayList<DeviceId> route = new ArrayList<>(); |
368 | route.add(srcSw); | 392 | route.add(srcSw); |
369 | route.add(sw.id()); | 393 | route.add(sw.id()); |
... | @@ -373,15 +397,16 @@ public class DefaultRoutingHandler { | ... | @@ -373,15 +397,16 @@ public class DefaultRoutingHandler { |
373 | } | 397 | } |
374 | } | 398 | } |
375 | 399 | ||
400 | + if (log.isTraceEnabled()) { | ||
376 | for (ArrayList<DeviceId> link: routes) { | 401 | for (ArrayList<DeviceId> link: routes) { |
377 | log.trace("Route changes - "); | 402 | log.trace("Route changes - "); |
378 | if (link.size() == 1) { | 403 | if (link.size() == 1) { |
379 | - log.trace(" : {} - all", link.get(0)); | 404 | + log.trace(" : all -> {}", link.get(0)); |
380 | } else { | 405 | } else { |
381 | - log.trace(" : {} - {}", link.get(0), link.get(1)); | 406 | + log.trace(" : {} -> {}", link.get(0), link.get(1)); |
407 | + } | ||
382 | } | 408 | } |
383 | } | 409 | } |
384 | - | ||
385 | return routes; | 410 | return routes; |
386 | } | 411 | } |
387 | 412 | ... | ... |
... | @@ -718,6 +718,17 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -718,6 +718,17 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
718 | } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) { | 718 | } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) { |
719 | processPortRemoved((Device) event.subject(), | 719 | processPortRemoved((Device) event.subject(), |
720 | ((DeviceEvent) event).port()); | 720 | ((DeviceEvent) event).port()); |
721 | + } else if (event.type() == DeviceEvent.Type.PORT_ADDED || | ||
722 | + event.type() == DeviceEvent.Type.PORT_UPDATED) { | ||
723 | + log.info("** PORT ADDED OR UPDATED {}/{} -> {}", | ||
724 | + (Device) event.subject(), | ||
725 | + ((DeviceEvent) event).port(), | ||
726 | + event.type()); | ||
727 | + /* XXX create method for single port filtering rules | ||
728 | + if (defaultRoutingHandler != null) { | ||
729 | + defaultRoutingHandler.populatePortAddressingRules( | ||
730 | + ((Device) event.subject()).id()); | ||
731 | + }*/ | ||
721 | } else { | 732 | } else { |
722 | log.warn("Unhandled event type: {}", event.type()); | 733 | log.warn("Unhandled event type: {}", event.type()); |
723 | } | 734 | } |
... | @@ -730,7 +741,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -730,7 +741,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
730 | } | 741 | } |
731 | 742 | ||
732 | private void processLinkAdded(Link link) { | 743 | private void processLinkAdded(Link link) { |
733 | - log.debug("A new link {} was added", link.toString()); | 744 | + log.info("** LINK ADDED {}", link.toString()); |
734 | if (!deviceConfiguration.isConfigured(link.src().deviceId())) { | 745 | if (!deviceConfiguration.isConfigured(link.src().deviceId())) { |
735 | log.warn("Source device of this link is not configured."); | 746 | log.warn("Source device of this link is not configured."); |
736 | return; | 747 | return; |
... | @@ -767,7 +778,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -767,7 +778,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
767 | } | 778 | } |
768 | 779 | ||
769 | private void processLinkRemoved(Link link) { | 780 | private void processLinkRemoved(Link link) { |
770 | - log.debug("A link {} was removed", link.toString()); | 781 | + log.info("** LINK REMOVED {}", link.toString()); |
771 | DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId()); | 782 | DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId()); |
772 | if (groupHandler != null) { | 783 | if (groupHandler != null) { |
773 | groupHandler.portDown(link.src().port(), | 784 | groupHandler.portDown(link.src().port(), |
... | @@ -782,7 +793,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -782,7 +793,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
782 | } | 793 | } |
783 | 794 | ||
784 | private void processDeviceAdded(Device device) { | 795 | private void processDeviceAdded(Device device) { |
785 | - log.debug("A new device with ID {} was added", device.id()); | 796 | + log.info("** DEVICE ADDED with ID {}", device.id()); |
786 | if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) { | 797 | if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) { |
787 | log.warn("Device configuration uploading. Device {} will be " | 798 | log.warn("Device configuration uploading. Device {} will be " |
788 | + "processed after config completes.", device.id()); | 799 | + "processed after config completes.", device.id()); |
... | @@ -816,12 +827,13 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -816,12 +827,13 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
816 | log.debug("updating groupHandlerMap with new config for device: {}", | 827 | log.debug("updating groupHandlerMap with new config for device: {}", |
817 | deviceId); | 828 | deviceId); |
818 | groupHandlerMap.put(deviceId, groupHandler); | 829 | groupHandlerMap.put(deviceId, groupHandler); |
830 | + } | ||
819 | // Also, in some cases, drivers may need extra | 831 | // Also, in some cases, drivers may need extra |
820 | // information to process rules (eg. Router IP/MAC); and so, we send | 832 | // information to process rules (eg. Router IP/MAC); and so, we send |
821 | // port addressing rules to the driver as well irrespective of whether | 833 | // port addressing rules to the driver as well irrespective of whether |
822 | // this instance is the master or not. | 834 | // this instance is the master or not. |
823 | defaultRoutingHandler.populatePortAddressingRules(deviceId); | 835 | defaultRoutingHandler.populatePortAddressingRules(deviceId); |
824 | - } | 836 | + |
825 | if (mastershipService.isLocalMaster(deviceId)) { | 837 | if (mastershipService.isLocalMaster(deviceId)) { |
826 | hostHandler.readInitialHosts(deviceId); | 838 | hostHandler.readInitialHosts(deviceId); |
827 | DefaultGroupHandler groupHandler = groupHandlerMap.get(deviceId); | 839 | DefaultGroupHandler groupHandler = groupHandlerMap.get(deviceId); |
... | @@ -866,7 +878,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -866,7 +878,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
866 | } | 878 | } |
867 | 879 | ||
868 | private void processPortRemoved(Device device, Port port) { | 880 | private void processPortRemoved(Device device, Port port) { |
869 | - log.debug("Port {} was removed", port.toString()); | 881 | + log.info("Port {} was removed", port.toString()); |
870 | DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); | 882 | DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); |
871 | if (groupHandler != null) { | 883 | if (groupHandler != null) { |
872 | groupHandler.portDown(port.number(), | 884 | groupHandler.portDown(port.number(), | ... | ... |
... | @@ -23,6 +23,8 @@ import org.onosproject.net.flowobjective.FlowObjectiveService; | ... | @@ -23,6 +23,8 @@ import org.onosproject.net.flowobjective.FlowObjectiveService; |
23 | import org.onosproject.net.flowobjective.ForwardingObjective; | 23 | import org.onosproject.net.flowobjective.ForwardingObjective; |
24 | import org.onosproject.net.flowobjective.NextObjective; | 24 | import org.onosproject.net.flowobjective.NextObjective; |
25 | 25 | ||
26 | +import com.google.common.collect.ImmutableList; | ||
27 | + | ||
26 | /** | 28 | /** |
27 | * Testing version of implementation on FlowObjectiveService. | 29 | * Testing version of implementation on FlowObjectiveService. |
28 | */ | 30 | */ |
... | @@ -60,6 +62,11 @@ public class FlowObjectiveAdapter implements FlowObjectiveService { | ... | @@ -60,6 +62,11 @@ public class FlowObjectiveAdapter implements FlowObjectiveService { |
60 | 62 | ||
61 | @Override | 63 | @Override |
62 | public List<String> getNextMappings() { | 64 | public List<String> getNextMappings() { |
63 | - return null; | 65 | + return ImmutableList.of(); |
66 | + } | ||
67 | + | ||
68 | + @Override | ||
69 | + public List<String> getPendingNexts() { | ||
70 | + return ImmutableList.of(); | ||
64 | } | 71 | } |
65 | } | 72 | } | ... | ... |
... | @@ -16,30 +16,30 @@ | ... | @@ -16,30 +16,30 @@ |
16 | package org.onosproject.cli.net; | 16 | package org.onosproject.cli.net; |
17 | 17 | ||
18 | import java.util.List; | 18 | import java.util.List; |
19 | +import org.onlab.osgi.ServiceNotFoundException; | ||
19 | 20 | ||
20 | -//import org.apache.karaf.shell.commands.Argument; | ||
21 | import org.apache.karaf.shell.commands.Command; | 21 | import org.apache.karaf.shell.commands.Command; |
22 | import org.onosproject.cli.AbstractShellCommand; | 22 | import org.onosproject.cli.AbstractShellCommand; |
23 | import org.onosproject.net.flowobjective.FlowObjectiveService; | 23 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
24 | 24 | ||
25 | /** | 25 | /** |
26 | * Returns a mapping of FlowObjective next-ids to the groups that get created | 26 | * Returns a mapping of FlowObjective next-ids to the groups that get created |
27 | - * by a device driver. | 27 | + * by a device driver. These mappings are controller instance specific. |
28 | */ | 28 | */ |
29 | -@Command(scope = "onos", name = "next-ids", | 29 | +@Command(scope = "onos", name = "obj-next-ids", |
30 | - description = "flow-objective next-ids to group-ids mapping") | 30 | + description = "flow-objectives next-ids to group-ids mapping") |
31 | public class FlowObjectiveNextListCommand extends AbstractShellCommand { | 31 | public class FlowObjectiveNextListCommand extends AbstractShellCommand { |
32 | 32 | ||
33 | - /*@Argument(index = 1, name = "uri", description = "Device ID", | 33 | + private static final String FORMAT_MAPPING = " %s"; |
34 | - required = false, multiValued = false) | 34 | + |
35 | - String uri = null; | ||
36 | - */ | ||
37 | - private static final String FORMAT_MAPPING = | ||
38 | - " %s"; | ||
39 | @Override | 35 | @Override |
40 | protected void execute() { | 36 | protected void execute() { |
37 | + try { | ||
41 | FlowObjectiveService service = get(FlowObjectiveService.class); | 38 | FlowObjectiveService service = get(FlowObjectiveService.class); |
42 | printNexts(service.getNextMappings()); | 39 | printNexts(service.getNextMappings()); |
40 | + } catch (ServiceNotFoundException e) { | ||
41 | + print(FORMAT_MAPPING, "FlowObjectiveService unavailable"); | ||
42 | + } | ||
43 | } | 43 | } |
44 | 44 | ||
45 | private void printNexts(List<String> nextGroupMappings) { | 45 | private void printNexts(List<String> nextGroupMappings) { | ... | ... |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.cli.net; | ||
17 | + | ||
18 | +import java.util.List; | ||
19 | + | ||
20 | +import org.apache.karaf.shell.commands.Command; | ||
21 | +import org.onlab.osgi.ServiceNotFoundException; | ||
22 | +import org.onosproject.cli.AbstractShellCommand; | ||
23 | +import org.onosproject.net.flowobjective.FlowObjectiveService; | ||
24 | + | ||
25 | +/** | ||
26 | + * Returns a list of FlowObjective next-ids waiting to get created by device-drivers. | ||
27 | + * Also returns the forwarding objectives waiting on the pending next-objectives. | ||
28 | + * These lists are controller instance specific. | ||
29 | + */ | ||
30 | +@Command(scope = "onos", name = "obj-pending-nexts", | ||
31 | + description = "flow-objectives pending next-objectives") | ||
32 | +public class FlowObjectivePendingNextCommand extends AbstractShellCommand { | ||
33 | + | ||
34 | + private static final String FORMAT_MAPPING = " %s"; | ||
35 | + | ||
36 | + @Override | ||
37 | + protected void execute() { | ||
38 | + try { | ||
39 | + FlowObjectiveService service = get(FlowObjectiveService.class); | ||
40 | + printNexts(service.getPendingNexts()); | ||
41 | + } catch (ServiceNotFoundException e) { | ||
42 | + print(FORMAT_MAPPING, "FlowObjectiveService unavailable"); | ||
43 | + } | ||
44 | + } | ||
45 | + | ||
46 | + private void printNexts(List<String> pendingNexts) { | ||
47 | + pendingNexts.forEach(str -> print(FORMAT_MAPPING, str)); | ||
48 | + } | ||
49 | + | ||
50 | +} |
... | @@ -31,6 +31,10 @@ | ... | @@ -31,6 +31,10 @@ |
31 | </command> | 31 | </command> |
32 | 32 | ||
33 | <command> | 33 | <command> |
34 | + <action class="org.onosproject.cli.net.FlowObjectivePendingNextCommand"/> | ||
35 | + </command> | ||
36 | + | ||
37 | + <command> | ||
34 | <action class="org.onosproject.cli.net.FlowObjectiveCompositionCommand"/> | 38 | <action class="org.onosproject.cli.net.FlowObjectiveCompositionCommand"/> |
35 | </command> | 39 | </command> |
36 | 40 | ... | ... |
... | @@ -95,7 +95,18 @@ public interface FlowObjectiveService { | ... | @@ -95,7 +95,18 @@ public interface FlowObjectiveService { |
95 | * | 95 | * |
96 | * @return a list of strings preformatted by the device-drivers to provide | 96 | * @return a list of strings preformatted by the device-drivers to provide |
97 | * information on next-id to group-id mapping. Consumed by the | 97 | * information on next-id to group-id mapping. Consumed by the |
98 | - * "next-ids" command on the CLI. | 98 | + * "obj-next-ids" command on the CLI. |
99 | */ | 99 | */ |
100 | List<String> getNextMappings(); | 100 | List<String> getNextMappings(); |
101 | + | ||
102 | + /** | ||
103 | + * Retrieve all nextObjectives that are waiting to hear back from device | ||
104 | + * drivers, and the forwarding-objectives that are waiting on the | ||
105 | + * successful completion of the next-objectives. Consumed by the | ||
106 | + * "obj-pending-nexts" command on the CLI. | ||
107 | + * | ||
108 | + * @return a list of strings preformatted to provide information on the | ||
109 | + * next-ids awaiting confirmation from the device-drivers. | ||
110 | + */ | ||
111 | + List<String> getPendingNexts(); | ||
101 | } | 112 | } | ... | ... |
... | @@ -482,4 +482,21 @@ public class FlowObjectiveManager implements FlowObjectiveService { | ... | @@ -482,4 +482,21 @@ public class FlowObjectiveManager implements FlowObjectiveService { |
482 | } | 482 | } |
483 | return mappings; | 483 | return mappings; |
484 | } | 484 | } |
485 | + | ||
486 | + @Override | ||
487 | + public List<String> getPendingNexts() { | ||
488 | + List<String> pendingNexts = new ArrayList<>(); | ||
489 | + for (Integer nextId : pendingForwards.keySet()) { | ||
490 | + Set<PendingNext> pnext = pendingForwards.get(nextId); | ||
491 | + StringBuffer pend = new StringBuffer(); | ||
492 | + pend.append("Next Id: ").append(Integer.toString(nextId)) | ||
493 | + .append(" :: "); | ||
494 | + for (PendingNext pn : pnext) { | ||
495 | + pend.append(Integer.toString(pn.forwardingObjective().id())) | ||
496 | + .append(" "); | ||
497 | + } | ||
498 | + pendingNexts.add(pend.toString()); | ||
499 | + } | ||
500 | + return pendingNexts; | ||
501 | + } | ||
485 | } | 502 | } | ... | ... |
... | @@ -15,6 +15,7 @@ | ... | @@ -15,6 +15,7 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.flowobjective.impl.composition; | 16 | package org.onosproject.net.flowobjective.impl.composition; |
17 | 17 | ||
18 | +import com.google.common.collect.ImmutableList; | ||
18 | import com.google.common.collect.Maps; | 19 | import com.google.common.collect.Maps; |
19 | import com.google.common.collect.Sets; | 20 | import com.google.common.collect.Sets; |
20 | import org.apache.felix.scr.annotations.Activate; | 21 | import org.apache.felix.scr.annotations.Activate; |
... | @@ -440,6 +441,12 @@ public class FlowObjectiveCompositionManager implements FlowObjectiveService { | ... | @@ -440,6 +441,12 @@ public class FlowObjectiveCompositionManager implements FlowObjectiveService { |
440 | @Override | 441 | @Override |
441 | public List<String> getNextMappings() { | 442 | public List<String> getNextMappings() { |
442 | // TODO Implementation deferred as this is an experimental component. | 443 | // TODO Implementation deferred as this is an experimental component. |
443 | - return null; | 444 | + return ImmutableList.of(); |
445 | + } | ||
446 | + | ||
447 | + @Override | ||
448 | + public List<String> getPendingNexts() { | ||
449 | + // TODO Implementation deferred as this is an experimental component. | ||
450 | + return ImmutableList.of(); | ||
444 | } | 451 | } |
445 | } | 452 | } | ... | ... |
... | @@ -1083,7 +1083,7 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -1083,7 +1083,7 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
1083 | } | 1083 | } |
1084 | // add port information for last group in group-chain | 1084 | // add port information for last group in group-chain |
1085 | List<Instruction> lastGroupIns = new ArrayList<Instruction>(); | 1085 | List<Instruction> lastGroupIns = new ArrayList<Instruction>(); |
1086 | - if (gchain != null) { | 1086 | + if (lastGroup != null) { |
1087 | lastGroupIns = lastGroup.buckets().buckets().get(0) | 1087 | lastGroupIns = lastGroup.buckets().buckets().get(0) |
1088 | .treatment().allInstructions(); | 1088 | .treatment().allInstructions(); |
1089 | } | 1089 | } | ... | ... |
-
Please register or login to post a comment