Committed by
Gerrit Code Review
ONOS-1438: Segment Routing rule population optimization fixes
Change-Id: I2cad2cd485282b904e035b209530005b93c90ffd
Showing
6 changed files
with
113 additions
and
37 deletions
... | @@ -184,21 +184,40 @@ public class DefaultRoutingHandler { | ... | @@ -184,21 +184,40 @@ public class DefaultRoutingHandler { |
184 | 184 | ||
185 | private boolean repopulateRoutingRulesForRoutes(Set<ArrayList<DeviceId>> routes) { | 185 | private boolean repopulateRoutingRulesForRoutes(Set<ArrayList<DeviceId>> routes) { |
186 | rulePopulator.resetCounter(); | 186 | rulePopulator.resetCounter(); |
187 | + HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> routesBydevice = | ||
188 | + new HashMap<>(); | ||
187 | for (ArrayList<DeviceId> link: routes) { | 189 | for (ArrayList<DeviceId> link: routes) { |
188 | // When only the source device is defined, reinstall routes to all other devices | 190 | // When only the source device is defined, reinstall routes to all other devices |
189 | if (link.size() == 1) { | 191 | if (link.size() == 1) { |
190 | log.trace("repopulateRoutingRulesForRoutes: running ECMP graph for device {}", link.get(0)); | 192 | log.trace("repopulateRoutingRulesForRoutes: running ECMP graph for device {}", link.get(0)); |
191 | ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(link.get(0), srManager); | 193 | ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(link.get(0), srManager); |
192 | if (populateEcmpRoutingRules(link.get(0), ecmpSpg)) { | 194 | if (populateEcmpRoutingRules(link.get(0), ecmpSpg)) { |
195 | + log.debug("Populating flow rules from {} to all is successful", | ||
196 | + link.get(0)); | ||
193 | currentEcmpSpgMap.put(link.get(0), ecmpSpg); | 197 | currentEcmpSpgMap.put(link.get(0), ecmpSpg); |
194 | } else { | 198 | } else { |
195 | log.warn("Failed to populate the flow rules from {} to all", link.get(0)); | 199 | log.warn("Failed to populate the flow rules from {} to all", link.get(0)); |
196 | return false; | 200 | return false; |
197 | } | 201 | } |
198 | } else { | 202 | } else { |
203 | + ArrayList<ArrayList<DeviceId>> deviceRoutes = | ||
204 | + routesBydevice.get(link.get(1)); | ||
205 | + if (deviceRoutes == null) { | ||
206 | + deviceRoutes = new ArrayList<>(); | ||
207 | + routesBydevice.put(link.get(1), deviceRoutes); | ||
208 | + } | ||
209 | + deviceRoutes.add(link); | ||
210 | + } | ||
211 | + } | ||
212 | + | ||
213 | + for (DeviceId impactedDevice : routesBydevice.keySet()) { | ||
214 | + ArrayList<ArrayList<DeviceId>> deviceRoutes = | ||
215 | + routesBydevice.get(impactedDevice); | ||
216 | + for (ArrayList<DeviceId> link: deviceRoutes) { | ||
217 | + log.debug("repopulate RoutingRules For Routes {} -> {}", | ||
218 | + link.get(0), link.get(1)); | ||
199 | DeviceId src = link.get(0); | 219 | DeviceId src = link.get(0); |
200 | DeviceId dst = link.get(1); | 220 | DeviceId dst = link.get(1); |
201 | - log.trace("repopulateRoutingRulesForRoutes: running ECMP graph for device {}", dst); | ||
202 | ECMPShortestPathGraph ecmpSpg = updatedEcmpSpgMap.get(dst); | 221 | ECMPShortestPathGraph ecmpSpg = updatedEcmpSpgMap.get(dst); |
203 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = | 222 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = |
204 | ecmpSpg.getAllLearnedSwitchesAndVia(); | 223 | ecmpSpg.getAllLearnedSwitchesAndVia(); |
... | @@ -220,10 +239,18 @@ public class DefaultRoutingHandler { | ... | @@ -220,10 +239,18 @@ public class DefaultRoutingHandler { |
220 | if (!populateEcmpRoutingRulePartial(targetSw, dst, nextHops)) { | 239 | if (!populateEcmpRoutingRulePartial(targetSw, dst, nextHops)) { |
221 | return false; | 240 | return false; |
222 | } | 241 | } |
242 | + log.debug("Populating flow rules from {} to {} is successful", | ||
243 | + targetSw, dst); | ||
223 | } | 244 | } |
224 | } | 245 | } |
225 | - currentEcmpSpgMap.put(dst, ecmpSpg); | 246 | + //currentEcmpSpgMap.put(dst, ecmpSpg); |
226 | } | 247 | } |
248 | + //Only if all the flows for all impacted routes to a | ||
249 | + //specific target are pushed successfully, update the | ||
250 | + //ECMP graph for that target. (Or else the next event | ||
251 | + //would not see any changes in the ECMP graphs) | ||
252 | + currentEcmpSpgMap.put(impactedDevice, | ||
253 | + updatedEcmpSpgMap.get(impactedDevice)); | ||
227 | } | 254 | } |
228 | return true; | 255 | return true; |
229 | } | 256 | } |
... | @@ -233,13 +260,15 @@ public class DefaultRoutingHandler { | ... | @@ -233,13 +260,15 @@ public class DefaultRoutingHandler { |
233 | Set<ArrayList<DeviceId>> routes = new HashSet<>(); | 260 | Set<ArrayList<DeviceId>> routes = new HashSet<>(); |
234 | 261 | ||
235 | for (Device sw : srManager.deviceService.getDevices()) { | 262 | for (Device sw : srManager.deviceService.getDevices()) { |
263 | + log.debug("Computing the impacted routes for device {} due to link fail", | ||
264 | + sw.id()); | ||
236 | if (srManager.mastershipService. | 265 | if (srManager.mastershipService. |
237 | getLocalRole(sw.id()) != MastershipRole.MASTER) { | 266 | getLocalRole(sw.id()) != MastershipRole.MASTER) { |
238 | continue; | 267 | continue; |
239 | } | 268 | } |
240 | ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); | 269 | ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); |
241 | if (ecmpSpg == null) { | 270 | if (ecmpSpg == null) { |
242 | - log.error("No existing ECMP path for switch {}", sw.id()); | 271 | + log.error("No existing ECMP graph for switch {}", sw.id()); |
243 | continue; | 272 | continue; |
244 | } | 273 | } |
245 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = | 274 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = |
... | @@ -252,8 +281,12 @@ public class DefaultRoutingHandler { | ... | @@ -252,8 +281,12 @@ public class DefaultRoutingHandler { |
252 | Set<ArrayList<DeviceId>> subLinks = | 281 | Set<ArrayList<DeviceId>> subLinks = |
253 | computeLinks(targetSw, destSw, swViaMap); | 282 | computeLinks(targetSw, destSw, swViaMap); |
254 | for (ArrayList<DeviceId> alink: subLinks) { | 283 | for (ArrayList<DeviceId> alink: subLinks) { |
255 | - if (alink.get(0).equals(linkFail.src().deviceId()) && | 284 | + if ((alink.get(0).equals(linkFail.src().deviceId()) && |
256 | - alink.get(1).equals(linkFail.dst().deviceId())) { | 285 | + alink.get(1).equals(linkFail.dst().deviceId())) |
286 | + || | ||
287 | + (alink.get(0).equals(linkFail.dst().deviceId()) && | ||
288 | + alink.get(1).equals(linkFail.src().deviceId()))) { | ||
289 | + log.debug("Impacted route:{}->{}", targetSw, destSw); | ||
257 | ArrayList<DeviceId> aRoute = new ArrayList<>(); | 290 | ArrayList<DeviceId> aRoute = new ArrayList<>(); |
258 | aRoute.add(targetSw); | 291 | aRoute.add(targetSw); |
259 | aRoute.add(destSw); | 292 | aRoute.add(destSw); |
... | @@ -274,9 +307,12 @@ public class DefaultRoutingHandler { | ... | @@ -274,9 +307,12 @@ public class DefaultRoutingHandler { |
274 | Set<ArrayList<DeviceId>> routes = new HashSet<>(); | 307 | Set<ArrayList<DeviceId>> routes = new HashSet<>(); |
275 | 308 | ||
276 | for (Device sw : srManager.deviceService.getDevices()) { | 309 | for (Device sw : srManager.deviceService.getDevices()) { |
310 | + log.debug("Computing the impacted routes for device {}", | ||
311 | + sw.id()); | ||
277 | if (srManager.mastershipService. | 312 | if (srManager.mastershipService. |
278 | getLocalRole(sw.id()) != MastershipRole.MASTER) { | 313 | getLocalRole(sw.id()) != MastershipRole.MASTER) { |
279 | - log.warn("No mastership for {} and skip route optimization"); | 314 | + log.debug("No mastership for {} and skip route optimization", |
315 | + sw.id()); | ||
280 | continue; | 316 | continue; |
281 | } | 317 | } |
282 | 318 | ||
... | @@ -295,7 +331,7 @@ public class DefaultRoutingHandler { | ... | @@ -295,7 +331,7 @@ public class DefaultRoutingHandler { |
295 | continue; | 331 | continue; |
296 | } | 332 | } |
297 | ECMPShortestPathGraph newEcmpSpg = updatedEcmpSpgMap.get(sw.id()); | 333 | ECMPShortestPathGraph newEcmpSpg = updatedEcmpSpgMap.get(sw.id()); |
298 | - currentEcmpSpgMap.put(sw.id(), newEcmpSpg); | 334 | + //currentEcmpSpgMap.put(sw.id(), newEcmpSpg); |
299 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = | 335 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = |
300 | ecmpSpg.getAllLearnedSwitchesAndVia(); | 336 | ecmpSpg.getAllLearnedSwitchesAndVia(); |
301 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchViaUpdated = | 337 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchViaUpdated = |
... | @@ -307,7 +343,8 @@ public class DefaultRoutingHandler { | ... | @@ -307,7 +343,8 @@ public class DefaultRoutingHandler { |
307 | for (DeviceId srcSw : swViaMapUpdated.keySet()) { | 343 | for (DeviceId srcSw : swViaMapUpdated.keySet()) { |
308 | ArrayList<ArrayList<DeviceId>> viaUpdated = swViaMapUpdated.get(srcSw); | 344 | ArrayList<ArrayList<DeviceId>> viaUpdated = swViaMapUpdated.get(srcSw); |
309 | ArrayList<ArrayList<DeviceId>> via = getVia(switchVia, srcSw); | 345 | ArrayList<ArrayList<DeviceId>> via = getVia(switchVia, srcSw); |
310 | - if (via.isEmpty() || !viaUpdated.equals(via)) { | 346 | + if ((via == null) || !viaUpdated.equals(via)) { |
347 | + log.debug("Impacted route:{}->{}", srcSw, sw.id()); | ||
311 | ArrayList<DeviceId> route = new ArrayList<>(); | 348 | ArrayList<DeviceId> route = new ArrayList<>(); |
312 | route.add(srcSw); | 349 | route.add(srcSw); |
313 | route.add(sw.id()); | 350 | route.add(sw.id()); |
... | @@ -318,7 +355,7 @@ public class DefaultRoutingHandler { | ... | @@ -318,7 +355,7 @@ public class DefaultRoutingHandler { |
318 | } | 355 | } |
319 | 356 | ||
320 | for (ArrayList<DeviceId> link: routes) { | 357 | for (ArrayList<DeviceId> link: routes) { |
321 | - log.trace("Link changes - "); | 358 | + log.trace("Route changes - "); |
322 | if (link.size() == 1) { | 359 | if (link.size() == 1) { |
323 | log.trace(" : {} - all", link.get(0)); | 360 | log.trace(" : {} - all", link.get(0)); |
324 | } else { | 361 | } else { |
... | @@ -341,7 +378,7 @@ public class DefaultRoutingHandler { | ... | @@ -341,7 +378,7 @@ public class DefaultRoutingHandler { |
341 | } | 378 | } |
342 | } | 379 | } |
343 | 380 | ||
344 | - return new ArrayList<>(); | 381 | + return null; |
345 | } | 382 | } |
346 | 383 | ||
347 | private Set<ArrayList<DeviceId>> computeLinks(DeviceId src, | 384 | private Set<ArrayList<DeviceId>> computeLinks(DeviceId src, | ... | ... |
... | @@ -133,7 +133,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -133,7 +133,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
133 | 133 | ||
134 | private NetworkConfigManager networkConfigService = new NetworkConfigManager();; | 134 | private NetworkConfigManager networkConfigService = new NetworkConfigManager();; |
135 | 135 | ||
136 | - private static int numOfEvents = 0; | 136 | + private Object threadSchedulerLock = new Object(); |
137 | + private static int numOfEventsQueued = 0; | ||
138 | + private static int numOfEventsExecuted = 0; | ||
137 | private static int numOfHandlerExecution = 0; | 139 | private static int numOfHandlerExecution = 0; |
138 | private static int numOfHandlerScheduled = 0; | 140 | private static int numOfHandlerScheduled = 0; |
139 | 141 | ||
... | @@ -325,6 +327,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -325,6 +327,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
325 | public void event(LinkEvent event) { | 327 | public void event(LinkEvent event) { |
326 | if (event.type() == LinkEvent.Type.LINK_ADDED | 328 | if (event.type() == LinkEvent.Type.LINK_ADDED |
327 | || event.type() == LinkEvent.Type.LINK_REMOVED) { | 329 | || event.type() == LinkEvent.Type.LINK_REMOVED) { |
330 | + log.debug("Event {} received from Link Service", event.type()); | ||
328 | scheduleEventHandlerIfNotScheduled(event); | 331 | scheduleEventHandlerIfNotScheduled(event); |
329 | } | 332 | } |
330 | } | 333 | } |
... | @@ -346,6 +349,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -346,6 +349,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
346 | case PORT_REMOVED: | 349 | case PORT_REMOVED: |
347 | case DEVICE_UPDATED: | 350 | case DEVICE_UPDATED: |
348 | case DEVICE_AVAILABILITY_CHANGED: | 351 | case DEVICE_AVAILABILITY_CHANGED: |
352 | + log.debug("Event {} received from Device Service", event.type()); | ||
349 | scheduleEventHandlerIfNotScheduled(event); | 353 | scheduleEventHandlerIfNotScheduled(event); |
350 | break; | 354 | break; |
351 | default: | 355 | default: |
... | @@ -355,19 +359,20 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -355,19 +359,20 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
355 | 359 | ||
356 | private void scheduleEventHandlerIfNotScheduled(Event event) { | 360 | private void scheduleEventHandlerIfNotScheduled(Event event) { |
357 | 361 | ||
358 | - synchronized (eventQueue) { | 362 | + synchronized (threadSchedulerLock) { |
359 | eventQueue.add(event); | 363 | eventQueue.add(event); |
360 | - numOfEvents++; | 364 | + numOfEventsQueued++; |
361 | - if (eventHandlerFuture == null || eventHandlerFuture.isDone()) { | 365 | + |
366 | + if ((numOfHandlerScheduled - numOfHandlerExecution) == 0) { | ||
367 | + //No pending scheduled event handling threads. So start a new one. | ||
362 | eventHandlerFuture = executorService | 368 | eventHandlerFuture = executorService |
363 | .schedule(eventHandler, 100, TimeUnit.MILLISECONDS); | 369 | .schedule(eventHandler, 100, TimeUnit.MILLISECONDS); |
364 | numOfHandlerScheduled++; | 370 | numOfHandlerScheduled++; |
365 | } | 371 | } |
366 | - } | 372 | + log.trace("numOfEventsQueued {}, numOfEventHanlderScheduled {}", |
367 | - | 373 | + numOfEventsQueued, |
368 | - log.trace("numOfEvents {}, numOfEventHanlderScheduled {}", numOfEvents, | ||
369 | numOfHandlerScheduled); | 374 | numOfHandlerScheduled); |
370 | - | 375 | + } |
371 | } | 376 | } |
372 | 377 | ||
373 | private class InternalEventHandler implements Runnable { | 378 | private class InternalEventHandler implements Runnable { |
... | @@ -375,10 +380,19 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -375,10 +380,19 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
375 | @Override | 380 | @Override |
376 | public void run() { | 381 | public void run() { |
377 | try { | 382 | try { |
378 | - synchronized (eventQueue) { | 383 | + while (true) { |
384 | + Event event = null; | ||
385 | + synchronized (threadSchedulerLock) { | ||
386 | + if (!eventQueue.isEmpty()) { | ||
387 | + event = eventQueue.poll(); | ||
388 | + numOfEventsExecuted++; | ||
389 | + } else { | ||
379 | numOfHandlerExecution++; | 390 | numOfHandlerExecution++; |
380 | - while (!eventQueue.isEmpty()) { | 391 | + log.debug("numOfHandlerExecution {} numOfEventsExecuted {}", |
381 | - Event event = eventQueue.poll(); | 392 | + numOfHandlerExecution, numOfEventsExecuted); |
393 | + break; | ||
394 | + } | ||
395 | + } | ||
382 | if (event.type() == LinkEvent.Type.LINK_ADDED) { | 396 | if (event.type() == LinkEvent.Type.LINK_ADDED) { |
383 | processLinkAdded((Link) event.subject()); | 397 | processLinkAdded((Link) event.subject()); |
384 | } else if (event.type() == LinkEvent.Type.LINK_REMOVED) { | 398 | } else if (event.type() == LinkEvent.Type.LINK_REMOVED) { |
... | @@ -398,9 +412,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -398,9 +412,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
398 | log.warn("Unhandled event type: {}", event.type()); | 412 | log.warn("Unhandled event type: {}", event.type()); |
399 | } | 413 | } |
400 | } | 414 | } |
401 | - } | ||
402 | - log.debug("numOfHandlerExecution {} numOfEventHanlderScheduled {} numOfEvents {}", | ||
403 | - numOfHandlerExecution, numOfHandlerScheduled, numOfEvents); | ||
404 | } catch (Exception e) { | 415 | } catch (Exception e) { |
405 | log.error("SegmentRouting event handler " | 416 | log.error("SegmentRouting event handler " |
406 | + "thread thrown an exception: {}", e); | 417 | + "thread thrown an exception: {}", e); |
... | @@ -433,9 +444,10 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -433,9 +444,10 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
433 | } | 444 | } |
434 | } | 445 | } |
435 | 446 | ||
436 | - //defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null); | 447 | + log.trace("Starting optimized route population process"); |
437 | - log.trace("processLinkAdded: re-starting route population process"); | 448 | + defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null); |
438 | - defaultRoutingHandler.startPopulationProcess(); | 449 | + //log.trace("processLinkAdded: re-starting route population process"); |
450 | + //defaultRoutingHandler.startPopulationProcess(); | ||
439 | } | 451 | } |
440 | 452 | ||
441 | private void processLinkRemoved(Link link) { | 453 | private void processLinkRemoved(Link link) { |
... | @@ -444,9 +456,10 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -444,9 +456,10 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
444 | if (groupHandler != null) { | 456 | if (groupHandler != null) { |
445 | groupHandler.portDown(link.src().port()); | 457 | groupHandler.portDown(link.src().port()); |
446 | } | 458 | } |
447 | - //defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link); | 459 | + log.trace("Starting optimized route population process"); |
448 | - log.trace("processLinkRemoved: re-starting route population process"); | 460 | + defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link); |
449 | - defaultRoutingHandler.startPopulationProcess(); | 461 | + //log.trace("processLinkRemoved: re-starting route population process"); |
462 | + //defaultRoutingHandler.startPopulationProcess(); | ||
450 | } | 463 | } |
451 | 464 | ||
452 | private void processDeviceAdded(Device device) { | 465 | private void processDeviceAdded(Device device) { | ... | ... |
... | @@ -35,6 +35,10 @@ public interface Group extends GroupDescription { | ... | @@ -35,6 +35,10 @@ public interface Group extends GroupDescription { |
35 | */ | 35 | */ |
36 | PENDING_ADD, | 36 | PENDING_ADD, |
37 | /** | 37 | /** |
38 | + * Group is missing in data plane and retrying GROUP ADD request. | ||
39 | + */ | ||
40 | + PENDING_ADD_RETRY, | ||
41 | + /** | ||
38 | * Group is created in the data plane. | 42 | * Group is created in the data plane. |
39 | */ | 43 | */ |
40 | ADDED, | 44 | ADDED, | ... | ... |
... | @@ -715,11 +715,12 @@ public class DistributedGroupStore | ... | @@ -715,11 +715,12 @@ public class DistributedGroupStore |
715 | existing.setLife(group.life()); | 715 | existing.setLife(group.life()); |
716 | existing.setPackets(group.packets()); | 716 | existing.setPackets(group.packets()); |
717 | existing.setBytes(group.bytes()); | 717 | existing.setBytes(group.bytes()); |
718 | - if (existing.state() == GroupState.PENDING_ADD) { | 718 | + if ((existing.state() == GroupState.PENDING_ADD) || |
719 | + (existing.state() == GroupState.PENDING_ADD_RETRY)) { | ||
719 | log.debug("addOrUpdateGroupEntry: group entry {} in device {} moving from {} to ADDED", | 720 | log.debug("addOrUpdateGroupEntry: group entry {} in device {} moving from {} to ADDED", |
720 | existing.id(), | 721 | existing.id(), |
721 | existing.deviceId(), | 722 | existing.deviceId(), |
722 | - GroupState.PENDING_ADD); | 723 | + existing.state()); |
723 | existing.setState(GroupState.ADDED); | 724 | existing.setState(GroupState.ADDED); |
724 | existing.setIsGroupStateAddedFirstTime(true); | 725 | existing.setIsGroupStateAddedFirstTime(true); |
725 | event = new GroupEvent(Type.GROUP_ADDED, existing); | 726 | event = new GroupEvent(Type.GROUP_ADDED, existing); |
... | @@ -839,6 +840,12 @@ public class DistributedGroupStore | ... | @@ -839,6 +840,12 @@ public class DistributedGroupStore |
839 | existing.deviceId()); | 840 | existing.deviceId()); |
840 | switch (operation.opType()) { | 841 | switch (operation.opType()) { |
841 | case ADD: | 842 | case ADD: |
843 | + if (existing.state() == GroupState.PENDING_ADD) { | ||
844 | + //TODO: Need to add support for passing the group | ||
845 | + //operation failure reason from group provider. | ||
846 | + //If the error type is anything other than GROUP_EXISTS, | ||
847 | + //then the GROUP_ADD_FAILED event should be raised even | ||
848 | + //in PENDING_ADD_RETRY state also. | ||
842 | notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); | 849 | notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); |
843 | log.warn("groupOperationFailed: cleaningup " | 850 | log.warn("groupOperationFailed: cleaningup " |
844 | + "group {} from store in device {}....", | 851 | + "group {} from store in device {}....", |
... | @@ -848,6 +855,7 @@ public class DistributedGroupStore | ... | @@ -848,6 +855,7 @@ public class DistributedGroupStore |
848 | //map update listener | 855 | //map update listener |
849 | getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), | 856 | getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), |
850 | existing.appCookie())); | 857 | existing.appCookie())); |
858 | + } | ||
851 | break; | 859 | break; |
852 | case MODIFY: | 860 | case MODIFY: |
853 | notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing)); | 861 | notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing)); |
... | @@ -1196,16 +1204,17 @@ public class DistributedGroupStore | ... | @@ -1196,16 +1204,17 @@ public class DistributedGroupStore |
1196 | break; | 1204 | break; |
1197 | case ADDED: | 1205 | case ADDED: |
1198 | case PENDING_ADD: | 1206 | case PENDING_ADD: |
1207 | + case PENDING_ADD_RETRY: | ||
1199 | case PENDING_UPDATE: | 1208 | case PENDING_UPDATE: |
1200 | log.debug("Group {} is in store but not on device {}", | 1209 | log.debug("Group {} is in store but not on device {}", |
1201 | group, group.deviceId()); | 1210 | group, group.deviceId()); |
1202 | StoredGroupEntry existing = | 1211 | StoredGroupEntry existing = |
1203 | getStoredGroupEntry(group.deviceId(), group.id()); | 1212 | getStoredGroupEntry(group.deviceId(), group.id()); |
1204 | - log.debug("groupMissing: group entry {} in device {} moving from {} to PENDING_ADD", | 1213 | + log.debug("groupMissing: group entry {} in device {} moving from {} to PENDING_ADD_RETRY", |
1205 | existing.id(), | 1214 | existing.id(), |
1206 | existing.deviceId(), | 1215 | existing.deviceId(), |
1207 | existing.state()); | 1216 | existing.state()); |
1208 | - existing.setState(Group.GroupState.PENDING_ADD); | 1217 | + existing.setState(Group.GroupState.PENDING_ADD_RETRY); |
1209 | //Re-PUT map entries to trigger map update events | 1218 | //Re-PUT map entries to trigger map update events |
1210 | getGroupStoreKeyMap(). | 1219 | getGroupStoreKeyMap(). |
1211 | put(new GroupStoreKeyMapKey(existing.deviceId(), | 1220 | put(new GroupStoreKeyMapKey(existing.deviceId(), | ... | ... |
... | @@ -215,6 +215,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -215,6 +215,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
215 | @Override | 215 | @Override |
216 | public void next(NextObjective nextObjective) { | 216 | public void next(NextObjective nextObjective) { |
217 | 217 | ||
218 | + log.debug("Processing NextObjective id{} op{}", nextObjective.id(), | ||
219 | + nextObjective.op()); | ||
218 | if (nextObjective.op() == Objective.Operation.REMOVE) { | 220 | if (nextObjective.op() == Objective.Operation.REMOVE) { |
219 | if (nextObjective.next().isEmpty()) { | 221 | if (nextObjective.next().isEmpty()) { |
220 | removeGroup(nextObjective); | 222 | removeGroup(nextObjective); |
... | @@ -243,6 +245,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -243,6 +245,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
243 | } | 245 | } |
244 | 246 | ||
245 | private void addGroup(NextObjective nextObjective) { | 247 | private void addGroup(NextObjective nextObjective) { |
248 | + log.debug("addGroup with type{} for nextObjective id {}", | ||
249 | + nextObjective.type(), nextObjective.id()); | ||
246 | switch (nextObjective.type()) { | 250 | switch (nextObjective.type()) { |
247 | case SIMPLE: | 251 | case SIMPLE: |
248 | log.debug("processing SIMPLE next objective"); | 252 | log.debug("processing SIMPLE next objective"); |
... | @@ -262,6 +266,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -262,6 +266,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
262 | key, | 266 | key, |
263 | null, | 267 | null, |
264 | nextObjective.appId()); | 268 | nextObjective.appId()); |
269 | + log.debug("Creating SIMPLE group for next objective id {}", | ||
270 | + nextObjective.id()); | ||
265 | groupService.addGroup(groupDescription); | 271 | groupService.addGroup(groupDescription); |
266 | pendingGroups.put(key, nextObjective); | 272 | pendingGroups.put(key, nextObjective); |
267 | } | 273 | } |
... | @@ -285,6 +291,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -285,6 +291,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
285 | key, | 291 | key, |
286 | null, | 292 | null, |
287 | nextObjective.appId()); | 293 | nextObjective.appId()); |
294 | + log.debug("Creating HASHED group for next objective id {}", | ||
295 | + nextObjective.id()); | ||
288 | groupService.addGroup(groupDescription); | 296 | groupService.addGroup(groupDescription); |
289 | pendingGroups.put(key, nextObjective); | 297 | pendingGroups.put(key, nextObjective); |
290 | } | 298 | } |
... | @@ -324,6 +332,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -324,6 +332,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
324 | return; | 332 | return; |
325 | } | 333 | } |
326 | GroupBuckets bucketsToAdd = new GroupBuckets(Collections.singletonList(bucket)); | 334 | GroupBuckets bucketsToAdd = new GroupBuckets(Collections.singletonList(bucket)); |
335 | + log.debug("Adding buckets to group id {} of next objective id {} in device {}", | ||
336 | + group.id(), nextObjective.id(), deviceId); | ||
327 | groupService.addBucketsToGroup(deviceId, key, bucketsToAdd, key, appId); | 337 | groupService.addBucketsToGroup(deviceId, key, bucketsToAdd, key, appId); |
328 | } | 338 | } |
329 | 339 | ||
... | @@ -352,6 +362,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -352,6 +362,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
352 | return; | 362 | return; |
353 | } | 363 | } |
354 | GroupBuckets removeBuckets = new GroupBuckets(Collections.singletonList(bucket)); | 364 | GroupBuckets removeBuckets = new GroupBuckets(Collections.singletonList(bucket)); |
365 | + log.debug("Removing buckets from group id {} of next objective id {} in device {}", | ||
366 | + group.id(), nextObjective.id(), deviceId); | ||
355 | groupService.removeBucketsFromGroup(deviceId, key, removeBuckets, key, appId); | 367 | groupService.removeBucketsFromGroup(deviceId, key, removeBuckets, key, appId); |
356 | } | 368 | } |
357 | } | 369 | } | ... | ... |
... | @@ -40,9 +40,10 @@ | ... | @@ -40,9 +40,10 @@ |
40 | "load": { | 40 | "load": { |
41 | "alpha": 0.9, | 41 | "alpha": 0.9, |
42 | "sprites": [ | 42 | "sprites": [ |
43 | - { "id": "rack", "pos":[300,600], "class":"blue1" }, | 43 | + { "id": "rack", "pos":[200,600], "class":"blue1" }, |
44 | - { "id": "rack", "pos":[500,600], "class":"blue1" }, | 44 | + { "id": "rack", "pos":[400,600], "class":"blue1" }, |
45 | - { "id": "rack", "pos":[700,600], "class":"blue1" } | 45 | + { "id": "rack", "pos":[600,600], "class":"blue1" }, |
46 | + { "id": "rack", "pos":[800,600], "class":"blue1" } | ||
46 | ], | 47 | ], |
47 | "labels": [ | 48 | "labels": [ |
48 | { "pos":[550,80], "text":"Segment Routing Demo", "class":"blue1", "size":1.4 } | 49 | { "pos":[550,80], "text":"Segment Routing Demo", "class":"blue1", "size":1.4 } | ... | ... |
-
Please register or login to post a comment