Srikanth Vavilapalli
Committed by Ali "The Bomb" Al-Shabibi

ONOS-895: Group manager implementation

Change-Id: Ie183f722fa39012f8de056961715c325e2388e63
...@@ -37,7 +37,7 @@ public class DefaultGroupId implements GroupId { ...@@ -37,7 +37,7 @@ public class DefaultGroupId implements GroupId {
37 37
38 @Override 38 @Override
39 public int id() { 39 public int id() {
40 - return 0; 40 + return this.id;
41 } 41 }
42 42
43 @Override 43 @Override
......
...@@ -17,7 +17,10 @@ package org.onosproject.net.group; ...@@ -17,7 +17,10 @@ package org.onosproject.net.group;
17 17
18 import static org.slf4j.LoggerFactory.getLogger; 18 import static org.slf4j.LoggerFactory.getLogger;
19 19
20 +import java.util.Objects;
21 +
20 import org.onosproject.core.GroupId; 22 import org.onosproject.core.GroupId;
23 +import org.onosproject.net.DeviceId;
21 import org.slf4j.Logger; 24 import org.slf4j.Logger;
22 25
23 /** 26 /**
...@@ -32,6 +35,7 @@ public class DefaultGroup extends DefaultGroupDescription ...@@ -32,6 +35,7 @@ public class DefaultGroup extends DefaultGroupDescription
32 private long life; 35 private long life;
33 private long packets; 36 private long packets;
34 private long bytes; 37 private long bytes;
38 + private long referenceCount;
35 private GroupId id; 39 private GroupId id;
36 40
37 /** 41 /**
...@@ -47,6 +51,29 @@ public class DefaultGroup extends DefaultGroupDescription ...@@ -47,6 +51,29 @@ public class DefaultGroup extends DefaultGroupDescription
47 this.life = 0; 51 this.life = 0;
48 this.packets = 0; 52 this.packets = 0;
49 this.bytes = 0; 53 this.bytes = 0;
54 + this.referenceCount = 0;
55 + }
56 +
57 + /**
58 + * Default group object constructor with the available information
59 + * from data plane.
60 + *
61 + * @param id group identifier
62 + * @param deviceId device identifier
63 + * @param type type of the group
64 + * @param buckets immutable list of group bucket
65 + */
66 + public DefaultGroup(GroupId id,
67 + DeviceId deviceId,
68 + GroupDescription.Type type,
69 + GroupBuckets buckets) {
70 + super(deviceId, type, buckets);
71 + this.id = id;
72 + this.state = GroupState.PENDING_ADD;
73 + this.life = 0;
74 + this.packets = 0;
75 + this.bytes = 0;
76 + this.referenceCount = 0;
50 } 77 }
51 78
52 /** 79 /**
...@@ -139,4 +166,43 @@ public class DefaultGroup extends DefaultGroupDescription ...@@ -139,4 +166,43 @@ public class DefaultGroup extends DefaultGroupDescription
139 this.bytes = bytes; 166 this.bytes = bytes;
140 } 167 }
141 168
169 + @Override
170 + public void setReferenceCount(long referenceCount) {
171 + this.referenceCount = referenceCount;
172 + }
173 +
174 + @Override
175 + public long referenceCount() {
176 + return referenceCount;
177 + }
178 +
179 + /*
180 + * The deviceId, type and buckets are used for hash.
181 + *
182 + * (non-Javadoc)
183 + * @see java.lang.Object#equals(java.lang.Object)
184 + */
185 + @Override
186 + public int hashCode() {
187 + return super.hashCode() + Objects.hash(id);
188 + }
189 +
190 + /*
191 + * The deviceId, groupId, type and buckets should be same.
192 + *
193 + * (non-Javadoc)
194 + * @see java.lang.Object#equals(java.lang.Object)
195 + */
196 + @Override
197 + public boolean equals(Object obj) {
198 + if (this == obj) {
199 + return true;
200 + }
201 + if (obj instanceof DefaultGroup) {
202 + DefaultGroup that = (DefaultGroup) obj;
203 + return super.equals(obj) &&
204 + Objects.equals(id, that.id);
205 + }
206 + return false;
207 + }
142 } 208 }
......
...@@ -18,6 +18,8 @@ package org.onosproject.net.group; ...@@ -18,6 +18,8 @@ package org.onosproject.net.group;
18 import static com.google.common.base.Preconditions.checkArgument; 18 import static com.google.common.base.Preconditions.checkArgument;
19 import static com.google.common.base.Preconditions.checkNotNull; 19 import static com.google.common.base.Preconditions.checkNotNull;
20 20
21 +import java.util.Objects;
22 +
21 import org.onosproject.core.GroupId; 23 import org.onosproject.core.GroupId;
22 import org.onosproject.net.PortNumber; 24 import org.onosproject.net.PortNumber;
23 import org.onosproject.net.flow.TrafficTreatment; 25 import org.onosproject.net.flow.TrafficTreatment;
...@@ -178,4 +180,36 @@ public final class DefaultGroupBucket implements GroupBucket { ...@@ -178,4 +180,36 @@ public final class DefaultGroupBucket implements GroupBucket {
178 public GroupId watchGroup() { 180 public GroupId watchGroup() {
179 return watchGroup; 181 return watchGroup;
180 } 182 }
183 +
184 + /*
185 + * The type and treatment can change on a given bucket
186 + *
187 + * (non-Javadoc)
188 + * @see java.lang.Object#equals(java.lang.Object)
189 + */
190 + @Override
191 + public int hashCode() {
192 + return Objects.hash(type, treatment);
193 + }
194 +
195 + /*
196 + * The priority and statistics can change on a given treatment and selector
197 + *
198 + * (non-Javadoc)
199 + * @see java.lang.Object#equals(java.lang.Object)
200 + */
201 + @Override
202 + public boolean equals(Object obj) {
203 + if (this == obj) {
204 + return true;
205 + }
206 + if (obj instanceof DefaultGroupBucket) {
207 + DefaultGroupBucket that = (DefaultGroupBucket) obj;
208 + return Objects.equals(type, that.type) &&
209 + this.treatment.instructions().containsAll(that.treatment.instructions()) &&
210 + that.treatment.instructions().containsAll(this.treatment.instructions());
211 + }
212 + return false;
213 + }
214 +
181 } 215 }
......
...@@ -17,6 +17,8 @@ package org.onosproject.net.group; ...@@ -17,6 +17,8 @@ package org.onosproject.net.group;
17 17
18 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkNotNull;
19 19
20 +import java.util.Objects;
21 +
20 import org.onosproject.core.ApplicationId; 22 import org.onosproject.core.ApplicationId;
21 import org.onosproject.net.DeviceId; 23 import org.onosproject.net.DeviceId;
22 24
...@@ -49,8 +51,8 @@ public class DefaultGroupDescription implements GroupDescription { ...@@ -49,8 +51,8 @@ public class DefaultGroupDescription implements GroupDescription {
49 this.type = checkNotNull(type); 51 this.type = checkNotNull(type);
50 this.deviceId = checkNotNull(deviceId); 52 this.deviceId = checkNotNull(deviceId);
51 this.buckets = checkNotNull(buckets); 53 this.buckets = checkNotNull(buckets);
52 - this.appCookie = checkNotNull(appCookie); 54 + this.appCookie = appCookie;
53 - this.appId = checkNotNull(appId); 55 + this.appId = appId;
54 } 56 }
55 57
56 /** 58 /**
...@@ -61,11 +63,27 @@ public class DefaultGroupDescription implements GroupDescription { ...@@ -61,11 +63,27 @@ public class DefaultGroupDescription implements GroupDescription {
61 * 63 *
62 */ 64 */
63 public DefaultGroupDescription(GroupDescription groupDesc) { 65 public DefaultGroupDescription(GroupDescription groupDesc) {
64 - this.type = checkNotNull(groupDesc.type()); 66 + this.type = groupDesc.type();
65 - this.deviceId = checkNotNull(groupDesc.deviceId()); 67 + this.deviceId = groupDesc.deviceId();
66 - this.buckets = checkNotNull(groupDesc.buckets()); 68 + this.buckets = groupDesc.buckets();
67 - this.appCookie = checkNotNull(groupDesc.appCookie()); 69 + this.appCookie = groupDesc.appCookie();
68 - this.appId = checkNotNull(groupDesc.appId()); 70 + this.appId = groupDesc.appId();
71 + }
72 +
73 + /**
74 + * Constructor to be used by group subsystem internal components.
75 + * Creates group description object from the information retrieved
76 + * from data plane.
77 + *
78 + * @param deviceId device identifier
79 + * @param type type of the group
80 + * @param buckets immutable list of group bucket
81 + *
82 + */
83 + public DefaultGroupDescription(DeviceId deviceId,
84 + GroupDescription.Type type,
85 + GroupBuckets buckets) {
86 + this(deviceId, type, buckets, null, null);
69 } 87 }
70 88
71 /** 89 /**
...@@ -118,4 +136,36 @@ public class DefaultGroupDescription implements GroupDescription { ...@@ -118,4 +136,36 @@ public class DefaultGroupDescription implements GroupDescription {
118 return this.buckets; 136 return this.buckets;
119 } 137 }
120 138
139 + @Override
140 + /*
141 + * The deviceId, type and buckets are used for hash.
142 + *
143 + * (non-Javadoc)
144 + * @see java.lang.Object#equals(java.lang.Object)
145 + */
146 + public int hashCode() {
147 + return Objects.hash(deviceId, type, buckets);
148 + }
149 +
150 + @Override
151 + /*
152 + * The deviceId, type and buckets should be same.
153 + *
154 + * (non-Javadoc)
155 + * @see java.lang.Object#equals(java.lang.Object)
156 + */
157 + public boolean equals(Object obj) {
158 + if (this == obj) {
159 + return true;
160 + }
161 + if (obj instanceof DefaultGroupDescription) {
162 + DefaultGroupDescription that = (DefaultGroupDescription) obj;
163 + return Objects.equals(deviceId, that.deviceId) &&
164 + Objects.equals(type, that.type) &&
165 + Objects.equals(buckets, that.buckets);
166 +
167 + }
168 + return false;
169 + }
170 +
121 } 171 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -26,6 +26,10 @@ public interface Group extends GroupDescription { ...@@ -26,6 +26,10 @@ public interface Group extends GroupDescription {
26 */ 26 */
27 public enum GroupState { 27 public enum GroupState {
28 /** 28 /**
29 + * Group create request is queued as group AUDIT is in progress.
30 + */
31 + WAITING_AUDIT_COMPLETE,
32 + /**
29 * Group create request is processed by ONOS and not yet 33 * Group create request is processed by ONOS and not yet
30 * received the confirmation from data plane. 34 * received the confirmation from data plane.
31 */ 35 */
...@@ -81,4 +85,11 @@ public interface Group extends GroupDescription { ...@@ -81,4 +85,11 @@ public interface Group extends GroupDescription {
81 * @return number of bytes 85 * @return number of bytes
82 */ 86 */
83 long bytes(); 87 long bytes();
88 +
89 + /**
90 + * Returns the number of flow rules or other groups reference this group.
91 + *
92 + * @return number of flow rules or other groups pointing to this group
93 + */
94 + long referenceCount();
84 } 95 }
......
...@@ -45,4 +45,25 @@ public final class GroupBuckets { ...@@ -45,4 +45,25 @@ public final class GroupBuckets {
45 return buckets; 45 return buckets;
46 } 46 }
47 47
48 + @Override
49 + public int hashCode() {
50 + int result = 17;
51 + int combinedHash = 0;
52 + for (GroupBucket bucket:buckets) {
53 + combinedHash = combinedHash + bucket.hashCode();
54 + }
55 + result = 31 * result + combinedHash;
56 +
57 + return result;
58 + }
59 +
60 + @Override
61 + public boolean equals(Object obj) {
62 + if (obj instanceof GroupBuckets) {
63 + return (this.buckets.containsAll(((GroupBuckets) obj).buckets) &&
64 + ((GroupBuckets) obj).buckets.containsAll(this.buckets));
65 + }
66 + return false;
67 + }
68 +
48 } 69 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -17,6 +17,8 @@ package org.onosproject.net.group; ...@@ -17,6 +17,8 @@ package org.onosproject.net.group;
17 17
18 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkNotNull;
19 19
20 +import java.util.Objects;
21 +
20 import org.onosproject.core.GroupId; 22 import org.onosproject.core.GroupId;
21 23
22 /** 24 /**
...@@ -142,4 +144,37 @@ public final class GroupOperation { ...@@ -142,4 +144,37 @@ public final class GroupOperation {
142 public GroupBuckets buckets() { 144 public GroupBuckets buckets() {
143 return this.buckets; 145 return this.buckets;
144 } 146 }
147 +
148 + @Override
149 + /*
150 + * The deviceId, type and buckets are used for hash.
151 + *
152 + * (non-Javadoc)
153 + * @see java.lang.Object#equals(java.lang.Object)
154 + */
155 + public int hashCode() {
156 + return (buckets != null) ? Objects.hash(groupId, opType, buckets) :
157 + Objects.hash(groupId, opType);
158 + }
159 +
160 + @Override
161 + /*
162 + * The deviceId, type and buckets should be same.
163 + *
164 + * (non-Javadoc)
165 + * @see java.lang.Object#equals(java.lang.Object)
166 + */
167 + public boolean equals(Object obj) {
168 + if (this == obj) {
169 + return true;
170 + }
171 + if (obj instanceof GroupOperation) {
172 + GroupOperation that = (GroupOperation) obj;
173 + return Objects.equals(groupId, that.groupId) &&
174 + Objects.equals(opType, that.opType) &&
175 + Objects.equals(buckets, that.buckets);
176 +
177 + }
178 + return false;
179 + }
145 } 180 }
...\ No newline at end of file ...\ No newline at end of file
......
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 +package org.onosproject.net.group;
17 +
18 +import org.onosproject.net.provider.ProviderRegistry;
19 +
20 +/**
21 + * Abstraction for a group provider registry.
22 + */
23 +public interface GroupProviderRegistry
24 + extends ProviderRegistry<GroupProvider, GroupProviderService> {
25 +}
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
16 package org.onosproject.net.group; 16 package org.onosproject.net.group;
17 17
18 import org.onosproject.core.ApplicationId; 18 import org.onosproject.core.ApplicationId;
19 -import org.onosproject.net.Device;
20 import org.onosproject.net.DeviceId; 19 import org.onosproject.net.DeviceId;
21 20
22 /** 21 /**
...@@ -27,7 +26,7 @@ import org.onosproject.net.DeviceId; ...@@ -27,7 +26,7 @@ import org.onosproject.net.DeviceId;
27 * specified in a group. 26 * specified in a group.
28 * "group" can also be used for grouping common actions of different flows, 27 * "group" can also be used for grouping common actions of different flows,
29 * so that in some scenarios only one group entry required to be modified 28 * so that in some scenarios only one group entry required to be modified
30 - * for all the referencing flow entries instead of modifying all of them 29 + * for all the referencing flow entries instead of modifying all of them.
31 * 30 *
32 * This implements semantics of a distributed authoritative group store 31 * This implements semantics of a distributed authoritative group store
33 * where the master copy of the groups lies with the controller and 32 * where the master copy of the groups lies with the controller and
...@@ -60,7 +59,7 @@ public interface GroupService { ...@@ -60,7 +59,7 @@ public interface GroupService {
60 * NOTE1: The presence of group object in the system does not 59 * NOTE1: The presence of group object in the system does not
61 * guarantee that the "group" is actually created in device. 60 * guarantee that the "group" is actually created in device.
62 * GROUP_ADDED notification would confirm the creation of 61 * GROUP_ADDED notification would confirm the creation of
63 - * this group in data plane 62 + * this group in data plane.
64 * 63 *
65 * @param deviceId device identifier 64 * @param deviceId device identifier
66 * @param appCookie application cookie to be used for lookup 65 * @param appCookie application cookie to be used for lookup
...@@ -73,7 +72,7 @@ public interface GroupService { ...@@ -73,7 +72,7 @@ public interface GroupService {
73 * Appends buckets to existing group. The caller can optionally 72 * Appends buckets to existing group. The caller can optionally
74 * associate a new cookie during this updation. GROUP_UPDATED or 73 * associate a new cookie during this updation. GROUP_UPDATED or
75 * GROUP_UPDATE_FAILED notifications would be provided along with 74 * GROUP_UPDATE_FAILED notifications would be provided along with
76 - * cookie depending on the result of the operation on the device 75 + * cookie depending on the result of the operation on the device.
77 * 76 *
78 * @param deviceId device identifier 77 * @param deviceId device identifier
79 * @param oldCookie cookie to be used to retrieve the existing group 78 * @param oldCookie cookie to be used to retrieve the existing group
...@@ -91,7 +90,7 @@ public interface GroupService { ...@@ -91,7 +90,7 @@ public interface GroupService {
91 * Removes buckets from existing group. The caller can optionally 90 * Removes buckets from existing group. The caller can optionally
92 * associate a new cookie during this updation. GROUP_UPDATED or 91 * associate a new cookie during this updation. GROUP_UPDATED or
93 * GROUP_UPDATE_FAILED notifications would be provided along with 92 * GROUP_UPDATE_FAILED notifications would be provided along with
94 - * cookie depending on the result of the operation on the device 93 + * cookie depending on the result of the operation on the device.
95 * 94 *
96 * @param deviceId device identifier 95 * @param deviceId device identifier
97 * @param oldCookie cookie to be used to retrieve the existing group 96 * @param oldCookie cookie to be used to retrieve the existing group
...@@ -99,7 +98,7 @@ public interface GroupService { ...@@ -99,7 +98,7 @@ public interface GroupService {
99 * @param newCookie immutable cookie to be used post update operation 98 * @param newCookie immutable cookie to be used post update operation
100 * @param appId Application Id 99 * @param appId Application Id
101 */ 100 */
102 - void removeBucketsFromGroup(Device deviceId, 101 + void removeBucketsFromGroup(DeviceId deviceId,
103 GroupKey oldCookie, 102 GroupKey oldCookie,
104 GroupBuckets buckets, 103 GroupBuckets buckets,
105 GroupKey newCookie, 104 GroupKey newCookie,
...@@ -109,13 +108,13 @@ public interface GroupService { ...@@ -109,13 +108,13 @@ public interface GroupService {
109 * Deletes a group associated to an application cookie. 108 * Deletes a group associated to an application cookie.
110 * GROUP_DELETED or GROUP_DELETE_FAILED notifications would be 109 * GROUP_DELETED or GROUP_DELETE_FAILED notifications would be
111 * provided along with cookie depending on the result of the 110 * provided along with cookie depending on the result of the
112 - * operation on the device 111 + * operation on the device.
113 * 112 *
114 * @param deviceId device identifier 113 * @param deviceId device identifier
115 * @param appCookie application cookie to be used for lookup 114 * @param appCookie application cookie to be used for lookup
116 * @param appId Application Id 115 * @param appId Application Id
117 */ 116 */
118 - void removeGroup(Device deviceId, GroupKey appCookie, ApplicationId appId); 117 + void removeGroup(DeviceId deviceId, GroupKey appCookie, ApplicationId appId);
119 118
120 /** 119 /**
121 * Retrieves all groups created by an application in the specified device 120 * Retrieves all groups created by an application in the specified device
...@@ -125,7 +124,7 @@ public interface GroupService { ...@@ -125,7 +124,7 @@ public interface GroupService {
125 * @param appId application id 124 * @param appId application id
126 * @return collection of immutable group objects created by the application 125 * @return collection of immutable group objects created by the application
127 */ 126 */
128 - Iterable<Group> getGroups(Device deviceId, ApplicationId appId); 127 + Iterable<Group> getGroups(DeviceId deviceId, ApplicationId appId);
129 128
130 /** 129 /**
131 * Adds the specified group listener. 130 * Adds the specified group listener.
......
...@@ -73,12 +73,14 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> { ...@@ -73,12 +73,14 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> {
73 * @param deviceId the device ID 73 * @param deviceId the device ID
74 * @param oldAppCookie the current group key 74 * @param oldAppCookie the current group key
75 * @param type update type 75 * @param type update type
76 - * @param newGroupDesc group description with updates 76 + * @param newBuckets group buckets for updates
77 + * @param newAppCookie optional new group key
77 */ 78 */
78 void updateGroupDescription(DeviceId deviceId, 79 void updateGroupDescription(DeviceId deviceId,
79 GroupKey oldAppCookie, 80 GroupKey oldAppCookie,
80 UpdateType type, 81 UpdateType type,
81 - GroupDescription newGroupDesc); 82 + GroupBuckets newBuckets,
83 + GroupKey newAppCookie);
82 84
83 /** 85 /**
84 * Triggers deleting the existing group entry. 86 * Triggers deleting the existing group entry.
...@@ -102,4 +104,43 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> { ...@@ -102,4 +104,43 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> {
102 * @param group group entry 104 * @param group group entry
103 */ 105 */
104 void removeGroupEntry(Group group); 106 void removeGroupEntry(Group group);
107 +
108 + /**
109 + * A group entry that is present in switch but not in the store.
110 + *
111 + * @param group group entry
112 + */
113 + void addOrUpdateExtraneousGroupEntry(Group group);
114 +
115 + /**
116 + * Remove the group entry from extraneous database.
117 + *
118 + * @param group group entry
119 + */
120 + void removeExtraneousGroupEntry(Group group);
121 +
122 + /**
123 + * Returns the extraneous groups associated with a device.
124 + *
125 + * @param deviceId the device ID
126 + *
127 + * @return the extraneous group entries
128 + */
129 + Iterable<Group> getExtraneousGroups(DeviceId deviceId);
130 +
131 + /**
132 + * Indicates the first group audit is completed.
133 + *
134 + * @param deviceId the device ID
135 + */
136 + void deviceInitialAuditCompleted(DeviceId deviceId);
137 +
138 + /**
139 + * Retrieves the initial group audit status for a device.
140 + *
141 + * @param deviceId the device ID
142 + *
143 + * @return initial group audit status
144 + */
145 + boolean deviceInitialAuditStatus(DeviceId deviceId);
105 } 146 }
......
...@@ -49,4 +49,10 @@ public interface StoredGroupEntry extends Group { ...@@ -49,4 +49,10 @@ public interface StoredGroupEntry extends Group {
49 */ 49 */
50 void setBytes(long bytes); 50 void setBytes(long bytes);
51 51
52 + /**
53 + * Sets number of flow rules or groups referencing this group entry.
54 + *
55 + * @param referenceCount reference count
56 + */
57 + void setReferenceCount(long referenceCount);
52 } 58 }
......
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 +/**
18 + * Core subsystem for group state.
19 + */
20 +package org.onosproject.net.group.impl;
...\ No newline at end of file ...\ No newline at end of file
...@@ -40,8 +40,10 @@ import org.onosproject.net.group.GroupBuckets; ...@@ -40,8 +40,10 @@ import org.onosproject.net.group.GroupBuckets;
40 import org.onosproject.net.group.GroupDescription; 40 import org.onosproject.net.group.GroupDescription;
41 import org.onosproject.net.group.GroupEvent; 41 import org.onosproject.net.group.GroupEvent;
42 import org.onosproject.net.group.GroupKey; 42 import org.onosproject.net.group.GroupKey;
43 -import org.onosproject.net.group.GroupStoreDelegate;
44 import org.onosproject.net.group.GroupStore.UpdateType; 43 import org.onosproject.net.group.GroupStore.UpdateType;
44 +import org.onosproject.net.group.GroupStoreDelegate;
45 +
46 +import com.google.common.collect.Iterables;
45 47
46 /** 48 /**
47 * Test of the simple DeviceStore implementation. 49 * Test of the simple DeviceStore implementation.
...@@ -135,8 +137,24 @@ public class SimpleGroupStoreTest { ...@@ -135,8 +137,24 @@ public class SimpleGroupStoreTest {
135 } 137 }
136 } 138 }
137 139
140 + /**
141 + * Tests group store operations. The following operations are tested:
142 + * a)Tests device group audit completion status change
143 + * b)Tests storeGroup operation
144 + * c)Tests getGroupCount operation
145 + * d)Tests getGroup operation
146 + * e)Tests getGroups operation
147 + * f)Tests addOrUpdateGroupEntry operation from southbound
148 + * g)Tests updateGroupDescription for ADD operation from northbound
149 + * h)Tests updateGroupDescription for REMOVE operation from northbound
150 + * i)Tests deleteGroupDescription operation from northbound
151 + * j)Tests removeGroupEntry operation from southbound
152 + */
138 @Test 153 @Test
139 public void testGroupStoreOperations() { 154 public void testGroupStoreOperations() {
155 + // Set the Device AUDIT completed in the store
156 + simpleGroupStore.deviceInitialAuditCompleted(D1);
157 +
140 ApplicationId appId = 158 ApplicationId appId =
141 new DefaultApplicationId(2, "org.groupstore.test"); 159 new DefaultApplicationId(2, "org.groupstore.test");
142 TestGroupKey key = new TestGroupKey("group1"); 160 TestGroupKey key = new TestGroupKey("group1");
...@@ -169,17 +187,17 @@ public class SimpleGroupStoreTest { ...@@ -169,17 +187,17 @@ public class SimpleGroupStoreTest {
169 groupBuckets, 187 groupBuckets,
170 GroupEvent.Type.GROUP_ADD_REQUESTED); 188 GroupEvent.Type.GROUP_ADD_REQUESTED);
171 simpleGroupStore.setDelegate(checkStoreGroupDelegate); 189 simpleGroupStore.setDelegate(checkStoreGroupDelegate);
172 - /* Testing storeGroup operation */ 190 + // Testing storeGroup operation
173 simpleGroupStore.storeGroupDescription(groupDesc); 191 simpleGroupStore.storeGroupDescription(groupDesc);
174 192
175 - /* Testing getGroupCount operation */ 193 + // Testing getGroupCount operation
176 assertEquals(1, simpleGroupStore.getGroupCount(D1)); 194 assertEquals(1, simpleGroupStore.getGroupCount(D1));
177 195
178 - /* Testing getGroup operation */ 196 + // Testing getGroup operation
179 Group createdGroup = simpleGroupStore.getGroup(D1, key); 197 Group createdGroup = simpleGroupStore.getGroup(D1, key);
180 checkStoreGroupDelegate.verifyGroupId(createdGroup.id()); 198 checkStoreGroupDelegate.verifyGroupId(createdGroup.id());
181 199
182 - /* Testing getGroups operation */ 200 + // Testing getGroups operation
183 Iterable<Group> createdGroups = simpleGroupStore.getGroups(D1); 201 Iterable<Group> createdGroups = simpleGroupStore.getGroups(D1);
184 int groupCount = 0; 202 int groupCount = 0;
185 for (Group group:createdGroups) { 203 for (Group group:createdGroups) {
...@@ -189,7 +207,7 @@ public class SimpleGroupStoreTest { ...@@ -189,7 +207,7 @@ public class SimpleGroupStoreTest {
189 assertEquals(1, groupCount); 207 assertEquals(1, groupCount);
190 simpleGroupStore.unsetDelegate(checkStoreGroupDelegate); 208 simpleGroupStore.unsetDelegate(checkStoreGroupDelegate);
191 209
192 - /* Testing addOrUpdateGroupEntry operation from southbound */ 210 + // Testing addOrUpdateGroupEntry operation from southbound
193 InternalGroupStoreDelegate addGroupEntryDelegate = 211 InternalGroupStoreDelegate addGroupEntryDelegate =
194 new InternalGroupStoreDelegate(key, 212 new InternalGroupStoreDelegate(key,
195 groupBuckets, 213 groupBuckets,
...@@ -198,7 +216,7 @@ public class SimpleGroupStoreTest { ...@@ -198,7 +216,7 @@ public class SimpleGroupStoreTest {
198 simpleGroupStore.addOrUpdateGroupEntry(createdGroup); 216 simpleGroupStore.addOrUpdateGroupEntry(createdGroup);
199 simpleGroupStore.unsetDelegate(addGroupEntryDelegate); 217 simpleGroupStore.unsetDelegate(addGroupEntryDelegate);
200 218
201 - /* Testing updateGroupDescription for ADD operation from northbound */ 219 + // Testing updateGroupDescription for ADD operation from northbound
202 TestGroupKey addKey = new TestGroupKey("group1AddBuckets"); 220 TestGroupKey addKey = new TestGroupKey("group1AddBuckets");
203 PortNumber[] newNeighborPorts = {PortNumber.portNumber(41), 221 PortNumber[] newNeighborPorts = {PortNumber.portNumber(41),
204 PortNumber.portNumber(42)}; 222 PortNumber.portNumber(42)};
...@@ -225,19 +243,14 @@ public class SimpleGroupStoreTest { ...@@ -225,19 +243,14 @@ public class SimpleGroupStoreTest {
225 updatedGroupBuckets, 243 updatedGroupBuckets,
226 GroupEvent.Type.GROUP_UPDATE_REQUESTED); 244 GroupEvent.Type.GROUP_UPDATE_REQUESTED);
227 simpleGroupStore.setDelegate(updateGroupDescDelegate); 245 simpleGroupStore.setDelegate(updateGroupDescDelegate);
228 - GroupDescription newGroupDesc = new DefaultGroupDescription(
229 - D1,
230 - Group.Type.SELECT,
231 - toAddGroupBuckets,
232 - addKey,
233 - appId);
234 simpleGroupStore.updateGroupDescription(D1, 246 simpleGroupStore.updateGroupDescription(D1,
235 key, 247 key,
236 UpdateType.ADD, 248 UpdateType.ADD,
237 - newGroupDesc); 249 + toAddGroupBuckets,
250 + addKey);
238 simpleGroupStore.unsetDelegate(updateGroupDescDelegate); 251 simpleGroupStore.unsetDelegate(updateGroupDescDelegate);
239 252
240 - /* Testing updateGroupDescription for REMOVE operation from northbound */ 253 + // Testing updateGroupDescription for REMOVE operation from northbound
241 TestGroupKey removeKey = new TestGroupKey("group1RemoveBuckets"); 254 TestGroupKey removeKey = new TestGroupKey("group1RemoveBuckets");
242 List<GroupBucket> toRemoveBuckets = new ArrayList<GroupBucket>(); 255 List<GroupBucket> toRemoveBuckets = new ArrayList<GroupBucket>();
243 toRemoveBuckets.add(updatedGroupBuckets.buckets().get(0)); 256 toRemoveBuckets.add(updatedGroupBuckets.buckets().get(0));
...@@ -252,23 +265,18 @@ public class SimpleGroupStoreTest { ...@@ -252,23 +265,18 @@ public class SimpleGroupStoreTest {
252 remainingGroupBuckets, 265 remainingGroupBuckets,
253 GroupEvent.Type.GROUP_UPDATE_REQUESTED); 266 GroupEvent.Type.GROUP_UPDATE_REQUESTED);
254 simpleGroupStore.setDelegate(removeGroupDescDelegate); 267 simpleGroupStore.setDelegate(removeGroupDescDelegate);
255 - GroupDescription removeGroupDesc = new DefaultGroupDescription(
256 - D1,
257 - Group.Type.SELECT,
258 - toRemoveGroupBuckets,
259 - removeKey,
260 - appId);
261 simpleGroupStore.updateGroupDescription(D1, 268 simpleGroupStore.updateGroupDescription(D1,
262 addKey, 269 addKey,
263 UpdateType.REMOVE, 270 UpdateType.REMOVE,
264 - removeGroupDesc); 271 + toRemoveGroupBuckets,
272 + removeKey);
265 simpleGroupStore.unsetDelegate(removeGroupDescDelegate); 273 simpleGroupStore.unsetDelegate(removeGroupDescDelegate);
266 274
267 - /* Testing getGroup operation */ 275 + // Testing getGroup operation
268 Group existingGroup = simpleGroupStore.getGroup(D1, removeKey); 276 Group existingGroup = simpleGroupStore.getGroup(D1, removeKey);
269 checkStoreGroupDelegate.verifyGroupId(existingGroup.id()); 277 checkStoreGroupDelegate.verifyGroupId(existingGroup.id());
270 278
271 - /* Testing addOrUpdateGroupEntry operation from southbound */ 279 + // Testing addOrUpdateGroupEntry operation from southbound
272 InternalGroupStoreDelegate updateGroupEntryDelegate = 280 InternalGroupStoreDelegate updateGroupEntryDelegate =
273 new InternalGroupStoreDelegate(removeKey, 281 new InternalGroupStoreDelegate(removeKey,
274 remainingGroupBuckets, 282 remainingGroupBuckets,
...@@ -277,7 +285,7 @@ public class SimpleGroupStoreTest { ...@@ -277,7 +285,7 @@ public class SimpleGroupStoreTest {
277 simpleGroupStore.addOrUpdateGroupEntry(existingGroup); 285 simpleGroupStore.addOrUpdateGroupEntry(existingGroup);
278 simpleGroupStore.unsetDelegate(updateGroupEntryDelegate); 286 simpleGroupStore.unsetDelegate(updateGroupEntryDelegate);
279 287
280 - /* Testing deleteGroupDescription operation from northbound */ 288 + // Testing deleteGroupDescription operation from northbound
281 InternalGroupStoreDelegate deleteGroupDescDelegate = 289 InternalGroupStoreDelegate deleteGroupDescDelegate =
282 new InternalGroupStoreDelegate(removeKey, 290 new InternalGroupStoreDelegate(removeKey,
283 remainingGroupBuckets, 291 remainingGroupBuckets,
...@@ -286,7 +294,7 @@ public class SimpleGroupStoreTest { ...@@ -286,7 +294,7 @@ public class SimpleGroupStoreTest {
286 simpleGroupStore.deleteGroupDescription(D1, removeKey); 294 simpleGroupStore.deleteGroupDescription(D1, removeKey);
287 simpleGroupStore.unsetDelegate(deleteGroupDescDelegate); 295 simpleGroupStore.unsetDelegate(deleteGroupDescDelegate);
288 296
289 - /* Testing removeGroupEntry operation from southbound */ 297 + // Testing removeGroupEntry operation from southbound
290 InternalGroupStoreDelegate removeGroupEntryDelegate = 298 InternalGroupStoreDelegate removeGroupEntryDelegate =
291 new InternalGroupStoreDelegate(removeKey, 299 new InternalGroupStoreDelegate(removeKey,
292 remainingGroupBuckets, 300 remainingGroupBuckets,
...@@ -294,17 +302,10 @@ public class SimpleGroupStoreTest { ...@@ -294,17 +302,10 @@ public class SimpleGroupStoreTest {
294 simpleGroupStore.setDelegate(removeGroupEntryDelegate); 302 simpleGroupStore.setDelegate(removeGroupEntryDelegate);
295 simpleGroupStore.removeGroupEntry(existingGroup); 303 simpleGroupStore.removeGroupEntry(existingGroup);
296 304
297 - /* Testing getGroup operation */ 305 + // Testing getGroup operation
298 existingGroup = simpleGroupStore.getGroup(D1, removeKey); 306 existingGroup = simpleGroupStore.getGroup(D1, removeKey);
299 assertEquals(null, existingGroup); 307 assertEquals(null, existingGroup);
300 - Iterable<Group> existingGroups = simpleGroupStore.getGroups(D1); 308 + assertEquals(0, Iterables.size(simpleGroupStore.getGroups(D1)));
301 - groupCount = 0;
302 - for (Group tmp:existingGroups) {
303 - /* To avoid warning */
304 - assertEquals(null, tmp);
305 - groupCount++;
306 - }
307 - assertEquals(0, groupCount);
308 assertEquals(0, simpleGroupStore.getGroupCount(D1)); 309 assertEquals(0, simpleGroupStore.getGroupCount(D1));
309 310
310 simpleGroupStore.unsetDelegate(removeGroupEntryDelegate); 311 simpleGroupStore.unsetDelegate(removeGroupEntryDelegate);
......