Committed by
Gerrit Code Review
ONOS-885: Group store interface definition and in-memory store implementation
Change-Id: I1125fbc23f1e58bcb8aaf5f67c02da610fa7ef25 ONOS-885: Group store interface definition and in-memory store implementation Change-Id: Id3794bed63785e10ed86c0b5d90bf875d127224c
Showing
21 changed files
with
1130 additions
and
69 deletions
| 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 static org.slf4j.LoggerFactory.getLogger; | ||
| 19 | + | ||
| 20 | +import org.onosproject.core.GroupId; | ||
| 21 | +import org.slf4j.Logger; | ||
| 22 | + | ||
| 23 | +/** | ||
| 24 | + * ONOS implementation of default group that is stored in the system. | ||
| 25 | + */ | ||
| 26 | +public class DefaultGroup extends DefaultGroupDescription | ||
| 27 | + implements Group, StoredGroupEntry { | ||
| 28 | + | ||
| 29 | + private final Logger log = getLogger(getClass()); | ||
| 30 | + | ||
| 31 | + private GroupState state; | ||
| 32 | + private long life; | ||
| 33 | + private long packets; | ||
| 34 | + private long bytes; | ||
| 35 | + private GroupId id; | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Default group object constructor with the parameters. | ||
| 39 | + * | ||
| 40 | + * @param id group identifier | ||
| 41 | + * @param groupDesc group description parameters | ||
| 42 | + */ | ||
| 43 | + public DefaultGroup(GroupId id, GroupDescription groupDesc) { | ||
| 44 | + super(groupDesc); | ||
| 45 | + this.id = id; | ||
| 46 | + this.state = GroupState.PENDING_ADD; | ||
| 47 | + this.life = 0; | ||
| 48 | + this.packets = 0; | ||
| 49 | + this.bytes = 0; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * Returns group identifier associated with a group object. | ||
| 54 | + * | ||
| 55 | + * @return GroupId Group Identifier | ||
| 56 | + */ | ||
| 57 | + @Override | ||
| 58 | + public GroupId id() { | ||
| 59 | + return this.id; | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + /** | ||
| 63 | + * Returns current state of a group object. | ||
| 64 | + * | ||
| 65 | + * @return GroupState Group State | ||
| 66 | + */ | ||
| 67 | + @Override | ||
| 68 | + public GroupState state() { | ||
| 69 | + return this.state; | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + /** | ||
| 73 | + * Returns the number of milliseconds this group has been alive. | ||
| 74 | + * | ||
| 75 | + * @return number of millis | ||
| 76 | + */ | ||
| 77 | + @Override | ||
| 78 | + public long life() { | ||
| 79 | + return this.life; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + /** | ||
| 83 | + * Returns the number of packets processed by this group. | ||
| 84 | + * | ||
| 85 | + * @return number of packets | ||
| 86 | + */ | ||
| 87 | + @Override | ||
| 88 | + public long packets() { | ||
| 89 | + return this.packets; | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + /** | ||
| 93 | + * Returns the number of bytes processed by this group. | ||
| 94 | + * | ||
| 95 | + * @return number of bytes | ||
| 96 | + */ | ||
| 97 | + @Override | ||
| 98 | + public long bytes() { | ||
| 99 | + return this.bytes; | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + /** | ||
| 103 | + * Sets the new state for this entry. | ||
| 104 | + * | ||
| 105 | + * @param newState new group entry state. | ||
| 106 | + */ | ||
| 107 | + @Override | ||
| 108 | + public void setState(Group.GroupState newState) { | ||
| 109 | + this.state = newState; | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + /** | ||
| 113 | + * Sets how long this entry has been entered in the system. | ||
| 114 | + * | ||
| 115 | + * @param life epoch time | ||
| 116 | + */ | ||
| 117 | + @Override | ||
| 118 | + public void setLife(long life) { | ||
| 119 | + this.life = life; | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + /** | ||
| 123 | + * Sets number of packets processed by this group entry. | ||
| 124 | + * | ||
| 125 | + * @param packets a long value | ||
| 126 | + */ | ||
| 127 | + @Override | ||
| 128 | + public void setPackets(long packets) { | ||
| 129 | + this.packets = packets; | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + /** | ||
| 133 | + * Sets number of bytes processed by this group entry. | ||
| 134 | + * | ||
| 135 | + * @param bytes a long value | ||
| 136 | + */ | ||
| 137 | + @Override | ||
| 138 | + public void setBytes(long bytes) { | ||
| 139 | + this.bytes = bytes; | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | +} |
| ... | @@ -15,12 +15,12 @@ | ... | @@ -15,12 +15,12 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.net.group; | 16 | package org.onosproject.net.group; |
| 17 | 17 | ||
| 18 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
| 19 | 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; | ||
| 20 | 20 | ||
| 21 | +import org.onosproject.core.GroupId; | ||
| 21 | import org.onosproject.net.PortNumber; | 22 | import org.onosproject.net.PortNumber; |
| 22 | import org.onosproject.net.flow.TrafficTreatment; | 23 | import org.onosproject.net.flow.TrafficTreatment; |
| 23 | -import org.onosproject.core.GroupId; | ||
| 24 | 24 | ||
| 25 | /** | 25 | /** |
| 26 | * Group bucket implementation. A group bucket is collection of | 26 | * Group bucket implementation. A group bucket is collection of |
| ... | @@ -65,7 +65,6 @@ public final class DefaultGroupBucket implements GroupBucket { | ... | @@ -65,7 +65,6 @@ public final class DefaultGroupBucket implements GroupBucket { |
| 65 | * Creates indirect group bucket. | 65 | * Creates indirect group bucket. |
| 66 | * | 66 | * |
| 67 | * @param treatment traffic treatment associated with group bucket | 67 | * @param treatment traffic treatment associated with group bucket |
| 68 | - * | ||
| 69 | * @return indirect group bucket object | 68 | * @return indirect group bucket object |
| 70 | */ | 69 | */ |
| 71 | public static GroupBucket createIndirectGroupBucket( | 70 | public static GroupBucket createIndirectGroupBucket( |
| ... | @@ -81,7 +80,6 @@ public final class DefaultGroupBucket implements GroupBucket { | ... | @@ -81,7 +80,6 @@ public final class DefaultGroupBucket implements GroupBucket { |
| 81 | * Creates select group bucket with weight as 1. | 80 | * Creates select group bucket with weight as 1. |
| 82 | * | 81 | * |
| 83 | * @param treatment traffic treatment associated with group bucket | 82 | * @param treatment traffic treatment associated with group bucket |
| 84 | - * | ||
| 85 | * @return select group bucket object | 83 | * @return select group bucket object |
| 86 | */ | 84 | */ |
| 87 | public static GroupBucket createSelectGroupBucket( | 85 | public static GroupBucket createSelectGroupBucket( |
| ... | @@ -98,7 +96,6 @@ public final class DefaultGroupBucket implements GroupBucket { | ... | @@ -98,7 +96,6 @@ public final class DefaultGroupBucket implements GroupBucket { |
| 98 | * | 96 | * |
| 99 | * @param treatment traffic treatment associated with group bucket | 97 | * @param treatment traffic treatment associated with group bucket |
| 100 | * @param weight weight associated with group bucket | 98 | * @param weight weight associated with group bucket |
| 101 | - * | ||
| 102 | * @return select group bucket object | 99 | * @return select group bucket object |
| 103 | */ | 100 | */ |
| 104 | public static GroupBucket createSelectGroupBucket( | 101 | public static GroupBucket createSelectGroupBucket( |
| ... | @@ -121,7 +118,6 @@ public final class DefaultGroupBucket implements GroupBucket { | ... | @@ -121,7 +118,6 @@ public final class DefaultGroupBucket implements GroupBucket { |
| 121 | * @param treatment traffic treatment associated with group bucket | 118 | * @param treatment traffic treatment associated with group bucket |
| 122 | * @param watchPort port that determines the liveness of group bucket | 119 | * @param watchPort port that determines the liveness of group bucket |
| 123 | * @param watchGroup group that determines the liveness of group bucket | 120 | * @param watchGroup group that determines the liveness of group bucket |
| 124 | - * | ||
| 125 | * @return failover group bucket object | 121 | * @return failover group bucket object |
| 126 | */ | 122 | */ |
| 127 | public static GroupBucket createFailoverGroupBucket( | 123 | public static GroupBucket createFailoverGroupBucket( |
| ... | @@ -142,7 +138,7 @@ public final class DefaultGroupBucket implements GroupBucket { | ... | @@ -142,7 +138,7 @@ public final class DefaultGroupBucket implements GroupBucket { |
| 142 | } | 138 | } |
| 143 | 139 | ||
| 144 | /** | 140 | /** |
| 145 | - * Return list of Traffic instructions that are part of the bucket. | 141 | + * Returns list of Traffic instructions that are part of the bucket. |
| 146 | * | 142 | * |
| 147 | * @return TrafficTreatment Traffic instruction list | 143 | * @return TrafficTreatment Traffic instruction list |
| 148 | */ | 144 | */ |
| ... | @@ -152,7 +148,7 @@ public final class DefaultGroupBucket implements GroupBucket { | ... | @@ -152,7 +148,7 @@ public final class DefaultGroupBucket implements GroupBucket { |
| 152 | } | 148 | } |
| 153 | 149 | ||
| 154 | /** | 150 | /** |
| 155 | - * Return weight of select group bucket. | 151 | + * Returns weight of select group bucket. |
| 156 | * | 152 | * |
| 157 | * @return short weight associated with a bucket | 153 | * @return short weight associated with a bucket |
| 158 | */ | 154 | */ |
| ... | @@ -162,7 +158,7 @@ public final class DefaultGroupBucket implements GroupBucket { | ... | @@ -162,7 +158,7 @@ public final class DefaultGroupBucket implements GroupBucket { |
| 162 | } | 158 | } |
| 163 | 159 | ||
| 164 | /** | 160 | /** |
| 165 | - * Return port number used for liveness detection for a | 161 | + * Returns port number used for liveness detection for a |
| 166 | * failover bucket. | 162 | * failover bucket. |
| 167 | * | 163 | * |
| 168 | * @return PortNumber port number used for liveness detection | 164 | * @return PortNumber port number used for liveness detection |
| ... | @@ -173,7 +169,7 @@ public final class DefaultGroupBucket implements GroupBucket { | ... | @@ -173,7 +169,7 @@ public final class DefaultGroupBucket implements GroupBucket { |
| 173 | } | 169 | } |
| 174 | 170 | ||
| 175 | /** | 171 | /** |
| 176 | - * Return group identifier used for liveness detection for a | 172 | + * Returns group identifier used for liveness detection for a |
| 177 | * failover bucket. | 173 | * failover bucket. |
| 178 | * | 174 | * |
| 179 | * @return GroupId group identifier to be used for liveness detection | 175 | * @return GroupId group identifier to be used for liveness detection | ... | ... |
| ... | @@ -20,6 +20,9 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -20,6 +20,9 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 20 | import org.onosproject.core.ApplicationId; | 20 | import org.onosproject.core.ApplicationId; |
| 21 | import org.onosproject.net.DeviceId; | 21 | import org.onosproject.net.DeviceId; |
| 22 | 22 | ||
| 23 | +/** | ||
| 24 | + * Default implementation of group description interface. | ||
| 25 | + */ | ||
| 23 | public class DefaultGroupDescription implements GroupDescription { | 26 | public class DefaultGroupDescription implements GroupDescription { |
| 24 | private final GroupDescription.Type type; | 27 | private final GroupDescription.Type type; |
| 25 | private final GroupBuckets buckets; | 28 | private final GroupBuckets buckets; |
| ... | @@ -28,15 +31,15 @@ public class DefaultGroupDescription implements GroupDescription { | ... | @@ -28,15 +31,15 @@ public class DefaultGroupDescription implements GroupDescription { |
| 28 | private final DeviceId deviceId; | 31 | private final DeviceId deviceId; |
| 29 | 32 | ||
| 30 | /** | 33 | /** |
| 34 | + * Constructor to be used by north bound applications. | ||
| 35 | + * NOTE: The caller of this subsystem MUST ensure the appCookie | ||
| 36 | + * provided in this API is immutable | ||
| 31 | * | 37 | * |
| 32 | * @param deviceId device identifier | 38 | * @param deviceId device identifier |
| 33 | * @param type type of the group | 39 | * @param type type of the group |
| 34 | * @param buckets immutable list of group bucket | 40 | * @param buckets immutable list of group bucket |
| 35 | * @param appCookie immutable application cookie to be associated with the group | 41 | * @param appCookie immutable application cookie to be associated with the group |
| 36 | * @param appId application id | 42 | * @param appId application id |
| 37 | - * | ||
| 38 | - * NOTE: The caller of this subsystem MUST ensure the appCookie | ||
| 39 | - * provided in this API is immutable | ||
| 40 | */ | 43 | */ |
| 41 | public DefaultGroupDescription(DeviceId deviceId, | 44 | public DefaultGroupDescription(DeviceId deviceId, |
| 42 | GroupDescription.Type type, | 45 | GroupDescription.Type type, |
| ... | @@ -51,7 +54,22 @@ public class DefaultGroupDescription implements GroupDescription { | ... | @@ -51,7 +54,22 @@ public class DefaultGroupDescription implements GroupDescription { |
| 51 | } | 54 | } |
| 52 | 55 | ||
| 53 | /** | 56 | /** |
| 54 | - * Return type of a group object. | 57 | + * Constructor to be used by group subsystem internal components. |
| 58 | + * Creates group description object from another object of same type. | ||
| 59 | + * | ||
| 60 | + * @param groupDesc group description object | ||
| 61 | + * | ||
| 62 | + */ | ||
| 63 | + public DefaultGroupDescription(GroupDescription groupDesc) { | ||
| 64 | + this.type = checkNotNull(groupDesc.type()); | ||
| 65 | + this.deviceId = checkNotNull(groupDesc.deviceId()); | ||
| 66 | + this.buckets = checkNotNull(groupDesc.buckets()); | ||
| 67 | + this.appCookie = checkNotNull(groupDesc.appCookie()); | ||
| 68 | + this.appId = checkNotNull(groupDesc.appId()); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * Returns type of a group object. | ||
| 55 | * | 73 | * |
| 56 | * @return GroupType group type | 74 | * @return GroupType group type |
| 57 | */ | 75 | */ |
| ... | @@ -61,7 +79,7 @@ public class DefaultGroupDescription implements GroupDescription { | ... | @@ -61,7 +79,7 @@ public class DefaultGroupDescription implements GroupDescription { |
| 61 | } | 79 | } |
| 62 | 80 | ||
| 63 | /** | 81 | /** |
| 64 | - * Return device identifier on which this group object is created. | 82 | + * Returns device identifier on which this group object is created. |
| 65 | * | 83 | * |
| 66 | * @return DeviceId device identifier | 84 | * @return DeviceId device identifier |
| 67 | */ | 85 | */ |
| ... | @@ -71,7 +89,7 @@ public class DefaultGroupDescription implements GroupDescription { | ... | @@ -71,7 +89,7 @@ public class DefaultGroupDescription implements GroupDescription { |
| 71 | } | 89 | } |
| 72 | 90 | ||
| 73 | /** | 91 | /** |
| 74 | - * Return application identifier that has created this group object. | 92 | + * Returns application identifier that has created this group object. |
| 75 | * | 93 | * |
| 76 | * @return ApplicationId application identifier | 94 | * @return ApplicationId application identifier |
| 77 | */ | 95 | */ |
| ... | @@ -81,7 +99,7 @@ public class DefaultGroupDescription implements GroupDescription { | ... | @@ -81,7 +99,7 @@ public class DefaultGroupDescription implements GroupDescription { |
| 81 | } | 99 | } |
| 82 | 100 | ||
| 83 | /** | 101 | /** |
| 84 | - * Return application cookie associated with a group object. | 102 | + * Returns application cookie associated with a group object. |
| 85 | * | 103 | * |
| 86 | * @return GroupKey application cookie | 104 | * @return GroupKey application cookie |
| 87 | */ | 105 | */ |
| ... | @@ -91,7 +109,7 @@ public class DefaultGroupDescription implements GroupDescription { | ... | @@ -91,7 +109,7 @@ public class DefaultGroupDescription implements GroupDescription { |
| 91 | } | 109 | } |
| 92 | 110 | ||
| 93 | /** | 111 | /** |
| 94 | - * Return group buckets of a group. | 112 | + * Returns group buckets of a group. |
| 95 | * | 113 | * |
| 96 | * @return GroupBuckets immutable list of group bucket | 114 | * @return GroupBuckets immutable list of group bucket |
| 97 | */ | 115 | */ | ... | ... |
| ... | @@ -23,35 +23,43 @@ import org.onosproject.core.GroupId; | ... | @@ -23,35 +23,43 @@ import org.onosproject.core.GroupId; |
| 23 | public interface Group extends GroupDescription { | 23 | public interface Group extends GroupDescription { |
| 24 | /** | 24 | /** |
| 25 | * State of the group object in ONOS. | 25 | * State of the group object in ONOS. |
| 26 | - * PENDING_ADD: group create request is processed by ONOS and | ||
| 27 | - * not yet received the confirmation from data plane | ||
| 28 | - * ADDED: group is created in the data plane | ||
| 29 | - * PENDING_UPDATE: group update request is processed by ONOS and | ||
| 30 | - * not received the confirmation from data plane post which state | ||
| 31 | - * moves to ADDED state | ||
| 32 | - * PENDING_DELETE: group delete request is processed by ONOS and | ||
| 33 | - * not received the confirmation from data plane | ||
| 34 | */ | 26 | */ |
| 35 | public enum GroupState { | 27 | public enum GroupState { |
| 28 | + /** | ||
| 29 | + * Group create request is processed by ONOS and not yet | ||
| 30 | + * received the confirmation from data plane. | ||
| 31 | + */ | ||
| 36 | PENDING_ADD, | 32 | PENDING_ADD, |
| 33 | + /** | ||
| 34 | + * Group is created in the data plane. | ||
| 35 | + */ | ||
| 37 | ADDED, | 36 | ADDED, |
| 37 | + /** | ||
| 38 | + * Group update request is processed by ONOS and not | ||
| 39 | + * received the confirmation from data plane post which | ||
| 40 | + * state moves to ADDED state. | ||
| 41 | + */ | ||
| 38 | PENDING_UPDATE, | 42 | PENDING_UPDATE, |
| 43 | + /** | ||
| 44 | + * Group delete request is processed by ONOS and not | ||
| 45 | + * received the confirmation from data plane. | ||
| 46 | + */ | ||
| 39 | PENDING_DELETE | 47 | PENDING_DELETE |
| 40 | } | 48 | } |
| 41 | 49 | ||
| 42 | /** | 50 | /** |
| 43 | - * Return group identifier associated with a group object. | 51 | + * Returns group identifier associated with a group object. |
| 44 | * | 52 | * |
| 45 | * @return GroupId Group Identifier | 53 | * @return GroupId Group Identifier |
| 46 | */ | 54 | */ |
| 47 | - public GroupId id(); | 55 | + GroupId id(); |
| 48 | 56 | ||
| 49 | /** | 57 | /** |
| 50 | - * Return current state of a group object. | 58 | + * Returns current state of a group object. |
| 51 | * | 59 | * |
| 52 | * @return GroupState Group State | 60 | * @return GroupState Group State |
| 53 | */ | 61 | */ |
| 54 | - public GroupState state(); | 62 | + GroupState state(); |
| 55 | 63 | ||
| 56 | /** | 64 | /** |
| 57 | * Returns the number of milliseconds this group has been alive. | 65 | * Returns the number of milliseconds this group has been alive. | ... | ... |
| ... | @@ -15,11 +15,12 @@ | ... | @@ -15,11 +15,12 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.net.group; | 16 | package org.onosproject.net.group; |
| 17 | 17 | ||
| 18 | +import org.onosproject.core.GroupId; | ||
| 18 | import org.onosproject.net.PortNumber; | 19 | import org.onosproject.net.PortNumber; |
| 19 | import org.onosproject.net.flow.TrafficTreatment; | 20 | import org.onosproject.net.flow.TrafficTreatment; |
| 20 | -import org.onosproject.core.GroupId; | ||
| 21 | 21 | ||
| 22 | -/* Group Bucket definition. A default group Bucket is collection of | 22 | +/** |
| 23 | + * Group Bucket definition. A default group Bucket is collection of | ||
| 23 | * Instructions that can be performed on a traffic flow. A failover | 24 | * Instructions that can be performed on a traffic flow. A failover |
| 24 | * group bucket is associated with a specific port or group that | 25 | * group bucket is associated with a specific port or group that |
| 25 | * controls its liveness. A select group bucket contains optional | 26 | * controls its liveness. A select group bucket contains optional |
| ... | @@ -27,28 +28,28 @@ import org.onosproject.core.GroupId; | ... | @@ -27,28 +28,28 @@ import org.onosproject.core.GroupId; |
| 27 | */ | 28 | */ |
| 28 | public interface GroupBucket { | 29 | public interface GroupBucket { |
| 29 | /** | 30 | /** |
| 30 | - * Return group type of the bucket. | 31 | + * Returns group type of the bucket. |
| 31 | * | 32 | * |
| 32 | * @return GroupType group type | 33 | * @return GroupType group type |
| 33 | */ | 34 | */ |
| 34 | public GroupDescription.Type type(); | 35 | public GroupDescription.Type type(); |
| 35 | 36 | ||
| 36 | /** | 37 | /** |
| 37 | - * Return list of Traffic instructions that are part of the bucket. | 38 | + * Returns list of Traffic instructions that are part of the bucket. |
| 38 | * | 39 | * |
| 39 | * @return TrafficTreatment traffic instruction list | 40 | * @return TrafficTreatment traffic instruction list |
| 40 | */ | 41 | */ |
| 41 | public TrafficTreatment treatment(); | 42 | public TrafficTreatment treatment(); |
| 42 | 43 | ||
| 43 | /** | 44 | /** |
| 44 | - * Return weight of select group bucket. | 45 | + * Returns weight of select group bucket. |
| 45 | * | 46 | * |
| 46 | * @return short weight associated with a bucket | 47 | * @return short weight associated with a bucket |
| 47 | */ | 48 | */ |
| 48 | public short weight(); | 49 | public short weight(); |
| 49 | 50 | ||
| 50 | /** | 51 | /** |
| 51 | - * Return port number used for liveness detection for a | 52 | + * Returns port number used for liveness detection for a |
| 52 | * failover bucket. | 53 | * failover bucket. |
| 53 | * | 54 | * |
| 54 | * @return PortNumber port number used for liveness detection | 55 | * @return PortNumber port number used for liveness detection |
| ... | @@ -56,7 +57,7 @@ public interface GroupBucket { | ... | @@ -56,7 +57,7 @@ public interface GroupBucket { |
| 56 | public PortNumber watchPort(); | 57 | public PortNumber watchPort(); |
| 57 | 58 | ||
| 58 | /** | 59 | /** |
| 59 | - * Return group identifier used for liveness detection for a | 60 | + * Returns group identifier used for liveness detection for a |
| 60 | * failover bucket. | 61 | * failover bucket. |
| 61 | * | 62 | * |
| 62 | * @return GroupId group identifier to be used for liveness detection | 63 | * @return GroupId group identifier to be used for liveness detection | ... | ... |
| ... | @@ -15,20 +15,21 @@ | ... | @@ -15,20 +15,21 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.net.group; | 16 | package org.onosproject.net.group; |
| 17 | 17 | ||
| 18 | -/* Generic group bucket entry representation that is stored in a | 18 | +/** |
| 19 | + * Generic group bucket entry representation that is stored in a | ||
| 19 | * group object. A group bucket entry provides additional info of | 20 | * group object. A group bucket entry provides additional info of |
| 20 | * group bucket like statistics...etc | 21 | * group bucket like statistics...etc |
| 21 | */ | 22 | */ |
| 22 | public interface GroupBucketEntry extends GroupBucket { | 23 | public interface GroupBucketEntry extends GroupBucket { |
| 23 | /** | 24 | /** |
| 24 | - * Return Number of packets processed by bucket. | 25 | + * Returns Number of packets processed by bucket. |
| 25 | * | 26 | * |
| 26 | * @return long | 27 | * @return long |
| 27 | */ | 28 | */ |
| 28 | public long packets(); | 29 | public long packets(); |
| 29 | 30 | ||
| 30 | /** | 31 | /** |
| 31 | - * Return Number of bytes processed by bucket. | 32 | + * Returns Number of bytes processed by bucket. |
| 32 | * | 33 | * |
| 33 | * @return long | 34 | * @return long |
| 34 | */ | 35 | */ | ... | ... |
| ... | @@ -19,9 +19,11 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -19,9 +19,11 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 19 | 19 | ||
| 20 | import java.util.List; | 20 | import java.util.List; |
| 21 | 21 | ||
| 22 | - | ||
| 23 | import com.google.common.collect.ImmutableList; | 22 | import com.google.common.collect.ImmutableList; |
| 24 | 23 | ||
| 24 | +/** | ||
| 25 | + * Immutable collection of group bucket. | ||
| 26 | + */ | ||
| 25 | public final class GroupBuckets { | 27 | public final class GroupBuckets { |
| 26 | private final List<GroupBucket> buckets; | 28 | private final List<GroupBucket> buckets; |
| 27 | 29 | ||
| ... | @@ -35,7 +37,7 @@ public final class GroupBuckets { | ... | @@ -35,7 +37,7 @@ public final class GroupBuckets { |
| 35 | } | 37 | } |
| 36 | 38 | ||
| 37 | /** | 39 | /** |
| 38 | - * Immutable list of group buckets. | 40 | + * Returns immutable list of group buckets. |
| 39 | * | 41 | * |
| 40 | * @return list of group bucket | 42 | * @return list of group bucket |
| 41 | */ | 43 | */ | ... | ... |
| ... | @@ -47,35 +47,35 @@ public interface GroupDescription { | ... | @@ -47,35 +47,35 @@ public interface GroupDescription { |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | /** | 49 | /** |
| 50 | - * Return type of a group object. | 50 | + * Returns type of a group object. |
| 51 | * | 51 | * |
| 52 | * @return GroupType group type | 52 | * @return GroupType group type |
| 53 | */ | 53 | */ |
| 54 | public Type type(); | 54 | public Type type(); |
| 55 | 55 | ||
| 56 | /** | 56 | /** |
| 57 | - * Return device identifier on which this group object is created. | 57 | + * Returns device identifier on which this group object is created. |
| 58 | * | 58 | * |
| 59 | * @return DeviceId device identifier | 59 | * @return DeviceId device identifier |
| 60 | */ | 60 | */ |
| 61 | public DeviceId deviceId(); | 61 | public DeviceId deviceId(); |
| 62 | 62 | ||
| 63 | /** | 63 | /** |
| 64 | - * Return application identifier that has created this group object. | 64 | + * Returns application identifier that has created this group object. |
| 65 | * | 65 | * |
| 66 | * @return ApplicationId application identifier | 66 | * @return ApplicationId application identifier |
| 67 | */ | 67 | */ |
| 68 | public ApplicationId appId(); | 68 | public ApplicationId appId(); |
| 69 | 69 | ||
| 70 | /** | 70 | /** |
| 71 | - * Return application cookie associated with a group object. | 71 | + * Returns application cookie associated with a group object. |
| 72 | * | 72 | * |
| 73 | * @return GroupKey application cookie | 73 | * @return GroupKey application cookie |
| 74 | */ | 74 | */ |
| 75 | public GroupKey appCookie(); | 75 | public GroupKey appCookie(); |
| 76 | 76 | ||
| 77 | /** | 77 | /** |
| 78 | - * Return group buckets of a group. | 78 | + * Returns group buckets of a group. |
| 79 | * | 79 | * |
| 80 | * @return GroupBuckets immutable list of group bucket | 80 | * @return GroupBuckets immutable list of group bucket |
| 81 | */ | 81 | */ | ... | ... |
| ... | @@ -18,7 +18,7 @@ package org.onosproject.net.group; | ... | @@ -18,7 +18,7 @@ package org.onosproject.net.group; |
| 18 | import org.onosproject.event.AbstractEvent; | 18 | import org.onosproject.event.AbstractEvent; |
| 19 | 19 | ||
| 20 | /** | 20 | /** |
| 21 | - * Describes flow rule event. | 21 | + * Describes group events. |
| 22 | */ | 22 | */ |
| 23 | public class GroupEvent extends AbstractEvent<GroupEvent.Type, Group> { | 23 | public class GroupEvent extends AbstractEvent<GroupEvent.Type, Group> { |
| 24 | 24 | ||
| ... | @@ -48,6 +48,10 @@ public class GroupEvent extends AbstractEvent<GroupEvent.Type, Group> { | ... | @@ -48,6 +48,10 @@ public class GroupEvent extends AbstractEvent<GroupEvent.Type, Group> { |
| 48 | */ | 48 | */ |
| 49 | GROUP_ADD_REQUESTED, | 49 | GROUP_ADD_REQUESTED, |
| 50 | /* | 50 | /* |
| 51 | + * Signifies that a request to update Group has been added to the store. | ||
| 52 | + */ | ||
| 53 | + GROUP_UPDATE_REQUESTED, | ||
| 54 | + /* | ||
| 51 | * Signifies that a request to delete Group has been added to the store. | 55 | * Signifies that a request to delete Group has been added to the store. |
| 52 | */ | 56 | */ |
| 53 | GROUP_REMOVE_REQUESTED, | 57 | GROUP_REMOVE_REQUESTED, | ... | ... |
| ... | @@ -15,8 +15,9 @@ | ... | @@ -15,8 +15,9 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.net.group; | 16 | package org.onosproject.net.group; |
| 17 | 17 | ||
| 18 | -/* Representation of generalized Key that would be used to store | 18 | +/** |
| 19 | - * groups in <Key, Value> store. Implementation of this interface | 19 | + * Representation of generalized Key that would be used to store |
| 20 | + * groups in < Key, Value > store. Implementation of this interface | ||
| 20 | * MUST override "equals()" and "hashcode()" methods. | 21 | * MUST override "equals()" and "hashcode()" methods. |
| 21 | */ | 22 | */ |
| 22 | public interface GroupKey { | 23 | public interface GroupKey { | ... | ... |
| ... | @@ -19,6 +19,11 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -19,6 +19,11 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 19 | 19 | ||
| 20 | import org.onosproject.core.GroupId; | 20 | import org.onosproject.core.GroupId; |
| 21 | 21 | ||
| 22 | +/** | ||
| 23 | + * Group operation definition to be used between core and provider | ||
| 24 | + * layers of group subsystem. | ||
| 25 | + * | ||
| 26 | + */ | ||
| 22 | public final class GroupOperation { | 27 | public final class GroupOperation { |
| 23 | private final Type opType; | 28 | private final Type opType; |
| 24 | private final GroupId groupId; | 29 | private final GroupId groupId; |
| ... | @@ -64,7 +69,6 @@ public final class GroupOperation { | ... | @@ -64,7 +69,6 @@ public final class GroupOperation { |
| 64 | * @param groupId group Identifier | 69 | * @param groupId group Identifier |
| 65 | * @param groupType type of the group | 70 | * @param groupType type of the group |
| 66 | * @param buckets immutable list of group buckets to be part of group | 71 | * @param buckets immutable list of group buckets to be part of group |
| 67 | - * | ||
| 68 | * @return add group operation object | 72 | * @return add group operation object |
| 69 | */ | 73 | */ |
| 70 | public static GroupOperation createAddGroupOperation(GroupId groupId, | 74 | public static GroupOperation createAddGroupOperation(GroupId groupId, |
| ... | @@ -80,7 +84,6 @@ public final class GroupOperation { | ... | @@ -80,7 +84,6 @@ public final class GroupOperation { |
| 80 | * @param groupId group Identifier | 84 | * @param groupId group Identifier |
| 81 | * @param groupType type of the group | 85 | * @param groupType type of the group |
| 82 | * @param buckets immutable list of group buckets to be part of group | 86 | * @param buckets immutable list of group buckets to be part of group |
| 83 | - * | ||
| 84 | * @return modify group operation object | 87 | * @return modify group operation object |
| 85 | */ | 88 | */ |
| 86 | public static GroupOperation createModifyGroupOperation(GroupId groupId, | 89 | public static GroupOperation createModifyGroupOperation(GroupId groupId, |
| ... | @@ -96,7 +99,6 @@ public final class GroupOperation { | ... | @@ -96,7 +99,6 @@ public final class GroupOperation { |
| 96 | * | 99 | * |
| 97 | * @param groupId group Identifier | 100 | * @param groupId group Identifier |
| 98 | * @param groupType type of the group | 101 | * @param groupType type of the group |
| 99 | - * | ||
| 100 | * @return delete group operation object | 102 | * @return delete group operation object |
| 101 | */ | 103 | */ |
| 102 | public static GroupOperation createDeleteGroupOperation(GroupId groupId, | 104 | public static GroupOperation createDeleteGroupOperation(GroupId groupId, |
| ... | @@ -106,7 +108,7 @@ public final class GroupOperation { | ... | @@ -106,7 +108,7 @@ public final class GroupOperation { |
| 106 | } | 108 | } |
| 107 | 109 | ||
| 108 | /** | 110 | /** |
| 109 | - * Return group operation type. | 111 | + * Returns group operation type. |
| 110 | * | 112 | * |
| 111 | * @return GroupOpType group operation type | 113 | * @return GroupOpType group operation type |
| 112 | */ | 114 | */ |
| ... | @@ -115,7 +117,7 @@ public final class GroupOperation { | ... | @@ -115,7 +117,7 @@ public final class GroupOperation { |
| 115 | } | 117 | } |
| 116 | 118 | ||
| 117 | /** | 119 | /** |
| 118 | - * Return group identifier attribute of the operation. | 120 | + * Returns group identifier attribute of the operation. |
| 119 | * | 121 | * |
| 120 | * @return GroupId group identifier | 122 | * @return GroupId group identifier |
| 121 | */ | 123 | */ |
| ... | @@ -124,7 +126,7 @@ public final class GroupOperation { | ... | @@ -124,7 +126,7 @@ public final class GroupOperation { |
| 124 | } | 126 | } |
| 125 | 127 | ||
| 126 | /** | 128 | /** |
| 127 | - * Return group type attribute of the operation. | 129 | + * Returns group type attribute of the operation. |
| 128 | * | 130 | * |
| 129 | * @return GroupType group type | 131 | * @return GroupType group type |
| 130 | */ | 132 | */ |
| ... | @@ -133,7 +135,7 @@ public final class GroupOperation { | ... | @@ -133,7 +135,7 @@ public final class GroupOperation { |
| 133 | } | 135 | } |
| 134 | 136 | ||
| 135 | /** | 137 | /** |
| 136 | - * Return group buckets associated with the operation. | 138 | + * Returns group buckets associated with the operation. |
| 137 | * | 139 | * |
| 138 | * @return GroupBuckets group buckets | 140 | * @return GroupBuckets group buckets |
| 139 | */ | 141 | */ | ... | ... |
| ... | @@ -19,9 +19,13 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -19,9 +19,13 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 19 | 19 | ||
| 20 | import java.util.List; | 20 | import java.util.List; |
| 21 | 21 | ||
| 22 | - | ||
| 23 | import com.google.common.collect.ImmutableList; | 22 | import com.google.common.collect.ImmutableList; |
| 24 | 23 | ||
| 24 | +/** | ||
| 25 | + * Immutable collection of group operation to be used between | ||
| 26 | + * core and provider layers of group subsystem. | ||
| 27 | + * | ||
| 28 | + */ | ||
| 25 | public final class GroupOperations { | 29 | public final class GroupOperations { |
| 26 | private final List<GroupOperation> operations; | 30 | private final List<GroupOperation> operations; |
| 27 | 31 | ||
| ... | @@ -35,7 +39,7 @@ public final class GroupOperations { | ... | @@ -35,7 +39,7 @@ public final class GroupOperations { |
| 35 | } | 39 | } |
| 36 | 40 | ||
| 37 | /** | 41 | /** |
| 38 | - * Immutable list of group operation. | 42 | + * Returns immutable list of group operation. |
| 39 | * | 43 | * |
| 40 | * @return list of group operation | 44 | * @return list of group operation |
| 41 | */ | 45 | */ | ... | ... |
| ... | @@ -19,12 +19,12 @@ import org.onosproject.net.DeviceId; | ... | @@ -19,12 +19,12 @@ import org.onosproject.net.DeviceId; |
| 19 | import org.onosproject.net.provider.Provider; | 19 | import org.onosproject.net.provider.Provider; |
| 20 | 20 | ||
| 21 | /** | 21 | /** |
| 22 | - * Abstraction of a flow rule provider. | 22 | + * Abstraction of group provider. |
| 23 | */ | 23 | */ |
| 24 | public interface GroupProvider extends Provider { | 24 | public interface GroupProvider extends Provider { |
| 25 | 25 | ||
| 26 | /** | 26 | /** |
| 27 | - * Perform a group operation in the specified device with the | 27 | + * Performs a batch of group operation in the specified device with the |
| 28 | * specified parameters. | 28 | * specified parameters. |
| 29 | * | 29 | * |
| 30 | * @param deviceId device identifier on which the batch of group | 30 | * @param deviceId device identifier on which the batch of group | ... | ... |
| ... | @@ -26,6 +26,11 @@ import org.onosproject.net.provider.ProviderService; | ... | @@ -26,6 +26,11 @@ import org.onosproject.net.provider.ProviderService; |
| 26 | */ | 26 | */ |
| 27 | public interface GroupProviderService extends ProviderService<GroupProvider> { | 27 | public interface GroupProviderService extends ProviderService<GroupProvider> { |
| 28 | 28 | ||
| 29 | + /** | ||
| 30 | + * Notifies core if any failure from data plane during group operations. | ||
| 31 | + * | ||
| 32 | + * @param operation offended group operation | ||
| 33 | + */ | ||
| 29 | void groupOperationFailed(GroupOperation operation); | 34 | void groupOperationFailed(GroupOperation operation); |
| 30 | 35 | ||
| 31 | /** | 36 | /** | ... | ... |
| ... | @@ -36,7 +36,7 @@ import org.onosproject.net.DeviceId; | ... | @@ -36,7 +36,7 @@ import org.onosproject.net.DeviceId; |
| 36 | public interface GroupService { | 36 | public interface GroupService { |
| 37 | 37 | ||
| 38 | /** | 38 | /** |
| 39 | - * Create a group in the specified device with the provided buckets. | 39 | + * Creates a group in the specified device with the provided buckets. |
| 40 | * This API provides an option for application to associate a cookie | 40 | * This API provides an option for application to associate a cookie |
| 41 | * while creating a group, so that applications can look-up the | 41 | * while creating a group, so that applications can look-up the |
| 42 | * groups based on the cookies. These Groups will be retained by | 42 | * groups based on the cookies. These Groups will be retained by |
| ... | @@ -55,7 +55,7 @@ public interface GroupService { | ... | @@ -55,7 +55,7 @@ public interface GroupService { |
| 55 | void addGroup(GroupDescription groupDesc); | 55 | void addGroup(GroupDescription groupDesc); |
| 56 | 56 | ||
| 57 | /** | 57 | /** |
| 58 | - * Return a group object associated to an application cookie. | 58 | + * Returns a group object associated to an application cookie. |
| 59 | * | 59 | * |
| 60 | * NOTE1: The presence of group object in the system does not | 60 | * NOTE1: The presence of group object in the system does not |
| 61 | * guarantee that the "group" is actually created in device. | 61 | * guarantee that the "group" is actually created in device. |
| ... | @@ -64,14 +64,13 @@ public interface GroupService { | ... | @@ -64,14 +64,13 @@ public interface GroupService { |
| 64 | * | 64 | * |
| 65 | * @param deviceId device identifier | 65 | * @param deviceId device identifier |
| 66 | * @param appCookie application cookie to be used for lookup | 66 | * @param appCookie application cookie to be used for lookup |
| 67 | - * | ||
| 68 | * @return group associated with the application cookie or | 67 | * @return group associated with the application cookie or |
| 69 | * NULL if Group is not found for the provided cookie | 68 | * NULL if Group is not found for the provided cookie |
| 70 | */ | 69 | */ |
| 71 | Group getGroup(DeviceId deviceId, GroupKey appCookie); | 70 | Group getGroup(DeviceId deviceId, GroupKey appCookie); |
| 72 | 71 | ||
| 73 | /** | 72 | /** |
| 74 | - * Append buckets to existing group. The caller can optionally | 73 | + * Appends buckets to existing group. The caller can optionally |
| 75 | * associate a new cookie during this updation. GROUP_UPDATED or | 74 | * associate a new cookie during this updation. GROUP_UPDATED or |
| 76 | * GROUP_UPDATE_FAILED notifications would be provided along with | 75 | * GROUP_UPDATE_FAILED notifications would be provided along with |
| 77 | * cookie depending on the result of the operation on the device | 76 | * cookie depending on the result of the operation on the device |
| ... | @@ -89,7 +88,7 @@ public interface GroupService { | ... | @@ -89,7 +88,7 @@ public interface GroupService { |
| 89 | ApplicationId appId); | 88 | ApplicationId appId); |
| 90 | 89 | ||
| 91 | /** | 90 | /** |
| 92 | - * Remove buckets from existing group. The caller can optionally | 91 | + * Removes buckets from existing group. The caller can optionally |
| 93 | * associate a new cookie during this updation. GROUP_UPDATED or | 92 | * associate a new cookie during this updation. GROUP_UPDATED or |
| 94 | * GROUP_UPDATE_FAILED notifications would be provided along with | 93 | * GROUP_UPDATE_FAILED notifications would be provided along with |
| 95 | * cookie depending on the result of the operation on the device | 94 | * cookie depending on the result of the operation on the device |
| ... | @@ -107,7 +106,7 @@ public interface GroupService { | ... | @@ -107,7 +106,7 @@ public interface GroupService { |
| 107 | ApplicationId appId); | 106 | ApplicationId appId); |
| 108 | 107 | ||
| 109 | /** | 108 | /** |
| 110 | - * Delete a group associated to an application cookie. | 109 | + * Deletes a group associated to an application cookie. |
| 111 | * GROUP_DELETED or GROUP_DELETE_FAILED notifications would be | 110 | * GROUP_DELETED or GROUP_DELETE_FAILED notifications would be |
| 112 | * provided along with cookie depending on the result of the | 111 | * provided along with cookie depending on the result of the |
| 113 | * operation on the device | 112 | * operation on the device |
| ... | @@ -119,12 +118,11 @@ public interface GroupService { | ... | @@ -119,12 +118,11 @@ public interface GroupService { |
| 119 | void removeGroup(Device deviceId, GroupKey appCookie, ApplicationId appId); | 118 | void removeGroup(Device deviceId, GroupKey appCookie, ApplicationId appId); |
| 120 | 119 | ||
| 121 | /** | 120 | /** |
| 122 | - * Retrieve all groups created by an application in the specified device | 121 | + * Retrieves all groups created by an application in the specified device |
| 123 | * as seen by current controller instance. | 122 | * as seen by current controller instance. |
| 124 | * | 123 | * |
| 125 | * @param deviceId device identifier | 124 | * @param deviceId device identifier |
| 126 | * @param appId application id | 125 | * @param appId application id |
| 127 | - * | ||
| 128 | * @return collection of immutable group objects created by the application | 126 | * @return collection of immutable group objects created by the application |
| 129 | */ | 127 | */ |
| 130 | Iterable<Group> getGroups(Device deviceId, ApplicationId appId); | 128 | Iterable<Group> getGroups(Device deviceId, ApplicationId appId); | ... | ... |
| 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.DeviceId; | ||
| 19 | +import org.onosproject.store.Store; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * Manages inventory of groups per device; not intended for direct use. | ||
| 23 | + */ | ||
| 24 | +public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> { | ||
| 25 | + | ||
| 26 | + public enum UpdateType { | ||
| 27 | + /** | ||
| 28 | + * Modify existing group entry by adding provided information. | ||
| 29 | + */ | ||
| 30 | + ADD, | ||
| 31 | + /** | ||
| 32 | + * Modify existing group by removing provided information from it. | ||
| 33 | + */ | ||
| 34 | + REMOVE | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Returns the number of groups for the specified device in the store. | ||
| 39 | + * | ||
| 40 | + * @param deviceId the device ID | ||
| 41 | + * @return number of groups for the specified device | ||
| 42 | + */ | ||
| 43 | + int getGroupCount(DeviceId deviceId); | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * Returns the groups associated with a device. | ||
| 47 | + * | ||
| 48 | + * @param deviceId the device ID | ||
| 49 | + * @return the group entries | ||
| 50 | + */ | ||
| 51 | + Iterable<Group> getGroups(DeviceId deviceId); | ||
| 52 | + | ||
| 53 | + /** | ||
| 54 | + * Returns the stored group entry. | ||
| 55 | + * | ||
| 56 | + * @param deviceId the device ID | ||
| 57 | + * @param appCookie the group key | ||
| 58 | + * @return a group associated with the key | ||
| 59 | + */ | ||
| 60 | + Group getGroup(DeviceId deviceId, GroupKey appCookie); | ||
| 61 | + | ||
| 62 | + /** | ||
| 63 | + * Stores a new group entry using the information from group description. | ||
| 64 | + * | ||
| 65 | + * @param groupDesc group description to be used to store group entry | ||
| 66 | + */ | ||
| 67 | + void storeGroupDescription(GroupDescription groupDesc); | ||
| 68 | + | ||
| 69 | + /** | ||
| 70 | + * Updates the existing group entry with the information | ||
| 71 | + * from group description. | ||
| 72 | + * | ||
| 73 | + * @param deviceId the device ID | ||
| 74 | + * @param oldAppCookie the current group key | ||
| 75 | + * @param type update type | ||
| 76 | + * @param newGroupDesc group description with updates | ||
| 77 | + */ | ||
| 78 | + void updateGroupDescription(DeviceId deviceId, | ||
| 79 | + GroupKey oldAppCookie, | ||
| 80 | + UpdateType type, | ||
| 81 | + GroupDescription newGroupDesc); | ||
| 82 | + | ||
| 83 | + /** | ||
| 84 | + * Triggers deleting the existing group entry. | ||
| 85 | + * | ||
| 86 | + * @param deviceId the device ID | ||
| 87 | + * @param appCookie the group key | ||
| 88 | + */ | ||
| 89 | + void deleteGroupDescription(DeviceId deviceId, | ||
| 90 | + GroupKey appCookie); | ||
| 91 | + | ||
| 92 | + /** | ||
| 93 | + * Stores a new group entry, or updates an existing entry. | ||
| 94 | + * | ||
| 95 | + * @param group group entry | ||
| 96 | + */ | ||
| 97 | + void addOrUpdateGroupEntry(Group group); | ||
| 98 | + | ||
| 99 | + /** | ||
| 100 | + * Removes the group entry from store. | ||
| 101 | + * | ||
| 102 | + * @param group group entry | ||
| 103 | + */ | ||
| 104 | + void removeGroupEntry(Group group); | ||
| 105 | +} |
| 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.store.StoreDelegate; | ||
| 19 | + | ||
| 20 | +/** | ||
| 21 | + * Group store delegate abstraction. | ||
| 22 | + */ | ||
| 23 | +public interface GroupStoreDelegate extends StoreDelegate<GroupEvent> { | ||
| 24 | +} |
| 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 | +/** | ||
| 19 | + * Interface that defines set methods for a group entry | ||
| 20 | + * that is stored in the system. | ||
| 21 | + */ | ||
| 22 | +public interface StoredGroupEntry extends Group { | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * Sets the new state for this entry. | ||
| 26 | + * | ||
| 27 | + * @param newState new group entry state. | ||
| 28 | + */ | ||
| 29 | + void setState(Group.GroupState newState); | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * Sets how long this entry has been entered in the system. | ||
| 33 | + * | ||
| 34 | + * @param life epoch time | ||
| 35 | + */ | ||
| 36 | + void setLife(long life); | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * Sets number of packets processed by this group entry. | ||
| 40 | + * | ||
| 41 | + * @param packets a long value | ||
| 42 | + */ | ||
| 43 | + void setPackets(long packets); | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * Sets number of bytes processed by this group entry. | ||
| 47 | + * | ||
| 48 | + * @param bytes a long value | ||
| 49 | + */ | ||
| 50 | + void setBytes(long bytes); | ||
| 51 | + | ||
| 52 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014 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 | + * Implementation of the group store. | ||
| 18 | + */ | ||
| 19 | +package org.onosproject.store.group.impl; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
core/store/trivial/src/main/java/org/onosproject/store/trivial/impl/SimpleGroupStore.java
0 → 100644
| 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.store.trivial.impl; | ||
| 17 | + | ||
| 18 | +import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked; | ||
| 19 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 20 | + | ||
| 21 | +import java.util.ArrayList; | ||
| 22 | +import java.util.List; | ||
| 23 | +import java.util.concurrent.ConcurrentHashMap; | ||
| 24 | +import java.util.concurrent.ConcurrentMap; | ||
| 25 | +import java.util.concurrent.atomic.AtomicInteger; | ||
| 26 | + | ||
| 27 | +import org.apache.felix.scr.annotations.Activate; | ||
| 28 | +import org.apache.felix.scr.annotations.Component; | ||
| 29 | +import org.apache.felix.scr.annotations.Deactivate; | ||
| 30 | +import org.apache.felix.scr.annotations.Service; | ||
| 31 | +import org.onlab.util.NewConcurrentHashMap; | ||
| 32 | +import org.onosproject.core.DefaultGroupId; | ||
| 33 | +import org.onosproject.core.GroupId; | ||
| 34 | +import org.onosproject.net.DeviceId; | ||
| 35 | +import org.onosproject.net.group.DefaultGroup; | ||
| 36 | +import org.onosproject.net.group.DefaultGroupDescription; | ||
| 37 | +import org.onosproject.net.group.Group; | ||
| 38 | +import org.onosproject.net.group.Group.GroupState; | ||
| 39 | +import org.onosproject.net.group.GroupBucket; | ||
| 40 | +import org.onosproject.net.group.GroupBuckets; | ||
| 41 | +import org.onosproject.net.group.GroupDescription; | ||
| 42 | +import org.onosproject.net.group.GroupEvent; | ||
| 43 | +import org.onosproject.net.group.GroupEvent.Type; | ||
| 44 | +import org.onosproject.net.group.GroupKey; | ||
| 45 | +import org.onosproject.net.group.GroupStore; | ||
| 46 | +import org.onosproject.net.group.GroupStoreDelegate; | ||
| 47 | +import org.onosproject.net.group.StoredGroupEntry; | ||
| 48 | +import org.onosproject.store.AbstractStore; | ||
| 49 | +import org.slf4j.Logger; | ||
| 50 | + | ||
| 51 | +import com.google.common.base.Function; | ||
| 52 | +import com.google.common.collect.FluentIterable; | ||
| 53 | + | ||
| 54 | +/** | ||
| 55 | + * Manages inventory of group entries using trivial in-memory implementation. | ||
| 56 | + */ | ||
| 57 | +@Component(immediate = true) | ||
| 58 | +@Service | ||
| 59 | +public class SimpleGroupStore | ||
| 60 | + extends AbstractStore<GroupEvent, GroupStoreDelegate> | ||
| 61 | + implements GroupStore { | ||
| 62 | + | ||
| 63 | + private final Logger log = getLogger(getClass()); | ||
| 64 | + | ||
| 65 | + // inner Map is per device group table | ||
| 66 | + private final ConcurrentMap<DeviceId, ConcurrentMap<GroupKey, StoredGroupEntry>> | ||
| 67 | + groupEntriesByKey = new ConcurrentHashMap<>(); | ||
| 68 | + private final ConcurrentMap<DeviceId, ConcurrentMap<GroupId, StoredGroupEntry>> | ||
| 69 | + groupEntriesById = new ConcurrentHashMap<>(); | ||
| 70 | + | ||
| 71 | + private final AtomicInteger groupIdGen = new AtomicInteger(); | ||
| 72 | + | ||
| 73 | + @Activate | ||
| 74 | + public void activate() { | ||
| 75 | + log.info("Started"); | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + @Deactivate | ||
| 79 | + public void deactivate() { | ||
| 80 | + groupEntriesByKey.clear(); | ||
| 81 | + groupEntriesById.clear(); | ||
| 82 | + log.info("Stopped"); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + private static NewConcurrentHashMap<GroupKey, StoredGroupEntry> lazyEmptyGroupKeyTable() { | ||
| 86 | + return NewConcurrentHashMap.<GroupKey, StoredGroupEntry>ifNeeded(); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + private static NewConcurrentHashMap<GroupId, StoredGroupEntry> lazyEmptyGroupIdTable() { | ||
| 90 | + return NewConcurrentHashMap.<GroupId, StoredGroupEntry>ifNeeded(); | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + /** | ||
| 94 | + * Returns the group key table for specified device. | ||
| 95 | + * | ||
| 96 | + * @param deviceId identifier of the device | ||
| 97 | + * @return Map representing group key table of given device. | ||
| 98 | + */ | ||
| 99 | + private ConcurrentMap<GroupKey, StoredGroupEntry> getGroupKeyTable(DeviceId deviceId) { | ||
| 100 | + return createIfAbsentUnchecked(groupEntriesByKey, | ||
| 101 | + deviceId, lazyEmptyGroupKeyTable()); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + /** | ||
| 105 | + * Returns the group id table for specified device. | ||
| 106 | + * | ||
| 107 | + * @param deviceId identifier of the device | ||
| 108 | + * @return Map representing group key table of given device. | ||
| 109 | + */ | ||
| 110 | + private ConcurrentMap<GroupId, StoredGroupEntry> getGroupIdTable(DeviceId deviceId) { | ||
| 111 | + return createIfAbsentUnchecked(groupEntriesById, | ||
| 112 | + deviceId, lazyEmptyGroupIdTable()); | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + /** | ||
| 116 | + * Returns the number of groups for the specified device in the store. | ||
| 117 | + * | ||
| 118 | + * @return number of groups for the specified device | ||
| 119 | + */ | ||
| 120 | + @Override | ||
| 121 | + public int getGroupCount(DeviceId deviceId) { | ||
| 122 | + return (groupEntriesByKey.get(deviceId) != null) ? | ||
| 123 | + groupEntriesByKey.get(deviceId).size() : 0; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + /** | ||
| 127 | + * Returns the groups associated with a device. | ||
| 128 | + * | ||
| 129 | + * @param deviceId the device ID | ||
| 130 | + * | ||
| 131 | + * @return the group entries | ||
| 132 | + */ | ||
| 133 | + @Override | ||
| 134 | + public Iterable<Group> getGroups(DeviceId deviceId) { | ||
| 135 | + // flatten and make iterator unmodifiable | ||
| 136 | + if (groupEntriesByKey.get(deviceId) != null) { | ||
| 137 | + return FluentIterable.from(groupEntriesByKey.get(deviceId).values()) | ||
| 138 | + .transform( | ||
| 139 | + new Function<StoredGroupEntry, Group>() { | ||
| 140 | + | ||
| 141 | + @Override | ||
| 142 | + public Group apply( | ||
| 143 | + StoredGroupEntry input) { | ||
| 144 | + return input; | ||
| 145 | + } | ||
| 146 | + }); | ||
| 147 | + } else { | ||
| 148 | + return null; | ||
| 149 | + } | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + /** | ||
| 153 | + * Returns the stored group entry. | ||
| 154 | + * | ||
| 155 | + * @param deviceId the device ID | ||
| 156 | + * @param appCookie the group key | ||
| 157 | + * | ||
| 158 | + * @return a group associated with the key | ||
| 159 | + */ | ||
| 160 | + @Override | ||
| 161 | + public Group getGroup(DeviceId deviceId, GroupKey appCookie) { | ||
| 162 | + return (groupEntriesByKey.get(deviceId) != null) ? | ||
| 163 | + groupEntriesByKey.get(deviceId).get(appCookie) : | ||
| 164 | + null; | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + /** | ||
| 168 | + * Stores a new group entry using the information from group description. | ||
| 169 | + * | ||
| 170 | + * @param groupDesc group description to be used to create group entry | ||
| 171 | + */ | ||
| 172 | + @Override | ||
| 173 | + public void storeGroupDescription(GroupDescription groupDesc) { | ||
| 174 | + /* Check if a group is existing with the same key */ | ||
| 175 | + if (getGroup(groupDesc.deviceId(), groupDesc.appCookie()) != null) { | ||
| 176 | + return; | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + /* Get a new group identifier */ | ||
| 180 | + GroupId id = new DefaultGroupId(groupIdGen.incrementAndGet()); | ||
| 181 | + /* Create a group entry object */ | ||
| 182 | + StoredGroupEntry group = new DefaultGroup(id, groupDesc); | ||
| 183 | + /* Insert the newly created group entry into concurrent key and id maps */ | ||
| 184 | + ConcurrentMap<GroupKey, StoredGroupEntry> keyTable = | ||
| 185 | + getGroupKeyTable(groupDesc.deviceId()); | ||
| 186 | + keyTable.put(groupDesc.appCookie(), group); | ||
| 187 | + ConcurrentMap<GroupId, StoredGroupEntry> idTable = | ||
| 188 | + getGroupIdTable(groupDesc.deviceId()); | ||
| 189 | + idTable.put(id, group); | ||
| 190 | + notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED, | ||
| 191 | + group)); | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + /** | ||
| 195 | + * Updates the existing group entry with the information | ||
| 196 | + * from group description. | ||
| 197 | + * | ||
| 198 | + * @param deviceId the device ID | ||
| 199 | + * @param oldAppCookie the current group key | ||
| 200 | + * @param type update type | ||
| 201 | + * @param newGroupDesc group description with updates | ||
| 202 | + */ | ||
| 203 | + @Override | ||
| 204 | + public void updateGroupDescription(DeviceId deviceId, | ||
| 205 | + GroupKey oldAppCookie, | ||
| 206 | + UpdateType type, | ||
| 207 | + GroupDescription newGroupDesc) { | ||
| 208 | + /* Check if a group is existing with the provided key */ | ||
| 209 | + Group oldGroup = getGroup(deviceId, oldAppCookie); | ||
| 210 | + if (oldGroup == null) { | ||
| 211 | + return; | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + List<GroupBucket> newBucketList = getUpdatedBucketList(oldGroup, | ||
| 215 | + type, | ||
| 216 | + newGroupDesc.buckets()); | ||
| 217 | + if (newBucketList != null) { | ||
| 218 | + /* Create a new group object from the old group */ | ||
| 219 | + GroupBuckets updatedBuckets = new GroupBuckets(newBucketList); | ||
| 220 | + GroupDescription updatedGroupDesc = new DefaultGroupDescription( | ||
| 221 | + oldGroup.deviceId(), | ||
| 222 | + oldGroup.type(), | ||
| 223 | + updatedBuckets, | ||
| 224 | + newGroupDesc.appCookie(), | ||
| 225 | + oldGroup.appId()); | ||
| 226 | + StoredGroupEntry newGroup = new DefaultGroup(oldGroup.id(), | ||
| 227 | + updatedGroupDesc); | ||
| 228 | + newGroup.setState(GroupState.PENDING_UPDATE); | ||
| 229 | + newGroup.setLife(oldGroup.life()); | ||
| 230 | + newGroup.setPackets(oldGroup.packets()); | ||
| 231 | + newGroup.setBytes(oldGroup.bytes()); | ||
| 232 | + /* Remove the old entry from maps and add new entry | ||
| 233 | + * using new key | ||
| 234 | + */ | ||
| 235 | + ConcurrentMap<GroupKey, StoredGroupEntry> keyTable = | ||
| 236 | + getGroupKeyTable(oldGroup.deviceId()); | ||
| 237 | + ConcurrentMap<GroupId, StoredGroupEntry> idTable = | ||
| 238 | + getGroupIdTable(oldGroup.deviceId()); | ||
| 239 | + keyTable.remove(oldGroup.appCookie()); | ||
| 240 | + idTable.remove(oldGroup.id()); | ||
| 241 | + keyTable.put(newGroup.appCookie(), newGroup); | ||
| 242 | + idTable.put(newGroup.id(), newGroup); | ||
| 243 | + notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, newGroup)); | ||
| 244 | + } | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + private List<GroupBucket> getUpdatedBucketList(Group oldGroup, | ||
| 248 | + UpdateType type, | ||
| 249 | + GroupBuckets buckets) { | ||
| 250 | + GroupBuckets oldBuckets = oldGroup.buckets(); | ||
| 251 | + List<GroupBucket> newBucketList = new ArrayList<GroupBucket>( | ||
| 252 | + oldBuckets.buckets()); | ||
| 253 | + boolean groupDescUpdated = false; | ||
| 254 | + | ||
| 255 | + if (type == UpdateType.ADD) { | ||
| 256 | + /* Check if the any of the new buckets are part of the | ||
| 257 | + * old bucket list | ||
| 258 | + */ | ||
| 259 | + for (GroupBucket addBucket:buckets.buckets()) { | ||
| 260 | + if (!newBucketList.contains(addBucket)) { | ||
| 261 | + newBucketList.add(addBucket); | ||
| 262 | + groupDescUpdated = true; | ||
| 263 | + } | ||
| 264 | + } | ||
| 265 | + } else if (type == UpdateType.REMOVE) { | ||
| 266 | + /* Check if the to be removed buckets are part of the | ||
| 267 | + * old bucket list | ||
| 268 | + */ | ||
| 269 | + for (GroupBucket removeBucket:buckets.buckets()) { | ||
| 270 | + if (newBucketList.contains(removeBucket)) { | ||
| 271 | + newBucketList.remove(removeBucket); | ||
| 272 | + groupDescUpdated = true; | ||
| 273 | + } | ||
| 274 | + } | ||
| 275 | + } | ||
| 276 | + | ||
| 277 | + if (groupDescUpdated) { | ||
| 278 | + return newBucketList; | ||
| 279 | + } else { | ||
| 280 | + return null; | ||
| 281 | + } | ||
| 282 | + } | ||
| 283 | + | ||
| 284 | + /** | ||
| 285 | + * Triggers deleting the existing group entry. | ||
| 286 | + * | ||
| 287 | + * @param deviceId the device ID | ||
| 288 | + * @param appCookie the group key | ||
| 289 | + */ | ||
| 290 | + @Override | ||
| 291 | + public void deleteGroupDescription(DeviceId deviceId, | ||
| 292 | + GroupKey appCookie) { | ||
| 293 | + /* Check if a group is existing with the provided key */ | ||
| 294 | + StoredGroupEntry existing = (groupEntriesByKey.get(deviceId) != null) ? | ||
| 295 | + groupEntriesByKey.get(deviceId).get(appCookie) : | ||
| 296 | + null; | ||
| 297 | + if (existing == null) { | ||
| 298 | + return; | ||
| 299 | + } | ||
| 300 | + | ||
| 301 | + synchronized (existing) { | ||
| 302 | + existing.setState(GroupState.PENDING_DELETE); | ||
| 303 | + } | ||
| 304 | + notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_REQUESTED, existing)); | ||
| 305 | + } | ||
| 306 | + | ||
| 307 | + /** | ||
| 308 | + * Stores a new group entry, or updates an existing entry. | ||
| 309 | + * | ||
| 310 | + * @param group group entry | ||
| 311 | + */ | ||
| 312 | + @Override | ||
| 313 | + public void addOrUpdateGroupEntry(Group group) { | ||
| 314 | + // check if this new entry is an update to an existing entry | ||
| 315 | + StoredGroupEntry existing = (groupEntriesById.get( | ||
| 316 | + group.deviceId()) != null) ? | ||
| 317 | + groupEntriesById.get(group.deviceId()).get(group.id()) : | ||
| 318 | + null; | ||
| 319 | + GroupEvent event = null; | ||
| 320 | + | ||
| 321 | + if (existing != null) { | ||
| 322 | + synchronized (existing) { | ||
| 323 | + existing.setLife(group.life()); | ||
| 324 | + existing.setPackets(group.packets()); | ||
| 325 | + existing.setBytes(group.bytes()); | ||
| 326 | + if (existing.state() == GroupState.PENDING_ADD) { | ||
| 327 | + existing.setState(GroupState.ADDED); | ||
| 328 | + event = new GroupEvent(Type.GROUP_ADDED, existing); | ||
| 329 | + } else { | ||
| 330 | + if (existing.state() == GroupState.PENDING_UPDATE) { | ||
| 331 | + existing.setState(GroupState.PENDING_UPDATE); | ||
| 332 | + } | ||
| 333 | + event = new GroupEvent(Type.GROUP_UPDATED, existing); | ||
| 334 | + } | ||
| 335 | + } | ||
| 336 | + } | ||
| 337 | + | ||
| 338 | + if (event != null) { | ||
| 339 | + notifyDelegate(event); | ||
| 340 | + } | ||
| 341 | + } | ||
| 342 | + | ||
| 343 | + /** | ||
| 344 | + * Removes the group entry from store. | ||
| 345 | + * | ||
| 346 | + * @param group group entry | ||
| 347 | + */ | ||
| 348 | + @Override | ||
| 349 | + public void removeGroupEntry(Group group) { | ||
| 350 | + StoredGroupEntry existing = (groupEntriesById.get( | ||
| 351 | + group.deviceId()) != null) ? | ||
| 352 | + groupEntriesById.get(group.deviceId()).get(group.id()) : | ||
| 353 | + null; | ||
| 354 | + | ||
| 355 | + if (existing != null) { | ||
| 356 | + ConcurrentMap<GroupKey, StoredGroupEntry> keyTable = | ||
| 357 | + getGroupKeyTable(existing.deviceId()); | ||
| 358 | + ConcurrentMap<GroupId, StoredGroupEntry> idTable = | ||
| 359 | + getGroupIdTable(existing.deviceId()); | ||
| 360 | + idTable.remove(existing.id()); | ||
| 361 | + keyTable.remove(existing.appCookie()); | ||
| 362 | + notifyDelegate(new GroupEvent(Type.GROUP_REMOVED, existing)); | ||
| 363 | + } | ||
| 364 | + } | ||
| 365 | +} |
core/store/trivial/src/test/java/org/onosproject/store/trivial/impl/SimpleGroupStoreTest.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright 2014 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.store.trivial.impl; | ||
| 17 | + | ||
| 18 | +import static org.junit.Assert.assertEquals; | ||
| 19 | +import static org.onosproject.net.DeviceId.deviceId; | ||
| 20 | + | ||
| 21 | +import java.util.ArrayList; | ||
| 22 | +import java.util.List; | ||
| 23 | + | ||
| 24 | +import org.junit.After; | ||
| 25 | +import org.junit.Before; | ||
| 26 | +import org.junit.Test; | ||
| 27 | +import org.onlab.packet.MacAddress; | ||
| 28 | +import org.onosproject.core.ApplicationId; | ||
| 29 | +import org.onosproject.core.DefaultApplicationId; | ||
| 30 | +import org.onosproject.core.GroupId; | ||
| 31 | +import org.onosproject.net.DeviceId; | ||
| 32 | +import org.onosproject.net.PortNumber; | ||
| 33 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 34 | +import org.onosproject.net.flow.TrafficTreatment; | ||
| 35 | +import org.onosproject.net.group.DefaultGroupBucket; | ||
| 36 | +import org.onosproject.net.group.DefaultGroupDescription; | ||
| 37 | +import org.onosproject.net.group.Group; | ||
| 38 | +import org.onosproject.net.group.GroupBucket; | ||
| 39 | +import org.onosproject.net.group.GroupBuckets; | ||
| 40 | +import org.onosproject.net.group.GroupDescription; | ||
| 41 | +import org.onosproject.net.group.GroupEvent; | ||
| 42 | +import org.onosproject.net.group.GroupKey; | ||
| 43 | +import org.onosproject.net.group.GroupStoreDelegate; | ||
| 44 | +import org.onosproject.net.group.GroupStore.UpdateType; | ||
| 45 | + | ||
| 46 | +/** | ||
| 47 | + * Test of the simple DeviceStore implementation. | ||
| 48 | + */ | ||
| 49 | +public class SimpleGroupStoreTest { | ||
| 50 | + | ||
| 51 | + private SimpleGroupStore simpleGroupStore; | ||
| 52 | + | ||
| 53 | + public static final DeviceId D1 = deviceId("of:1"); | ||
| 54 | + | ||
| 55 | + @Before | ||
| 56 | + public void setUp() throws Exception { | ||
| 57 | + simpleGroupStore = new SimpleGroupStore(); | ||
| 58 | + simpleGroupStore.activate(); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + @After | ||
| 62 | + public void tearDown() throws Exception { | ||
| 63 | + simpleGroupStore.deactivate(); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + public class TestGroupKey implements GroupKey { | ||
| 67 | + private String groupId; | ||
| 68 | + | ||
| 69 | + public TestGroupKey(String id) { | ||
| 70 | + this.groupId = id; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + public String id() { | ||
| 74 | + return this.groupId; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + @Override | ||
| 78 | + public int hashCode() { | ||
| 79 | + return groupId.hashCode(); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + @Override | ||
| 83 | + public boolean equals(Object obj) { | ||
| 84 | + if (obj instanceof TestGroupKey) { | ||
| 85 | + return this.groupId.equals(((TestGroupKey) obj).id()); | ||
| 86 | + } | ||
| 87 | + return false; | ||
| 88 | + } | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + private class InternalGroupStoreDelegate | ||
| 92 | + implements GroupStoreDelegate { | ||
| 93 | + private GroupId createdGroupId = null; | ||
| 94 | + private GroupKey createdGroupKey; | ||
| 95 | + private GroupBuckets createdBuckets; | ||
| 96 | + private GroupEvent.Type expectedEvent; | ||
| 97 | + | ||
| 98 | + public InternalGroupStoreDelegate(GroupKey key, | ||
| 99 | + GroupBuckets buckets, | ||
| 100 | + GroupEvent.Type expectedEvent) { | ||
| 101 | + this.createdBuckets = buckets; | ||
| 102 | + this.createdGroupKey = key; | ||
| 103 | + this.expectedEvent = expectedEvent; | ||
| 104 | + } | ||
| 105 | + @Override | ||
| 106 | + public void notify(GroupEvent event) { | ||
| 107 | + assertEquals(expectedEvent, event.type()); | ||
| 108 | + assertEquals(Group.Type.SELECT, event.subject().type()); | ||
| 109 | + assertEquals(D1, event.subject().deviceId()); | ||
| 110 | + assertEquals(createdGroupKey, event.subject().appCookie()); | ||
| 111 | + assertEquals(createdBuckets.buckets(), event.subject().buckets().buckets()); | ||
| 112 | + if (expectedEvent == GroupEvent.Type.GROUP_ADD_REQUESTED) { | ||
| 113 | + createdGroupId = event.subject().id(); | ||
| 114 | + assertEquals(Group.GroupState.PENDING_ADD, | ||
| 115 | + event.subject().state()); | ||
| 116 | + } else if (expectedEvent == GroupEvent.Type.GROUP_ADDED) { | ||
| 117 | + createdGroupId = event.subject().id(); | ||
| 118 | + assertEquals(Group.GroupState.ADDED, | ||
| 119 | + event.subject().state()); | ||
| 120 | + } else if (expectedEvent == GroupEvent.Type.GROUP_UPDATE_REQUESTED) { | ||
| 121 | + assertEquals(Group.GroupState.PENDING_UPDATE, | ||
| 122 | + event.subject().state()); | ||
| 123 | + } else if (expectedEvent == GroupEvent.Type.GROUP_REMOVE_REQUESTED) { | ||
| 124 | + assertEquals(Group.GroupState.PENDING_DELETE, | ||
| 125 | + event.subject().state()); | ||
| 126 | + } else if (expectedEvent == GroupEvent.Type.GROUP_REMOVED) { | ||
| 127 | + createdGroupId = event.subject().id(); | ||
| 128 | + assertEquals(Group.GroupState.PENDING_DELETE, | ||
| 129 | + event.subject().state()); | ||
| 130 | + } | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + public void verifyGroupId(GroupId id) { | ||
| 134 | + assertEquals(createdGroupId, id); | ||
| 135 | + } | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + @Test | ||
| 139 | + public void testGroupStoreOperations() { | ||
| 140 | + ApplicationId appId = | ||
| 141 | + new DefaultApplicationId(2, "org.groupstore.test"); | ||
| 142 | + TestGroupKey key = new TestGroupKey("group1"); | ||
| 143 | + PortNumber[] ports = {PortNumber.portNumber(31), | ||
| 144 | + PortNumber.portNumber(32)}; | ||
| 145 | + List<PortNumber> outPorts = new ArrayList<PortNumber>(); | ||
| 146 | + outPorts.add(ports[0]); | ||
| 147 | + outPorts.add(ports[1]); | ||
| 148 | + | ||
| 149 | + List<GroupBucket> buckets = new ArrayList<GroupBucket>(); | ||
| 150 | + for (PortNumber portNumber: outPorts) { | ||
| 151 | + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); | ||
| 152 | + tBuilder.setOutput(portNumber) | ||
| 153 | + .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) | ||
| 154 | + .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01")) | ||
| 155 | + .pushMpls() | ||
| 156 | + .setMpls(106); | ||
| 157 | + buckets.add(DefaultGroupBucket.createSelectGroupBucket( | ||
| 158 | + tBuilder.build())); | ||
| 159 | + } | ||
| 160 | + GroupBuckets groupBuckets = new GroupBuckets(buckets); | ||
| 161 | + GroupDescription groupDesc = new DefaultGroupDescription( | ||
| 162 | + D1, | ||
| 163 | + Group.Type.SELECT, | ||
| 164 | + groupBuckets, | ||
| 165 | + key, | ||
| 166 | + appId); | ||
| 167 | + InternalGroupStoreDelegate checkStoreGroupDelegate = | ||
| 168 | + new InternalGroupStoreDelegate(key, | ||
| 169 | + groupBuckets, | ||
| 170 | + GroupEvent.Type.GROUP_ADD_REQUESTED); | ||
| 171 | + simpleGroupStore.setDelegate(checkStoreGroupDelegate); | ||
| 172 | + /* Testing storeGroup operation */ | ||
| 173 | + simpleGroupStore.storeGroupDescription(groupDesc); | ||
| 174 | + | ||
| 175 | + /* Testing getGroupCount operation */ | ||
| 176 | + assertEquals(1, simpleGroupStore.getGroupCount(D1)); | ||
| 177 | + | ||
| 178 | + /* Testing getGroup operation */ | ||
| 179 | + Group createdGroup = simpleGroupStore.getGroup(D1, key); | ||
| 180 | + checkStoreGroupDelegate.verifyGroupId(createdGroup.id()); | ||
| 181 | + | ||
| 182 | + /* Testing getGroups operation */ | ||
| 183 | + Iterable<Group> createdGroups = simpleGroupStore.getGroups(D1); | ||
| 184 | + int groupCount = 0; | ||
| 185 | + for (Group group:createdGroups) { | ||
| 186 | + checkStoreGroupDelegate.verifyGroupId(group.id()); | ||
| 187 | + groupCount++; | ||
| 188 | + } | ||
| 189 | + assertEquals(1, groupCount); | ||
| 190 | + simpleGroupStore.unsetDelegate(checkStoreGroupDelegate); | ||
| 191 | + | ||
| 192 | + /* Testing addOrUpdateGroupEntry operation from southbound */ | ||
| 193 | + InternalGroupStoreDelegate addGroupEntryDelegate = | ||
| 194 | + new InternalGroupStoreDelegate(key, | ||
| 195 | + groupBuckets, | ||
| 196 | + GroupEvent.Type.GROUP_ADDED); | ||
| 197 | + simpleGroupStore.setDelegate(addGroupEntryDelegate); | ||
| 198 | + simpleGroupStore.addOrUpdateGroupEntry(createdGroup); | ||
| 199 | + simpleGroupStore.unsetDelegate(addGroupEntryDelegate); | ||
| 200 | + | ||
| 201 | + /* Testing updateGroupDescription for ADD operation from northbound */ | ||
| 202 | + TestGroupKey addKey = new TestGroupKey("group1AddBuckets"); | ||
| 203 | + PortNumber[] newNeighborPorts = {PortNumber.portNumber(41), | ||
| 204 | + PortNumber.portNumber(42)}; | ||
| 205 | + List<PortNumber> newOutPorts = new ArrayList<PortNumber>(); | ||
| 206 | + newOutPorts.add(newNeighborPorts[0]); | ||
| 207 | + newOutPorts.add(newNeighborPorts[1]); | ||
| 208 | + | ||
| 209 | + List<GroupBucket> toAddBuckets = new ArrayList<GroupBucket>(); | ||
| 210 | + for (PortNumber portNumber: newOutPorts) { | ||
| 211 | + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); | ||
| 212 | + tBuilder.setOutput(portNumber) | ||
| 213 | + .setEthDst(MacAddress.valueOf("00:00:00:00:00:03")) | ||
| 214 | + .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01")) | ||
| 215 | + .pushMpls() | ||
| 216 | + .setMpls(106); | ||
| 217 | + toAddBuckets.add(DefaultGroupBucket.createSelectGroupBucket( | ||
| 218 | + tBuilder.build())); | ||
| 219 | + } | ||
| 220 | + GroupBuckets toAddGroupBuckets = new GroupBuckets(toAddBuckets); | ||
| 221 | + buckets.addAll(toAddBuckets); | ||
| 222 | + GroupBuckets updatedGroupBuckets = new GroupBuckets(buckets); | ||
| 223 | + InternalGroupStoreDelegate updateGroupDescDelegate = | ||
| 224 | + new InternalGroupStoreDelegate(addKey, | ||
| 225 | + updatedGroupBuckets, | ||
| 226 | + GroupEvent.Type.GROUP_UPDATE_REQUESTED); | ||
| 227 | + simpleGroupStore.setDelegate(updateGroupDescDelegate); | ||
| 228 | + GroupDescription newGroupDesc = new DefaultGroupDescription( | ||
| 229 | + D1, | ||
| 230 | + Group.Type.SELECT, | ||
| 231 | + toAddGroupBuckets, | ||
| 232 | + addKey, | ||
| 233 | + appId); | ||
| 234 | + simpleGroupStore.updateGroupDescription(D1, | ||
| 235 | + key, | ||
| 236 | + UpdateType.ADD, | ||
| 237 | + newGroupDesc); | ||
| 238 | + simpleGroupStore.unsetDelegate(updateGroupDescDelegate); | ||
| 239 | + | ||
| 240 | + /* Testing updateGroupDescription for REMOVE operation from northbound */ | ||
| 241 | + TestGroupKey removeKey = new TestGroupKey("group1RemoveBuckets"); | ||
| 242 | + List<GroupBucket> toRemoveBuckets = new ArrayList<GroupBucket>(); | ||
| 243 | + toRemoveBuckets.add(updatedGroupBuckets.buckets().get(0)); | ||
| 244 | + toRemoveBuckets.add(updatedGroupBuckets.buckets().get(1)); | ||
| 245 | + GroupBuckets toRemoveGroupBuckets = new GroupBuckets(toRemoveBuckets); | ||
| 246 | + List<GroupBucket> remainingBuckets = new ArrayList<GroupBucket>(); | ||
| 247 | + remainingBuckets.add(updatedGroupBuckets.buckets().get(2)); | ||
| 248 | + remainingBuckets.add(updatedGroupBuckets.buckets().get(3)); | ||
| 249 | + GroupBuckets remainingGroupBuckets = new GroupBuckets(remainingBuckets); | ||
| 250 | + InternalGroupStoreDelegate removeGroupDescDelegate = | ||
| 251 | + new InternalGroupStoreDelegate(removeKey, | ||
| 252 | + remainingGroupBuckets, | ||
| 253 | + GroupEvent.Type.GROUP_UPDATE_REQUESTED); | ||
| 254 | + simpleGroupStore.setDelegate(removeGroupDescDelegate); | ||
| 255 | + GroupDescription removeGroupDesc = new DefaultGroupDescription( | ||
| 256 | + D1, | ||
| 257 | + Group.Type.SELECT, | ||
| 258 | + toRemoveGroupBuckets, | ||
| 259 | + removeKey, | ||
| 260 | + appId); | ||
| 261 | + simpleGroupStore.updateGroupDescription(D1, | ||
| 262 | + addKey, | ||
| 263 | + UpdateType.REMOVE, | ||
| 264 | + removeGroupDesc); | ||
| 265 | + simpleGroupStore.unsetDelegate(removeGroupDescDelegate); | ||
| 266 | + | ||
| 267 | + /* Testing getGroup operation */ | ||
| 268 | + Group existingGroup = simpleGroupStore.getGroup(D1, removeKey); | ||
| 269 | + checkStoreGroupDelegate.verifyGroupId(existingGroup.id()); | ||
| 270 | + | ||
| 271 | + /* Testing addOrUpdateGroupEntry operation from southbound */ | ||
| 272 | + InternalGroupStoreDelegate updateGroupEntryDelegate = | ||
| 273 | + new InternalGroupStoreDelegate(removeKey, | ||
| 274 | + remainingGroupBuckets, | ||
| 275 | + GroupEvent.Type.GROUP_UPDATED); | ||
| 276 | + simpleGroupStore.setDelegate(updateGroupEntryDelegate); | ||
| 277 | + simpleGroupStore.addOrUpdateGroupEntry(existingGroup); | ||
| 278 | + simpleGroupStore.unsetDelegate(updateGroupEntryDelegate); | ||
| 279 | + | ||
| 280 | + /* Testing deleteGroupDescription operation from northbound */ | ||
| 281 | + InternalGroupStoreDelegate deleteGroupDescDelegate = | ||
| 282 | + new InternalGroupStoreDelegate(removeKey, | ||
| 283 | + remainingGroupBuckets, | ||
| 284 | + GroupEvent.Type.GROUP_REMOVE_REQUESTED); | ||
| 285 | + simpleGroupStore.setDelegate(deleteGroupDescDelegate); | ||
| 286 | + simpleGroupStore.deleteGroupDescription(D1, removeKey); | ||
| 287 | + simpleGroupStore.unsetDelegate(deleteGroupDescDelegate); | ||
| 288 | + | ||
| 289 | + /* Testing removeGroupEntry operation from southbound */ | ||
| 290 | + InternalGroupStoreDelegate removeGroupEntryDelegate = | ||
| 291 | + new InternalGroupStoreDelegate(removeKey, | ||
| 292 | + remainingGroupBuckets, | ||
| 293 | + GroupEvent.Type.GROUP_REMOVED); | ||
| 294 | + simpleGroupStore.setDelegate(removeGroupEntryDelegate); | ||
| 295 | + simpleGroupStore.removeGroupEntry(existingGroup); | ||
| 296 | + | ||
| 297 | + /* Testing getGroup operation */ | ||
| 298 | + existingGroup = simpleGroupStore.getGroup(D1, removeKey); | ||
| 299 | + assertEquals(null, existingGroup); | ||
| 300 | + Iterable<Group> existingGroups = 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 | + | ||
| 310 | + simpleGroupStore.unsetDelegate(removeGroupEntryDelegate); | ||
| 311 | + | ||
| 312 | + } | ||
| 313 | +} | ||
| 314 | + |
-
Please register or login to post a comment