Srikanth Vavilapalli
Committed by Gerrit Code Review

ONOS-1438: Segment Routing rule population optimization fixes

Change-Id: I2cad2cd485282b904e035b209530005b93c90ffd
...@@ -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 }
372 + log.trace("numOfEventsQueued {}, numOfEventHanlderScheduled {}",
373 + numOfEventsQueued,
374 + numOfHandlerScheduled);
366 } 375 }
367 -
368 - log.trace("numOfEvents {}, numOfEventHanlderScheduled {}", numOfEvents,
369 - numOfHandlerScheduled);
370 -
371 } 376 }
372 377
373 private class InternalEventHandler implements Runnable { 378 private class InternalEventHandler implements Runnable {
...@@ -375,32 +380,38 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -375,32 +380,38 @@ 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) {
379 - numOfHandlerExecution++; 384 + Event event = null;
380 - while (!eventQueue.isEmpty()) { 385 + synchronized (threadSchedulerLock) {
381 - Event event = eventQueue.poll(); 386 + if (!eventQueue.isEmpty()) {
382 - if (event.type() == LinkEvent.Type.LINK_ADDED) { 387 + event = eventQueue.poll();
383 - processLinkAdded((Link) event.subject()); 388 + numOfEventsExecuted++;
384 - } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
385 - processLinkRemoved((Link) event.subject());
386 - //} else if (event.type() == GroupEvent.Type.GROUP_ADDED) {
387 - // processGroupAdded((Group) event.subject());
388 - } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED ||
389 - event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
390 - event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
391 - if (deviceService.isAvailable(((Device) event.subject()).id())) {
392 - processDeviceAdded((Device) event.subject());
393 - }
394 - } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
395 - processPortRemoved((Device) event.subject(),
396 - ((DeviceEvent) event).port());
397 } else { 389 } else {
398 - log.warn("Unhandled event type: {}", event.type()); 390 + numOfHandlerExecution++;
391 + log.debug("numOfHandlerExecution {} numOfEventsExecuted {}",
392 + numOfHandlerExecution, numOfEventsExecuted);
393 + break;
399 } 394 }
400 } 395 }
396 + if (event.type() == LinkEvent.Type.LINK_ADDED) {
397 + processLinkAdded((Link) event.subject());
398 + } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
399 + processLinkRemoved((Link) event.subject());
400 + //} else if (event.type() == GroupEvent.Type.GROUP_ADDED) {
401 + // processGroupAdded((Group) event.subject());
402 + } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED ||
403 + event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
404 + event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
405 + if (deviceService.isAvailable(((Device) event.subject()).id())) {
406 + processDeviceAdded((Device) event.subject());
407 + }
408 + } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
409 + processPortRemoved((Device) event.subject(),
410 + ((DeviceEvent) event).port());
411 + } else {
412 + log.warn("Unhandled event type: {}", event.type());
413 + }
401 } 414 }
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,15 +840,22 @@ public class DistributedGroupStore ...@@ -839,15 +840,22 @@ public class DistributedGroupStore
839 existing.deviceId()); 840 existing.deviceId());
840 switch (operation.opType()) { 841 switch (operation.opType()) {
841 case ADD: 842 case ADD:
842 - notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); 843 + if (existing.state() == GroupState.PENDING_ADD) {
843 - log.warn("groupOperationFailed: cleaningup " 844 + //TODO: Need to add support for passing the group
844 - + "group {} from store in device {}....", 845 + //operation failure reason from group provider.
845 - existing.id(), 846 + //If the error type is anything other than GROUP_EXISTS,
846 - existing.deviceId()); 847 + //then the GROUP_ADD_FAILED event should be raised even
847 - //Removal from groupid based map will happen in the 848 + //in PENDING_ADD_RETRY state also.
848 - //map update listener 849 + notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing));
849 - getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), 850 + log.warn("groupOperationFailed: cleaningup "
850 - existing.appCookie())); 851 + + "group {} from store in device {}....",
852 + existing.id(),
853 + existing.deviceId());
854 + //Removal from groupid based map will happen in the
855 + //map update listener
856 + getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(),
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 }
......