@Test public void testGroupOperationFailed() { TestDelegate delegate = new TestDelegate(); groupStore.setDelegate(delegate); groupStore.deviceInitialAuditCompleted(deviceId1, true); groupStore.deviceInitialAuditCompleted(deviceId2, true); groupStore.storeGroupDescription(groupDescription1); groupStore.storeGroupDescription(groupDescription2); List<GroupEvent> eventsAfterAdds = delegate.eventsSeen(); assertThat(eventsAfterAdds, hasSize(2)); eventsAfterAdds.stream().forEach(event -> assertThat(event.type(), is(GroupEvent.Type.GROUP_ADD_REQUESTED))); delegate.resetEvents(); GroupOperation opAdd = GroupOperation.createAddGroupOperation(groupId1, GroupDescription.Type.INDIRECT, buckets); groupStore.groupOperationFailed(deviceId1, opAdd); List<GroupEvent> eventsAfterAddFailed = delegate.eventsSeen(); assertThat(eventsAfterAddFailed, hasSize(2)); assertThat(eventsAfterAddFailed.get(0).type(), is(GroupEvent.Type.GROUP_ADD_FAILED)); assertThat(eventsAfterAddFailed.get(1).type(), is(GroupEvent.Type.GROUP_REMOVED)); delegate.resetEvents(); GroupOperation opModify = GroupOperation.createModifyGroupOperation(groupId2, GroupDescription.Type.INDIRECT, buckets); groupStore.groupOperationFailed(deviceId2, opModify); List<GroupEvent> eventsAfterModifyFailed = delegate.eventsSeen(); assertThat(eventsAfterModifyFailed, hasSize(1)); assertThat(eventsAfterModifyFailed.get(0).type(), is(GroupEvent.Type.GROUP_UPDATE_FAILED)); delegate.resetEvents(); GroupOperation opDelete = GroupOperation.createDeleteGroupOperation(groupId2, GroupDescription.Type.INDIRECT); groupStore.groupOperationFailed(deviceId2, opDelete); List<GroupEvent> eventsAfterDeleteFailed = delegate.eventsSeen(); assertThat(eventsAfterDeleteFailed, hasSize(1)); assertThat(eventsAfterDeleteFailed.get(0).type(), is(GroupEvent.Type.GROUP_REMOVE_FAILED)); delegate.resetEvents(); }
@Override public void groupOperationFailed(DeviceId deviceId, GroupOperation operation) { StoredGroupEntry existing = getStoredGroupEntry(deviceId, operation.groupId()); if (existing == null) { log.warn("No group entry with ID {} found ", operation.groupId()); return; } log.warn("groupOperationFailed: group operation {} failed" + "for group {} in device {} with code {}", operation.opType(), existing.id(), existing.deviceId(), operation.failureCode()); if (operation.failureCode() == GroupOperation.GroupMsgErrorCode.GROUP_EXISTS) { log.warn("Current extraneous groups in device:{} are: {}", deviceId, getExtraneousGroups(deviceId)); if (operation.buckets().equals(existing.buckets())) { if (existing.state() == GroupState.PENDING_ADD) { log.info("GROUP_EXISTS: GroupID and Buckets match for group in pending " + "add state - moving to ADDED for group {} in device {}", existing.id(), deviceId); addOrUpdateGroupEntry(existing); return; } else { log.warn("GROUP EXISTS: Group ID matched but buckets did not. " + "Operation: {} Existing: {}", operation.buckets(), existing.buckets()); } } } switch (operation.opType()) { case ADD: if (existing.state() == GroupState.PENDING_ADD) { notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); log.warn("groupOperationFailed: cleaningup " + "group {} from store in device {}....", existing.id(), existing.deviceId()); getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), existing.appCookie())); } break; case MODIFY: notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing)); break; case DELETE: notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_FAILED, existing)); break; default: log.warn("Unknown group operation type {}", operation.opType()); } }
DistributedGroupStore extends AbstractStore<GroupEvent, GroupStoreDelegate> implements GroupStore { @Override public void groupOperationFailed(DeviceId deviceId, GroupOperation operation) { StoredGroupEntry existing = getStoredGroupEntry(deviceId, operation.groupId()); if (existing == null) { log.warn("No group entry with ID {} found ", operation.groupId()); return; } log.warn("groupOperationFailed: group operation {} failed" + "for group {} in device {} with code {}", operation.opType(), existing.id(), existing.deviceId(), operation.failureCode()); if (operation.failureCode() == GroupOperation.GroupMsgErrorCode.GROUP_EXISTS) { log.warn("Current extraneous groups in device:{} are: {}", deviceId, getExtraneousGroups(deviceId)); if (operation.buckets().equals(existing.buckets())) { if (existing.state() == GroupState.PENDING_ADD) { log.info("GROUP_EXISTS: GroupID and Buckets match for group in pending " + "add state - moving to ADDED for group {} in device {}", existing.id(), deviceId); addOrUpdateGroupEntry(existing); return; } else { log.warn("GROUP EXISTS: Group ID matched but buckets did not. " + "Operation: {} Existing: {}", operation.buckets(), existing.buckets()); } } } switch (operation.opType()) { case ADD: if (existing.state() == GroupState.PENDING_ADD) { notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); log.warn("groupOperationFailed: cleaningup " + "group {} from store in device {}....", existing.id(), existing.deviceId()); getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), existing.appCookie())); } break; case MODIFY: notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing)); break; case DELETE: notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_FAILED, existing)); break; default: log.warn("Unknown group operation type {}", operation.opType()); } } }
DistributedGroupStore extends AbstractStore<GroupEvent, GroupStoreDelegate> implements GroupStore { @Override public void groupOperationFailed(DeviceId deviceId, GroupOperation operation) { StoredGroupEntry existing = getStoredGroupEntry(deviceId, operation.groupId()); if (existing == null) { log.warn("No group entry with ID {} found ", operation.groupId()); return; } log.warn("groupOperationFailed: group operation {} failed" + "for group {} in device {} with code {}", operation.opType(), existing.id(), existing.deviceId(), operation.failureCode()); if (operation.failureCode() == GroupOperation.GroupMsgErrorCode.GROUP_EXISTS) { log.warn("Current extraneous groups in device:{} are: {}", deviceId, getExtraneousGroups(deviceId)); if (operation.buckets().equals(existing.buckets())) { if (existing.state() == GroupState.PENDING_ADD) { log.info("GROUP_EXISTS: GroupID and Buckets match for group in pending " + "add state - moving to ADDED for group {} in device {}", existing.id(), deviceId); addOrUpdateGroupEntry(existing); return; } else { log.warn("GROUP EXISTS: Group ID matched but buckets did not. " + "Operation: {} Existing: {}", operation.buckets(), existing.buckets()); } } } switch (operation.opType()) { case ADD: if (existing.state() == GroupState.PENDING_ADD) { notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); log.warn("groupOperationFailed: cleaningup " + "group {} from store in device {}....", existing.id(), existing.deviceId()); getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), existing.appCookie())); } break; case MODIFY: notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing)); break; case DELETE: notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_FAILED, existing)); break; default: log.warn("Unknown group operation type {}", operation.opType()); } }  }
DistributedGroupStore extends AbstractStore<GroupEvent, GroupStoreDelegate> implements GroupStore { @Override public void groupOperationFailed(DeviceId deviceId, GroupOperation operation) { StoredGroupEntry existing = getStoredGroupEntry(deviceId, operation.groupId()); if (existing == null) { log.warn("No group entry with ID {} found ", operation.groupId()); return; } log.warn("groupOperationFailed: group operation {} failed" + "for group {} in device {} with code {}", operation.opType(), existing.id(), existing.deviceId(), operation.failureCode()); if (operation.failureCode() == GroupOperation.GroupMsgErrorCode.GROUP_EXISTS) { log.warn("Current extraneous groups in device:{} are: {}", deviceId, getExtraneousGroups(deviceId)); if (operation.buckets().equals(existing.buckets())) { if (existing.state() == GroupState.PENDING_ADD) { log.info("GROUP_EXISTS: GroupID and Buckets match for group in pending " + "add state - moving to ADDED for group {} in device {}", existing.id(), deviceId); addOrUpdateGroupEntry(existing); return; } else { log.warn("GROUP EXISTS: Group ID matched but buckets did not. " + "Operation: {} Existing: {}", operation.buckets(), existing.buckets()); } } } switch (operation.opType()) { case ADD: if (existing.state() == GroupState.PENDING_ADD) { notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); log.warn("groupOperationFailed: cleaningup " + "group {} from store in device {}....", existing.id(), existing.deviceId()); getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), existing.appCookie())); } break; case MODIFY: notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing)); break; case DELETE: notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_FAILED, existing)); break; default: log.warn("Unknown group operation type {}", operation.opType()); } }  @Activate void activate(); @Deactivate void deactivate(); @Modified void modified(ComponentContext context); @Override int getGroupCount(DeviceId deviceId); @Override Iterable<Group> getGroups(DeviceId deviceId); @Override Group getGroup(DeviceId deviceId, GroupKey appCookie); @Override Group getGroup(DeviceId deviceId, GroupId groupId); @Override void storeGroupDescription(GroupDescription groupDesc); @Override void updateGroupDescription(DeviceId deviceId,
                                       GroupKey oldAppCookie,
                                       UpdateType type,
                                       GroupBuckets newBuckets,
                                       GroupKey newAppCookie); @Override void deleteGroupDescription(DeviceId deviceId,
                                       GroupKey appCookie); @Override void addOrUpdateGroupEntry(Group group); @Override void removeGroupEntry(Group group); @Override void purgeGroupEntry(DeviceId deviceId); @Override void deviceInitialAuditCompleted(DeviceId deviceId,
                                            boolean completed); @Override boolean deviceInitialAuditStatus(DeviceId deviceId); @Override void groupOperationFailed(DeviceId deviceId, GroupOperation operation); @Override void addOrUpdateExtraneousGroupEntry(Group group); @Override void removeExtraneousGroupEntry(Group group); @Override Iterable<Group> getExtraneousGroups(DeviceId deviceId); @Override void pushGroupMetrics(DeviceId deviceId,
                                 Collection<Group> groupEntries); }
DistributedGroupStore extends AbstractStore<GroupEvent, GroupStoreDelegate> implements GroupStore { @Override public void groupOperationFailed(DeviceId deviceId, GroupOperation operation) { StoredGroupEntry existing = getStoredGroupEntry(deviceId, operation.groupId()); if (existing == null) { log.warn("No group entry with ID {} found ", operation.groupId()); return; } log.warn("groupOperationFailed: group operation {} failed" + "for group {} in device {} with code {}", operation.opType(), existing.id(), existing.deviceId(), operation.failureCode()); if (operation.failureCode() == GroupOperation.GroupMsgErrorCode.GROUP_EXISTS) { log.warn("Current extraneous groups in device:{} are: {}", deviceId, getExtraneousGroups(deviceId)); if (operation.buckets().equals(existing.buckets())) { if (existing.state() == GroupState.PENDING_ADD) { log.info("GROUP_EXISTS: GroupID and Buckets match for group in pending " + "add state - moving to ADDED for group {} in device {}", existing.id(), deviceId); addOrUpdateGroupEntry(existing); return; } else { log.warn("GROUP EXISTS: Group ID matched but buckets did not. " + "Operation: {} Existing: {}", operation.buckets(), existing.buckets()); } } } switch (operation.opType()) { case ADD: if (existing.state() == GroupState.PENDING_ADD) { notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); log.warn("groupOperationFailed: cleaningup " + "group {} from store in device {}....", existing.id(), existing.deviceId()); getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), existing.appCookie())); } break; case MODIFY: notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing)); break; case DELETE: notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_FAILED, existing)); break; default: log.warn("Unknown group operation type {}", operation.opType()); } }  @Activate void activate(); @Deactivate void deactivate(); @Modified void modified(ComponentContext context); @Override int getGroupCount(DeviceId deviceId); @Override Iterable<Group> getGroups(DeviceId deviceId); @Override Group getGroup(DeviceId deviceId, GroupKey appCookie); @Override Group getGroup(DeviceId deviceId, GroupId groupId); @Override void storeGroupDescription(GroupDescription groupDesc); @Override void updateGroupDescription(DeviceId deviceId,
                                       GroupKey oldAppCookie,
                                       UpdateType type,
                                       GroupBuckets newBuckets,
                                       GroupKey newAppCookie); @Override void deleteGroupDescription(DeviceId deviceId,
                                       GroupKey appCookie); @Override void addOrUpdateGroupEntry(Group group); @Override void removeGroupEntry(Group group); @Override void purgeGroupEntry(DeviceId deviceId); @Override void deviceInitialAuditCompleted(DeviceId deviceId,
                                            boolean completed); @Override boolean deviceInitialAuditStatus(DeviceId deviceId); @Override void groupOperationFailed(DeviceId deviceId, GroupOperation operation); @Override void addOrUpdateExtraneousGroupEntry(Group group); @Override void removeExtraneousGroupEntry(Group group); @Override Iterable<Group> getExtraneousGroups(DeviceId deviceId); @Override void pushGroupMetrics(DeviceId deviceId,
                                 Collection<Group> groupEntries);  }