ONOS-1823 and ONOS-1838:Segment Routing Multi-instance Support-1
Change-Id: I3cc848415a609a9c4001d135e51104c62fb2830d
Showing
18 changed files
with
867 additions
and
324 deletions
... | @@ -89,14 +89,18 @@ public class DefaultRoutingHandler { | ... | @@ -89,14 +89,18 @@ public class DefaultRoutingHandler { |
89 | populationStatus = Status.STARTED; | 89 | populationStatus = Status.STARTED; |
90 | rulePopulator.resetCounter(); | 90 | rulePopulator.resetCounter(); |
91 | log.info("Starts to populate routing rules"); | 91 | log.info("Starts to populate routing rules"); |
92 | + log.debug("populateAllRoutingRules: populationStatus is STARTED"); | ||
92 | 93 | ||
93 | for (Device sw : srManager.deviceService.getDevices()) { | 94 | for (Device sw : srManager.deviceService.getDevices()) { |
94 | if (srManager.mastershipService.getLocalRole(sw.id()) != MastershipRole.MASTER) { | 95 | if (srManager.mastershipService.getLocalRole(sw.id()) != MastershipRole.MASTER) { |
96 | + log.debug("populateAllRoutingRules: skipping device {}...we are not master", | ||
97 | + sw.id()); | ||
95 | continue; | 98 | continue; |
96 | } | 99 | } |
97 | 100 | ||
98 | ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(sw.id(), srManager); | 101 | ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(sw.id(), srManager); |
99 | if (!populateEcmpRoutingRules(sw.id(), ecmpSpg)) { | 102 | if (!populateEcmpRoutingRules(sw.id(), ecmpSpg)) { |
103 | + log.debug("populateAllRoutingRules: populationStatus is ABORTED"); | ||
100 | populationStatus = Status.ABORTED; | 104 | populationStatus = Status.ABORTED; |
101 | log.debug("Abort routing rule population"); | 105 | log.debug("Abort routing rule population"); |
102 | return false; | 106 | return false; |
... | @@ -106,6 +110,7 @@ public class DefaultRoutingHandler { | ... | @@ -106,6 +110,7 @@ public class DefaultRoutingHandler { |
106 | // TODO: Set adjacency routing rule for all switches | 110 | // TODO: Set adjacency routing rule for all switches |
107 | } | 111 | } |
108 | 112 | ||
113 | + log.debug("populateAllRoutingRules: populationStatus is SUCCEEDED"); | ||
109 | populationStatus = Status.SUCCEEDED; | 114 | populationStatus = Status.SUCCEEDED; |
110 | log.info("Completes routing rule population. Total # of rules pushed : {}", | 115 | log.info("Completes routing rule population. Total # of rules pushed : {}", |
111 | rulePopulator.getCounter()); | 116 | rulePopulator.getCounter()); |
... | @@ -144,6 +149,8 @@ public class DefaultRoutingHandler { | ... | @@ -144,6 +149,8 @@ public class DefaultRoutingHandler { |
144 | log.info("Starts rule population from link change"); | 149 | log.info("Starts rule population from link change"); |
145 | 150 | ||
146 | Set<ArrayList<DeviceId>> routeChanges; | 151 | Set<ArrayList<DeviceId>> routeChanges; |
152 | + log.trace("populateRoutingRulesForLinkStatusChange: " | ||
153 | + + "populationStatus is STARTED"); | ||
147 | populationStatus = Status.STARTED; | 154 | populationStatus = Status.STARTED; |
148 | if (linkFail == null) { | 155 | if (linkFail == null) { |
149 | // Compare all routes of existing ECMP SPG with the new ones | 156 | // Compare all routes of existing ECMP SPG with the new ones |
... | @@ -155,16 +162,19 @@ public class DefaultRoutingHandler { | ... | @@ -155,16 +162,19 @@ public class DefaultRoutingHandler { |
155 | 162 | ||
156 | if (routeChanges.isEmpty()) { | 163 | if (routeChanges.isEmpty()) { |
157 | log.info("No route changes for the link status change"); | 164 | log.info("No route changes for the link status change"); |
165 | + log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is SUCCEEDED"); | ||
158 | populationStatus = Status.SUCCEEDED; | 166 | populationStatus = Status.SUCCEEDED; |
159 | return true; | 167 | return true; |
160 | } | 168 | } |
161 | 169 | ||
162 | if (repopulateRoutingRulesForRoutes(routeChanges)) { | 170 | if (repopulateRoutingRulesForRoutes(routeChanges)) { |
171 | + log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is SUCCEEDED"); | ||
163 | populationStatus = Status.SUCCEEDED; | 172 | populationStatus = Status.SUCCEEDED; |
164 | log.info("Complete to repopulate the rules. # of rules populated : {}", | 173 | log.info("Complete to repopulate the rules. # of rules populated : {}", |
165 | rulePopulator.getCounter()); | 174 | rulePopulator.getCounter()); |
166 | return true; | 175 | return true; |
167 | } else { | 176 | } else { |
177 | + log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is ABORTED"); | ||
168 | populationStatus = Status.ABORTED; | 178 | populationStatus = Status.ABORTED; |
169 | log.warn("Failed to repopulate the rules."); | 179 | log.warn("Failed to repopulate the rules."); |
170 | return false; | 180 | return false; |
... | @@ -177,6 +187,7 @@ public class DefaultRoutingHandler { | ... | @@ -177,6 +187,7 @@ public class DefaultRoutingHandler { |
177 | for (ArrayList<DeviceId> link: routes) { | 187 | for (ArrayList<DeviceId> link: routes) { |
178 | // When only the source device is defined, reinstall routes to all other devices | 188 | // When only the source device is defined, reinstall routes to all other devices |
179 | if (link.size() == 1) { | 189 | if (link.size() == 1) { |
190 | + log.trace("repopulateRoutingRulesForRoutes: running ECMP graph for device {}", link.get(0)); | ||
180 | ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(link.get(0), srManager); | 191 | ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(link.get(0), srManager); |
181 | if (populateEcmpRoutingRules(link.get(0), ecmpSpg)) { | 192 | if (populateEcmpRoutingRules(link.get(0), ecmpSpg)) { |
182 | currentEcmpSpgMap.put(link.get(0), ecmpSpg); | 193 | currentEcmpSpgMap.put(link.get(0), ecmpSpg); |
... | @@ -187,8 +198,7 @@ public class DefaultRoutingHandler { | ... | @@ -187,8 +198,7 @@ public class DefaultRoutingHandler { |
187 | } else { | 198 | } else { |
188 | DeviceId src = link.get(0); | 199 | DeviceId src = link.get(0); |
189 | DeviceId dst = link.get(1); | 200 | DeviceId dst = link.get(1); |
190 | - log.trace("repopulateRoutingRulesForRoutes: running ECMP graph " | 201 | + log.trace("repopulateRoutingRulesForRoutes: running ECMP graph for device {}", dst); |
191 | - + "for device {}", dst); | ||
192 | ECMPShortestPathGraph ecmpSpg = updatedEcmpSpgMap.get(dst); | 202 | ECMPShortestPathGraph ecmpSpg = updatedEcmpSpgMap.get(dst); |
193 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = | 203 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = |
194 | ecmpSpg.getAllLearnedSwitchesAndVia(); | 204 | ecmpSpg.getAllLearnedSwitchesAndVia(); |
... | @@ -278,14 +288,12 @@ public class DefaultRoutingHandler { | ... | @@ -278,14 +288,12 @@ public class DefaultRoutingHandler { |
278 | log.debug("Checking route change for switch {}", sw.id()); | 288 | log.debug("Checking route change for switch {}", sw.id()); |
279 | ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); | 289 | ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); |
280 | if (ecmpSpg == null) { | 290 | if (ecmpSpg == null) { |
281 | - log.debug("No existing ECMP path for Switch {}", sw.id()); | 291 | + log.debug("No existing ECMP graph for device {}", sw.id()); |
282 | ArrayList<DeviceId> route = new ArrayList<>(); | 292 | ArrayList<DeviceId> route = new ArrayList<>(); |
283 | route.add(sw.id()); | 293 | route.add(sw.id()); |
284 | routes.add(route); | 294 | routes.add(route); |
285 | continue; | 295 | continue; |
286 | } | 296 | } |
287 | - log.debug("computeRouteChange: running ECMP graph " | ||
288 | - + "for device {}", sw.id()); | ||
289 | ECMPShortestPathGraph newEcmpSpg = updatedEcmpSpgMap.get(sw.id()); | 297 | ECMPShortestPathGraph newEcmpSpg = updatedEcmpSpgMap.get(sw.id()); |
290 | currentEcmpSpgMap.put(sw.id(), newEcmpSpg); | 298 | currentEcmpSpgMap.put(sw.id(), newEcmpSpg); |
291 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = | 299 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = |
... | @@ -400,6 +408,8 @@ public class DefaultRoutingHandler { | ... | @@ -400,6 +408,8 @@ public class DefaultRoutingHandler { |
400 | // rule for both subnet and router IP. | 408 | // rule for both subnet and router IP. |
401 | if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) { | 409 | if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) { |
402 | List<Ip4Prefix> subnets = config.getSubnets(destSw); | 410 | List<Ip4Prefix> subnets = config.getSubnets(destSw); |
411 | + log.debug("populateEcmpRoutingRulePartial in device {} towards {} for subnets {}", | ||
412 | + targetSw, destSw, subnets); | ||
403 | result = rulePopulator.populateIpRuleForSubnet(targetSw, | 413 | result = rulePopulator.populateIpRuleForSubnet(targetSw, |
404 | subnets, | 414 | subnets, |
405 | destSw, | 415 | destSw, |
... | @@ -410,6 +420,8 @@ public class DefaultRoutingHandler { | ... | @@ -410,6 +420,8 @@ public class DefaultRoutingHandler { |
410 | 420 | ||
411 | Ip4Address routerIp = config.getRouterIp(destSw); | 421 | Ip4Address routerIp = config.getRouterIp(destSw); |
412 | IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); | 422 | IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); |
423 | + log.debug("populateEcmpRoutingRulePartial in device {} towards {} for router IP {}", | ||
424 | + targetSw, destSw, routerIpPrefix); | ||
413 | result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix, destSw, nextHops); | 425 | result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix, destSw, nextHops); |
414 | if (!result) { | 426 | if (!result) { |
415 | return false; | 427 | return false; |
... | @@ -419,6 +431,8 @@ public class DefaultRoutingHandler { | ... | @@ -419,6 +431,8 @@ public class DefaultRoutingHandler { |
419 | } else if (config.isEdgeDevice(targetSw)) { | 431 | } else if (config.isEdgeDevice(targetSw)) { |
420 | Ip4Address routerIp = config.getRouterIp(destSw); | 432 | Ip4Address routerIp = config.getRouterIp(destSw); |
421 | IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); | 433 | IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); |
434 | + log.debug("populateEcmpRoutingRulePartial in device {} towards {} for router IP {}", | ||
435 | + targetSw, destSw, routerIpPrefix); | ||
422 | result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix, destSw, nextHops); | 436 | result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix, destSw, nextHops); |
423 | if (!result) { | 437 | if (!result) { |
424 | return false; | 438 | return false; |
... | @@ -426,6 +440,8 @@ public class DefaultRoutingHandler { | ... | @@ -426,6 +440,8 @@ public class DefaultRoutingHandler { |
426 | } | 440 | } |
427 | 441 | ||
428 | // Populates MPLS rules to all routers | 442 | // Populates MPLS rules to all routers |
443 | + log.debug("populateEcmpRoutingRulePartial in device{} towards {} for all MPLS rules", | ||
444 | + targetSw, destSw); | ||
429 | result = rulePopulator.populateMplsRule(targetSw, destSw, nextHops); | 445 | result = rulePopulator.populateMplsRule(targetSw, destSw, nextHops); |
430 | if (!result) { | 446 | if (!result) { |
431 | return false; | 447 | return false; |
... | @@ -453,9 +469,13 @@ public class DefaultRoutingHandler { | ... | @@ -453,9 +469,13 @@ public class DefaultRoutingHandler { |
453 | public void startPopulationProcess() { | 469 | public void startPopulationProcess() { |
454 | synchronized (populationStatus) { | 470 | synchronized (populationStatus) { |
455 | if (populationStatus == Status.IDLE | 471 | if (populationStatus == Status.IDLE |
456 | - || populationStatus == Status.SUCCEEDED) { | 472 | + || populationStatus == Status.SUCCEEDED |
473 | + || populationStatus == Status.ABORTED) { | ||
457 | populationStatus = Status.STARTED; | 474 | populationStatus = Status.STARTED; |
458 | populateAllRoutingRules(); | 475 | populateAllRoutingRules(); |
476 | + } else { | ||
477 | + log.warn("Not initiating startPopulationProcess as populationStatus is {}", | ||
478 | + populationStatus); | ||
459 | } | 479 | } |
460 | } | 480 | } |
461 | } | 481 | } | ... | ... |
... | @@ -99,6 +99,9 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -99,6 +99,9 @@ public class DeviceConfiguration implements DeviceProperties { |
99 | deviceConfigMap.get(deviceId).nodeSid); | 99 | deviceConfigMap.get(deviceId).nodeSid); |
100 | return deviceConfigMap.get(deviceId).nodeSid; | 100 | return deviceConfigMap.get(deviceId).nodeSid; |
101 | } else { | 101 | } else { |
102 | + log.warn("getSegmentId for device {} " | ||
103 | + + "throwing IllegalStateException " | ||
104 | + + "because device does not exist in config", deviceId); | ||
102 | throw new IllegalStateException(); | 105 | throw new IllegalStateException(); |
103 | } | 106 | } |
104 | } | 107 | } |
... | @@ -151,6 +154,9 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -151,6 +154,9 @@ public class DeviceConfiguration implements DeviceProperties { |
151 | deviceConfigMap.get(deviceId).mac); | 154 | deviceConfigMap.get(deviceId).mac); |
152 | return deviceConfigMap.get(deviceId).mac; | 155 | return deviceConfigMap.get(deviceId).mac; |
153 | } else { | 156 | } else { |
157 | + log.warn("getDeviceMac for device {} " | ||
158 | + + "throwing IllegalStateException " | ||
159 | + + "because device does not exist in config", deviceId); | ||
154 | throw new IllegalStateException(); | 160 | throw new IllegalStateException(); |
155 | } | 161 | } |
156 | } | 162 | } |
... | @@ -168,6 +174,9 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -168,6 +174,9 @@ public class DeviceConfiguration implements DeviceProperties { |
168 | deviceConfigMap.get(deviceId).ip); | 174 | deviceConfigMap.get(deviceId).ip); |
169 | return deviceConfigMap.get(deviceId).ip; | 175 | return deviceConfigMap.get(deviceId).ip; |
170 | } else { | 176 | } else { |
177 | + log.warn("getRouterIp for device {} " | ||
178 | + + "throwing IllegalStateException " | ||
179 | + + "because device does not exist in config", deviceId); | ||
171 | throw new IllegalStateException(); | 180 | throw new IllegalStateException(); |
172 | } | 181 | } |
173 | } | 182 | } |
... | @@ -187,6 +196,9 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -187,6 +196,9 @@ public class DeviceConfiguration implements DeviceProperties { |
187 | deviceConfigMap.get(deviceId).isEdge); | 196 | deviceConfigMap.get(deviceId).isEdge); |
188 | return deviceConfigMap.get(deviceId).isEdge; | 197 | return deviceConfigMap.get(deviceId).isEdge; |
189 | } else { | 198 | } else { |
199 | + log.warn("isEdgeDevice for device {} " | ||
200 | + + "throwing IllegalStateException " | ||
201 | + + "because device does not exist in config", deviceId); | ||
190 | throw new IllegalStateException(); | 202 | throw new IllegalStateException(); |
191 | } | 203 | } |
192 | } | 204 | } | ... | ... |
... | @@ -217,6 +217,11 @@ public class RoutingRulePopulator { | ... | @@ -217,6 +217,11 @@ public class RoutingRulePopulator { |
217 | 217 | ||
218 | // If the next hop is the destination router, do PHP | 218 | // If the next hop is the destination router, do PHP |
219 | if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) { | 219 | if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) { |
220 | + log.debug("populateMplsRule: Installing MPLS forwarding objective for " | ||
221 | + + "label {} in switch {} with PHP", | ||
222 | + config.getSegmentId(destSwId), | ||
223 | + deviceId); | ||
224 | + | ||
220 | ForwardingObjective.Builder fwdObjBosBuilder = | 225 | ForwardingObjective.Builder fwdObjBosBuilder = |
221 | getMplsForwardingObjective(deviceId, | 226 | getMplsForwardingObjective(deviceId, |
222 | destSwId, | 227 | destSwId, |
... | @@ -237,6 +242,11 @@ public class RoutingRulePopulator { | ... | @@ -237,6 +242,11 @@ public class RoutingRulePopulator { |
237 | return false; | 242 | return false; |
238 | } | 243 | } |
239 | } else { | 244 | } else { |
245 | + log.debug("Installing MPLS forwarding objective for " | ||
246 | + + "label {} in switch {} without PHP", | ||
247 | + config.getSegmentId(destSwId), | ||
248 | + deviceId); | ||
249 | + | ||
240 | ForwardingObjective.Builder fwdObjBosBuilder = | 250 | ForwardingObjective.Builder fwdObjBosBuilder = |
241 | getMplsForwardingObjective(deviceId, | 251 | getMplsForwardingObjective(deviceId, |
242 | destSwId, | 252 | destSwId, |
... | @@ -264,8 +274,6 @@ public class RoutingRulePopulator { | ... | @@ -264,8 +274,6 @@ public class RoutingRulePopulator { |
264 | .makePermanent()).withSelector(selector) | 274 | .makePermanent()).withSelector(selector) |
265 | .withPriority(100)) | 275 | .withPriority(100)) |
266 | .withFlag(ForwardingObjective.Flag.SPECIFIC); | 276 | .withFlag(ForwardingObjective.Flag.SPECIFIC); |
267 | - log.debug("Installing MPLS forwarding objective in switch {}", | ||
268 | - deviceId); | ||
269 | srManager.flowObjectiveService.forward(deviceId, | 277 | srManager.flowObjectiveService.forward(deviceId, |
270 | fwdObjBuilder.add()); | 278 | fwdObjBuilder.add()); |
271 | rulePopulationCounter.incrementAndGet(); | 279 | rulePopulationCounter.incrementAndGet(); | ... | ... |
... | @@ -22,23 +22,22 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -22,23 +22,22 @@ import org.apache.felix.scr.annotations.Reference; |
22 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 22 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
23 | import org.onlab.packet.Ethernet; | 23 | import org.onlab.packet.Ethernet; |
24 | import org.onlab.packet.IPv4; | 24 | import org.onlab.packet.IPv4; |
25 | +import org.onlab.util.KryoNamespace; | ||
25 | import org.onosproject.core.ApplicationId; | 26 | import org.onosproject.core.ApplicationId; |
26 | import org.onosproject.core.CoreService; | 27 | import org.onosproject.core.CoreService; |
27 | import org.onosproject.event.Event; | 28 | import org.onosproject.event.Event; |
28 | import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler; | 29 | import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler; |
29 | import org.onosproject.segmentrouting.grouphandler.NeighborSet; | 30 | import org.onosproject.segmentrouting.grouphandler.NeighborSet; |
31 | +import org.onosproject.segmentrouting.grouphandler.NeighborSetNextObjectiveStoreKey; | ||
30 | import org.onosproject.mastership.MastershipService; | 32 | import org.onosproject.mastership.MastershipService; |
31 | import org.onosproject.net.Device; | 33 | import org.onosproject.net.Device; |
32 | import org.onosproject.net.DeviceId; | 34 | import org.onosproject.net.DeviceId; |
33 | import org.onosproject.net.Link; | 35 | import org.onosproject.net.Link; |
34 | -import org.onosproject.net.MastershipRole; | ||
35 | import org.onosproject.net.Port; | 36 | import org.onosproject.net.Port; |
36 | import org.onosproject.net.device.DeviceEvent; | 37 | import org.onosproject.net.device.DeviceEvent; |
37 | import org.onosproject.net.device.DeviceListener; | 38 | import org.onosproject.net.device.DeviceListener; |
38 | import org.onosproject.net.device.DeviceService; | 39 | import org.onosproject.net.device.DeviceService; |
39 | import org.onosproject.net.flowobjective.FlowObjectiveService; | 40 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
40 | -import org.onosproject.net.group.Group; | ||
41 | -import org.onosproject.net.group.GroupEvent; | ||
42 | import org.onosproject.net.group.GroupKey; | 41 | import org.onosproject.net.group.GroupKey; |
43 | import org.onosproject.net.host.HostService; | 42 | import org.onosproject.net.host.HostService; |
44 | import org.onosproject.net.intent.IntentService; | 43 | import org.onosproject.net.intent.IntentService; |
... | @@ -51,9 +50,16 @@ import org.onosproject.net.packet.PacketProcessor; | ... | @@ -51,9 +50,16 @@ import org.onosproject.net.packet.PacketProcessor; |
51 | import org.onosproject.net.packet.PacketService; | 50 | import org.onosproject.net.packet.PacketService; |
52 | import org.onosproject.net.topology.TopologyService; | 51 | import org.onosproject.net.topology.TopologyService; |
53 | import org.onosproject.segmentrouting.config.NetworkConfigManager; | 52 | import org.onosproject.segmentrouting.config.NetworkConfigManager; |
53 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
54 | +import org.onosproject.store.service.EventuallyConsistentMapBuilder; | ||
55 | +import org.onosproject.store.service.StorageService; | ||
56 | +import org.onosproject.store.service.WallClockTimestamp; | ||
57 | +import org.onosproject.store.service.WallclockClockManager; | ||
54 | import org.slf4j.Logger; | 58 | import org.slf4j.Logger; |
55 | import org.slf4j.LoggerFactory; | 59 | import org.slf4j.LoggerFactory; |
56 | 60 | ||
61 | +import java.net.URI; | ||
62 | +import java.util.HashSet; | ||
57 | import java.util.Map; | 63 | import java.util.Map; |
58 | import java.util.concurrent.ConcurrentHashMap; | 64 | import java.util.concurrent.ConcurrentHashMap; |
59 | import java.util.concurrent.ConcurrentLinkedQueue; | 65 | import java.util.concurrent.ConcurrentLinkedQueue; |
... | @@ -112,6 +118,11 @@ public class SegmentRoutingManager { | ... | @@ -112,6 +118,11 @@ public class SegmentRoutingManager { |
112 | private static ScheduledFuture<?> eventHandlerFuture = null; | 118 | private static ScheduledFuture<?> eventHandlerFuture = null; |
113 | private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>(); | 119 | private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>(); |
114 | private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>(); | 120 | private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>(); |
121 | + // Per device next objective ID store with (device id + neighbor set) as key | ||
122 | + private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, | ||
123 | + Integer> nsNextObjStore = null; | ||
124 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
125 | + protected StorageService storageService; | ||
115 | 126 | ||
116 | private NetworkConfigManager networkConfigService = new NetworkConfigManager();; | 127 | private NetworkConfigManager networkConfigService = new NetworkConfigManager();; |
117 | 128 | ||
... | @@ -119,10 +130,34 @@ public class SegmentRoutingManager { | ... | @@ -119,10 +130,34 @@ public class SegmentRoutingManager { |
119 | private static int numOfHandlerExecution = 0; | 130 | private static int numOfHandlerExecution = 0; |
120 | private static int numOfHandlerScheduled = 0; | 131 | private static int numOfHandlerScheduled = 0; |
121 | 132 | ||
133 | + private KryoNamespace.Builder kryoBuilder = null; | ||
134 | + | ||
122 | @Activate | 135 | @Activate |
123 | protected void activate() { | 136 | protected void activate() { |
124 | appId = coreService | 137 | appId = coreService |
125 | .registerApplication("org.onosproject.segmentrouting"); | 138 | .registerApplication("org.onosproject.segmentrouting"); |
139 | + | ||
140 | + kryoBuilder = new KryoNamespace.Builder() | ||
141 | + .register(NeighborSetNextObjectiveStoreKey.class, | ||
142 | + NeighborSet.class, | ||
143 | + DeviceId.class, | ||
144 | + URI.class, | ||
145 | + WallClockTimestamp.class, | ||
146 | + org.onosproject.cluster.NodeId.class, | ||
147 | + HashSet.class | ||
148 | + ); | ||
149 | + | ||
150 | + log.debug("Creating EC map nsnextobjectivestore"); | ||
151 | + EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer> | ||
152 | + nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder(); | ||
153 | + | ||
154 | + nsNextObjStore = nsNextObjMapBuilder | ||
155 | + .withName("nsnextobjectivestore") | ||
156 | + .withSerializer(kryoBuilder) | ||
157 | + .withClockService(new WallclockClockManager<>()) | ||
158 | + .build(); | ||
159 | + log.trace("Current size {}", nsNextObjStore.size()); | ||
160 | + | ||
126 | networkConfigService.init(); | 161 | networkConfigService.init(); |
127 | deviceConfiguration = new DeviceConfiguration(networkConfigService); | 162 | deviceConfiguration = new DeviceConfiguration(networkConfigService); |
128 | arpHandler = new ArpHandler(this); | 163 | arpHandler = new ArpHandler(this); |
... | @@ -136,20 +171,18 @@ public class SegmentRoutingManager { | ... | @@ -136,20 +171,18 @@ public class SegmentRoutingManager { |
136 | deviceService.addListener(new InternalDeviceListener()); | 171 | deviceService.addListener(new InternalDeviceListener()); |
137 | 172 | ||
138 | for (Device device : deviceService.getDevices()) { | 173 | for (Device device : deviceService.getDevices()) { |
139 | - if (mastershipService.getLocalRole(device.id()) == MastershipRole.MASTER) { | 174 | + //Irrespective whether the local is a MASTER or not for this device, |
175 | + //create group handler instance and push default TTP flow rules. | ||
176 | + //Because in a multi-instance setup, instances can initiate | ||
177 | + //groups for any devices. Also the default TTP rules are needed | ||
178 | + //to be pushed before inserting any IP table entries for any device | ||
140 | DefaultGroupHandler groupHandler = DefaultGroupHandler | 179 | DefaultGroupHandler groupHandler = DefaultGroupHandler |
141 | .createGroupHandler(device.id(), appId, | 180 | .createGroupHandler(device.id(), appId, |
142 | deviceConfiguration, linkService, | 181 | deviceConfiguration, linkService, |
143 | - flowObjectiveService); | 182 | + flowObjectiveService, |
183 | + nsNextObjStore); | ||
144 | groupHandlerMap.put(device.id(), groupHandler); | 184 | groupHandlerMap.put(device.id(), groupHandler); |
145 | defaultRoutingHandler.populateTtpRules(device.id()); | 185 | defaultRoutingHandler.populateTtpRules(device.id()); |
146 | - log.debug("Initiating default group handling for {}", device.id()); | ||
147 | - } else { | ||
148 | - log.debug("Activate: Local role {} " | ||
149 | - + "is not MASTER for device {}", | ||
150 | - mastershipService.getLocalRole(device.id()), | ||
151 | - device.id()); | ||
152 | - } | ||
153 | } | 186 | } |
154 | 187 | ||
155 | defaultRoutingHandler.startPopulationProcess(); | 188 | defaultRoutingHandler.startPopulationProcess(); |
... | @@ -180,8 +213,14 @@ public class SegmentRoutingManager { | ... | @@ -180,8 +213,14 @@ public class SegmentRoutingManager { |
180 | 213 | ||
181 | public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) { | 214 | public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) { |
182 | 215 | ||
183 | - return (groupHandlerMap.get(deviceId) != null) ? groupHandlerMap | 216 | + if (groupHandlerMap.get(deviceId) != null) { |
184 | - .get(deviceId).getNextObjectiveId(ns) : -1; | 217 | + log.trace("getNextObjectiveId query in device {}", deviceId); |
218 | + return groupHandlerMap | ||
219 | + .get(deviceId).getNextObjectiveId(ns); | ||
220 | + } else { | ||
221 | + log.warn("getNextObjectiveId query in device {} not found", deviceId); | ||
222 | + return -1; | ||
223 | + } | ||
185 | } | 224 | } |
186 | 225 | ||
187 | private class InternalPacketProcessor implements PacketProcessor { | 226 | private class InternalPacketProcessor implements PacketProcessor { |
... | @@ -224,12 +263,12 @@ public class SegmentRoutingManager { | ... | @@ -224,12 +263,12 @@ public class SegmentRoutingManager { |
224 | 263 | ||
225 | @Override | 264 | @Override |
226 | public void event(DeviceEvent event) { | 265 | public void event(DeviceEvent event) { |
227 | - if (mastershipService.getLocalRole(event.subject().id()) != MastershipRole.MASTER) { | 266 | + /*if (mastershipService.getLocalRole(event.subject().id()) != MastershipRole.MASTER) { |
228 | log.debug("Local role {} is not MASTER for device {}", | 267 | log.debug("Local role {} is not MASTER for device {}", |
229 | mastershipService.getLocalRole(event.subject().id()), | 268 | mastershipService.getLocalRole(event.subject().id()), |
230 | event.subject().id()); | 269 | event.subject().id()); |
231 | return; | 270 | return; |
232 | - } | 271 | + }*/ |
233 | 272 | ||
234 | switch (event.type()) { | 273 | switch (event.type()) { |
235 | case DEVICE_ADDED: | 274 | case DEVICE_ADDED: |
... | @@ -245,6 +284,7 @@ public class SegmentRoutingManager { | ... | @@ -245,6 +284,7 @@ public class SegmentRoutingManager { |
245 | 284 | ||
246 | private void scheduleEventHandlerIfNotScheduled(Event event) { | 285 | private void scheduleEventHandlerIfNotScheduled(Event event) { |
247 | 286 | ||
287 | + synchronized (eventQueue) { | ||
248 | eventQueue.add(event); | 288 | eventQueue.add(event); |
249 | numOfEvents++; | 289 | numOfEvents++; |
250 | if (eventHandlerFuture == null || eventHandlerFuture.isDone()) { | 290 | if (eventHandlerFuture == null || eventHandlerFuture.isDone()) { |
... | @@ -252,6 +292,7 @@ public class SegmentRoutingManager { | ... | @@ -252,6 +292,7 @@ public class SegmentRoutingManager { |
252 | .schedule(eventHandler, 100, TimeUnit.MILLISECONDS); | 292 | .schedule(eventHandler, 100, TimeUnit.MILLISECONDS); |
253 | numOfHandlerScheduled++; | 293 | numOfHandlerScheduled++; |
254 | } | 294 | } |
295 | + } | ||
255 | 296 | ||
256 | log.trace("numOfEvents {}, numOfEventHanlderScheduled {}", numOfEvents, | 297 | log.trace("numOfEvents {}, numOfEventHanlderScheduled {}", numOfEvents, |
257 | numOfHandlerScheduled); | 298 | numOfHandlerScheduled); |
... | @@ -262,6 +303,8 @@ public class SegmentRoutingManager { | ... | @@ -262,6 +303,8 @@ public class SegmentRoutingManager { |
262 | 303 | ||
263 | @Override | 304 | @Override |
264 | public void run() { | 305 | public void run() { |
306 | + try { | ||
307 | + synchronized (eventQueue) { | ||
265 | numOfHandlerExecution++; | 308 | numOfHandlerExecution++; |
266 | while (!eventQueue.isEmpty()) { | 309 | while (!eventQueue.isEmpty()) { |
267 | Event event = eventQueue.poll(); | 310 | Event event = eventQueue.poll(); |
... | @@ -269,8 +312,8 @@ public class SegmentRoutingManager { | ... | @@ -269,8 +312,8 @@ public class SegmentRoutingManager { |
269 | processLinkAdded((Link) event.subject()); | 312 | processLinkAdded((Link) event.subject()); |
270 | } else if (event.type() == LinkEvent.Type.LINK_REMOVED) { | 313 | } else if (event.type() == LinkEvent.Type.LINK_REMOVED) { |
271 | processLinkRemoved((Link) event.subject()); | 314 | processLinkRemoved((Link) event.subject()); |
272 | - } else if (event.type() == GroupEvent.Type.GROUP_ADDED) { | 315 | + //} else if (event.type() == GroupEvent.Type.GROUP_ADDED) { |
273 | - processGroupAdded((Group) event.subject()); | 316 | + // processGroupAdded((Group) event.subject()); |
274 | } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED || | 317 | } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED || |
275 | event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED || | 318 | event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED || |
276 | event.type() == DeviceEvent.Type.DEVICE_UPDATED) { | 319 | event.type() == DeviceEvent.Type.DEVICE_UPDATED) { |
... | @@ -284,22 +327,44 @@ public class SegmentRoutingManager { | ... | @@ -284,22 +327,44 @@ public class SegmentRoutingManager { |
284 | log.warn("Unhandled event type: {}", event.type()); | 327 | log.warn("Unhandled event type: {}", event.type()); |
285 | } | 328 | } |
286 | } | 329 | } |
330 | + } | ||
287 | log.debug("numOfHandlerExecution {} numOfEventHanlderScheduled {} numOfEvents {}", | 331 | log.debug("numOfHandlerExecution {} numOfEventHanlderScheduled {} numOfEvents {}", |
288 | numOfHandlerExecution, numOfHandlerScheduled, numOfEvents); | 332 | numOfHandlerExecution, numOfHandlerScheduled, numOfEvents); |
333 | + } catch (Exception e) { | ||
334 | + log.error("SegmentRouting event handler " | ||
335 | + + "thread thrown an exception: {}", e); | ||
336 | + } | ||
289 | } | 337 | } |
290 | } | 338 | } |
291 | 339 | ||
292 | private void processLinkAdded(Link link) { | 340 | private void processLinkAdded(Link link) { |
293 | log.debug("A new link {} was added", link.toString()); | 341 | log.debug("A new link {} was added", link.toString()); |
294 | 342 | ||
295 | - if (mastershipService.getLocalRole(link.src().deviceId()) == MastershipRole.MASTER) { | 343 | + //Irrespective whether the local is a MASTER or not for this device, |
344 | + //create group handler instance and push default TTP flow rules. | ||
345 | + //Because in a multi-instance setup, instances can initiate | ||
346 | + //groups for any devices. Also the default TTP rules are needed | ||
347 | + //to be pushed before inserting any IP table entries for any device | ||
296 | DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src() | 348 | DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src() |
297 | .deviceId()); | 349 | .deviceId()); |
298 | if (groupHandler != null) { | 350 | if (groupHandler != null) { |
299 | groupHandler.linkUp(link); | 351 | groupHandler.linkUp(link); |
352 | + } else { | ||
353 | + Device device = deviceService.getDevice(link.src().deviceId()); | ||
354 | + if (device != null) { | ||
355 | + log.warn("processLinkAdded: Link Added " | ||
356 | + + "Notification without Device Added " | ||
357 | + + "event, still handling it"); | ||
358 | + processDeviceAdded(device); | ||
359 | + groupHandler = groupHandlerMap.get(link.src() | ||
360 | + .deviceId()); | ||
361 | + groupHandler.linkUp(link); | ||
300 | } | 362 | } |
301 | } | 363 | } |
302 | - defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null); | 364 | + |
365 | + //defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null); | ||
366 | + log.trace("processLinkAdded: re-starting route population process"); | ||
367 | + defaultRoutingHandler.startPopulationProcess(); | ||
303 | } | 368 | } |
304 | 369 | ||
305 | private void processLinkRemoved(Link link) { | 370 | private void processLinkRemoved(Link link) { |
... | @@ -308,20 +373,27 @@ public class SegmentRoutingManager { | ... | @@ -308,20 +373,27 @@ public class SegmentRoutingManager { |
308 | if (groupHandler != null) { | 373 | if (groupHandler != null) { |
309 | groupHandler.portDown(link.src().port()); | 374 | groupHandler.portDown(link.src().port()); |
310 | } | 375 | } |
311 | - defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link); | 376 | + //defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link); |
312 | - } | 377 | + log.trace("processLinkRemoved: re-starting route population process"); |
313 | - | 378 | + defaultRoutingHandler.startPopulationProcess(); |
314 | - private void processGroupAdded(Group group) { | ||
315 | - log.debug("A new group with ID {} was added", group.id()); | ||
316 | - defaultRoutingHandler.resumePopulationProcess(); | ||
317 | } | 379 | } |
318 | 380 | ||
319 | private void processDeviceAdded(Device device) { | 381 | private void processDeviceAdded(Device device) { |
320 | log.debug("A new device with ID {} was added", device.id()); | 382 | log.debug("A new device with ID {} was added", device.id()); |
321 | - defaultRoutingHandler.populateTtpRules(device.id()); | 383 | + //Irrespective whether the local is a MASTER or not for this device, |
322 | - DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler(device | 384 | + //create group handler instance and push default TTP flow rules. |
323 | - .id(), appId, deviceConfiguration, linkService, flowObjectiveService); | 385 | + //Because in a multi-instance setup, instances can initiate |
386 | + //groups for any devices. Also the default TTP rules are needed | ||
387 | + //to be pushed before inserting any IP table entries for any device | ||
388 | + DefaultGroupHandler dgh = DefaultGroupHandler. | ||
389 | + createGroupHandler(device.id(), | ||
390 | + appId, | ||
391 | + deviceConfiguration, | ||
392 | + linkService, | ||
393 | + flowObjectiveService, | ||
394 | + nsNextObjStore); | ||
324 | groupHandlerMap.put(device.id(), dgh); | 395 | groupHandlerMap.put(device.id(), dgh); |
396 | + defaultRoutingHandler.populateTtpRules(device.id()); | ||
325 | } | 397 | } |
326 | 398 | ||
327 | private void processPortRemoved(Device device, Port port) { | 399 | private void processPortRemoved(Device device, Port port) { | ... | ... |
... | @@ -19,16 +19,12 @@ import java.util.HashSet; | ... | @@ -19,16 +19,12 @@ import java.util.HashSet; |
19 | import java.util.List; | 19 | import java.util.List; |
20 | import java.util.Set; | 20 | import java.util.Set; |
21 | 21 | ||
22 | -import org.onlab.packet.MplsLabel; | ||
23 | import org.onosproject.core.ApplicationId; | 22 | import org.onosproject.core.ApplicationId; |
24 | import org.onosproject.net.DeviceId; | 23 | import org.onosproject.net.DeviceId; |
25 | import org.onosproject.net.Link; | 24 | import org.onosproject.net.Link; |
26 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
27 | -import org.onosproject.net.flow.TrafficTreatment; | ||
28 | -import org.onosproject.net.flowobjective.DefaultNextObjective; | ||
29 | import org.onosproject.net.flowobjective.FlowObjectiveService; | 25 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
30 | -import org.onosproject.net.flowobjective.NextObjective; | ||
31 | import org.onosproject.net.link.LinkService; | 26 | import org.onosproject.net.link.LinkService; |
27 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
32 | 28 | ||
33 | /** | 29 | /** |
34 | * Default ECMP group handler creation module for an edge device. | 30 | * Default ECMP group handler creation module for an edge device. |
... | @@ -53,8 +49,11 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { | ... | @@ -53,8 +49,11 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { |
53 | ApplicationId appId, | 49 | ApplicationId appId, |
54 | DeviceProperties config, | 50 | DeviceProperties config, |
55 | LinkService linkService, | 51 | LinkService linkService, |
56 | - FlowObjectiveService flowObjService) { | 52 | + FlowObjectiveService flowObjService, |
57 | - super(deviceId, appId, config, linkService, flowObjService); | 53 | + EventuallyConsistentMap< |
54 | + NeighborSetNextObjectiveStoreKey, | ||
55 | + Integer> nsNextObjStore) { | ||
56 | + super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore); | ||
58 | } | 57 | } |
59 | 58 | ||
60 | @Override | 59 | @Override |
... | @@ -108,7 +107,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { | ... | @@ -108,7 +107,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { |
108 | 107 | ||
109 | @Override | 108 | @Override |
110 | protected void newPortToExistingNeighbor(Link newNeighborLink) { | 109 | protected void newPortToExistingNeighbor(Link newNeighborLink) { |
111 | - log.debug("New port to existing neighbor: Updating " | 110 | + /*log.debug("New port to existing neighbor: Updating " |
112 | + "groups for edge device {}", deviceId); | 111 | + "groups for edge device {}", deviceId); |
113 | addNeighborAtPort(newNeighborLink.dst().deviceId(), | 112 | addNeighborAtPort(newNeighborLink.dst().deviceId(), |
114 | newNeighborLink.src().port()); | 113 | newNeighborLink.src().port()); |
... | @@ -129,7 +128,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { | ... | @@ -129,7 +128,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { |
129 | mplsLabel(ns.getEdgeLabel())); | 128 | mplsLabel(ns.getEdgeLabel())); |
130 | } | 129 | } |
131 | 130 | ||
132 | - Integer nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); | 131 | + Integer nextId = deviceNextObjectiveIds.get(ns); |
133 | if (nextId != null) { | 132 | if (nextId != null) { |
134 | NextObjective.Builder nextObjBuilder = DefaultNextObjective | 133 | NextObjective.Builder nextObjBuilder = DefaultNextObjective |
135 | .builder().withId(nextId) | 134 | .builder().withId(nextId) |
... | @@ -140,7 +139,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { | ... | @@ -140,7 +139,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { |
140 | NextObjective nextObjective = nextObjBuilder.add(); | 139 | NextObjective nextObjective = nextObjBuilder.add(); |
141 | flowObjectiveService.next(deviceId, nextObjective); | 140 | flowObjectiveService.next(deviceId, nextObjective); |
142 | } | 141 | } |
143 | - } | 142 | + }*/ |
144 | } | 143 | } |
145 | 144 | ||
146 | @Override | 145 | @Override | ... | ... |
... | @@ -26,6 +26,7 @@ import java.util.HashSet; | ... | @@ -26,6 +26,7 @@ import java.util.HashSet; |
26 | import java.util.List; | 26 | import java.util.List; |
27 | import java.util.Random; | 27 | import java.util.Random; |
28 | import java.util.Set; | 28 | import java.util.Set; |
29 | +import java.util.stream.Collectors; | ||
29 | 30 | ||
30 | import org.onlab.packet.MacAddress; | 31 | import org.onlab.packet.MacAddress; |
31 | import org.onlab.packet.MplsLabel; | 32 | import org.onlab.packet.MplsLabel; |
... | @@ -42,6 +43,7 @@ import org.onosproject.net.flowobjective.NextObjective; | ... | @@ -42,6 +43,7 @@ import org.onosproject.net.flowobjective.NextObjective; |
42 | import org.onosproject.net.group.DefaultGroupKey; | 43 | import org.onosproject.net.group.DefaultGroupKey; |
43 | import org.onosproject.net.group.GroupKey; | 44 | import org.onosproject.net.group.GroupKey; |
44 | import org.onosproject.net.link.LinkService; | 45 | import org.onosproject.net.link.LinkService; |
46 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
45 | import org.slf4j.Logger; | 47 | import org.slf4j.Logger; |
46 | 48 | ||
47 | /** | 49 | /** |
... | @@ -66,8 +68,10 @@ public class DefaultGroupHandler { | ... | @@ -66,8 +68,10 @@ public class DefaultGroupHandler { |
66 | new HashMap<DeviceId, Set<PortNumber>>(); | 68 | new HashMap<DeviceId, Set<PortNumber>>(); |
67 | protected HashMap<PortNumber, DeviceId> portDeviceMap = | 69 | protected HashMap<PortNumber, DeviceId> portDeviceMap = |
68 | new HashMap<PortNumber, DeviceId>(); | 70 | new HashMap<PortNumber, DeviceId>(); |
69 | - protected HashMap<GroupKey, Integer> deviceNextObjectiveIds = | 71 | + //protected HashMap<NeighborSet, Integer> deviceNextObjectiveIds = |
70 | - new HashMap<GroupKey, Integer>(); | 72 | + // new HashMap<NeighborSet, Integer>(); |
73 | + protected EventuallyConsistentMap< | ||
74 | + NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null; | ||
71 | protected Random rand = new Random(); | 75 | protected Random rand = new Random(); |
72 | 76 | ||
73 | protected KryoNamespace.Builder kryo = new KryoNamespace.Builder() | 77 | protected KryoNamespace.Builder kryo = new KryoNamespace.Builder() |
... | @@ -81,7 +85,10 @@ public class DefaultGroupHandler { | ... | @@ -81,7 +85,10 @@ public class DefaultGroupHandler { |
81 | protected DefaultGroupHandler(DeviceId deviceId, ApplicationId appId, | 85 | protected DefaultGroupHandler(DeviceId deviceId, ApplicationId appId, |
82 | DeviceProperties config, | 86 | DeviceProperties config, |
83 | LinkService linkService, | 87 | LinkService linkService, |
84 | - FlowObjectiveService flowObjService) { | 88 | + FlowObjectiveService flowObjService, |
89 | + EventuallyConsistentMap< | ||
90 | + NeighborSetNextObjectiveStoreKey, | ||
91 | + Integer> nsNextObjStore) { | ||
85 | this.deviceId = checkNotNull(deviceId); | 92 | this.deviceId = checkNotNull(deviceId); |
86 | this.appId = checkNotNull(appId); | 93 | this.appId = checkNotNull(appId); |
87 | this.deviceConfig = checkNotNull(config); | 94 | this.deviceConfig = checkNotNull(config); |
... | @@ -91,6 +98,7 @@ public class DefaultGroupHandler { | ... | @@ -91,6 +98,7 @@ public class DefaultGroupHandler { |
91 | isEdgeRouter = config.isEdgeDevice(deviceId); | 98 | isEdgeRouter = config.isEdgeDevice(deviceId); |
92 | nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId)); | 99 | nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId)); |
93 | this.flowObjectiveService = flowObjService; | 100 | this.flowObjectiveService = flowObjService; |
101 | + this.nsNextObjStore = nsNextObjStore; | ||
94 | 102 | ||
95 | populateNeighborMaps(); | 103 | populateNeighborMaps(); |
96 | } | 104 | } |
... | @@ -111,13 +119,20 @@ public class DefaultGroupHandler { | ... | @@ -111,13 +119,20 @@ public class DefaultGroupHandler { |
111 | ApplicationId appId, | 119 | ApplicationId appId, |
112 | DeviceProperties config, | 120 | DeviceProperties config, |
113 | LinkService linkService, | 121 | LinkService linkService, |
114 | - FlowObjectiveService flowObjService) { | 122 | + FlowObjectiveService flowObjService, |
123 | + EventuallyConsistentMap< | ||
124 | + NeighborSetNextObjectiveStoreKey, | ||
125 | + Integer> nsNextObjStore) { | ||
115 | if (config.isEdgeDevice(deviceId)) { | 126 | if (config.isEdgeDevice(deviceId)) { |
116 | return new DefaultEdgeGroupHandler(deviceId, appId, config, | 127 | return new DefaultEdgeGroupHandler(deviceId, appId, config, |
117 | - linkService, flowObjService); | 128 | + linkService, |
129 | + flowObjService, | ||
130 | + nsNextObjStore); | ||
118 | } else { | 131 | } else { |
119 | return new DefaultTransitGroupHandler(deviceId, appId, config, | 132 | return new DefaultTransitGroupHandler(deviceId, appId, config, |
120 | - linkService, flowObjService); | 133 | + linkService, |
134 | + flowObjService, | ||
135 | + nsNextObjStore); | ||
121 | } | 136 | } |
122 | } | 137 | } |
123 | 138 | ||
... | @@ -150,12 +165,56 @@ public class DefaultGroupHandler { | ... | @@ -150,12 +165,56 @@ public class DefaultGroupHandler { |
150 | 165 | ||
151 | log.debug("Device {} linkUp at local port {} to neighbor {}", deviceId, | 166 | log.debug("Device {} linkUp at local port {} to neighbor {}", deviceId, |
152 | newLink.src().port(), newLink.dst().deviceId()); | 167 | newLink.src().port(), newLink.dst().deviceId()); |
153 | - if (devicePortMap.get(newLink.dst().deviceId()) == null) { | 168 | + addNeighborAtPort(newLink.dst().deviceId(), |
169 | + newLink.src().port()); | ||
170 | + /*if (devicePortMap.get(newLink.dst().deviceId()) == null) { | ||
154 | // New Neighbor | 171 | // New Neighbor |
155 | newNeighbor(newLink); | 172 | newNeighbor(newLink); |
156 | } else { | 173 | } else { |
157 | // Old Neighbor | 174 | // Old Neighbor |
158 | newPortToExistingNeighbor(newLink); | 175 | newPortToExistingNeighbor(newLink); |
176 | + }*/ | ||
177 | + Set<NeighborSet> nsSet = nsNextObjStore.keySet() | ||
178 | + .stream() | ||
179 | + .filter((nsStoreEntry) -> (nsStoreEntry.deviceId().equals(deviceId))) | ||
180 | + .map((nsStoreEntry) -> (nsStoreEntry.neighborSet())) | ||
181 | + .filter((ns) -> (ns.getDeviceIds() | ||
182 | + .contains(newLink.dst().deviceId()))) | ||
183 | + .collect(Collectors.toSet()); | ||
184 | + log.trace("linkUp: nsNextObjStore contents for device {}:", | ||
185 | + deviceId, | ||
186 | + nsSet); | ||
187 | + for (NeighborSet ns : nsSet) { | ||
188 | + // Create the new bucket to be updated | ||
189 | + TrafficTreatment.Builder tBuilder = | ||
190 | + DefaultTrafficTreatment.builder(); | ||
191 | + tBuilder.setOutput(newLink.src().port()) | ||
192 | + .setEthDst(deviceConfig.getDeviceMac( | ||
193 | + newLink.dst().deviceId())) | ||
194 | + .setEthSrc(nodeMacAddr); | ||
195 | + if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { | ||
196 | + tBuilder.pushMpls() | ||
197 | + .setMpls(MplsLabel. | ||
198 | + mplsLabel(ns.getEdgeLabel())); | ||
199 | + } | ||
200 | + | ||
201 | + Integer nextId = nsNextObjStore. | ||
202 | + get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); | ||
203 | + if (nextId != null) { | ||
204 | + NextObjective.Builder nextObjBuilder = DefaultNextObjective | ||
205 | + .builder().withId(nextId) | ||
206 | + .withType(NextObjective.Type.HASHED).fromApp(appId); | ||
207 | + | ||
208 | + nextObjBuilder.addTreatment(tBuilder.build()); | ||
209 | + | ||
210 | + log.debug("linkUp in device {}: Adding Bucket " | ||
211 | + + "with Port {} to next object id {}", | ||
212 | + deviceId, | ||
213 | + newLink.src().port(), | ||
214 | + nextId); | ||
215 | + NextObjective nextObjective = nextObjBuilder.add(); | ||
216 | + flowObjectiveService.next(deviceId, nextObjective); | ||
217 | + } | ||
159 | } | 218 | } |
160 | } | 219 | } |
161 | 220 | ||
... | @@ -171,10 +230,20 @@ public class DefaultGroupHandler { | ... | @@ -171,10 +230,20 @@ public class DefaultGroupHandler { |
171 | } | 230 | } |
172 | log.debug("Device {} portDown {} to neighbor {}", deviceId, port, | 231 | log.debug("Device {} portDown {} to neighbor {}", deviceId, port, |
173 | portDeviceMap.get(port)); | 232 | portDeviceMap.get(port)); |
174 | - Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(portDeviceMap | 233 | + /*Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(portDeviceMap |
175 | .get(port), | 234 | .get(port), |
176 | devicePortMap | 235 | devicePortMap |
177 | - .keySet()); | 236 | + .keySet());*/ |
237 | + Set<NeighborSet> nsSet = nsNextObjStore.keySet() | ||
238 | + .stream() | ||
239 | + .filter((nsStoreEntry) -> (nsStoreEntry.deviceId().equals(deviceId))) | ||
240 | + .map((nsStoreEntry) -> (nsStoreEntry.neighborSet())) | ||
241 | + .filter((ns) -> (ns.getDeviceIds() | ||
242 | + .contains(portDeviceMap.get(port)))) | ||
243 | + .collect(Collectors.toSet()); | ||
244 | + log.trace("portDown: nsNextObjStore contents for device {}:", | ||
245 | + deviceId, | ||
246 | + nsSet); | ||
178 | for (NeighborSet ns : nsSet) { | 247 | for (NeighborSet ns : nsSet) { |
179 | // Create the bucket to be removed | 248 | // Create the bucket to be removed |
180 | TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment | 249 | TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment |
... | @@ -187,13 +256,19 @@ public class DefaultGroupHandler { | ... | @@ -187,13 +256,19 @@ public class DefaultGroupHandler { |
187 | .getEdgeLabel())); | 256 | .getEdgeLabel())); |
188 | } | 257 | } |
189 | 258 | ||
190 | - Integer nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); | 259 | + Integer nextId = nsNextObjStore. |
260 | + get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); | ||
191 | if (nextId != null) { | 261 | if (nextId != null) { |
192 | NextObjective.Builder nextObjBuilder = DefaultNextObjective | 262 | NextObjective.Builder nextObjBuilder = DefaultNextObjective |
193 | .builder().withType(NextObjective.Type.SIMPLE).withId(nextId).fromApp(appId); | 263 | .builder().withType(NextObjective.Type.SIMPLE).withId(nextId).fromApp(appId); |
194 | 264 | ||
195 | nextObjBuilder.addTreatment(tBuilder.build()); | 265 | nextObjBuilder.addTreatment(tBuilder.build()); |
196 | 266 | ||
267 | + log.debug("portDown in device {}: Removing Bucket " | ||
268 | + + "with Port {} to next object id {}", | ||
269 | + deviceId, | ||
270 | + port, | ||
271 | + nextId); | ||
197 | NextObjective nextObjective = nextObjBuilder.remove(); | 272 | NextObjective nextObjective = nextObjBuilder.remove(); |
198 | 273 | ||
199 | flowObjectiveService.next(deviceId, nextObjective); | 274 | flowObjectiveService.next(deviceId, nextObjective); |
... | @@ -214,14 +289,31 @@ public class DefaultGroupHandler { | ... | @@ -214,14 +289,31 @@ public class DefaultGroupHandler { |
214 | * @return int if found or -1 | 289 | * @return int if found or -1 |
215 | */ | 290 | */ |
216 | public int getNextObjectiveId(NeighborSet ns) { | 291 | public int getNextObjectiveId(NeighborSet ns) { |
217 | - Integer nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); | 292 | + Integer nextId = nsNextObjStore. |
293 | + get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); | ||
218 | if (nextId == null) { | 294 | if (nextId == null) { |
295 | + log.trace("getNextObjectiveId in device{}: Next objective id " | ||
296 | + + "not found for {} and creating", deviceId, ns); | ||
297 | + log.trace("getNextObjectiveId: nsNextObjStore contents for device {}: {}", | ||
298 | + deviceId, | ||
299 | + nsNextObjStore.entrySet() | ||
300 | + .stream() | ||
301 | + .filter((nsStoreEntry) -> | ||
302 | + (nsStoreEntry.getKey().deviceId().equals(deviceId))) | ||
303 | + .collect(Collectors.toList())); | ||
219 | createGroupsFromNeighborsets(Collections.singleton(ns)); | 304 | createGroupsFromNeighborsets(Collections.singleton(ns)); |
220 | - nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); | 305 | + nextId = nsNextObjStore. |
306 | + get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); | ||
221 | if (nextId == null) { | 307 | if (nextId == null) { |
222 | log.warn("getNextObjectiveId: unable to create next objective"); | 308 | log.warn("getNextObjectiveId: unable to create next objective"); |
223 | return -1; | 309 | return -1; |
310 | + } else { | ||
311 | + log.debug("getNextObjectiveId in device{}: Next objective id {} " | ||
312 | + + "created for {}", deviceId, nextId.intValue(), ns); | ||
224 | } | 313 | } |
314 | + } else { | ||
315 | + log.trace("getNextObjectiveId in device{}: Next objective id {} " | ||
316 | + + "found for {}", deviceId, nextId.intValue(), ns); | ||
225 | } | 317 | } |
226 | return nextId.intValue(); | 318 | return nextId.intValue(); |
227 | } | 319 | } |
... | @@ -338,6 +430,10 @@ public class DefaultGroupHandler { | ... | @@ -338,6 +430,10 @@ public class DefaultGroupHandler { |
338 | if (devicePortMap.get(d) == null) { | 430 | if (devicePortMap.get(d) == null) { |
339 | log.warn("Device {} is not in the port map yet", d); | 431 | log.warn("Device {} is not in the port map yet", d); |
340 | return; | 432 | return; |
433 | + } else if (devicePortMap.get(d).size() == 0) { | ||
434 | + log.warn("There are no ports for " | ||
435 | + + "the Device {} in the port map yet", d); | ||
436 | + return; | ||
341 | } | 437 | } |
342 | 438 | ||
343 | for (PortNumber sp : devicePortMap.get(d)) { | 439 | for (PortNumber sp : devicePortMap.get(d)) { |
... | @@ -356,7 +452,11 @@ public class DefaultGroupHandler { | ... | @@ -356,7 +452,11 @@ public class DefaultGroupHandler { |
356 | 452 | ||
357 | NextObjective nextObj = nextObjBuilder.add(); | 453 | NextObjective nextObj = nextObjBuilder.add(); |
358 | flowObjectiveService.next(deviceId, nextObj); | 454 | flowObjectiveService.next(deviceId, nextObj); |
359 | - deviceNextObjectiveIds.put(getGroupKey(ns), nextId); | 455 | + log.debug("createGroupsFromNeighborsets: Submited " |
456 | + + "next objective {} in device {}", | ||
457 | + nextId, deviceId); | ||
458 | + nsNextObjStore.put(new NeighborSetNextObjectiveStoreKey(deviceId, ns), | ||
459 | + nextId); | ||
360 | } | 460 | } |
361 | } | 461 | } |
362 | 462 | ... | ... |
... | @@ -18,16 +18,12 @@ package org.onosproject.segmentrouting.grouphandler; | ... | @@ -18,16 +18,12 @@ package org.onosproject.segmentrouting.grouphandler; |
18 | import java.util.HashSet; | 18 | import java.util.HashSet; |
19 | import java.util.Set; | 19 | import java.util.Set; |
20 | 20 | ||
21 | -import org.onlab.packet.MplsLabel; | ||
22 | import org.onosproject.core.ApplicationId; | 21 | import org.onosproject.core.ApplicationId; |
23 | import org.onosproject.net.DeviceId; | 22 | import org.onosproject.net.DeviceId; |
24 | import org.onosproject.net.Link; | 23 | import org.onosproject.net.Link; |
25 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
26 | -import org.onosproject.net.flow.TrafficTreatment; | ||
27 | -import org.onosproject.net.flowobjective.DefaultNextObjective; | ||
28 | import org.onosproject.net.flowobjective.FlowObjectiveService; | 24 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
29 | -import org.onosproject.net.flowobjective.NextObjective; | ||
30 | import org.onosproject.net.link.LinkService; | 25 | import org.onosproject.net.link.LinkService; |
26 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
31 | 27 | ||
32 | /** | 28 | /** |
33 | * Default ECMP group handler creation module for a transit device. | 29 | * Default ECMP group handler creation module for a transit device. |
... | @@ -47,8 +43,11 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { | ... | @@ -47,8 +43,11 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { |
47 | ApplicationId appId, | 43 | ApplicationId appId, |
48 | DeviceProperties config, | 44 | DeviceProperties config, |
49 | LinkService linkService, | 45 | LinkService linkService, |
50 | - FlowObjectiveService flowObjService) { | 46 | + FlowObjectiveService flowObjService, |
51 | - super(deviceId, appId, config, linkService, flowObjService); | 47 | + EventuallyConsistentMap< |
48 | + NeighborSetNextObjectiveStoreKey, | ||
49 | + Integer> nsNextObjStore) { | ||
50 | + super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore); | ||
52 | } | 51 | } |
53 | 52 | ||
54 | @Override | 53 | @Override |
... | @@ -96,7 +95,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { | ... | @@ -96,7 +95,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { |
96 | 95 | ||
97 | @Override | 96 | @Override |
98 | protected void newPortToExistingNeighbor(Link newNeighborLink) { | 97 | protected void newPortToExistingNeighbor(Link newNeighborLink) { |
99 | - log.debug("New port to existing neighbor: Updating " | 98 | + /*log.debug("New port to existing neighbor: Updating " |
100 | + "groups for transit device {}", deviceId); | 99 | + "groups for transit device {}", deviceId); |
101 | addNeighborAtPort(newNeighborLink.dst().deviceId(), | 100 | addNeighborAtPort(newNeighborLink.dst().deviceId(), |
102 | newNeighborLink.src().port()); | 101 | newNeighborLink.src().port()); |
... | @@ -118,7 +117,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { | ... | @@ -118,7 +117,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { |
118 | } | 117 | } |
119 | 118 | ||
120 | 119 | ||
121 | - Integer nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); | 120 | + Integer nextId = deviceNextObjectiveIds.get(ns); |
122 | if (nextId != null) { | 121 | if (nextId != null) { |
123 | NextObjective.Builder nextObjBuilder = DefaultNextObjective | 122 | NextObjective.Builder nextObjBuilder = DefaultNextObjective |
124 | .builder().withId(nextId) | 123 | .builder().withId(nextId) |
... | @@ -129,7 +128,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { | ... | @@ -129,7 +128,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { |
129 | NextObjective nextObjective = nextObjBuilder.add(); | 128 | NextObjective nextObjective = nextObjBuilder.add(); |
130 | flowObjectiveService.next(deviceId, nextObjective); | 129 | flowObjectiveService.next(deviceId, nextObjective); |
131 | } | 130 | } |
132 | - } | 131 | + }*/ |
133 | } | 132 | } |
134 | 133 | ||
135 | @Override | 134 | @Override | ... | ... |
1 | +/* | ||
2 | + * Copyright 2015 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 | + | ||
17 | +package org.onosproject.segmentrouting.grouphandler; | ||
18 | + | ||
19 | +import java.util.Objects; | ||
20 | + | ||
21 | +import org.onosproject.net.DeviceId; | ||
22 | + | ||
23 | +/** | ||
24 | + * Class definition of Key for Neighborset to NextObjective store. | ||
25 | + */ | ||
26 | +public class NeighborSetNextObjectiveStoreKey { | ||
27 | + private final DeviceId deviceId; | ||
28 | + private final NeighborSet ns; | ||
29 | + | ||
30 | + public NeighborSetNextObjectiveStoreKey(DeviceId deviceId, | ||
31 | + NeighborSet ns) { | ||
32 | + this.deviceId = deviceId; | ||
33 | + this.ns = ns; | ||
34 | + } | ||
35 | + | ||
36 | + public DeviceId deviceId() { | ||
37 | + return this.deviceId; | ||
38 | + } | ||
39 | + | ||
40 | + public NeighborSet neighborSet() { | ||
41 | + return this.ns; | ||
42 | + } | ||
43 | + | ||
44 | + @Override | ||
45 | + public boolean equals(Object o) { | ||
46 | + if (this == o) { | ||
47 | + return true; | ||
48 | + } | ||
49 | + if (!(o instanceof NeighborSetNextObjectiveStoreKey)) { | ||
50 | + return false; | ||
51 | + } | ||
52 | + NeighborSetNextObjectiveStoreKey that = | ||
53 | + (NeighborSetNextObjectiveStoreKey) o; | ||
54 | + return (Objects.equals(this.deviceId, that.deviceId) && | ||
55 | + Objects.equals(this.ns, that.ns)); | ||
56 | + } | ||
57 | + | ||
58 | + // The list of neighbor ids and label are used for comparison. | ||
59 | + @Override | ||
60 | + public int hashCode() { | ||
61 | + int result = 17; | ||
62 | + result = 31 * result + Objects.hashCode(this.deviceId) | ||
63 | + + Objects.hashCode(this.ns); | ||
64 | + | ||
65 | + return result; | ||
66 | + } | ||
67 | + | ||
68 | + @Override | ||
69 | + public String toString() { | ||
70 | + return "Device: " + deviceId + " Neighborset: " + ns; | ||
71 | + } | ||
72 | +} |
... | @@ -27,6 +27,7 @@ import java.util.List; | ... | @@ -27,6 +27,7 @@ import java.util.List; |
27 | import org.onlab.packet.MplsLabel; | 27 | import org.onlab.packet.MplsLabel; |
28 | import org.onosproject.core.ApplicationId; | 28 | import org.onosproject.core.ApplicationId; |
29 | import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType; | 29 | import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType; |
30 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
30 | import org.onosproject.net.DeviceId; | 31 | import org.onosproject.net.DeviceId; |
31 | import org.onosproject.net.PortNumber; | 32 | import org.onosproject.net.PortNumber; |
32 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 33 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
... | @@ -58,8 +59,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler { | ... | @@ -58,8 +59,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler { |
58 | ApplicationId appId, | 59 | ApplicationId appId, |
59 | DeviceProperties config, | 60 | DeviceProperties config, |
60 | LinkService linkService, | 61 | LinkService linkService, |
61 | - FlowObjectiveService flowObjService) { | 62 | + FlowObjectiveService flowObjService, |
62 | - super(deviceId, appId, config, linkService, flowObjService); | 63 | + EventuallyConsistentMap< |
64 | + NeighborSetNextObjectiveStoreKey, | ||
65 | + Integer> nsNextObjStore) { | ||
66 | + super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore); | ||
63 | } | 67 | } |
64 | 68 | ||
65 | public PolicyGroupIdentifier createPolicyGroupChain(String id, | 69 | public PolicyGroupIdentifier createPolicyGroupChain(String id, | ... | ... |
... | @@ -15,6 +15,8 @@ | ... | @@ -15,6 +15,8 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.group; | 16 | package org.onosproject.net.group; |
17 | 17 | ||
18 | +import java.util.Collection; | ||
19 | + | ||
18 | import org.onosproject.core.GroupId; | 20 | import org.onosproject.core.GroupId; |
19 | import org.onosproject.net.DeviceId; | 21 | import org.onosproject.net.DeviceId; |
20 | import org.onosproject.store.Store; | 22 | import org.onosproject.store.Store; |
... | @@ -162,4 +164,12 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> { | ... | @@ -162,4 +164,12 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> { |
162 | * @param operation the group operation failed | 164 | * @param operation the group operation failed |
163 | */ | 165 | */ |
164 | void groupOperationFailed(DeviceId deviceId, GroupOperation operation); | 166 | void groupOperationFailed(DeviceId deviceId, GroupOperation operation); |
167 | + | ||
168 | + /** | ||
169 | + * Submits the group metrics to store for a given device ID. | ||
170 | + * | ||
171 | + * @param deviceId the device ID | ||
172 | + * @param groupEntries the group entries as received from southbound | ||
173 | + */ | ||
174 | + void pushGroupMetrics(DeviceId deviceId, Collection<Group> groupEntries); | ||
165 | } | 175 | } | ... | ... |
... | @@ -15,7 +15,11 @@ | ... | @@ -15,7 +15,11 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.group.impl; | 16 | package org.onosproject.net.group.impl; |
17 | 17 | ||
18 | -import com.google.common.collect.Sets; | 18 | +import static org.slf4j.LoggerFactory.getLogger; |
19 | + | ||
20 | +import java.util.Collection; | ||
21 | +import java.util.Collections; | ||
22 | + | ||
19 | import org.apache.felix.scr.annotations.Activate; | 23 | import org.apache.felix.scr.annotations.Activate; |
20 | import org.apache.felix.scr.annotations.Component; | 24 | import org.apache.felix.scr.annotations.Component; |
21 | import org.apache.felix.scr.annotations.Deactivate; | 25 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -48,13 +52,6 @@ import org.onosproject.net.provider.AbstractProviderRegistry; | ... | @@ -48,13 +52,6 @@ import org.onosproject.net.provider.AbstractProviderRegistry; |
48 | import org.onosproject.net.provider.AbstractProviderService; | 52 | import org.onosproject.net.provider.AbstractProviderService; |
49 | import org.slf4j.Logger; | 53 | import org.slf4j.Logger; |
50 | 54 | ||
51 | -import java.util.Collection; | ||
52 | -import java.util.Collections; | ||
53 | -import java.util.Iterator; | ||
54 | -import java.util.Set; | ||
55 | - | ||
56 | -import static org.slf4j.LoggerFactory.getLogger; | ||
57 | - | ||
58 | /** | 55 | /** |
59 | * Provides implementation of the group service APIs. | 56 | * Provides implementation of the group service APIs. |
60 | */ | 57 | */ |
... | @@ -316,131 +313,13 @@ public class GroupManager | ... | @@ -316,131 +313,13 @@ public class GroupManager |
316 | store.groupOperationFailed(deviceId, operation); | 313 | store.groupOperationFailed(deviceId, operation); |
317 | } | 314 | } |
318 | 315 | ||
319 | - private void groupMissing(Group group) { | ||
320 | - checkValidity(); | ||
321 | - GroupProvider gp = getProvider(group.deviceId()); | ||
322 | - switch (group.state()) { | ||
323 | - case PENDING_DELETE: | ||
324 | - log.debug("Group {} delete confirmation from device {}", | ||
325 | - group, group.deviceId()); | ||
326 | - store.removeGroupEntry(group); | ||
327 | - break; | ||
328 | - case ADDED: | ||
329 | - case PENDING_ADD: | ||
330 | - log.debug("Group {} is in store but not on device {}", | ||
331 | - group, group.deviceId()); | ||
332 | - GroupOperation groupAddOp = GroupOperation. | ||
333 | - createAddGroupOperation(group.id(), | ||
334 | - group.type(), | ||
335 | - group.buckets()); | ||
336 | - GroupOperations groupOps = new GroupOperations( | ||
337 | - Collections.singletonList(groupAddOp)); | ||
338 | - gp.performGroupOperation(group.deviceId(), groupOps); | ||
339 | - break; | ||
340 | - default: | ||
341 | - log.debug("Group {} has not been installed.", group); | ||
342 | - break; | ||
343 | - } | ||
344 | - } | ||
345 | - | ||
346 | - | ||
347 | - private void extraneousGroup(Group group) { | ||
348 | - log.debug("Group {} is on device {} but not in store.", | ||
349 | - group, group.deviceId()); | ||
350 | - checkValidity(); | ||
351 | - store.addOrUpdateExtraneousGroupEntry(group); | ||
352 | - } | ||
353 | - | ||
354 | - private void groupAdded(Group group) { | ||
355 | - checkValidity(); | ||
356 | - | ||
357 | - log.trace("Group {} Added or Updated in device {}", | ||
358 | - group, group.deviceId()); | ||
359 | - store.addOrUpdateGroupEntry(group); | ||
360 | - } | ||
361 | - | ||
362 | @Override | 316 | @Override |
363 | public void pushGroupMetrics(DeviceId deviceId, | 317 | public void pushGroupMetrics(DeviceId deviceId, |
364 | Collection<Group> groupEntries) { | 318 | Collection<Group> groupEntries) { |
365 | log.trace("Received group metrics from device {}", | 319 | log.trace("Received group metrics from device {}", |
366 | deviceId); | 320 | deviceId); |
367 | - boolean deviceInitialAuditStatus = | 321 | + checkValidity(); |
368 | - store.deviceInitialAuditStatus(deviceId); | 322 | + store.pushGroupMetrics(deviceId, groupEntries); |
369 | - Set<Group> southboundGroupEntries = | ||
370 | - Sets.newHashSet(groupEntries); | ||
371 | - Set<Group> storedGroupEntries = | ||
372 | - Sets.newHashSet(store.getGroups(deviceId)); | ||
373 | - Set<Group> extraneousStoredEntries = | ||
374 | - Sets.newHashSet(store.getExtraneousGroups(deviceId)); | ||
375 | - | ||
376 | - log.trace("Displaying all ({}) southboundGroupEntries for device {}", | ||
377 | - southboundGroupEntries.size(), | ||
378 | - deviceId); | ||
379 | - for (Iterator<Group> it = southboundGroupEntries.iterator(); it.hasNext();) { | ||
380 | - Group group = it.next(); | ||
381 | - log.trace("Group {} in device {}", group, deviceId); | ||
382 | - } | ||
383 | - | ||
384 | - log.trace("Displaying all ({}) stored group entries for device {}", | ||
385 | - storedGroupEntries.size(), | ||
386 | - deviceId); | ||
387 | - for (Iterator<Group> it1 = storedGroupEntries.iterator(); it1.hasNext();) { | ||
388 | - Group group = it1.next(); | ||
389 | - log.trace("Stored Group {} for device {}", group, deviceId); | ||
390 | - } | ||
391 | - | ||
392 | - for (Iterator<Group> it2 = southboundGroupEntries.iterator(); it2.hasNext();) { | ||
393 | - Group group = it2.next(); | ||
394 | - if (storedGroupEntries.remove(group)) { | ||
395 | - // we both have the group, let's update some info then. | ||
396 | - log.trace("Group AUDIT: group {} exists " | ||
397 | - + "in both planes for device {}", | ||
398 | - group.id(), deviceId); | ||
399 | - groupAdded(group); | ||
400 | - it2.remove(); | ||
401 | - } | ||
402 | - } | ||
403 | - for (Group group : southboundGroupEntries) { | ||
404 | - if (store.getGroup(group.deviceId(), group.id()) != null) { | ||
405 | - // There is a group existing with the same id | ||
406 | - // It is possible that group update is | ||
407 | - // in progress while we got a stale info from switch | ||
408 | - if (!storedGroupEntries.remove(store.getGroup( | ||
409 | - group.deviceId(), group.id()))) { | ||
410 | - log.warn("Group AUDIT: Inconsistent state:" | ||
411 | - + "Group exists in ID based table while " | ||
412 | - + "not present in key based table"); | ||
413 | - } | ||
414 | - } else { | ||
415 | - // there are groups in the switch that aren't in the store | ||
416 | - log.trace("Group AUDIT: extraneous group {} exists " | ||
417 | - + "in data plane for device {}", | ||
418 | - group.id(), deviceId); | ||
419 | - extraneousStoredEntries.remove(group); | ||
420 | - extraneousGroup(group); | ||
421 | - } | ||
422 | - } | ||
423 | - for (Group group : storedGroupEntries) { | ||
424 | - // there are groups in the store that aren't in the switch | ||
425 | - log.trace("Group AUDIT: group {} missing " | ||
426 | - + "in data plane for device {}", | ||
427 | - group.id(), deviceId); | ||
428 | - groupMissing(group); | ||
429 | - } | ||
430 | - for (Group group : extraneousStoredEntries) { | ||
431 | - // there are groups in the extraneous store that | ||
432 | - // aren't in the switch | ||
433 | - log.trace("Group AUDIT: clearing extransoeus group {} " | ||
434 | - + "from store for device {}", | ||
435 | - group.id(), deviceId); | ||
436 | - store.removeExtraneousGroupEntry(group); | ||
437 | - } | ||
438 | - | ||
439 | - if (!deviceInitialAuditStatus) { | ||
440 | - log.debug("Group AUDIT: Setting device {} initial " | ||
441 | - + "AUDIT completed", deviceId); | ||
442 | - store.deviceInitialAuditCompleted(deviceId, true); | ||
443 | - } | ||
444 | } | 323 | } |
445 | } | 324 | } |
446 | 325 | ||
... | @@ -450,10 +329,16 @@ public class GroupManager | ... | @@ -450,10 +329,16 @@ public class GroupManager |
450 | public void event(DeviceEvent event) { | 329 | public void event(DeviceEvent event) { |
451 | switch (event.type()) { | 330 | switch (event.type()) { |
452 | case DEVICE_REMOVED: | 331 | case DEVICE_REMOVED: |
453 | - log.debug("Clearing device {} initial " | 332 | + case DEVICE_AVAILABILITY_CHANGED: |
454 | - + "AUDIT completed status as device is going down", | 333 | + if (!deviceService.isAvailable(event.subject().id())) { |
334 | + log.debug("GroupService DeviceListener: Received event {}." | ||
335 | + + "Device is no more available." | ||
336 | + + "Clearing device {} initial " | ||
337 | + + "AUDIT completed status", | ||
338 | + event.type(), | ||
455 | event.subject().id()); | 339 | event.subject().id()); |
456 | store.deviceInitialAuditCompleted(event.subject().id(), false); | 340 | store.deviceInitialAuditCompleted(event.subject().id(), false); |
341 | + } | ||
457 | break; | 342 | break; |
458 | 343 | ||
459 | default: | 344 | default: | ... | ... |
... | @@ -17,6 +17,7 @@ package org.onosproject.store.group.impl; | ... | @@ -17,6 +17,7 @@ package org.onosproject.store.group.impl; |
17 | 17 | ||
18 | import com.google.common.collect.FluentIterable; | 18 | import com.google.common.collect.FluentIterable; |
19 | import com.google.common.collect.Iterables; | 19 | import com.google.common.collect.Iterables; |
20 | +import com.google.common.collect.Sets; | ||
20 | 21 | ||
21 | import org.apache.felix.scr.annotations.Activate; | 22 | import org.apache.felix.scr.annotations.Activate; |
22 | import org.apache.felix.scr.annotations.Component; | 23 | import org.apache.felix.scr.annotations.Component; |
... | @@ -63,7 +64,9 @@ import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | ... | @@ -63,7 +64,9 @@ import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
63 | import org.onosproject.store.cluster.messaging.ClusterMessage; | 64 | import org.onosproject.store.cluster.messaging.ClusterMessage; |
64 | import org.onosproject.store.cluster.messaging.ClusterMessageHandler; | 65 | import org.onosproject.store.cluster.messaging.ClusterMessageHandler; |
65 | import org.onosproject.store.service.MultiValuedTimestamp; | 66 | import org.onosproject.store.service.MultiValuedTimestamp; |
67 | +import org.onosproject.store.serializers.DeviceIdSerializer; | ||
66 | import org.onosproject.store.serializers.KryoNamespaces; | 68 | import org.onosproject.store.serializers.KryoNamespaces; |
69 | +import org.onosproject.store.serializers.URISerializer; | ||
67 | import org.onosproject.store.service.ClockService; | 70 | import org.onosproject.store.service.ClockService; |
68 | import org.onosproject.store.service.EventuallyConsistentMap; | 71 | import org.onosproject.store.service.EventuallyConsistentMap; |
69 | import org.onosproject.store.service.EventuallyConsistentMapBuilder; | 72 | import org.onosproject.store.service.EventuallyConsistentMapBuilder; |
... | @@ -74,10 +77,13 @@ import org.slf4j.Logger; | ... | @@ -74,10 +77,13 @@ import org.slf4j.Logger; |
74 | 77 | ||
75 | import java.net.URI; | 78 | import java.net.URI; |
76 | import java.util.ArrayList; | 79 | import java.util.ArrayList; |
80 | +import java.util.Collection; | ||
77 | import java.util.HashMap; | 81 | import java.util.HashMap; |
82 | +import java.util.Iterator; | ||
78 | import java.util.List; | 83 | import java.util.List; |
79 | import java.util.Objects; | 84 | import java.util.Objects; |
80 | import java.util.Optional; | 85 | import java.util.Optional; |
86 | +import java.util.Set; | ||
81 | import java.util.concurrent.ConcurrentHashMap; | 87 | import java.util.concurrent.ConcurrentHashMap; |
82 | import java.util.concurrent.ConcurrentMap; | 88 | import java.util.concurrent.ConcurrentMap; |
83 | import java.util.concurrent.ExecutorService; | 89 | import java.util.concurrent.ExecutorService; |
... | @@ -156,8 +162,8 @@ public class DistributedGroupStore | ... | @@ -156,8 +162,8 @@ public class DistributedGroupStore |
156 | GroupStoreIdMapKey.class, | 162 | GroupStoreIdMapKey.class, |
157 | GroupStoreMapKey.class | 163 | GroupStoreMapKey.class |
158 | ) | 164 | ) |
159 | - .register(URI.class) | 165 | + .register(new URISerializer(), URI.class) |
160 | - .register(DeviceId.class) | 166 | + .register(new DeviceIdSerializer(), DeviceId.class) |
161 | .register(PortNumber.class) | 167 | .register(PortNumber.class) |
162 | .register(DefaultApplicationId.class) | 168 | .register(DefaultApplicationId.class) |
163 | .register(DefaultTrafficTreatment.class, | 169 | .register(DefaultTrafficTreatment.class, |
... | @@ -207,7 +213,8 @@ public class DistributedGroupStore | ... | @@ -207,7 +213,8 @@ public class DistributedGroupStore |
207 | .withClockService(new GroupStoreLogicalClockManager<>()) | 213 | .withClockService(new GroupStoreLogicalClockManager<>()) |
208 | .build(); | 214 | .build(); |
209 | groupStoreEntriesByKey.addListener(new GroupStoreKeyMapListener()); | 215 | groupStoreEntriesByKey.addListener(new GroupStoreKeyMapListener()); |
210 | - log.trace("Current size {}", groupStoreEntriesByKey.size()); | 216 | + log.debug("Current size of groupstorekeymap:{}", |
217 | + groupStoreEntriesByKey.size()); | ||
211 | 218 | ||
212 | log.debug("Creating EC map pendinggroupkeymap"); | 219 | log.debug("Creating EC map pendinggroupkeymap"); |
213 | EventuallyConsistentMapBuilder<GroupStoreKeyMapKey, StoredGroupEntry> | 220 | EventuallyConsistentMapBuilder<GroupStoreKeyMapKey, StoredGroupEntry> |
... | @@ -218,7 +225,8 @@ public class DistributedGroupStore | ... | @@ -218,7 +225,8 @@ public class DistributedGroupStore |
218 | .withSerializer(kryoBuilder) | 225 | .withSerializer(kryoBuilder) |
219 | .withClockService(new GroupStoreLogicalClockManager<>()) | 226 | .withClockService(new GroupStoreLogicalClockManager<>()) |
220 | .build(); | 227 | .build(); |
221 | - log.trace("Current size {}", auditPendingReqQueue.size()); | 228 | + log.debug("Current size of pendinggroupkeymap:{}", |
229 | + auditPendingReqQueue.size()); | ||
222 | 230 | ||
223 | log.info("Started"); | 231 | log.info("Started"); |
224 | } | 232 | } |
... | @@ -305,13 +313,21 @@ public class DistributedGroupStore | ... | @@ -305,13 +313,21 @@ public class DistributedGroupStore |
305 | @Override | 313 | @Override |
306 | public Iterable<Group> getGroups(DeviceId deviceId) { | 314 | public Iterable<Group> getGroups(DeviceId deviceId) { |
307 | // flatten and make iterator unmodifiable | 315 | // flatten and make iterator unmodifiable |
308 | - log.trace("getGroups: for device {} total number of groups {}", | 316 | + log.debug("getGroups: for device {} total number of groups {}", |
309 | deviceId, getGroupStoreKeyMap().values().size()); | 317 | deviceId, getGroupStoreKeyMap().values().size()); |
310 | return FluentIterable.from(getGroupStoreKeyMap().values()) | 318 | return FluentIterable.from(getGroupStoreKeyMap().values()) |
311 | .filter(input -> input.deviceId().equals(deviceId)) | 319 | .filter(input -> input.deviceId().equals(deviceId)) |
312 | .transform(input -> input); | 320 | .transform(input -> input); |
313 | } | 321 | } |
314 | 322 | ||
323 | + private Iterable<StoredGroupEntry> getStoredGroups(DeviceId deviceId) { | ||
324 | + // flatten and make iterator unmodifiable | ||
325 | + log.debug("getGroups: for device {} total number of groups {}", | ||
326 | + deviceId, getGroupStoreKeyMap().values().size()); | ||
327 | + return FluentIterable.from(getGroupStoreKeyMap().values()) | ||
328 | + .filter(input -> input.deviceId().equals(deviceId)); | ||
329 | + } | ||
330 | + | ||
315 | /** | 331 | /** |
316 | * Returns the stored group entry. | 332 | * Returns the stored group entry. |
317 | * | 333 | * |
... | @@ -359,6 +375,7 @@ public class DistributedGroupStore | ... | @@ -359,6 +375,7 @@ public class DistributedGroupStore |
359 | break; | 375 | break; |
360 | } | 376 | } |
361 | } | 377 | } |
378 | + log.debug("getFreeGroupIdValue: Next Free ID is {}", freeId); | ||
362 | return freeId; | 379 | return freeId; |
363 | } | 380 | } |
364 | 381 | ||
... | @@ -369,7 +386,7 @@ public class DistributedGroupStore | ... | @@ -369,7 +386,7 @@ public class DistributedGroupStore |
369 | */ | 386 | */ |
370 | @Override | 387 | @Override |
371 | public void storeGroupDescription(GroupDescription groupDesc) { | 388 | public void storeGroupDescription(GroupDescription groupDesc) { |
372 | - log.trace("In storeGroupDescription"); | 389 | + log.debug("In storeGroupDescription"); |
373 | // Check if a group is existing with the same key | 390 | // Check if a group is existing with the same key |
374 | if (getGroup(groupDesc.deviceId(), groupDesc.appCookie()) != null) { | 391 | if (getGroup(groupDesc.deviceId(), groupDesc.appCookie()) != null) { |
375 | log.warn("Group already exists with the same key {}", | 392 | log.warn("Group already exists with the same key {}", |
... | @@ -380,8 +397,15 @@ public class DistributedGroupStore | ... | @@ -380,8 +397,15 @@ public class DistributedGroupStore |
380 | // Check if group to be created by a remote instance | 397 | // Check if group to be created by a remote instance |
381 | if (mastershipService.getLocalRole( | 398 | if (mastershipService.getLocalRole( |
382 | groupDesc.deviceId()) != MastershipRole.MASTER) { | 399 | groupDesc.deviceId()) != MastershipRole.MASTER) { |
383 | - log.debug("Device {} local role is not MASTER", | 400 | + log.debug("storeGroupDescription: Device {} local role is not MASTER", |
384 | groupDesc.deviceId()); | 401 | groupDesc.deviceId()); |
402 | + if (mastershipService.getMasterFor(groupDesc.deviceId()) == null) { | ||
403 | + log.error("No Master for device {}..." | ||
404 | + + "Can not perform add group operation", | ||
405 | + groupDesc.deviceId()); | ||
406 | + //TODO: Send Group operation failure event | ||
407 | + return; | ||
408 | + } | ||
385 | GroupStoreMessage groupOp = GroupStoreMessage. | 409 | GroupStoreMessage groupOp = GroupStoreMessage. |
386 | createGroupAddRequestMsg(groupDesc.deviceId(), | 410 | createGroupAddRequestMsg(groupDesc.deviceId(), |
387 | groupDesc); | 411 | groupDesc); |
... | @@ -394,9 +418,9 @@ public class DistributedGroupStore | ... | @@ -394,9 +418,9 @@ public class DistributedGroupStore |
394 | groupOp, | 418 | groupOp, |
395 | mastershipService.getMasterFor(groupDesc.deviceId())); | 419 | mastershipService.getMasterFor(groupDesc.deviceId())); |
396 | //TODO: Send Group operation failure event | 420 | //TODO: Send Group operation failure event |
421 | + return; | ||
397 | } | 422 | } |
398 | - log.debug("Sent Group operation request for device {} " | 423 | + log.debug("Sent Group operation request for device {} to remote MASTER {}", |
399 | - + "to remote MASTER {}", | ||
400 | groupDesc.deviceId(), | 424 | groupDesc.deviceId(), |
401 | mastershipService.getMasterFor(groupDesc.deviceId())); | 425 | mastershipService.getMasterFor(groupDesc.deviceId())); |
402 | return; | 426 | return; |
... | @@ -417,8 +441,7 @@ public class DistributedGroupStore | ... | @@ -417,8 +441,7 @@ public class DistributedGroupStore |
417 | // Device group audit has not completed yet | 441 | // Device group audit has not completed yet |
418 | // Add this group description to pending group key table | 442 | // Add this group description to pending group key table |
419 | // Create a group entry object with Dummy Group ID | 443 | // Create a group entry object with Dummy Group ID |
420 | - log.debug("storeGroupDescriptionInternal: Device {} AUDIT " | 444 | + log.debug("storeGroupDescriptionInternal: Device {} AUDIT pending...Queuing Group ADD request", |
421 | - + "pending...Queuing Group ADD request", | ||
422 | groupDesc.deviceId()); | 445 | groupDesc.deviceId()); |
423 | StoredGroupEntry group = new DefaultGroup(dummyGroupId, groupDesc); | 446 | StoredGroupEntry group = new DefaultGroup(dummyGroupId, groupDesc); |
424 | group.setState(GroupState.WAITING_AUDIT_COMPLETE); | 447 | group.setState(GroupState.WAITING_AUDIT_COMPLETE); |
... | @@ -447,6 +470,9 @@ public class DistributedGroupStore | ... | @@ -447,6 +470,9 @@ public class DistributedGroupStore |
447 | // avoid any chances of duplication in group id generation | 470 | // avoid any chances of duplication in group id generation |
448 | getGroupIdTable(groupDesc.deviceId()). | 471 | getGroupIdTable(groupDesc.deviceId()). |
449 | put(id, group); | 472 | put(id, group); |
473 | + log.debug("storeGroupDescriptionInternal: Processing Group ADD request for Id {} in device {}", | ||
474 | + id, | ||
475 | + groupDesc.deviceId()); | ||
450 | notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED, | 476 | notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED, |
451 | group)); | 477 | group)); |
452 | } | 478 | } |
... | @@ -470,6 +496,15 @@ public class DistributedGroupStore | ... | @@ -470,6 +496,15 @@ public class DistributedGroupStore |
470 | // Check if group update to be done by a remote instance | 496 | // Check if group update to be done by a remote instance |
471 | if (mastershipService.getMasterFor(deviceId) != null && | 497 | if (mastershipService.getMasterFor(deviceId) != null && |
472 | mastershipService.getLocalRole(deviceId) != MastershipRole.MASTER) { | 498 | mastershipService.getLocalRole(deviceId) != MastershipRole.MASTER) { |
499 | + log.debug("updateGroupDescription: Device {} local role is not MASTER", | ||
500 | + deviceId); | ||
501 | + if (mastershipService.getMasterFor(deviceId) == null) { | ||
502 | + log.error("No Master for device {}..." | ||
503 | + + "Can not perform update group operation", | ||
504 | + deviceId); | ||
505 | + //TODO: Send Group operation failure event | ||
506 | + return; | ||
507 | + } | ||
473 | GroupStoreMessage groupOp = GroupStoreMessage. | 508 | GroupStoreMessage groupOp = GroupStoreMessage. |
474 | createGroupUpdateRequestMsg(deviceId, | 509 | createGroupUpdateRequestMsg(deviceId, |
475 | oldAppCookie, | 510 | oldAppCookie, |
... | @@ -488,6 +523,8 @@ public class DistributedGroupStore | ... | @@ -488,6 +523,8 @@ public class DistributedGroupStore |
488 | } | 523 | } |
489 | return; | 524 | return; |
490 | } | 525 | } |
526 | + log.debug("updateGroupDescription for device {} is getting handled locally", | ||
527 | + deviceId); | ||
491 | updateGroupDescriptionInternal(deviceId, | 528 | updateGroupDescriptionInternal(deviceId, |
492 | oldAppCookie, | 529 | oldAppCookie, |
493 | type, | 530 | type, |
... | @@ -503,6 +540,7 @@ public class DistributedGroupStore | ... | @@ -503,6 +540,7 @@ public class DistributedGroupStore |
503 | // Check if a group is existing with the provided key | 540 | // Check if a group is existing with the provided key |
504 | Group oldGroup = getGroup(deviceId, oldAppCookie); | 541 | Group oldGroup = getGroup(deviceId, oldAppCookie); |
505 | if (oldGroup == null) { | 542 | if (oldGroup == null) { |
543 | + log.warn("updateGroupDescriptionInternal: Group not found...strange"); | ||
506 | return; | 544 | return; |
507 | } | 545 | } |
508 | 546 | ||
... | @@ -522,6 +560,10 @@ public class DistributedGroupStore | ... | @@ -522,6 +560,10 @@ public class DistributedGroupStore |
522 | oldGroup.appId()); | 560 | oldGroup.appId()); |
523 | StoredGroupEntry newGroup = new DefaultGroup(oldGroup.id(), | 561 | StoredGroupEntry newGroup = new DefaultGroup(oldGroup.id(), |
524 | updatedGroupDesc); | 562 | updatedGroupDesc); |
563 | + log.debug("updateGroupDescriptionInternal: group entry {} in device {} moving from {} to PENDING_UPDATE", | ||
564 | + oldGroup.id(), | ||
565 | + oldGroup.deviceId(), | ||
566 | + oldGroup.state()); | ||
525 | newGroup.setState(GroupState.PENDING_UPDATE); | 567 | newGroup.setState(GroupState.PENDING_UPDATE); |
526 | newGroup.setLife(oldGroup.life()); | 568 | newGroup.setLife(oldGroup.life()); |
527 | newGroup.setPackets(oldGroup.packets()); | 569 | newGroup.setPackets(oldGroup.packets()); |
... | @@ -529,10 +571,15 @@ public class DistributedGroupStore | ... | @@ -529,10 +571,15 @@ public class DistributedGroupStore |
529 | //Update the group entry in groupkey based map. | 571 | //Update the group entry in groupkey based map. |
530 | //Update to groupid based map will happen in the | 572 | //Update to groupid based map will happen in the |
531 | //groupkey based map update listener | 573 | //groupkey based map update listener |
574 | + log.debug("updateGroupDescriptionInternal with type {}: Group updated with buckets", | ||
575 | + type); | ||
532 | getGroupStoreKeyMap(). | 576 | getGroupStoreKeyMap(). |
533 | put(new GroupStoreKeyMapKey(newGroup.deviceId(), | 577 | put(new GroupStoreKeyMapKey(newGroup.deviceId(), |
534 | newGroup.appCookie()), newGroup); | 578 | newGroup.appCookie()), newGroup); |
535 | notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, newGroup)); | 579 | notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, newGroup)); |
580 | + } else { | ||
581 | + log.warn("updateGroupDescriptionInternal with type {}: No " | ||
582 | + + "change in the buckets in update", type); | ||
536 | } | 583 | } |
537 | } | 584 | } |
538 | 585 | ||
... | @@ -583,6 +630,15 @@ public class DistributedGroupStore | ... | @@ -583,6 +630,15 @@ public class DistributedGroupStore |
583 | // Check if group to be deleted by a remote instance | 630 | // Check if group to be deleted by a remote instance |
584 | if (mastershipService. | 631 | if (mastershipService. |
585 | getLocalRole(deviceId) != MastershipRole.MASTER) { | 632 | getLocalRole(deviceId) != MastershipRole.MASTER) { |
633 | + log.debug("deleteGroupDescription: Device {} local role is not MASTER", | ||
634 | + deviceId); | ||
635 | + if (mastershipService.getMasterFor(deviceId) == null) { | ||
636 | + log.error("No Master for device {}..." | ||
637 | + + "Can not perform delete group operation", | ||
638 | + deviceId); | ||
639 | + //TODO: Send Group operation failure event | ||
640 | + return; | ||
641 | + } | ||
586 | GroupStoreMessage groupOp = GroupStoreMessage. | 642 | GroupStoreMessage groupOp = GroupStoreMessage. |
587 | createGroupDeleteRequestMsg(deviceId, | 643 | createGroupDeleteRequestMsg(deviceId, |
588 | appCookie); | 644 | appCookie); |
... | @@ -598,6 +654,8 @@ public class DistributedGroupStore | ... | @@ -598,6 +654,8 @@ public class DistributedGroupStore |
598 | } | 654 | } |
599 | return; | 655 | return; |
600 | } | 656 | } |
657 | + log.debug("deleteGroupDescription in device {} is getting handled locally", | ||
658 | + deviceId); | ||
601 | deleteGroupDescriptionInternal(deviceId, appCookie); | 659 | deleteGroupDescriptionInternal(deviceId, appCookie); |
602 | } | 660 | } |
603 | 661 | ||
... | @@ -609,9 +667,15 @@ public class DistributedGroupStore | ... | @@ -609,9 +667,15 @@ public class DistributedGroupStore |
609 | return; | 667 | return; |
610 | } | 668 | } |
611 | 669 | ||
670 | + log.debug("deleteGroupDescriptionInternal: group entry {} in device {} moving from {} to PENDING_DELETE", | ||
671 | + existing.id(), | ||
672 | + existing.deviceId(), | ||
673 | + existing.state()); | ||
612 | synchronized (existing) { | 674 | synchronized (existing) { |
613 | existing.setState(GroupState.PENDING_DELETE); | 675 | existing.setState(GroupState.PENDING_DELETE); |
614 | } | 676 | } |
677 | + log.debug("deleteGroupDescriptionInternal: in device {} issuing GROUP_REMOVE_REQUESTED", | ||
678 | + deviceId); | ||
615 | notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_REQUESTED, existing)); | 679 | notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_REQUESTED, existing)); |
616 | } | 680 | } |
617 | 681 | ||
... | @@ -628,8 +692,7 @@ public class DistributedGroupStore | ... | @@ -628,8 +692,7 @@ public class DistributedGroupStore |
628 | GroupEvent event = null; | 692 | GroupEvent event = null; |
629 | 693 | ||
630 | if (existing != null) { | 694 | if (existing != null) { |
631 | - log.trace("addOrUpdateGroupEntry: updating group " | 695 | + log.debug("addOrUpdateGroupEntry: updating group entry {} in device {}", |
632 | - + "entry {} in device {}", | ||
633 | group.id(), | 696 | group.id(), |
634 | group.deviceId()); | 697 | group.deviceId()); |
635 | synchronized (existing) { | 698 | synchronized (existing) { |
... | @@ -653,10 +716,18 @@ public class DistributedGroupStore | ... | @@ -653,10 +716,18 @@ public class DistributedGroupStore |
653 | existing.setPackets(group.packets()); | 716 | existing.setPackets(group.packets()); |
654 | existing.setBytes(group.bytes()); | 717 | existing.setBytes(group.bytes()); |
655 | if (existing.state() == GroupState.PENDING_ADD) { | 718 | if (existing.state() == GroupState.PENDING_ADD) { |
719 | + log.debug("addOrUpdateGroupEntry: group entry {} in device {} moving from {} to ADDED", | ||
720 | + existing.id(), | ||
721 | + existing.deviceId(), | ||
722 | + GroupState.PENDING_ADD); | ||
656 | existing.setState(GroupState.ADDED); | 723 | existing.setState(GroupState.ADDED); |
657 | existing.setIsGroupStateAddedFirstTime(true); | 724 | existing.setIsGroupStateAddedFirstTime(true); |
658 | event = new GroupEvent(Type.GROUP_ADDED, existing); | 725 | event = new GroupEvent(Type.GROUP_ADDED, existing); |
659 | } else { | 726 | } else { |
727 | + log.debug("addOrUpdateGroupEntry: group entry {} in device {} moving from {} to ADDED", | ||
728 | + existing.id(), | ||
729 | + existing.deviceId(), | ||
730 | + GroupState.PENDING_UPDATE); | ||
660 | existing.setState(GroupState.ADDED); | 731 | existing.setState(GroupState.ADDED); |
661 | existing.setIsGroupStateAddedFirstTime(false); | 732 | existing.setIsGroupStateAddedFirstTime(false); |
662 | event = new GroupEvent(Type.GROUP_UPDATED, existing); | 733 | event = new GroupEvent(Type.GROUP_UPDATED, existing); |
... | @@ -687,8 +758,7 @@ public class DistributedGroupStore | ... | @@ -687,8 +758,7 @@ public class DistributedGroupStore |
687 | group.id()); | 758 | group.id()); |
688 | 759 | ||
689 | if (existing != null) { | 760 | if (existing != null) { |
690 | - log.trace("removeGroupEntry: removing group " | 761 | + log.debug("removeGroupEntry: removing group entry {} in device {}", |
691 | - + "entry {} in device {}", | ||
692 | group.id(), | 762 | group.id(), |
693 | group.deviceId()); | 763 | group.deviceId()); |
694 | //Removal from groupid based map will happen in the | 764 | //Removal from groupid based map will happen in the |
... | @@ -696,6 +766,11 @@ public class DistributedGroupStore | ... | @@ -696,6 +766,11 @@ public class DistributedGroupStore |
696 | getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), | 766 | getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), |
697 | existing.appCookie())); | 767 | existing.appCookie())); |
698 | notifyDelegate(new GroupEvent(Type.GROUP_REMOVED, existing)); | 768 | notifyDelegate(new GroupEvent(Type.GROUP_REMOVED, existing)); |
769 | + } else { | ||
770 | + log.warn("removeGroupEntry for {} in device{} is " | ||
771 | + + "not existing in our maps", | ||
772 | + group.id(), | ||
773 | + group.deviceId()); | ||
699 | } | 774 | } |
700 | } | 775 | } |
701 | 776 | ||
... | @@ -704,8 +779,8 @@ public class DistributedGroupStore | ... | @@ -704,8 +779,8 @@ public class DistributedGroupStore |
704 | boolean completed) { | 779 | boolean completed) { |
705 | synchronized (deviceAuditStatus) { | 780 | synchronized (deviceAuditStatus) { |
706 | if (completed) { | 781 | if (completed) { |
707 | - log.debug("deviceInitialAuditCompleted: AUDIT " | 782 | + log.debug("AUDIT completed for device {}", |
708 | - + "completed for device {}", deviceId); | 783 | + deviceId); |
709 | deviceAuditStatus.put(deviceId, true); | 784 | deviceAuditStatus.put(deviceId, true); |
710 | // Execute all pending group requests | 785 | // Execute all pending group requests |
711 | List<StoredGroupEntry> pendingGroupRequests = | 786 | List<StoredGroupEntry> pendingGroupRequests = |
... | @@ -713,9 +788,7 @@ public class DistributedGroupStore | ... | @@ -713,9 +788,7 @@ public class DistributedGroupStore |
713 | .stream() | 788 | .stream() |
714 | .filter(g-> g.deviceId().equals(deviceId)) | 789 | .filter(g-> g.deviceId().equals(deviceId)) |
715 | .collect(Collectors.toList()); | 790 | .collect(Collectors.toList()); |
716 | - log.trace("deviceInitialAuditCompleted: processing " | 791 | + log.debug("processing pending group add requests for device {} and number of pending requests {}", |
717 | - + "pending group add requests for device {} and " | ||
718 | - + "number of pending requests {}", | ||
719 | deviceId, | 792 | deviceId, |
720 | pendingGroupRequests.size()); | 793 | pendingGroupRequests.size()); |
721 | for (Group group:pendingGroupRequests) { | 794 | for (Group group:pendingGroupRequests) { |
... | @@ -733,8 +806,7 @@ public class DistributedGroupStore | ... | @@ -733,8 +806,7 @@ public class DistributedGroupStore |
733 | } else { | 806 | } else { |
734 | Boolean audited = deviceAuditStatus.get(deviceId); | 807 | Boolean audited = deviceAuditStatus.get(deviceId); |
735 | if (audited != null && audited) { | 808 | if (audited != null && audited) { |
736 | - log.debug("deviceInitialAuditCompleted: Clearing AUDIT " | 809 | + log.debug("Clearing AUDIT status for device {}", deviceId); |
737 | - + "status for device {}", deviceId); | ||
738 | deviceAuditStatus.put(deviceId, false); | 810 | deviceAuditStatus.put(deviceId, false); |
739 | } | 811 | } |
740 | } | 812 | } |
... | @@ -760,9 +832,22 @@ public class DistributedGroupStore | ... | @@ -760,9 +832,22 @@ public class DistributedGroupStore |
760 | return; | 832 | return; |
761 | } | 833 | } |
762 | 834 | ||
835 | + log.warn("groupOperationFailed: group operation {} failed" | ||
836 | + + "for group {} in device {}", | ||
837 | + operation.opType(), | ||
838 | + existing.id(), | ||
839 | + existing.deviceId()); | ||
763 | switch (operation.opType()) { | 840 | switch (operation.opType()) { |
764 | case ADD: | 841 | case ADD: |
765 | notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); | 842 | notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); |
843 | + log.warn("groupOperationFailed: cleaningup " | ||
844 | + + "group {} from store in device {}....", | ||
845 | + existing.id(), | ||
846 | + existing.deviceId()); | ||
847 | + //Removal from groupid based map will happen in the | ||
848 | + //map update listener | ||
849 | + getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), | ||
850 | + existing.appCookie())); | ||
766 | break; | 851 | break; |
767 | case MODIFY: | 852 | case MODIFY: |
768 | notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing)); | 853 | notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing)); |
... | @@ -773,17 +858,11 @@ public class DistributedGroupStore | ... | @@ -773,17 +858,11 @@ public class DistributedGroupStore |
773 | default: | 858 | default: |
774 | log.warn("Unknown group operation type {}", operation.opType()); | 859 | log.warn("Unknown group operation type {}", operation.opType()); |
775 | } | 860 | } |
776 | - | ||
777 | - //Removal from groupid based map will happen in the | ||
778 | - //map update listener | ||
779 | - getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), | ||
780 | - existing.appCookie())); | ||
781 | } | 861 | } |
782 | 862 | ||
783 | @Override | 863 | @Override |
784 | public void addOrUpdateExtraneousGroupEntry(Group group) { | 864 | public void addOrUpdateExtraneousGroupEntry(Group group) { |
785 | - log.trace("addOrUpdateExtraneousGroupEntry: add/update extraneous " | 865 | + log.debug("add/update extraneous group entry {} in device {}", |
786 | - + "group entry {} in device {}", | ||
787 | group.id(), | 866 | group.id(), |
788 | group.deviceId()); | 867 | group.deviceId()); |
789 | ConcurrentMap<GroupId, Group> extraneousIdTable = | 868 | ConcurrentMap<GroupId, Group> extraneousIdTable = |
... | @@ -791,8 +870,7 @@ public class DistributedGroupStore | ... | @@ -791,8 +870,7 @@ public class DistributedGroupStore |
791 | extraneousIdTable.put(group.id(), group); | 870 | extraneousIdTable.put(group.id(), group); |
792 | // Check the reference counter | 871 | // Check the reference counter |
793 | if (group.referenceCount() == 0) { | 872 | if (group.referenceCount() == 0) { |
794 | - log.trace("addOrUpdateExtraneousGroupEntry: Flow reference " | 873 | + log.debug("Flow reference counter is zero and triggering remove", |
795 | - + "counter is zero and triggering remove", | ||
796 | group.id(), | 874 | group.id(), |
797 | group.deviceId()); | 875 | group.deviceId()); |
798 | notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_REQUESTED, group)); | 876 | notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_REQUESTED, group)); |
... | @@ -801,8 +879,7 @@ public class DistributedGroupStore | ... | @@ -801,8 +879,7 @@ public class DistributedGroupStore |
801 | 879 | ||
802 | @Override | 880 | @Override |
803 | public void removeExtraneousGroupEntry(Group group) { | 881 | public void removeExtraneousGroupEntry(Group group) { |
804 | - log.trace("removeExtraneousGroupEntry: remove extraneous " | 882 | + log.debug("remove extraneous group entry {} of device {} from store", |
805 | - + "group entry {} of device {} from store", | ||
806 | group.id(), | 883 | group.id(), |
807 | group.deviceId()); | 884 | group.deviceId()); |
808 | ConcurrentMap<GroupId, Group> extraneousIdTable = | 885 | ConcurrentMap<GroupId, Group> extraneousIdTable = |
... | @@ -842,29 +919,47 @@ public class DistributedGroupStore | ... | @@ -842,29 +919,47 @@ public class DistributedGroupStore |
842 | public void event(EventuallyConsistentMapEvent<GroupStoreKeyMapKey, | 919 | public void event(EventuallyConsistentMapEvent<GroupStoreKeyMapKey, |
843 | StoredGroupEntry> mapEvent) { | 920 | StoredGroupEntry> mapEvent) { |
844 | GroupEvent groupEvent = null; | 921 | GroupEvent groupEvent = null; |
922 | + GroupStoreKeyMapKey key = mapEvent.key(); | ||
845 | StoredGroupEntry group = mapEvent.value(); | 923 | StoredGroupEntry group = mapEvent.value(); |
846 | - log.trace("GroupStoreKeyMapListener: received groupid map event {}", | 924 | + if ((key == null) && (group == null)) { |
847 | - mapEvent.type()); | 925 | + log.error("GroupStoreKeyMapListener: Received " |
926 | + + "event {} with null entry", mapEvent.type()); | ||
927 | + return; | ||
928 | + } else if (group == null) { | ||
929 | + group = getGroupIdTable(key.deviceId()).values() | ||
930 | + .stream() | ||
931 | + .filter((storedGroup) -> (storedGroup.appCookie().equals(key.appCookie))) | ||
932 | + .findFirst().get(); | ||
933 | + if (group == null) { | ||
934 | + log.error("GroupStoreKeyMapListener: Received " | ||
935 | + + "event {} with null entry... can not process", mapEvent.type()); | ||
936 | + return; | ||
937 | + } | ||
938 | + } | ||
939 | + log.trace("received groupid map event {} for id {} in device {}", | ||
940 | + mapEvent.type(), | ||
941 | + group.id(), | ||
942 | + key.deviceId()); | ||
848 | if (mapEvent.type() == EventuallyConsistentMapEvent.Type.PUT) { | 943 | if (mapEvent.type() == EventuallyConsistentMapEvent.Type.PUT) { |
849 | - log.trace("GroupStoreKeyMapListener: Received PUT event"); | ||
850 | // Update the group ID table | 944 | // Update the group ID table |
851 | getGroupIdTable(group.deviceId()).put(group.id(), group); | 945 | getGroupIdTable(group.deviceId()).put(group.id(), group); |
852 | if (mapEvent.value().state() == Group.GroupState.ADDED) { | 946 | if (mapEvent.value().state() == Group.GroupState.ADDED) { |
853 | if (mapEvent.value().isGroupStateAddedFirstTime()) { | 947 | if (mapEvent.value().isGroupStateAddedFirstTime()) { |
854 | groupEvent = new GroupEvent(Type.GROUP_ADDED, | 948 | groupEvent = new GroupEvent(Type.GROUP_ADDED, |
855 | mapEvent.value()); | 949 | mapEvent.value()); |
856 | - log.trace("GroupStoreKeyMapListener: Received first time " | 950 | + log.trace("Received first time GROUP_ADDED state update for id {} in device {}", |
857 | - + "GROUP_ADDED state update"); | 951 | + group.id(), |
952 | + group.deviceId()); | ||
858 | } else { | 953 | } else { |
859 | groupEvent = new GroupEvent(Type.GROUP_UPDATED, | 954 | groupEvent = new GroupEvent(Type.GROUP_UPDATED, |
860 | mapEvent.value()); | 955 | mapEvent.value()); |
861 | - log.trace("GroupStoreKeyMapListener: Received following " | 956 | + log.trace("Received following GROUP_ADDED state update for id {} in device {}", |
862 | - + "GROUP_ADDED state update"); | 957 | + group.id(), |
958 | + group.deviceId()); | ||
863 | } | 959 | } |
864 | } | 960 | } |
865 | } else if (mapEvent.type() == EventuallyConsistentMapEvent.Type.REMOVE) { | 961 | } else if (mapEvent.type() == EventuallyConsistentMapEvent.Type.REMOVE) { |
866 | - log.trace("GroupStoreKeyMapListener: Received REMOVE event"); | 962 | + groupEvent = new GroupEvent(Type.GROUP_REMOVED, group); |
867 | - groupEvent = new GroupEvent(Type.GROUP_REMOVED, mapEvent.value()); | ||
868 | // Remove the entry from the group ID table | 963 | // Remove the entry from the group ID table |
869 | getGroupIdTable(group.deviceId()).remove(group.id(), group); | 964 | getGroupIdTable(group.deviceId()).remove(group.id(), group); |
870 | } | 965 | } |
... | @@ -882,37 +977,35 @@ public class DistributedGroupStore | ... | @@ -882,37 +977,35 @@ public class DistributedGroupStore |
882 | implements ClusterMessageHandler { | 977 | implements ClusterMessageHandler { |
883 | @Override | 978 | @Override |
884 | public void handle(ClusterMessage message) { | 979 | public void handle(ClusterMessage message) { |
885 | - log.trace("ClusterGroupMsgHandler: received remote group message"); | 980 | + if (message.subject().equals( |
886 | - if (message.subject() == | 981 | + GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST)) { |
887 | - GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST) { | ||
888 | GroupStoreMessage groupOp = kryoBuilder. | 982 | GroupStoreMessage groupOp = kryoBuilder. |
889 | build().deserialize(message.payload()); | 983 | build().deserialize(message.payload()); |
890 | - log.trace("received remote group operation request"); | 984 | + log.debug("received remote group operation {} request for device {}", |
891 | - if (!(mastershipService. | 985 | + groupOp.type(), |
986 | + groupOp.deviceId()); | ||
987 | + if (mastershipService. | ||
892 | getLocalRole(groupOp.deviceId()) != | 988 | getLocalRole(groupOp.deviceId()) != |
893 | - MastershipRole.MASTER)) { | 989 | + MastershipRole.MASTER) { |
894 | log.warn("ClusterGroupMsgHandler: This node is not " | 990 | log.warn("ClusterGroupMsgHandler: This node is not " |
895 | + "MASTER for device {}", groupOp.deviceId()); | 991 | + "MASTER for device {}", groupOp.deviceId()); |
896 | return; | 992 | return; |
897 | } | 993 | } |
898 | if (groupOp.type() == GroupStoreMessage.Type.ADD) { | 994 | if (groupOp.type() == GroupStoreMessage.Type.ADD) { |
899 | - log.trace("processing remote group " | ||
900 | - + "add operation request"); | ||
901 | storeGroupDescriptionInternal(groupOp.groupDesc()); | 995 | storeGroupDescriptionInternal(groupOp.groupDesc()); |
902 | } else if (groupOp.type() == GroupStoreMessage.Type.UPDATE) { | 996 | } else if (groupOp.type() == GroupStoreMessage.Type.UPDATE) { |
903 | - log.trace("processing remote group " | ||
904 | - + "update operation request"); | ||
905 | updateGroupDescriptionInternal(groupOp.deviceId(), | 997 | updateGroupDescriptionInternal(groupOp.deviceId(), |
906 | groupOp.appCookie(), | 998 | groupOp.appCookie(), |
907 | groupOp.updateType(), | 999 | groupOp.updateType(), |
908 | groupOp.updateBuckets(), | 1000 | groupOp.updateBuckets(), |
909 | groupOp.newAppCookie()); | 1001 | groupOp.newAppCookie()); |
910 | } else if (groupOp.type() == GroupStoreMessage.Type.DELETE) { | 1002 | } else if (groupOp.type() == GroupStoreMessage.Type.DELETE) { |
911 | - log.trace("processing remote group " | ||
912 | - + "delete operation request"); | ||
913 | deleteGroupDescriptionInternal(groupOp.deviceId(), | 1003 | deleteGroupDescriptionInternal(groupOp.deviceId(), |
914 | groupOp.appCookie()); | 1004 | groupOp.appCookie()); |
915 | } | 1005 | } |
1006 | + } else { | ||
1007 | + log.warn("ClusterGroupMsgHandler: Unknown remote message type {}", | ||
1008 | + message.subject()); | ||
916 | } | 1009 | } |
917 | } | 1010 | } |
918 | } | 1011 | } |
... | @@ -927,6 +1020,10 @@ public class DistributedGroupStore | ... | @@ -927,6 +1020,10 @@ public class DistributedGroupStore |
927 | this.deviceId = deviceId; | 1020 | this.deviceId = deviceId; |
928 | } | 1021 | } |
929 | 1022 | ||
1023 | + public DeviceId deviceId() { | ||
1024 | + return deviceId; | ||
1025 | + } | ||
1026 | + | ||
930 | @Override | 1027 | @Override |
931 | public boolean equals(Object o) { | 1028 | public boolean equals(Object o) { |
932 | if (this == o) { | 1029 | if (this == o) { |
... | @@ -1010,4 +1107,127 @@ public class DistributedGroupStore | ... | @@ -1010,4 +1107,127 @@ public class DistributedGroupStore |
1010 | return result; | 1107 | return result; |
1011 | } | 1108 | } |
1012 | } | 1109 | } |
1110 | + | ||
1111 | + @Override | ||
1112 | + public void pushGroupMetrics(DeviceId deviceId, | ||
1113 | + Collection<Group> groupEntries) { | ||
1114 | + boolean deviceInitialAuditStatus = | ||
1115 | + deviceInitialAuditStatus(deviceId); | ||
1116 | + Set<Group> southboundGroupEntries = | ||
1117 | + Sets.newHashSet(groupEntries); | ||
1118 | + Set<StoredGroupEntry> storedGroupEntries = | ||
1119 | + Sets.newHashSet(getStoredGroups(deviceId)); | ||
1120 | + Set<Group> extraneousStoredEntries = | ||
1121 | + Sets.newHashSet(getExtraneousGroups(deviceId)); | ||
1122 | + | ||
1123 | + log.trace("pushGroupMetrics: Displaying all ({}) southboundGroupEntries for device {}", | ||
1124 | + southboundGroupEntries.size(), | ||
1125 | + deviceId); | ||
1126 | + for (Iterator<Group> it = southboundGroupEntries.iterator(); it.hasNext();) { | ||
1127 | + Group group = it.next(); | ||
1128 | + log.trace("Group {} in device {}", group, deviceId); | ||
1129 | + } | ||
1130 | + | ||
1131 | + log.trace("Displaying all ({}) stored group entries for device {}", | ||
1132 | + storedGroupEntries.size(), | ||
1133 | + deviceId); | ||
1134 | + for (Iterator<StoredGroupEntry> it1 = storedGroupEntries.iterator(); | ||
1135 | + it1.hasNext();) { | ||
1136 | + Group group = it1.next(); | ||
1137 | + log.trace("Stored Group {} for device {}", group, deviceId); | ||
1138 | + } | ||
1139 | + | ||
1140 | + for (Iterator<Group> it2 = southboundGroupEntries.iterator(); it2.hasNext();) { | ||
1141 | + Group group = it2.next(); | ||
1142 | + if (storedGroupEntries.remove(group)) { | ||
1143 | + // we both have the group, let's update some info then. | ||
1144 | + log.trace("Group AUDIT: group {} exists in both planes for device {}", | ||
1145 | + group.id(), deviceId); | ||
1146 | + groupAdded(group); | ||
1147 | + it2.remove(); | ||
1148 | + } | ||
1149 | + } | ||
1150 | + for (Group group : southboundGroupEntries) { | ||
1151 | + if (getGroup(group.deviceId(), group.id()) != null) { | ||
1152 | + // There is a group existing with the same id | ||
1153 | + // It is possible that group update is | ||
1154 | + // in progress while we got a stale info from switch | ||
1155 | + if (!storedGroupEntries.remove(getGroup( | ||
1156 | + group.deviceId(), group.id()))) { | ||
1157 | + log.warn("Group AUDIT: Inconsistent state:" | ||
1158 | + + "Group exists in ID based table while " | ||
1159 | + + "not present in key based table"); | ||
1160 | + } | ||
1161 | + } else { | ||
1162 | + // there are groups in the switch that aren't in the store | ||
1163 | + log.debug("Group AUDIT: extraneous group {} exists in data plane for device {}", | ||
1164 | + group.id(), deviceId); | ||
1165 | + extraneousStoredEntries.remove(group); | ||
1166 | + extraneousGroup(group); | ||
1167 | + } | ||
1168 | + } | ||
1169 | + for (Group group : storedGroupEntries) { | ||
1170 | + // there are groups in the store that aren't in the switch | ||
1171 | + log.debug("Group AUDIT: group {} missing in data plane for device {}", | ||
1172 | + group.id(), deviceId); | ||
1173 | + groupMissing(group); | ||
1174 | + } | ||
1175 | + for (Group group : extraneousStoredEntries) { | ||
1176 | + // there are groups in the extraneous store that | ||
1177 | + // aren't in the switch | ||
1178 | + log.debug("Group AUDIT: clearing extransoeus group {} from store for device {}", | ||
1179 | + group.id(), deviceId); | ||
1180 | + removeExtraneousGroupEntry(group); | ||
1181 | + } | ||
1182 | + | ||
1183 | + if (!deviceInitialAuditStatus) { | ||
1184 | + log.debug("Group AUDIT: Setting device {} initial AUDIT completed", | ||
1185 | + deviceId); | ||
1186 | + deviceInitialAuditCompleted(deviceId, true); | ||
1187 | + } | ||
1188 | + } | ||
1189 | + | ||
1190 | + private void groupMissing(Group group) { | ||
1191 | + switch (group.state()) { | ||
1192 | + case PENDING_DELETE: | ||
1193 | + log.debug("Group {} delete confirmation from device {}", | ||
1194 | + group, group.deviceId()); | ||
1195 | + removeGroupEntry(group); | ||
1196 | + break; | ||
1197 | + case ADDED: | ||
1198 | + case PENDING_ADD: | ||
1199 | + case PENDING_UPDATE: | ||
1200 | + log.debug("Group {} is in store but not on device {}", | ||
1201 | + group, group.deviceId()); | ||
1202 | + StoredGroupEntry existing = | ||
1203 | + getStoredGroupEntry(group.deviceId(), group.id()); | ||
1204 | + log.debug("groupMissing: group entry {} in device {} moving from {} to PENDING_ADD", | ||
1205 | + existing.id(), | ||
1206 | + existing.deviceId(), | ||
1207 | + existing.state()); | ||
1208 | + existing.setState(Group.GroupState.PENDING_ADD); | ||
1209 | + //Re-PUT map entries to trigger map update events | ||
1210 | + getGroupStoreKeyMap(). | ||
1211 | + put(new GroupStoreKeyMapKey(existing.deviceId(), | ||
1212 | + existing.appCookie()), existing); | ||
1213 | + notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED, | ||
1214 | + group)); | ||
1215 | + break; | ||
1216 | + default: | ||
1217 | + log.debug("Group {} has not been installed.", group); | ||
1218 | + break; | ||
1219 | + } | ||
1220 | + } | ||
1221 | + | ||
1222 | + private void extraneousGroup(Group group) { | ||
1223 | + log.debug("Group {} is on device {} but not in store.", | ||
1224 | + group, group.deviceId()); | ||
1225 | + addOrUpdateExtraneousGroupEntry(group); | ||
1226 | + } | ||
1227 | + | ||
1228 | + private void groupAdded(Group group) { | ||
1229 | + log.trace("Group {} Added or Updated in device {}", | ||
1230 | + group, group.deviceId()); | ||
1231 | + addOrUpdateGroupEntry(group); | ||
1232 | + } | ||
1013 | } | 1233 | } | ... | ... |
... | @@ -315,6 +315,7 @@ public final class KryoNamespaces { | ... | @@ -315,6 +315,7 @@ public final class KryoNamespaces { |
315 | Instructions.DropInstruction.class, | 315 | Instructions.DropInstruction.class, |
316 | Instructions.OutputInstruction.class, | 316 | Instructions.OutputInstruction.class, |
317 | Instructions.GroupInstruction.class, | 317 | Instructions.GroupInstruction.class, |
318 | + Instructions.TableTypeTransition.class, | ||
318 | L0ModificationInstruction.class, | 319 | L0ModificationInstruction.class, |
319 | L0ModificationInstruction.L0SubType.class, | 320 | L0ModificationInstruction.L0SubType.class, |
320 | L0ModificationInstruction.ModLambdaInstruction.class, | 321 | L0ModificationInstruction.ModLambdaInstruction.class, | ... | ... |
... | @@ -19,9 +19,12 @@ import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsent | ... | @@ -19,9 +19,12 @@ import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsent |
19 | import static org.slf4j.LoggerFactory.getLogger; | 19 | import static org.slf4j.LoggerFactory.getLogger; |
20 | 20 | ||
21 | import java.util.ArrayList; | 21 | import java.util.ArrayList; |
22 | +import java.util.Collection; | ||
22 | import java.util.HashMap; | 23 | import java.util.HashMap; |
24 | +import java.util.Iterator; | ||
23 | import java.util.List; | 25 | import java.util.List; |
24 | import java.util.Optional; | 26 | import java.util.Optional; |
27 | +import java.util.Set; | ||
25 | import java.util.concurrent.ConcurrentHashMap; | 28 | import java.util.concurrent.ConcurrentHashMap; |
26 | import java.util.concurrent.ConcurrentMap; | 29 | import java.util.concurrent.ConcurrentMap; |
27 | import java.util.concurrent.atomic.AtomicInteger; | 30 | import java.util.concurrent.atomic.AtomicInteger; |
... | @@ -54,6 +57,7 @@ import org.slf4j.Logger; | ... | @@ -54,6 +57,7 @@ import org.slf4j.Logger; |
54 | 57 | ||
55 | import com.google.common.base.Function; | 58 | import com.google.common.base.Function; |
56 | import com.google.common.collect.FluentIterable; | 59 | import com.google.common.collect.FluentIterable; |
60 | +import com.google.common.collect.Sets; | ||
57 | 61 | ||
58 | /** | 62 | /** |
59 | * Manages inventory of group entries using trivial in-memory implementation. | 63 | * Manages inventory of group entries using trivial in-memory implementation. |
... | @@ -583,4 +587,131 @@ public class SimpleGroupStore | ... | @@ -583,4 +587,131 @@ public class SimpleGroupStore |
583 | getExtraneousGroupIdTable(deviceId).values()); | 587 | getExtraneousGroupIdTable(deviceId).values()); |
584 | } | 588 | } |
585 | 589 | ||
590 | + @Override | ||
591 | + public void pushGroupMetrics(DeviceId deviceId, | ||
592 | + Collection<Group> groupEntries) { | ||
593 | + boolean deviceInitialAuditStatus = | ||
594 | + deviceInitialAuditStatus(deviceId); | ||
595 | + Set<Group> southboundGroupEntries = | ||
596 | + Sets.newHashSet(groupEntries); | ||
597 | + Set<Group> storedGroupEntries = | ||
598 | + Sets.newHashSet(getGroups(deviceId)); | ||
599 | + Set<Group> extraneousStoredEntries = | ||
600 | + Sets.newHashSet(getExtraneousGroups(deviceId)); | ||
601 | + | ||
602 | + log.trace("pushGroupMetrics: Displaying all ({}) " | ||
603 | + + "southboundGroupEntries for device {}", | ||
604 | + southboundGroupEntries.size(), | ||
605 | + deviceId); | ||
606 | + for (Iterator<Group> it = southboundGroupEntries.iterator(); it.hasNext();) { | ||
607 | + Group group = it.next(); | ||
608 | + log.trace("Group {} in device {}", group, deviceId); | ||
609 | + } | ||
610 | + | ||
611 | + log.trace("Displaying all ({}) stored group entries for device {}", | ||
612 | + storedGroupEntries.size(), | ||
613 | + deviceId); | ||
614 | + for (Iterator<Group> it1 = storedGroupEntries.iterator(); | ||
615 | + it1.hasNext();) { | ||
616 | + Group group = it1.next(); | ||
617 | + log.trace("Stored Group {} for device {}", group, deviceId); | ||
618 | + } | ||
619 | + | ||
620 | + for (Iterator<Group> it2 = southboundGroupEntries.iterator(); it2.hasNext();) { | ||
621 | + Group group = it2.next(); | ||
622 | + if (storedGroupEntries.remove(group)) { | ||
623 | + // we both have the group, let's update some info then. | ||
624 | + log.trace("Group AUDIT: group {} exists " | ||
625 | + + "in both planes for device {}", | ||
626 | + group.id(), deviceId); | ||
627 | + groupAdded(group); | ||
628 | + it2.remove(); | ||
629 | + } | ||
630 | + } | ||
631 | + for (Group group : southboundGroupEntries) { | ||
632 | + if (getGroup(group.deviceId(), group.id()) != null) { | ||
633 | + // There is a group existing with the same id | ||
634 | + // It is possible that group update is | ||
635 | + // in progress while we got a stale info from switch | ||
636 | + if (!storedGroupEntries.remove(getGroup( | ||
637 | + group.deviceId(), group.id()))) { | ||
638 | + log.warn("Group AUDIT: Inconsistent state:" | ||
639 | + + "Group exists in ID based table while " | ||
640 | + + "not present in key based table"); | ||
641 | + } | ||
642 | + } else { | ||
643 | + // there are groups in the switch that aren't in the store | ||
644 | + log.trace("Group AUDIT: extraneous group {} exists " | ||
645 | + + "in data plane for device {}", | ||
646 | + group.id(), deviceId); | ||
647 | + extraneousStoredEntries.remove(group); | ||
648 | + extraneousGroup(group); | ||
649 | + } | ||
650 | + } | ||
651 | + for (Group group : storedGroupEntries) { | ||
652 | + // there are groups in the store that aren't in the switch | ||
653 | + log.trace("Group AUDIT: group {} missing " | ||
654 | + + "in data plane for device {}", | ||
655 | + group.id(), deviceId); | ||
656 | + groupMissing(group); | ||
657 | + } | ||
658 | + for (Group group : extraneousStoredEntries) { | ||
659 | + // there are groups in the extraneous store that | ||
660 | + // aren't in the switch | ||
661 | + log.trace("Group AUDIT: clearing extransoeus group {} " | ||
662 | + + "from store for device {}", | ||
663 | + group.id(), deviceId); | ||
664 | + removeExtraneousGroupEntry(group); | ||
665 | + } | ||
666 | + | ||
667 | + if (!deviceInitialAuditStatus) { | ||
668 | + log.debug("Group AUDIT: Setting device {} initial " | ||
669 | + + "AUDIT completed", deviceId); | ||
670 | + deviceInitialAuditCompleted(deviceId, true); | ||
671 | + } | ||
672 | + } | ||
673 | + | ||
674 | + private void groupMissing(Group group) { | ||
675 | + switch (group.state()) { | ||
676 | + case PENDING_DELETE: | ||
677 | + log.debug("Group {} delete confirmation from device {}", | ||
678 | + group, group.deviceId()); | ||
679 | + removeGroupEntry(group); | ||
680 | + break; | ||
681 | + case ADDED: | ||
682 | + case PENDING_ADD: | ||
683 | + case PENDING_UPDATE: | ||
684 | + log.debug("Group {} is in store but not on device {}", | ||
685 | + group, group.deviceId()); | ||
686 | + StoredGroupEntry existing = (groupEntriesById.get( | ||
687 | + group.deviceId()) != null) ? | ||
688 | + groupEntriesById.get(group.deviceId()).get(group.id()) : | ||
689 | + null; | ||
690 | + log.trace("groupMissing: group " | ||
691 | + + "entry {} in device {} moving " | ||
692 | + + "from {} to PENDING_ADD", | ||
693 | + existing.id(), | ||
694 | + existing.deviceId(), | ||
695 | + existing.state()); | ||
696 | + existing.setState(Group.GroupState.PENDING_ADD); | ||
697 | + notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED, | ||
698 | + group)); | ||
699 | + break; | ||
700 | + default: | ||
701 | + log.debug("Group {} has not been installed.", group); | ||
702 | + break; | ||
703 | + } | ||
704 | + } | ||
705 | + | ||
706 | + private void extraneousGroup(Group group) { | ||
707 | + log.debug("Group {} is on device {} but not in store.", | ||
708 | + group, group.deviceId()); | ||
709 | + addOrUpdateExtraneousGroupEntry(group); | ||
710 | + } | ||
711 | + | ||
712 | + private void groupAdded(Group group) { | ||
713 | + log.trace("Group {} Added or Updated in device {}", | ||
714 | + group, group.deviceId()); | ||
715 | + addOrUpdateGroupEntry(group); | ||
716 | + } | ||
586 | } | 717 | } | ... | ... |
... | @@ -195,11 +195,17 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -195,11 +195,17 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
195 | @Override | 195 | @Override |
196 | public void onSuccess(FlowRuleOperations ops) { | 196 | public void onSuccess(FlowRuleOperations ops) { |
197 | pass(fwd); | 197 | pass(fwd); |
198 | + log.debug("Provisioned tables in {} with " | ||
199 | + + "forwarding rules for segment " | ||
200 | + + "router", deviceId); | ||
198 | } | 201 | } |
199 | 202 | ||
200 | @Override | 203 | @Override |
201 | public void onError(FlowRuleOperations ops) { | 204 | public void onError(FlowRuleOperations ops) { |
202 | fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED); | 205 | fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED); |
206 | + log.warn("Failed to provision tables in {} with " | ||
207 | + + "forwarding rules for segment router", | ||
208 | + deviceId); | ||
203 | } | 209 | } |
204 | })); | 210 | })); |
205 | 211 | ||
... | @@ -228,6 +234,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -228,6 +234,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
228 | } | 234 | } |
229 | 235 | ||
230 | private void removeGroup(NextObjective nextObjective) { | 236 | private void removeGroup(NextObjective nextObjective) { |
237 | + log.debug("removeGroup in {}: for next objective id {}", | ||
238 | + deviceId, nextObjective.id()); | ||
231 | final GroupKey key = new DefaultGroupKey( | 239 | final GroupKey key = new DefaultGroupKey( |
232 | appKryo.serialize(nextObjective.id())); | 240 | appKryo.serialize(nextObjective.id())); |
233 | groupService.removeGroup(deviceId, key, appId); | 241 | groupService.removeGroup(deviceId, key, appId); |
... | @@ -293,6 +301,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -293,6 +301,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
293 | } | 301 | } |
294 | 302 | ||
295 | private void addBucketToGroup(NextObjective nextObjective) { | 303 | private void addBucketToGroup(NextObjective nextObjective) { |
304 | + log.debug("addBucketToGroup in {}: for next objective id {}", | ||
305 | + deviceId, nextObjective.id()); | ||
296 | Collection<TrafficTreatment> treatments = nextObjective.next(); | 306 | Collection<TrafficTreatment> treatments = nextObjective.next(); |
297 | TrafficTreatment treatment = treatments.iterator().next(); | 307 | TrafficTreatment treatment = treatments.iterator().next(); |
298 | final GroupKey key = new DefaultGroupKey( | 308 | final GroupKey key = new DefaultGroupKey( |
... | @@ -317,6 +327,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -317,6 +327,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
317 | } | 327 | } |
318 | 328 | ||
319 | private void removeBucketFromGroup(NextObjective nextObjective) { | 329 | private void removeBucketFromGroup(NextObjective nextObjective) { |
330 | + log.debug("removeBucketFromGroup in {}: for next objective id {}", | ||
331 | + deviceId, nextObjective.id()); | ||
320 | NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id()); | 332 | NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id()); |
321 | if (nextGroup != null) { | 333 | if (nextGroup != null) { |
322 | Collection<TrafficTreatment> treatments = nextObjective.next(); | 334 | Collection<TrafficTreatment> treatments = nextObjective.next(); |
... | @@ -369,7 +381,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -369,7 +381,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
369 | if ((ethType == null) || | 381 | if ((ethType == null) || |
370 | ((((short) ethType.ethType()) != Ethernet.TYPE_IPV4) && | 382 | ((((short) ethType.ethType()) != Ethernet.TYPE_IPV4) && |
371 | (((short) ethType.ethType()) != Ethernet.MPLS_UNICAST))) { | 383 | (((short) ethType.ethType()) != Ethernet.MPLS_UNICAST))) { |
372 | - log.debug("processSpecific: Unsupported " | 384 | + log.warn("processSpecific: Unsupported " |
373 | + "forwarding objective criteraia"); | 385 | + "forwarding objective criteraia"); |
374 | fail(fwd, ObjectiveError.UNSUPPORTED); | 386 | fail(fwd, ObjectiveError.UNSUPPORTED); |
375 | return Collections.emptySet(); | 387 | return Collections.emptySet(); |
... | @@ -424,6 +436,10 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -424,6 +436,10 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
424 | } | 436 | } |
425 | treatmentBuilder.group(group.id()); | 437 | treatmentBuilder.group(group.id()); |
426 | log.debug("Adding OUTGROUP action"); | 438 | log.debug("Adding OUTGROUP action"); |
439 | + } else { | ||
440 | + log.warn("processSpecific: No associated next objective object"); | ||
441 | + fail(fwd, ObjectiveError.GROUPMISSING); | ||
442 | + return Collections.emptySet(); | ||
427 | } | 443 | } |
428 | } | 444 | } |
429 | 445 | ||
... | @@ -485,15 +501,39 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -485,15 +501,39 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
485 | return rules; | 501 | return rules; |
486 | } | 502 | } |
487 | 503 | ||
504 | + protected List<FlowRule> processVlanIdFilter(Criterion c, | ||
505 | + FilteringObjective filt, | ||
506 | + ApplicationId applicationId) { | ||
507 | + List<FlowRule> rules = new ArrayList<FlowRule>(); | ||
508 | + VlanIdCriterion v = (VlanIdCriterion) c; | ||
509 | + log.debug("adding rule for VLAN: {}", v.vlanId()); | ||
510 | + TrafficSelector.Builder selector = DefaultTrafficSelector | ||
511 | + .builder(); | ||
512 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment | ||
513 | + .builder(); | ||
514 | + PortCriterion p = (PortCriterion) filt.key(); | ||
515 | + if (v.vlanId() != VlanId.NONE) { | ||
516 | + selector.matchVlanId(v.vlanId()); | ||
517 | + selector.matchInPort(p.port()); | ||
518 | + treatment.deferred().popVlan(); | ||
519 | + } | ||
520 | + treatment.transition(tmacTableId); | ||
521 | + FlowRule rule = DefaultFlowRule.builder().forDevice(deviceId) | ||
522 | + .withSelector(selector.build()) | ||
523 | + .withTreatment(treatment.build()) | ||
524 | + .withPriority(filt.priority()).fromApp(applicationId) | ||
525 | + .makePermanent().forTable(vlanTableId).build(); | ||
526 | + rules.add(rule); | ||
527 | + | ||
528 | + return rules; | ||
529 | + } | ||
530 | + | ||
488 | private void processFilter(FilteringObjective filt, boolean install, | 531 | private void processFilter(FilteringObjective filt, boolean install, |
489 | ApplicationId applicationId) { | 532 | ApplicationId applicationId) { |
490 | // This driver only processes filtering criteria defined with switch | 533 | // This driver only processes filtering criteria defined with switch |
491 | // ports as the key | 534 | // ports as the key |
492 | - PortCriterion p; | 535 | + if (filt.key().equals(Criteria.dummy()) |
493 | - if (!filt.key().equals(Criteria.dummy()) | 536 | + || filt.key().type() != Criterion.Type.IN_PORT) { |
494 | - && filt.key().type() == Criterion.Type.IN_PORT) { | ||
495 | - p = (PortCriterion) filt.key(); | ||
496 | - } else { | ||
497 | log.warn("No key defined in filtering objective from app: {}. Not" | 537 | log.warn("No key defined in filtering objective from app: {}. Not" |
498 | + "processing filtering objective", applicationId); | 538 | + "processing filtering objective", applicationId); |
499 | fail(filt, ObjectiveError.UNKNOWN); | 539 | fail(filt, ObjectiveError.UNKNOWN); |
... | @@ -509,24 +549,11 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -509,24 +549,11 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
509 | ops = install ? ops.add(rule) : ops.remove(rule); | 549 | ops = install ? ops.add(rule) : ops.remove(rule); |
510 | } | 550 | } |
511 | } else if (c.type() == Criterion.Type.VLAN_VID) { | 551 | } else if (c.type() == Criterion.Type.VLAN_VID) { |
512 | - VlanIdCriterion v = (VlanIdCriterion) c; | 552 | + for (FlowRule rule : processVlanIdFilter(c, |
513 | - log.debug("adding rule for VLAN: {}", v.vlanId()); | 553 | + filt, |
514 | - TrafficSelector.Builder selector = DefaultTrafficSelector | 554 | + applicationId)) { |
515 | - .builder(); | ||
516 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment | ||
517 | - .builder(); | ||
518 | - if (v.vlanId() != VlanId.NONE) { | ||
519 | - selector.matchVlanId(v.vlanId()); | ||
520 | - selector.matchInPort(p.port()); | ||
521 | - treatment.deferred().popVlan(); | ||
522 | - } | ||
523 | - treatment.transition(tmacTableId); | ||
524 | - FlowRule rule = DefaultFlowRule.builder().forDevice(deviceId) | ||
525 | - .withSelector(selector.build()) | ||
526 | - .withTreatment(treatment.build()) | ||
527 | - .withPriority(filt.priority()).fromApp(applicationId) | ||
528 | - .makePermanent().forTable(vlanTableId).build(); | ||
529 | ops = install ? ops.add(rule) : ops.remove(rule); | 555 | ops = install ? ops.add(rule) : ops.remove(rule); |
556 | + } | ||
530 | } else if (c.type() == Criterion.Type.IPV4_DST) { | 557 | } else if (c.type() == Criterion.Type.IPV4_DST) { |
531 | IPCriterion ip = (IPCriterion) c; | 558 | IPCriterion ip = (IPCriterion) c; |
532 | log.debug("adding rule for IP: {}", ip.ip()); | 559 | log.debug("adding rule for IP: {}", ip.ip()); |
... | @@ -554,13 +581,15 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -554,13 +581,15 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
554 | @Override | 581 | @Override |
555 | public void onSuccess(FlowRuleOperations ops) { | 582 | public void onSuccess(FlowRuleOperations ops) { |
556 | pass(filt); | 583 | pass(filt); |
557 | - log.info("Provisioned tables for segment router"); | 584 | + log.debug("Provisioned tables in {} with fitering " |
585 | + + "rules for segment router", deviceId); | ||
558 | } | 586 | } |
559 | 587 | ||
560 | @Override | 588 | @Override |
561 | public void onError(FlowRuleOperations ops) { | 589 | public void onError(FlowRuleOperations ops) { |
562 | fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED); | 590 | fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED); |
563 | - log.info("Failed to provision tables for segment router"); | 591 | + log.warn("Failed to provision tables in {} with " |
592 | + + "fitering rules for segment router", deviceId); | ||
564 | } | 593 | } |
565 | })); | 594 | })); |
566 | } | 595 | } |
... | @@ -618,6 +647,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -618,6 +647,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
618 | @Override | 647 | @Override |
619 | public void event(GroupEvent event) { | 648 | public void event(GroupEvent event) { |
620 | if (event.type() == GroupEvent.Type.GROUP_ADDED) { | 649 | if (event.type() == GroupEvent.Type.GROUP_ADDED) { |
650 | + log.debug("InnerGroupListener: Group ADDED " | ||
651 | + + "event received in device {}", deviceId); | ||
621 | GroupKey key = event.subject().appCookie(); | 652 | GroupKey key = event.subject().appCookie(); |
622 | 653 | ||
623 | NextObjective obj = pendingGroups.getIfPresent(key); | 654 | NextObjective obj = pendingGroups.getIfPresent(key); |
... | @@ -628,6 +659,9 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -628,6 +659,9 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
628 | pass(obj); | 659 | pass(obj); |
629 | pendingGroups.invalidate(key); | 660 | pendingGroups.invalidate(key); |
630 | } | 661 | } |
662 | + } else if (event.type() == GroupEvent.Type.GROUP_ADD_FAILED) { | ||
663 | + log.warn("InnerGroupListener: Group ADD " | ||
664 | + + "failed event received in device {}", deviceId); | ||
631 | } | 665 | } |
632 | } | 666 | } |
633 | } | 667 | } | ... | ... |
... | @@ -15,7 +15,6 @@ | ... | @@ -15,7 +15,6 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.driver.pipeline; | 16 | package org.onosproject.driver.pipeline; |
17 | 17 | ||
18 | -import java.util.ArrayList; | ||
19 | import java.util.Collection; | 18 | import java.util.Collection; |
20 | import java.util.Collections; | 19 | import java.util.Collections; |
21 | import java.util.List; | 20 | import java.util.List; |
... | @@ -145,6 +144,10 @@ public class SpringOpenTTPDell extends SpringOpenTTP { | ... | @@ -145,6 +144,10 @@ public class SpringOpenTTPDell extends SpringOpenTTP { |
145 | } | 144 | } |
146 | treatmentBuilder.group(group.id()); | 145 | treatmentBuilder.group(group.id()); |
147 | log.debug("Adding OUTGROUP action"); | 146 | log.debug("Adding OUTGROUP action"); |
147 | + } else { | ||
148 | + log.warn("processSpecific: No associated next objective object"); | ||
149 | + fail(fwd, ObjectiveError.GROUPMISSING); | ||
150 | + return Collections.emptySet(); | ||
148 | } | 151 | } |
149 | } | 152 | } |
150 | 153 | ||
... | @@ -175,43 +178,23 @@ public class SpringOpenTTPDell extends SpringOpenTTP { | ... | @@ -175,43 +178,23 @@ public class SpringOpenTTPDell extends SpringOpenTTP { |
175 | protected List<FlowRule> processEthDstFilter(Criterion c, | 178 | protected List<FlowRule> processEthDstFilter(Criterion c, |
176 | FilteringObjective filt, | 179 | FilteringObjective filt, |
177 | ApplicationId applicationId) { | 180 | ApplicationId applicationId) { |
178 | - List<FlowRule> rules = new ArrayList<FlowRule>(); | ||
179 | - EthCriterion e = (EthCriterion) c; | ||
180 | - TrafficSelector.Builder selectorIp = DefaultTrafficSelector | ||
181 | - .builder(); | ||
182 | - TrafficTreatment.Builder treatmentIp = DefaultTrafficTreatment | ||
183 | - .builder(); | ||
184 | - | ||
185 | // Store device termination Mac to be used in IP flow entries | 181 | // Store device termination Mac to be used in IP flow entries |
182 | + EthCriterion e = (EthCriterion) c; | ||
186 | deviceTMac = e.mac(); | 183 | deviceTMac = e.mac(); |
187 | 184 | ||
188 | - selectorIp.matchEthDst(e.mac()); | 185 | + log.debug("For now not adding any TMAC rules " |
189 | - selectorIp.matchEthType(Ethernet.TYPE_IPV4); | 186 | + + "into Dell switches as it is ignoring"); |
190 | - treatmentIp.transition(ipv4UnicastTableId); | 187 | + |
191 | - FlowRule ruleIp = DefaultFlowRule.builder().forDevice(deviceId) | 188 | + return Collections.emptyList(); |
192 | - .withSelector(selectorIp.build()) | ||
193 | - .withTreatment(treatmentIp.build()) | ||
194 | - .withPriority(filt.priority()).fromApp(applicationId) | ||
195 | - .makePermanent().forTable(tmacTableId).build(); | ||
196 | - log.debug("adding IP ETH rule for MAC: {}", e.mac()); | ||
197 | - rules.add(ruleIp); | ||
198 | - | ||
199 | - TrafficSelector.Builder selectorMpls = DefaultTrafficSelector | ||
200 | - .builder(); | ||
201 | - TrafficTreatment.Builder treatmentMpls = DefaultTrafficTreatment | ||
202 | - .builder(); | ||
203 | - selectorMpls.matchEthDst(e.mac()); | ||
204 | - selectorMpls.matchEthType(Ethernet.MPLS_UNICAST); | ||
205 | - treatmentMpls.transition(mplsTableId); | ||
206 | - FlowRule ruleMpls = DefaultFlowRule.builder() | ||
207 | - .forDevice(deviceId).withSelector(selectorMpls.build()) | ||
208 | - .withTreatment(treatmentMpls.build()) | ||
209 | - .withPriority(filt.priority()).fromApp(applicationId) | ||
210 | - .makePermanent().forTable(tmacTableId).build(); | ||
211 | - log.debug("adding MPLS ETH rule for MAC: {}", e.mac()); | ||
212 | - rules.add(ruleMpls); | ||
213 | - | ||
214 | - return rules; | ||
215 | } | 189 | } |
216 | 190 | ||
191 | + @Override | ||
192 | + protected List<FlowRule> processVlanIdFilter(Criterion c, | ||
193 | + FilteringObjective filt, | ||
194 | + ApplicationId applicationId) { | ||
195 | + log.debug("For now not adding any VLAN rules " | ||
196 | + + "into Dell switches as it is ignoring"); | ||
197 | + | ||
198 | + return Collections.emptyList(); | ||
199 | + } | ||
217 | } | 200 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -37,13 +37,6 @@ | ... | @@ -37,13 +37,6 @@ |
37 | <behaviour api="org.onosproject.net.behaviour.Pipeliner" | 37 | <behaviour api="org.onosproject.net.behaviour.Pipeliner" |
38 | impl="org.onosproject.driver.pipeline.SpringOpenTTPDell"/> | 38 | impl="org.onosproject.driver.pipeline.SpringOpenTTPDell"/> |
39 | </driver> | 39 | </driver> |
40 | - <driver name="cpqd" manufacturer="Stanford University, Ericsson Research and CPqD Research" | ||
41 | - hwVersion="OpenFlow 1.3 Reference Userspace Switch" swVersion=".*"> | ||
42 | - <behaviour api="org.onosproject.net.behaviour.Pipeliner" | ||
43 | - impl="org.onosproject.driver.pipeline.SpringOpenTTP"/> | ||
44 | - <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" | ||
45 | - impl="org.onosproject.driver.handshaker.OFSwitchImplSpringOpenTTP"/> | ||
46 | - </driver> | ||
47 | <driver name="linc-oe" extends="default" | 40 | <driver name="linc-oe" extends="default" |
48 | manufacturer="FlowForwarding.org" hwVersion="Unknown" swVersion="LINC-OE OpenFlow Software Switch 1.1"> | 41 | manufacturer="FlowForwarding.org" hwVersion="Unknown" swVersion="LINC-OE OpenFlow Software Switch 1.1"> |
49 | <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" | 42 | <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" | ... | ... |
... | @@ -295,7 +295,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { | ... | @@ -295,7 +295,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { |
295 | return; | 295 | return; |
296 | } | 296 | } |
297 | if (m.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { | 297 | if (m.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { |
298 | - log.warn("Stats reply indicates more stats from sw {} for " | 298 | + log.debug("Stats reply indicates more stats from sw {} for " |
299 | + "port description", | 299 | + "port description", |
300 | h.getSwitchInfoString()); | 300 | h.getSwitchInfoString()); |
301 | h.portDescReplies.add((OFPortDescStatsReply)m); | 301 | h.portDescReplies.add((OFPortDescStatsReply)m); | ... | ... |
-
Please register or login to post a comment