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