Committed by
Ali "The Bomb" Al-Shabibi
ONOS-895: Group manager implementation
Change-Id: Ie183f722fa39012f8de056961715c325e2388e63
Showing
16 changed files
with
363 additions
and
54 deletions
| ... | @@ -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 | } | ... | ... |
This diff is collapsed. Click to expand it.
| 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 |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
| ... | @@ -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); | ... | ... |
-
Please register or login to post a comment