Srikanth Vavilapalli
Committed by Gerrit Code Review

Distributed group store using eventual consistent map abstraction

Change-Id: I618a0f6fa80e0e25285d7a2026032f09ba90aa70
Showing 25 changed files with 566 additions and 173 deletions
...@@ -15,11 +15,14 @@ ...@@ -15,11 +15,14 @@
15 */ 15 */
16 package org.onosproject.bgprouter; 16 package org.onosproject.bgprouter;
17 17
18 -import com.google.common.collect.ConcurrentHashMultiset; 18 +import java.util.Collection;
19 -import com.google.common.collect.HashMultimap; 19 +import java.util.Collections;
20 -import com.google.common.collect.Maps; 20 +import java.util.HashMap;
21 -import com.google.common.collect.Multimap; 21 +import java.util.HashSet;
22 -import com.google.common.collect.Multiset; 22 +import java.util.Map;
23 +import java.util.Set;
24 +import java.util.stream.Collectors;
25 +
23 import org.apache.felix.scr.annotations.Activate; 26 import org.apache.felix.scr.annotations.Activate;
24 import org.apache.felix.scr.annotations.Component; 27 import org.apache.felix.scr.annotations.Component;
25 import org.apache.felix.scr.annotations.Deactivate; 28 import org.apache.felix.scr.annotations.Deactivate;
...@@ -30,6 +33,7 @@ import org.onlab.packet.IpAddress; ...@@ -30,6 +33,7 @@ import org.onlab.packet.IpAddress;
30 import org.onlab.packet.IpPrefix; 33 import org.onlab.packet.IpPrefix;
31 import org.onlab.packet.MacAddress; 34 import org.onlab.packet.MacAddress;
32 import org.onlab.packet.VlanId; 35 import org.onlab.packet.VlanId;
36 +import org.onlab.util.KryoNamespace;
33 import org.onosproject.config.NetworkConfigService; 37 import org.onosproject.config.NetworkConfigService;
34 import org.onosproject.core.ApplicationId; 38 import org.onosproject.core.ApplicationId;
35 import org.onosproject.core.CoreService; 39 import org.onosproject.core.CoreService;
...@@ -47,12 +51,12 @@ import org.onosproject.net.flow.TrafficSelector; ...@@ -47,12 +51,12 @@ import org.onosproject.net.flow.TrafficSelector;
47 import org.onosproject.net.flow.TrafficTreatment; 51 import org.onosproject.net.flow.TrafficTreatment;
48 import org.onosproject.net.group.DefaultGroupBucket; 52 import org.onosproject.net.group.DefaultGroupBucket;
49 import org.onosproject.net.group.DefaultGroupDescription; 53 import org.onosproject.net.group.DefaultGroupDescription;
54 +import org.onosproject.net.group.DefaultGroupKey;
50 import org.onosproject.net.group.Group; 55 import org.onosproject.net.group.Group;
51 import org.onosproject.net.group.GroupBucket; 56 import org.onosproject.net.group.GroupBucket;
52 import org.onosproject.net.group.GroupBuckets; 57 import org.onosproject.net.group.GroupBuckets;
53 import org.onosproject.net.group.GroupDescription; 58 import org.onosproject.net.group.GroupDescription;
54 import org.onosproject.net.group.GroupEvent; 59 import org.onosproject.net.group.GroupEvent;
55 -import org.onosproject.net.group.GroupKey;
56 import org.onosproject.net.group.GroupListener; 60 import org.onosproject.net.group.GroupListener;
57 import org.onosproject.net.group.GroupService; 61 import org.onosproject.net.group.GroupService;
58 import org.onosproject.net.host.InterfaceIpAddress; 62 import org.onosproject.net.host.InterfaceIpAddress;
...@@ -67,13 +71,11 @@ import org.onosproject.routing.config.RoutingConfigurationService; ...@@ -67,13 +71,11 @@ import org.onosproject.routing.config.RoutingConfigurationService;
67 import org.slf4j.Logger; 71 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory; 72 import org.slf4j.LoggerFactory;
69 73
70 -import java.util.Collection; 74 +import com.google.common.collect.ConcurrentHashMultiset;
71 -import java.util.Collections; 75 +import com.google.common.collect.HashMultimap;
72 -import java.util.HashMap; 76 +import com.google.common.collect.Maps;
73 -import java.util.HashSet; 77 +import com.google.common.collect.Multimap;
74 -import java.util.Map; 78 +import com.google.common.collect.Multiset;
75 -import java.util.Set;
76 -import java.util.stream.Collectors;
77 79
78 /** 80 /**
79 * BgpRouter component. 81 * BgpRouter component.
...@@ -126,7 +128,7 @@ public class BgpRouter { ...@@ -126,7 +128,7 @@ public class BgpRouter {
126 private final Map<IpAddress, NextHop> nextHops = Maps.newHashMap(); 128 private final Map<IpAddress, NextHop> nextHops = Maps.newHashMap();
127 129
128 // Stores FIB updates that are waiting for groups to be set up 130 // Stores FIB updates that are waiting for groups to be set up
129 - private final Multimap<GroupKey, FibEntry> pendingUpdates = HashMultimap.create(); 131 + private final Multimap<NextHopGroupKey, FibEntry> pendingUpdates = HashMultimap.create();
130 132
131 // Device id of data-plane switch - should be learned from config 133 // Device id of data-plane switch - should be learned from config
132 private DeviceId deviceId; 134 private DeviceId deviceId;
...@@ -143,6 +145,11 @@ public class BgpRouter { ...@@ -143,6 +145,11 @@ public class BgpRouter {
143 145
144 private InternalTableHandler provisionStaticTables = new InternalTableHandler(); 146 private InternalTableHandler provisionStaticTables = new InternalTableHandler();
145 147
148 + private KryoNamespace.Builder appKryo = new KryoNamespace.Builder()
149 + .register(IpAddress.Version.class)
150 + .register(IpAddress.class)
151 + .register(NextHopGroupKey.class);
152 +
146 @Activate 153 @Activate
147 protected void activate() { 154 protected void activate() {
148 appId = coreService.registerApplication(BGP_ROUTER_APP); 155 appId = coreService.registerApplication(BGP_ROUTER_APP);
...@@ -210,7 +217,9 @@ public class BgpRouter { ...@@ -210,7 +217,9 @@ public class BgpRouter {
210 Group group; 217 Group group;
211 synchronized (pendingUpdates) { 218 synchronized (pendingUpdates) {
212 NextHop nextHop = nextHops.get(entry.nextHopIp()); 219 NextHop nextHop = nextHops.get(entry.nextHopIp());
213 - group = groupService.getGroup(deviceId, nextHop.group()); 220 + group = groupService.getGroup(deviceId,
221 + new DefaultGroupKey(
222 + appKryo.build().serialize(nextHop.group())));
214 223
215 if (group == null) { 224 if (group == null) {
216 log.debug("Adding pending flow {}", update.entry()); 225 log.debug("Adding pending flow {}", update.entry());
...@@ -309,7 +318,7 @@ public class BgpRouter { ...@@ -309,7 +318,7 @@ public class BgpRouter {
309 GroupDescription.Type.INDIRECT, 318 GroupDescription.Type.INDIRECT,
310 new GroupBuckets(Collections 319 new GroupBuckets(Collections
311 .singletonList(bucket)), 320 .singletonList(bucket)),
312 - groupKey, 321 + new DefaultGroupKey(appKryo.build().serialize(groupKey)),
313 appId); 322 appId);
314 323
315 groupService.addGroup(groupDescription); 324 groupService.addGroup(groupDescription);
...@@ -329,7 +338,10 @@ public class BgpRouter { ...@@ -329,7 +338,10 @@ public class BgpRouter {
329 return null; 338 return null;
330 } 339 }
331 340
332 - Group group = groupService.getGroup(deviceId, nextHop.group()); 341 + Group group = groupService.getGroup(deviceId,
342 + new DefaultGroupKey(appKryo.
343 + build().
344 + serialize(nextHop.group())));
333 345
334 // FIXME disabling group deletes for now until we verify the logic is OK 346 // FIXME disabling group deletes for now until we verify the logic is OK
335 /*if (nextHopsCount.remove(nextHopIp, 1) <= 1) { 347 /*if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
...@@ -339,7 +351,9 @@ public class BgpRouter { ...@@ -339,7 +351,9 @@ public class BgpRouter {
339 351
340 nextHops.remove(nextHopIp); 352 nextHops.remove(nextHopIp);
341 353
342 - groupService.removeGroup(deviceId, nextHop.group(), appId); 354 + groupService.removeGroup(deviceId,
355 + new DefaultGroupKey(appKryo.build().serialize(nextHop.group())),
356 + appId);
343 }*/ 357 }*/
344 358
345 return group; 359 return group;
...@@ -699,8 +713,10 @@ public class BgpRouter { ...@@ -699,8 +713,10 @@ public class BgpRouter {
699 event.type() == GroupEvent.Type.GROUP_UPDATED) { 713 event.type() == GroupEvent.Type.GROUP_UPDATED) {
700 synchronized (pendingUpdates) { 714 synchronized (pendingUpdates) {
701 715
716 + NextHopGroupKey nhGroupKey =
717 + appKryo.build().deserialize(group.appCookie().key());
702 Map<FibEntry, Group> entriesToInstall = 718 Map<FibEntry, Group> entriesToInstall =
703 - pendingUpdates.removeAll(group.appCookie()) 719 + pendingUpdates.removeAll(nhGroupKey)
704 .stream() 720 .stream()
705 .collect(Collectors 721 .collect(Collectors
706 .toMap(e -> e, e -> group)); 722 .toMap(e -> e, e -> group));
......
...@@ -15,12 +15,12 @@ ...@@ -15,12 +15,12 @@
15 */ 15 */
16 package org.onosproject.bgprouter; 16 package org.onosproject.bgprouter;
17 17
18 -import com.google.common.base.MoreObjects; 18 +import java.util.Objects;
19 +
19 import org.onlab.packet.IpAddress; 20 import org.onlab.packet.IpAddress;
20 import org.onlab.packet.MacAddress; 21 import org.onlab.packet.MacAddress;
21 -import org.onosproject.net.group.GroupKey;
22 22
23 -import java.util.Objects; 23 +import com.google.common.base.MoreObjects;
24 24
25 /** 25 /**
26 * Represents a next hop for routing, whose MAC address has already been resolved. 26 * Represents a next hop for routing, whose MAC address has already been resolved.
...@@ -29,7 +29,7 @@ public class NextHop { ...@@ -29,7 +29,7 @@ public class NextHop {
29 29
30 private final IpAddress ip; 30 private final IpAddress ip;
31 private final MacAddress mac; 31 private final MacAddress mac;
32 - private final GroupKey group; 32 + private final NextHopGroupKey group;
33 33
34 /** 34 /**
35 * Creates a new next hop. 35 * Creates a new next hop.
...@@ -38,7 +38,7 @@ public class NextHop { ...@@ -38,7 +38,7 @@ public class NextHop {
38 * @param mac next hop's MAC address 38 * @param mac next hop's MAC address
39 * @param group next hop's group 39 * @param group next hop's group
40 */ 40 */
41 - public NextHop(IpAddress ip, MacAddress mac, GroupKey group) { 41 + public NextHop(IpAddress ip, MacAddress mac, NextHopGroupKey group) {
42 this.ip = ip; 42 this.ip = ip;
43 this.mac = mac; 43 this.mac = mac;
44 this.group = group; 44 this.group = group;
...@@ -67,7 +67,7 @@ public class NextHop { ...@@ -67,7 +67,7 @@ public class NextHop {
67 * 67 *
68 * @return group 68 * @return group
69 */ 69 */
70 - public GroupKey group() { 70 + public NextHopGroupKey group() {
71 return group; 71 return group;
72 } 72 }
73 73
......
...@@ -15,18 +15,18 @@ ...@@ -15,18 +15,18 @@
15 */ 15 */
16 package org.onosproject.bgprouter; 16 package org.onosproject.bgprouter;
17 17
18 -import com.google.common.base.MoreObjects; 18 +import static com.google.common.base.Preconditions.checkNotNull;
19 -import org.onlab.packet.IpAddress;
20 -import org.onosproject.net.group.GroupKey;
21 19
22 import java.util.Objects; 20 import java.util.Objects;
23 21
24 -import static com.google.common.base.Preconditions.checkNotNull; 22 +import org.onlab.packet.IpAddress;
23 +
24 +import com.google.common.base.MoreObjects;
25 25
26 /** 26 /**
27 * Identifier for a next hop group. 27 * Identifier for a next hop group.
28 */ 28 */
29 -public class NextHopGroupKey implements GroupKey { 29 +public class NextHopGroupKey {
30 30
31 private final IpAddress address; 31 private final IpAddress address;
32 32
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
22 <parent> 22 <parent>
23 <groupId>org.onosproject</groupId> 23 <groupId>org.onosproject</groupId>
24 <artifactId>onos-apps</artifactId> 24 <artifactId>onos-apps</artifactId>
25 - <version>1.1.0-SNAPSHOT</version> 25 + <version>1.2.0-SNAPSHOT</version>
26 <relativePath>../pom.xml</relativePath> 26 <relativePath>../pom.xml</relativePath>
27 </parent> 27 </parent>
28 28
......
...@@ -124,16 +124,23 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { ...@@ -124,16 +124,23 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
124 tBuilder.setOutput(newNeighborLink.src().port()) 124 tBuilder.setOutput(newNeighborLink.src().port())
125 .setEthDst(deviceConfig.getDeviceMac( 125 .setEthDst(deviceConfig.getDeviceMac(
126 newNeighborLink.dst().deviceId())) 126 newNeighborLink.dst().deviceId()))
127 - .setEthSrc(nodeMacAddr) 127 + .setEthSrc(nodeMacAddr);
128 - .pushMpls() 128 + if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
129 - .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); 129 + tBuilder.pushMpls()
130 + .setMpls(MplsLabel.
131 + mplsLabel(ns.getEdgeLabel()));
132 + }
130 GroupBucket updatedBucket = DefaultGroupBucket. 133 GroupBucket updatedBucket = DefaultGroupBucket.
131 createSelectGroupBucket(tBuilder.build()); 134 createSelectGroupBucket(tBuilder.build());
132 GroupBuckets updatedBuckets = new GroupBuckets( 135 GroupBuckets updatedBuckets = new GroupBuckets(
133 Arrays.asList(updatedBucket)); 136 Arrays.asList(updatedBucket));
134 log.debug("newPortToExistingNeighborAtEdgeRouter: " 137 log.debug("newPortToExistingNeighborAtEdgeRouter: "
135 + "groupService.addBucketsToGroup for neighborset{}", ns); 138 + "groupService.addBucketsToGroup for neighborset{}", ns);
136 - groupService.addBucketsToGroup(deviceId, ns, updatedBuckets, ns, appId); 139 + groupService.addBucketsToGroup(deviceId,
140 + getGroupKey(ns),
141 + updatedBuckets,
142 + getGroupKey(ns),
143 + appId);
137 } 144 }
138 } 145 }
139 146
......
...@@ -18,6 +18,7 @@ package org.onosproject.grouphandler; ...@@ -18,6 +18,7 @@ package org.onosproject.grouphandler;
18 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkNotNull;
19 import static org.slf4j.LoggerFactory.getLogger; 19 import static org.slf4j.LoggerFactory.getLogger;
20 20
21 +import java.net.URI;
21 import java.util.ArrayList; 22 import java.util.ArrayList;
22 import java.util.Arrays; 23 import java.util.Arrays;
23 import java.util.HashMap; 24 import java.util.HashMap;
...@@ -27,6 +28,7 @@ import java.util.Set; ...@@ -27,6 +28,7 @@ import java.util.Set;
27 28
28 import org.onlab.packet.MacAddress; 29 import org.onlab.packet.MacAddress;
29 import org.onlab.packet.MplsLabel; 30 import org.onlab.packet.MplsLabel;
31 +import org.onlab.util.KryoNamespace;
30 import org.onosproject.core.ApplicationId; 32 import org.onosproject.core.ApplicationId;
31 import org.onosproject.net.DeviceId; 33 import org.onosproject.net.DeviceId;
32 import org.onosproject.net.Link; 34 import org.onosproject.net.Link;
...@@ -35,6 +37,7 @@ import org.onosproject.net.flow.DefaultTrafficTreatment; ...@@ -35,6 +37,7 @@ import org.onosproject.net.flow.DefaultTrafficTreatment;
35 import org.onosproject.net.flow.TrafficTreatment; 37 import org.onosproject.net.flow.TrafficTreatment;
36 import org.onosproject.net.group.DefaultGroupBucket; 38 import org.onosproject.net.group.DefaultGroupBucket;
37 import org.onosproject.net.group.DefaultGroupDescription; 39 import org.onosproject.net.group.DefaultGroupDescription;
40 +import org.onosproject.net.group.DefaultGroupKey;
38 import org.onosproject.net.group.Group; 41 import org.onosproject.net.group.Group;
39 import org.onosproject.net.group.GroupBucket; 42 import org.onosproject.net.group.GroupBucket;
40 import org.onosproject.net.group.GroupBuckets; 43 import org.onosproject.net.group.GroupBuckets;
...@@ -71,6 +74,16 @@ public class DefaultGroupHandler { ...@@ -71,6 +74,16 @@ public class DefaultGroupHandler {
71 new HashMap<PortNumber, DeviceId>(); 74 new HashMap<PortNumber, DeviceId>();
72 75
73 private GroupListener listener = new InternalGroupListener(); 76 private GroupListener listener = new InternalGroupListener();
77 + protected KryoNamespace.Builder kryo = new KryoNamespace.Builder()
78 + .register(URI.class)
79 + .register(HashSet.class)
80 + .register(DeviceId.class)
81 + .register(PortNumber.class)
82 + .register(NeighborSet.class)
83 + .register(PolicyGroupIdentifier.class)
84 + .register(PolicyGroupParams.class)
85 + .register(GroupBucketIdentifier.class)
86 + .register(GroupBucketIdentifier.BucketOutputType.class);
74 87
75 protected DefaultGroupHandler(DeviceId deviceId, 88 protected DefaultGroupHandler(DeviceId deviceId,
76 ApplicationId appId, 89 ApplicationId appId,
...@@ -185,9 +198,11 @@ public class DefaultGroupHandler { ...@@ -185,9 +198,11 @@ public class DefaultGroupHandler {
185 tBuilder.setOutput(port) 198 tBuilder.setOutput(port)
186 .setEthDst(deviceConfig.getDeviceMac( 199 .setEthDst(deviceConfig.getDeviceMac(
187 portDeviceMap.get(port))) 200 portDeviceMap.get(port)))
188 - .setEthSrc(nodeMacAddr) 201 + .setEthSrc(nodeMacAddr);
189 - .pushMpls() 202 + if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
203 + tBuilder.pushMpls()
190 .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); 204 .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel()));
205 + }
191 GroupBucket removeBucket = DefaultGroupBucket. 206 GroupBucket removeBucket = DefaultGroupBucket.
192 createSelectGroupBucket(tBuilder.build()); 207 createSelectGroupBucket(tBuilder.build());
193 GroupBuckets removeBuckets = new GroupBuckets( 208 GroupBuckets removeBuckets = new GroupBuckets(
...@@ -196,9 +211,9 @@ public class DefaultGroupHandler { ...@@ -196,9 +211,9 @@ public class DefaultGroupHandler {
196 + "groupService.removeBucketsFromGroup " 211 + "groupService.removeBucketsFromGroup "
197 + "for neighborset{}", deviceId, ns); 212 + "for neighborset{}", deviceId, ns);
198 groupService.removeBucketsFromGroup(deviceId, 213 groupService.removeBucketsFromGroup(deviceId,
199 - ns, 214 + getGroupKey(ns),
200 removeBuckets, 215 removeBuckets,
201 - ns, 216 + getGroupKey(ns),
202 appId); 217 appId);
203 } 218 }
204 219
...@@ -331,9 +346,12 @@ public class DefaultGroupHandler { ...@@ -331,9 +346,12 @@ public class DefaultGroupHandler {
331 DefaultTrafficTreatment.builder(); 346 DefaultTrafficTreatment.builder();
332 tBuilder.setOutput(sp) 347 tBuilder.setOutput(sp)
333 .setEthDst(deviceConfig.getDeviceMac(d)) 348 .setEthDst(deviceConfig.getDeviceMac(d))
334 - .setEthSrc(nodeMacAddr) 349 + .setEthSrc(nodeMacAddr);
335 - .pushMpls() 350 + if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
336 - .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); 351 + tBuilder.pushMpls()
352 + .setMpls(MplsLabel.
353 + mplsLabel(ns.getEdgeLabel()));
354 + }
337 buckets.add(DefaultGroupBucket.createSelectGroupBucket( 355 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
338 tBuilder.build())); 356 tBuilder.build()));
339 } 357 }
...@@ -343,7 +361,7 @@ public class DefaultGroupHandler { ...@@ -343,7 +361,7 @@ public class DefaultGroupHandler {
343 deviceId, 361 deviceId,
344 Group.Type.SELECT, 362 Group.Type.SELECT,
345 groupBuckets, 363 groupBuckets,
346 - ns, 364 + getGroupKey(ns),
347 appId); 365 appId);
348 log.debug("createGroupsFromNeighborsets: " 366 log.debug("createGroupsFromNeighborsets: "
349 + "groupService.addGroup for neighborset{}", ns); 367 + "groupService.addGroup for neighborset{}", ns);
...@@ -386,4 +404,8 @@ public class DefaultGroupHandler { ...@@ -386,4 +404,8 @@ public class DefaultGroupHandler {
386 handleGroupEvent(event); 404 handleGroupEvent(event);
387 } 405 }
388 } 406 }
407 +
408 + protected GroupKey getGroupKey(Object obj) {
409 + return new DefaultGroupKey(kryo.build().serialize(obj));
410 + }
389 } 411 }
......
...@@ -17,8 +17,10 @@ package org.onosproject.grouphandler; ...@@ -17,8 +17,10 @@ package org.onosproject.grouphandler;
17 17
18 import static org.slf4j.LoggerFactory.getLogger; 18 import static org.slf4j.LoggerFactory.getLogger;
19 19
20 +import java.net.URI;
20 import java.util.Arrays; 21 import java.util.Arrays;
21 import java.util.HashMap; 22 import java.util.HashMap;
23 +import java.util.HashSet;
22 import java.util.List; 24 import java.util.List;
23 25
24 import org.apache.felix.scr.annotations.Activate; 26 import org.apache.felix.scr.annotations.Activate;
...@@ -27,10 +29,13 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -27,10 +29,13 @@ import org.apache.felix.scr.annotations.Deactivate;
27 import org.apache.felix.scr.annotations.Reference; 29 import org.apache.felix.scr.annotations.Reference;
28 import org.apache.felix.scr.annotations.ReferenceCardinality; 30 import org.apache.felix.scr.annotations.ReferenceCardinality;
29 import org.onlab.packet.MacAddress; 31 import org.onlab.packet.MacAddress;
32 +import org.onlab.util.KryoNamespace;
30 import org.onosproject.core.ApplicationId; 33 import org.onosproject.core.ApplicationId;
31 import org.onosproject.core.CoreService; 34 import org.onosproject.core.CoreService;
35 +import org.onosproject.mastership.MastershipService;
32 import org.onosproject.net.Device; 36 import org.onosproject.net.Device;
33 import org.onosproject.net.DeviceId; 37 import org.onosproject.net.DeviceId;
38 +import org.onosproject.net.MastershipRole;
34 import org.onosproject.net.device.DeviceEvent; 39 import org.onosproject.net.device.DeviceEvent;
35 import org.onosproject.net.device.DeviceListener; 40 import org.onosproject.net.device.DeviceListener;
36 import org.onosproject.net.device.DeviceService; 41 import org.onosproject.net.device.DeviceService;
...@@ -69,10 +74,18 @@ public class DefaultGroupHandlerApp { ...@@ -69,10 +74,18 @@ public class DefaultGroupHandlerApp {
69 protected GroupService groupService; 74 protected GroupService groupService;
70 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 75 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
71 protected CoreService coreService; 76 protected CoreService coreService;
77 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
78 + protected MastershipService mastershipService;
72 79
73 private DeviceListener deviceListener = new InternalDeviceListener(); 80 private DeviceListener deviceListener = new InternalDeviceListener();
74 private LinkListener linkListener = new InternalLinkListener(); 81 private LinkListener linkListener = new InternalLinkListener();
75 82
83 + protected KryoNamespace.Builder kryo = new KryoNamespace.Builder()
84 + .register(URI.class)
85 + .register(HashSet.class)
86 + .register(DeviceId.class)
87 + .register(NeighborSet.class);
88 +
76 @Activate 89 @Activate
77 public void activate() { 90 public void activate() {
78 appId = coreService.registerApplication("org.onosproject.defaultgrouphandler"); 91 appId = coreService.registerApplication("org.onosproject.defaultgrouphandler");
...@@ -80,6 +93,8 @@ public class DefaultGroupHandlerApp { ...@@ -80,6 +93,8 @@ public class DefaultGroupHandlerApp {
80 deviceService.addListener(deviceListener); 93 deviceService.addListener(deviceListener);
81 linkService.addListener(linkListener); 94 linkService.addListener(linkListener);
82 for (Device device: deviceService.getDevices()) { 95 for (Device device: deviceService.getDevices()) {
96 + if (mastershipService.
97 + getLocalRole(device.id()) == MastershipRole.MASTER) {
83 log.debug("Initiating default group handling for {}", device.id()); 98 log.debug("Initiating default group handling for {}", device.id());
84 DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler(device.id(), 99 DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler(device.id(),
85 appId, 100 appId,
...@@ -88,6 +103,13 @@ public class DefaultGroupHandlerApp { ...@@ -88,6 +103,13 @@ public class DefaultGroupHandlerApp {
88 groupService); 103 groupService);
89 dgh.createGroups(); 104 dgh.createGroups();
90 dghMap.put(device.id(), dgh); 105 dghMap.put(device.id(), dgh);
106 + } else {
107 + log.debug("Activate: Local role {} "
108 + + "is not MASTER for device {}",
109 + mastershipService.
110 + getLocalRole(device.id()),
111 + device.id());
112 + }
91 } 113 }
92 log.info("Activated"); 114 log.info("Activated");
93 } 115 }
...@@ -165,6 +187,14 @@ public class DefaultGroupHandlerApp { ...@@ -165,6 +187,14 @@ public class DefaultGroupHandlerApp {
165 187
166 @Override 188 @Override
167 public void event(DeviceEvent event) { 189 public void event(DeviceEvent event) {
190 + if (mastershipService.
191 + getLocalRole(event.subject().id()) != MastershipRole.MASTER) {
192 + log.debug("Local role {} is not MASTER for device {}",
193 + mastershipService.
194 + getLocalRole(event.subject().id()),
195 + event.subject().id());
196 + return;
197 + }
168 switch (event.type()) { 198 switch (event.type()) {
169 case DEVICE_ADDED: 199 case DEVICE_ADDED:
170 log.debug("Initiating default group handling for {}", event.subject().id()); 200 log.debug("Initiating default group handling for {}", event.subject().id());
...@@ -193,6 +223,16 @@ public class DefaultGroupHandlerApp { ...@@ -193,6 +223,16 @@ public class DefaultGroupHandlerApp {
193 223
194 @Override 224 @Override
195 public void event(LinkEvent event) { 225 public void event(LinkEvent event) {
226 + if (mastershipService.
227 + getLocalRole(event.subject().src().deviceId()) !=
228 + MastershipRole.MASTER) {
229 + log.debug("InternalLinkListener: Local role {} "
230 + + "is not MASTER for device {}",
231 + mastershipService.
232 + getLocalRole(event.subject().src().deviceId()),
233 + event.subject().src().deviceId());
234 + return;
235 + }
196 switch (event.type()) { 236 switch (event.type()) {
197 case LINK_ADDED: 237 case LINK_ADDED:
198 if (dghMap.get(event.subject().src().deviceId()) != null) { 238 if (dghMap.get(event.subject().src().deviceId()) != null) {
......
...@@ -112,16 +112,23 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { ...@@ -112,16 +112,23 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler {
112 tBuilder.setOutput(newNeighborLink.src().port()) 112 tBuilder.setOutput(newNeighborLink.src().port())
113 .setEthDst(deviceConfig.getDeviceMac( 113 .setEthDst(deviceConfig.getDeviceMac(
114 newNeighborLink.dst().deviceId())) 114 newNeighborLink.dst().deviceId()))
115 - .setEthSrc(nodeMacAddr) 115 + .setEthSrc(nodeMacAddr);
116 - .pushMpls() 116 + if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
117 - .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); 117 + tBuilder.pushMpls()
118 + .setMpls(MplsLabel.
119 + mplsLabel(ns.getEdgeLabel()));
120 + }
118 GroupBucket updatedBucket = DefaultGroupBucket. 121 GroupBucket updatedBucket = DefaultGroupBucket.
119 createSelectGroupBucket(tBuilder.build()); 122 createSelectGroupBucket(tBuilder.build());
120 GroupBuckets updatedBuckets = new GroupBuckets( 123 GroupBuckets updatedBuckets = new GroupBuckets(
121 Arrays.asList(updatedBucket)); 124 Arrays.asList(updatedBucket));
122 log.debug("newPortToExistingNeighborAtEdgeRouter: " 125 log.debug("newPortToExistingNeighborAtEdgeRouter: "
123 + "groupService.addBucketsToGroup for neighborset{}", ns); 126 + "groupService.addBucketsToGroup for neighborset{}", ns);
124 - groupService.addBucketsToGroup(deviceId, ns, updatedBuckets, ns, appId); 127 + groupService.addBucketsToGroup(deviceId,
128 + getGroupKey(ns),
129 + updatedBuckets,
130 + getGroupKey(ns),
131 + appId);
125 } 132 }
126 } 133 }
127 134
......
...@@ -18,7 +18,6 @@ package org.onosproject.grouphandler; ...@@ -18,7 +18,6 @@ package org.onosproject.grouphandler;
18 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkNotNull;
19 19
20 import org.onosproject.net.PortNumber; 20 import org.onosproject.net.PortNumber;
21 -import org.onosproject.net.group.GroupKey;
22 21
23 /** 22 /**
24 * Representation of policy group bucket identifier. Not exposed to 23 * Representation of policy group bucket identifier. Not exposed to
...@@ -28,7 +27,7 @@ public class GroupBucketIdentifier { ...@@ -28,7 +27,7 @@ public class GroupBucketIdentifier {
28 private int label; 27 private int label;
29 private BucketOutputType type; 28 private BucketOutputType type;
30 private PortNumber outPort; 29 private PortNumber outPort;
31 - private GroupKey outGroup; 30 + private PolicyGroupIdentifier outGroup;
32 31
33 protected enum BucketOutputType { 32 protected enum BucketOutputType {
34 PORT, 33 PORT,
...@@ -44,7 +43,7 @@ public class GroupBucketIdentifier { ...@@ -44,7 +43,7 @@ public class GroupBucketIdentifier {
44 } 43 }
45 44
46 protected GroupBucketIdentifier(int label, 45 protected GroupBucketIdentifier(int label,
47 - GroupKey outGroup) { 46 + PolicyGroupIdentifier outGroup) {
48 this.label = label; 47 this.label = label;
49 this.type = BucketOutputType.GROUP; 48 this.type = BucketOutputType.GROUP;
50 this.outPort = null; 49 this.outPort = null;
...@@ -63,7 +62,7 @@ public class GroupBucketIdentifier { ...@@ -63,7 +62,7 @@ public class GroupBucketIdentifier {
63 return this.outPort; 62 return this.outPort;
64 } 63 }
65 64
66 - protected GroupKey outGroup() { 65 + protected PolicyGroupIdentifier outGroup() {
67 return this.outGroup; 66 return this.outGroup;
68 } 67 }
69 } 68 }
......
...@@ -23,7 +23,6 @@ import java.util.Objects; ...@@ -23,7 +23,6 @@ import java.util.Objects;
23 import java.util.Set; 23 import java.util.Set;
24 24
25 import org.onosproject.net.DeviceId; 25 import org.onosproject.net.DeviceId;
26 -import org.onosproject.net.group.GroupKey;
27 26
28 /** 27 /**
29 * Representation of a set of neighbor switch dpids along with edge node 28 * Representation of a set of neighbor switch dpids along with edge node
...@@ -31,9 +30,10 @@ import org.onosproject.net.group.GroupKey; ...@@ -31,9 +30,10 @@ import org.onosproject.net.group.GroupKey;
31 * ECMP-group that hashes packets to a set of ports connecting to the 30 * ECMP-group that hashes packets to a set of ports connecting to the
32 * neighbors in this set. 31 * neighbors in this set.
33 */ 32 */
34 -public class NeighborSet implements GroupKey { 33 +public class NeighborSet {
35 private final Set<DeviceId> neighbors; 34 private final Set<DeviceId> neighbors;
36 private final int edgeLabel; 35 private final int edgeLabel;
36 + public static final int NO_EDGE_LABEL = -1;
37 37
38 /** 38 /**
39 * Constructor with set of neighbors. Edge label is 39 * Constructor with set of neighbors. Edge label is
...@@ -43,7 +43,7 @@ public class NeighborSet implements GroupKey { ...@@ -43,7 +43,7 @@ public class NeighborSet implements GroupKey {
43 */ 43 */
44 public NeighborSet(Set<DeviceId> neighbors) { 44 public NeighborSet(Set<DeviceId> neighbors) {
45 checkNotNull(neighbors); 45 checkNotNull(neighbors);
46 - this.edgeLabel = -1; 46 + this.edgeLabel = NO_EDGE_LABEL;
47 this.neighbors = new HashSet<DeviceId>(); 47 this.neighbors = new HashSet<DeviceId>();
48 this.neighbors.addAll(neighbors); 48 this.neighbors.addAll(neighbors);
49 } 49 }
...@@ -65,7 +65,7 @@ public class NeighborSet implements GroupKey { ...@@ -65,7 +65,7 @@ public class NeighborSet implements GroupKey {
65 * Default constructor for kryo serialization. 65 * Default constructor for kryo serialization.
66 */ 66 */
67 public NeighborSet() { 67 public NeighborSet() {
68 - this.edgeLabel = -1; 68 + this.edgeLabel = NO_EDGE_LABEL;
69 this.neighbors = new HashSet<DeviceId>(); 69 this.neighbors = new HashSet<DeviceId>();
70 } 70 }
71 71
......
...@@ -37,7 +37,6 @@ import org.onosproject.net.group.GroupBucket; ...@@ -37,7 +37,6 @@ import org.onosproject.net.group.GroupBucket;
37 import org.onosproject.net.group.GroupBuckets; 37 import org.onosproject.net.group.GroupBuckets;
38 import org.onosproject.net.group.GroupDescription; 38 import org.onosproject.net.group.GroupDescription;
39 import org.onosproject.net.group.GroupEvent; 39 import org.onosproject.net.group.GroupEvent;
40 -import org.onosproject.net.group.GroupKey;
41 import org.onosproject.net.group.GroupService; 40 import org.onosproject.net.group.GroupService;
42 import org.onosproject.net.link.LinkService; 41 import org.onosproject.net.link.LinkService;
43 import org.slf4j.Logger; 42 import org.slf4j.Logger;
...@@ -49,18 +48,17 @@ import org.slf4j.Logger; ...@@ -49,18 +48,17 @@ import org.slf4j.Logger;
49 public class PolicyGroupHandler extends DefaultGroupHandler { 48 public class PolicyGroupHandler extends DefaultGroupHandler {
50 49
51 private final Logger log = getLogger(getClass()); 50 private final Logger log = getLogger(getClass());
52 - private HashMap<GroupKey, GroupKey> dependentGroups = 51 + private HashMap<PolicyGroupIdentifier, PolicyGroupIdentifier> dependentGroups =
53 - new HashMap<GroupKey, GroupKey>(); 52 + new HashMap<PolicyGroupIdentifier, PolicyGroupIdentifier>();
54 53
55 /** 54 /**
56 - * Creates policy group handler object. 55 + * Policy group handler constructor.
57 * 56 *
58 * @param deviceId device identifier 57 * @param deviceId device identifier
59 * @param appId application identifier 58 * @param appId application identifier
60 * @param config interface to retrieve the device properties 59 * @param config interface to retrieve the device properties
61 * @param linkService link service object 60 * @param linkService link service object
62 * @param groupService group service object 61 * @param groupService group service object
63 - * @return policy group handler type
64 */ 62 */
65 public PolicyGroupHandler(DeviceId deviceId, 63 public PolicyGroupHandler(DeviceId deviceId,
66 ApplicationId appId, 64 ApplicationId appId,
...@@ -175,9 +173,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -175,9 +173,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
175 tBuilder.setOutput(bucketId.outPort()) 173 tBuilder.setOutput(bucketId.outPort())
176 .setEthDst(deviceConfig. 174 .setEthDst(deviceConfig.
177 getDeviceMac(neighbor)) 175 getDeviceMac(neighbor))
178 - .setEthSrc(nodeMacAddr) 176 + .setEthSrc(nodeMacAddr);
179 - .pushMpls() 177 + if (bucketId.label() != NeighborSet.NO_EDGE_LABEL) {
178 + tBuilder.pushMpls()
180 .setMpls(MplsLabel.mplsLabel(bucketId.label())); 179 .setMpls(MplsLabel.mplsLabel(bucketId.label()));
180 + }
181 //TODO: BoS 181 //TODO: BoS
182 outBuckets.add(DefaultGroupBucket. 182 outBuckets.add(DefaultGroupBucket.
183 createSelectGroupBucket(tBuilder.build())); 183 createSelectGroupBucket(tBuilder.build()));
...@@ -196,8 +196,7 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -196,8 +196,7 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
196 protected void handleGroupEvent(GroupEvent event) { 196 protected void handleGroupEvent(GroupEvent event) {
197 if (event.type() == GroupEvent.Type.GROUP_ADDED) { 197 if (event.type() == GroupEvent.Type.GROUP_ADDED) {
198 if (dependentGroups.get(event.subject().appCookie()) != null) { 198 if (dependentGroups.get(event.subject().appCookie()) != null) {
199 - PolicyGroupIdentifier dependentGroupKey = (PolicyGroupIdentifier) 199 + PolicyGroupIdentifier dependentGroupKey = dependentGroups.get(event.subject().appCookie());
200 - dependentGroups.get(event.subject().appCookie());
201 dependentGroups.remove(event.subject().appCookie()); 200 dependentGroups.remove(event.subject().appCookie());
202 boolean fullyResolved = true; 201 boolean fullyResolved = true;
203 for (GroupBucketIdentifier bucketId: 202 for (GroupBucketIdentifier bucketId:
...@@ -217,8 +216,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -217,8 +216,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
217 dependentGroupKey.bucketIds()) { 216 dependentGroupKey.bucketIds()) {
218 TrafficTreatment.Builder tBuilder = 217 TrafficTreatment.Builder tBuilder =
219 DefaultTrafficTreatment.builder(); 218 DefaultTrafficTreatment.builder();
219 + if (bucketId.label() != NeighborSet.NO_EDGE_LABEL) {
220 tBuilder.pushMpls() 220 tBuilder.pushMpls()
221 - .setMpls(MplsLabel.mplsLabel(bucketId.label())); 221 + .setMpls(MplsLabel.
222 + mplsLabel(bucketId.label()));
223 + }
222 //TODO: BoS 224 //TODO: BoS
223 if (bucketId.type() == BucketOutputType.PORT) { 225 if (bucketId.type() == BucketOutputType.PORT) {
224 DeviceId neighbor = portDeviceMap. 226 DeviceId neighbor = portDeviceMap.
...@@ -230,12 +232,14 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -230,12 +232,14 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
230 } else { 232 } else {
231 if (groupService. 233 if (groupService.
232 getGroup(deviceId, 234 getGroup(deviceId,
233 - bucketId.outGroup()) == null) { 235 + getGroupKey(bucketId.
236 + outGroup())) == null) {
234 throw new IllegalStateException(); 237 throw new IllegalStateException();
235 } 238 }
236 GroupId indirectGroupId = groupService. 239 GroupId indirectGroupId = groupService.
237 getGroup(deviceId, 240 getGroup(deviceId,
238 - bucketId.outGroup()).id(); 241 + getGroupKey(bucketId.
242 + outGroup())).id();
239 tBuilder.group(indirectGroupId); 243 tBuilder.group(indirectGroupId);
240 } 244 }
241 outBuckets.add(DefaultGroupBucket. 245 outBuckets.add(DefaultGroupBucket.
...@@ -251,7 +255,7 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -251,7 +255,7 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
251 } 255 }
252 } 256 }
253 257
254 - public GroupKey generatePolicyGroupKey(String id, 258 + public PolicyGroupIdentifier generatePolicyGroupKey(String id,
255 List<PolicyGroupParams> params) { 259 List<PolicyGroupParams> params) {
256 List<GroupBucketIdentifier> bucketIds = new ArrayList<GroupBucketIdentifier>(); 260 List<GroupBucketIdentifier> bucketIds = new ArrayList<GroupBucketIdentifier>();
257 for (PolicyGroupParams param: params) { 261 for (PolicyGroupParams param: params) {
...@@ -320,25 +324,28 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -320,25 +324,28 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
320 return innermostGroupkey; 324 return innermostGroupkey;
321 } 325 }
322 326
323 - public void removeGroupChain(GroupKey key) { 327 + public void removeGroupChain(PolicyGroupIdentifier key) {
324 if (!(key instanceof PolicyGroupIdentifier)) { 328 if (!(key instanceof PolicyGroupIdentifier)) {
325 throw new IllegalArgumentException(); 329 throw new IllegalArgumentException();
326 } 330 }
327 - List<GroupKey> groupsToBeDeleted = new ArrayList<GroupKey>(); 331 + List<PolicyGroupIdentifier> groupsToBeDeleted =
332 + new ArrayList<PolicyGroupIdentifier>();
328 groupsToBeDeleted.add(key); 333 groupsToBeDeleted.add(key);
329 334
330 - Iterator<GroupKey> it = groupsToBeDeleted.iterator(); 335 + Iterator<PolicyGroupIdentifier> it =
336 + groupsToBeDeleted.iterator();
331 337
332 while (it.hasNext()) { 338 while (it.hasNext()) {
333 - PolicyGroupIdentifier innerMostGroupKey = 339 + PolicyGroupIdentifier innerMostGroupKey = it.next();
334 - (PolicyGroupIdentifier) it.next();
335 for (GroupBucketIdentifier bucketId: 340 for (GroupBucketIdentifier bucketId:
336 innerMostGroupKey.bucketIds()) { 341 innerMostGroupKey.bucketIds()) {
337 if (bucketId.type() != BucketOutputType.GROUP) { 342 if (bucketId.type() != BucketOutputType.GROUP) {
338 groupsToBeDeleted.add(bucketId.outGroup()); 343 groupsToBeDeleted.add(bucketId.outGroup());
339 } 344 }
340 } 345 }
341 - groupService.removeGroup(deviceId, innerMostGroupKey, appId); 346 + groupService.removeGroup(deviceId,
347 + getGroupKey(innerMostGroupKey),
348 + appId);
342 it.remove(); 349 it.remove();
343 } 350 }
344 } 351 }
......
...@@ -17,14 +17,12 @@ package org.onosproject.grouphandler; ...@@ -17,14 +17,12 @@ package org.onosproject.grouphandler;
17 17
18 import java.util.List; 18 import java.util.List;
19 19
20 -import org.onosproject.net.group.GroupKey;
21 -
22 /** 20 /**
23 * Representation of policy based group identifiers. 21 * Representation of policy based group identifiers.
24 * Opaque to group handler applications and only the outermost 22 * Opaque to group handler applications and only the outermost
25 * policy group identifier in a chain is visible to the applications. 23 * policy group identifier in a chain is visible to the applications.
26 */ 24 */
27 -public class PolicyGroupIdentifier implements GroupKey { 25 +public class PolicyGroupIdentifier {
28 private String id; 26 private String id;
29 private List<PolicyGroupParams> inputParams; 27 private List<PolicyGroupParams> inputParams;
30 private List<GroupBucketIdentifier> bucketIds; 28 private List<GroupBucketIdentifier> bucketIds;
......
...@@ -16,13 +16,11 @@ ...@@ -16,13 +16,11 @@
16 package org.onosproject.net.group; 16 package org.onosproject.net.group;
17 17
18 import static com.google.common.base.MoreObjects.toStringHelper; 18 import static com.google.common.base.MoreObjects.toStringHelper;
19 -import static org.slf4j.LoggerFactory.getLogger;
20 19
21 import java.util.Objects; 20 import java.util.Objects;
22 21
23 import org.onosproject.core.GroupId; 22 import org.onosproject.core.GroupId;
24 import org.onosproject.net.DeviceId; 23 import org.onosproject.net.DeviceId;
25 -import org.slf4j.Logger;
26 24
27 /** 25 /**
28 * ONOS implementation of default group that is stored in the system. 26 * ONOS implementation of default group that is stored in the system.
...@@ -30,9 +28,8 @@ import org.slf4j.Logger; ...@@ -30,9 +28,8 @@ import org.slf4j.Logger;
30 public class DefaultGroup extends DefaultGroupDescription 28 public class DefaultGroup extends DefaultGroupDescription
31 implements Group, StoredGroupEntry { 29 implements Group, StoredGroupEntry {
32 30
33 - private final Logger log = getLogger(getClass());
34 -
35 private GroupState state; 31 private GroupState state;
32 + private boolean isGroupStateAddedFirstTime;
36 private long life; 33 private long life;
37 private long packets; 34 private long packets;
38 private long bytes; 35 private long bytes;
...@@ -215,4 +212,14 @@ public class DefaultGroup extends DefaultGroupDescription ...@@ -215,4 +212,14 @@ public class DefaultGroup extends DefaultGroupDescription
215 .add("state", state) 212 .add("state", state)
216 .toString(); 213 .toString();
217 } 214 }
215 +
216 + @Override
217 + public void setIsGroupStateAddedFirstTime(boolean isGroupStateAddedFirstTime) {
218 + this.isGroupStateAddedFirstTime = isGroupStateAddedFirstTime;
219 + }
220 +
221 + @Override
222 + public boolean isGroupStateAddedFirstTime() {
223 + return isGroupStateAddedFirstTime;
224 + }
218 } 225 }
......
...@@ -41,7 +41,8 @@ public class DefaultGroupDescription implements GroupDescription { ...@@ -41,7 +41,8 @@ public class DefaultGroupDescription implements GroupDescription {
41 * @param deviceId device identifier 41 * @param deviceId device identifier
42 * @param type type of the group 42 * @param type type of the group
43 * @param buckets immutable list of group bucket 43 * @param buckets immutable list of group bucket
44 - * @param appCookie immutable application cookie to be associated with the group 44 + * @param appCookie immutable application cookie of type DefaultGroupKey
45 + * to be associated with the group
45 * @param appId application id 46 * @param appId application id
46 */ 47 */
47 public DefaultGroupDescription(DeviceId deviceId, 48 public DefaultGroupDescription(DeviceId deviceId,
......
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 com.google.common.base.Preconditions.checkNotNull;
19 +
20 +import java.util.Arrays;
21 +
22 +/**
23 + * Default implementation of group key interface.
24 + */
25 +public class DefaultGroupKey implements GroupKey {
26 +
27 + private final byte[] key;
28 +
29 + public DefaultGroupKey(byte[] key) {
30 + this.key = checkNotNull(key);
31 + }
32 +
33 + @Override
34 + public byte[] key() {
35 + return key;
36 + }
37 +
38 + @Override
39 + public boolean equals(Object o) {
40 + if (this == o) {
41 + return true;
42 + }
43 + if (!(o instanceof DefaultGroupKey)) {
44 + return false;
45 + }
46 + DefaultGroupKey that = (DefaultGroupKey) o;
47 + return (Arrays.equals(this.key, that.key));
48 + }
49 +
50 + @Override
51 + public int hashCode() {
52 + return Arrays.hashCode(this.key);
53 + }
54 +
55 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -17,8 +17,15 @@ package org.onosproject.net.group; ...@@ -17,8 +17,15 @@ package org.onosproject.net.group;
17 17
18 /** 18 /**
19 * Representation of generalized Key that would be used to store 19 * Representation of generalized Key that would be used to store
20 - * groups in &lt; Key, Value &gt; store. Implementation of this interface 20 + * groups in &lt; Key, Value &gt; store. This key uses a generic
21 - * MUST override "equals()" and "hashcode()" methods. 21 + * byte array so that applications can associate their groups with
22 + * any of their data by translating it into a byte array.
22 */ 23 */
23 public interface GroupKey { 24 public interface GroupKey {
25 + /**
26 + * Returns the byte representation of key.
27 + *
28 + * @return byte array
29 + */
30 + public byte[] key();
24 } 31 }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
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.DeviceId; 19 import org.onosproject.net.DeviceId;
19 import org.onosproject.store.Store; 20 import org.onosproject.store.Store;
20 21
...@@ -60,6 +61,15 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> { ...@@ -60,6 +61,15 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> {
60 Group getGroup(DeviceId deviceId, GroupKey appCookie); 61 Group getGroup(DeviceId deviceId, GroupKey appCookie);
61 62
62 /** 63 /**
64 + * Returns the stored group entry for an id.
65 + *
66 + * @param deviceId the device ID
67 + * @param groupId the group identifier
68 + * @return a group associated with the key
69 + */
70 + Group getGroup(DeviceId deviceId, GroupId groupId);
71 +
72 + /**
63 * Stores a new group entry using the information from group description. 73 * Stores a new group entry using the information from group description.
64 * 74 *
65 * @param groupDesc group description to be used to store group entry 75 * @param groupDesc group description to be used to store group entry
......
...@@ -29,6 +29,23 @@ public interface StoredGroupEntry extends Group { ...@@ -29,6 +29,23 @@ public interface StoredGroupEntry extends Group {
29 void setState(Group.GroupState newState); 29 void setState(Group.GroupState newState);
30 30
31 /** 31 /**
32 + * Sets if group has transitioned to ADDED state for the first time.
33 + * This is to differentiate state transitions "from PENDING_ADD to ADDED"
34 + * and "from PENDING_UPDATE to ADDED". For internal use only.
35 + *
36 + * @param isGroupAddedFirstTime true if group moves to ADDED state
37 + * for the first time.
38 + */
39 + void setIsGroupStateAddedFirstTime(boolean isGroupAddedFirstTime);
40 +
41 + /**
42 + * Returns the isGroupStateAddedFirstTime value. For internal use only.
43 + *
44 + * @return isGroupStateAddedFirstTime value
45 + */
46 + boolean isGroupStateAddedFirstTime();
47 +
48 + /**
32 * Sets how long this entry has been entered in the system. 49 * Sets how long this entry has been entered in the system.
33 * 50 *
34 * @param life epoch time 51 * @param life epoch time
......
...@@ -15,7 +15,13 @@ ...@@ -15,7 +15,13 @@
15 */ 15 */
16 package org.onosproject.net.group.impl; 16 package org.onosproject.net.group.impl;
17 17
18 -import com.google.common.collect.Sets; 18 +import static org.slf4j.LoggerFactory.getLogger;
19 +
20 +import java.util.Arrays;
21 +import java.util.Collection;
22 +import java.util.Iterator;
23 +import java.util.Set;
24 +
19 import org.apache.felix.scr.annotations.Activate; 25 import org.apache.felix.scr.annotations.Activate;
20 import org.apache.felix.scr.annotations.Component; 26 import org.apache.felix.scr.annotations.Component;
21 import org.apache.felix.scr.annotations.Deactivate; 27 import org.apache.felix.scr.annotations.Deactivate;
...@@ -48,12 +54,7 @@ import org.onosproject.net.provider.AbstractProviderRegistry; ...@@ -48,12 +54,7 @@ import org.onosproject.net.provider.AbstractProviderRegistry;
48 import org.onosproject.net.provider.AbstractProviderService; 54 import org.onosproject.net.provider.AbstractProviderService;
49 import org.slf4j.Logger; 55 import org.slf4j.Logger;
50 56
51 -import java.util.Arrays; 57 +import com.google.common.collect.Sets;
52 -import java.util.Collection;
53 -import java.util.Iterator;
54 -import java.util.Set;
55 -
56 -import static org.slf4j.LoggerFactory.getLogger;
57 58
58 /** 59 /**
59 * Provides implementation of the group service APIs. 60 * Provides implementation of the group service APIs.
...@@ -103,6 +104,7 @@ public class GroupManager ...@@ -103,6 +104,7 @@ public class GroupManager
103 */ 104 */
104 @Override 105 @Override
105 public void addGroup(GroupDescription groupDesc) { 106 public void addGroup(GroupDescription groupDesc) {
107 + log.trace("In addGroup API");
106 store.storeGroupDescription(groupDesc); 108 store.storeGroupDescription(groupDesc);
107 } 109 }
108 110
...@@ -121,6 +123,7 @@ public class GroupManager ...@@ -121,6 +123,7 @@ public class GroupManager
121 */ 123 */
122 @Override 124 @Override
123 public Group getGroup(DeviceId deviceId, GroupKey appCookie) { 125 public Group getGroup(DeviceId deviceId, GroupKey appCookie) {
126 + log.trace("In getGroup API");
124 return store.getGroup(deviceId, appCookie); 127 return store.getGroup(deviceId, appCookie);
125 } 128 }
126 129
...@@ -142,6 +145,7 @@ public class GroupManager ...@@ -142,6 +145,7 @@ public class GroupManager
142 GroupBuckets buckets, 145 GroupBuckets buckets,
143 GroupKey newCookie, 146 GroupKey newCookie,
144 ApplicationId appId) { 147 ApplicationId appId) {
148 + log.trace("In addBucketsToGroup API");
145 store.updateGroupDescription(deviceId, 149 store.updateGroupDescription(deviceId,
146 oldCookie, 150 oldCookie,
147 UpdateType.ADD, 151 UpdateType.ADD,
...@@ -167,6 +171,7 @@ public class GroupManager ...@@ -167,6 +171,7 @@ public class GroupManager
167 GroupBuckets buckets, 171 GroupBuckets buckets,
168 GroupKey newCookie, 172 GroupKey newCookie,
169 ApplicationId appId) { 173 ApplicationId appId) {
174 + log.trace("In removeBucketsFromGroup API");
170 store.updateGroupDescription(deviceId, 175 store.updateGroupDescription(deviceId,
171 oldCookie, 176 oldCookie,
172 UpdateType.REMOVE, 177 UpdateType.REMOVE,
...@@ -188,6 +193,7 @@ public class GroupManager ...@@ -188,6 +193,7 @@ public class GroupManager
188 public void removeGroup(DeviceId deviceId, 193 public void removeGroup(DeviceId deviceId,
189 GroupKey appCookie, 194 GroupKey appCookie,
190 ApplicationId appId) { 195 ApplicationId appId) {
196 + log.trace("In removeGroup API");
191 store.deleteGroupDescription(deviceId, appCookie); 197 store.deleteGroupDescription(deviceId, appCookie);
192 } 198 }
193 199
...@@ -202,11 +208,13 @@ public class GroupManager ...@@ -202,11 +208,13 @@ public class GroupManager
202 @Override 208 @Override
203 public Iterable<Group> getGroups(DeviceId deviceId, 209 public Iterable<Group> getGroups(DeviceId deviceId,
204 ApplicationId appId) { 210 ApplicationId appId) {
211 + log.trace("In getGroups API");
205 return store.getGroups(deviceId); 212 return store.getGroups(deviceId);
206 } 213 }
207 214
208 @Override 215 @Override
209 public Iterable<Group> getGroups(DeviceId deviceId) { 216 public Iterable<Group> getGroups(DeviceId deviceId) {
217 + log.trace("In getGroups API");
210 return store.getGroups(deviceId); 218 return store.getGroups(deviceId);
211 } 219 }
212 220
...@@ -217,6 +225,7 @@ public class GroupManager ...@@ -217,6 +225,7 @@ public class GroupManager
217 */ 225 */
218 @Override 226 @Override
219 public void addListener(GroupListener listener) { 227 public void addListener(GroupListener listener) {
228 + log.trace("In addListener API");
220 listenerRegistry.addListener(listener); 229 listenerRegistry.addListener(listener);
221 } 230 }
222 231
...@@ -227,6 +236,7 @@ public class GroupManager ...@@ -227,6 +236,7 @@ public class GroupManager
227 */ 236 */
228 @Override 237 @Override
229 public void removeListener(GroupListener listener) { 238 public void removeListener(GroupListener listener) {
239 + log.trace("In removeListener API");
230 listenerRegistry.removeListener(listener); 240 listenerRegistry.removeListener(listener);
231 } 241 }
232 242
...@@ -364,30 +374,45 @@ public class GroupManager ...@@ -364,30 +374,45 @@ public class GroupManager
364 Set<Group> extraneousStoredEntries = 374 Set<Group> extraneousStoredEntries =
365 Sets.newHashSet(store.getExtraneousGroups(deviceId)); 375 Sets.newHashSet(store.getExtraneousGroups(deviceId));
366 376
367 - log.trace("Displaying all southboundGroupEntries for device {}", deviceId); 377 + log.trace("Displaying all ({}) southboundGroupEntries for device {}",
378 + southboundGroupEntries.size(),
379 + deviceId);
368 for (Iterator<Group> it = southboundGroupEntries.iterator(); it.hasNext();) { 380 for (Iterator<Group> it = southboundGroupEntries.iterator(); it.hasNext();) {
369 Group group = it.next(); 381 Group group = it.next();
370 log.trace("Group {} in device {}", group, deviceId); 382 log.trace("Group {} in device {}", group, deviceId);
371 } 383 }
372 384
373 - log.trace("Displaying all stored group entries for device {}", deviceId); 385 + log.trace("Displaying all ({}) stored group entries for device {}",
374 - for (Iterator<Group> it = storedGroupEntries.iterator(); it.hasNext();) { 386 + storedGroupEntries.size(),
375 - Group group = it.next(); 387 + deviceId);
388 + for (Iterator<Group> it1 = storedGroupEntries.iterator(); it1.hasNext();) {
389 + Group group = it1.next();
376 log.trace("Stored Group {} for device {}", group, deviceId); 390 log.trace("Stored Group {} for device {}", group, deviceId);
377 } 391 }
378 392
379 - for (Iterator<Group> it = southboundGroupEntries.iterator(); it.hasNext();) { 393 + for (Iterator<Group> it2 = southboundGroupEntries.iterator(); it2.hasNext();) {
380 - Group group = it.next(); 394 + Group group = it2.next();
381 if (storedGroupEntries.remove(group)) { 395 if (storedGroupEntries.remove(group)) {
382 // we both have the group, let's update some info then. 396 // we both have the group, let's update some info then.
383 log.trace("Group AUDIT: group {} exists " 397 log.trace("Group AUDIT: group {} exists "
384 + "in both planes for device {}", 398 + "in both planes for device {}",
385 group.id(), deviceId); 399 group.id(), deviceId);
386 groupAdded(group); 400 groupAdded(group);
387 - it.remove(); 401 + it2.remove();
388 } 402 }
389 } 403 }
390 for (Group group : southboundGroupEntries) { 404 for (Group group : southboundGroupEntries) {
405 + if (store.getGroup(group.deviceId(), group.id()) != null) {
406 + // There is a group existing with the same id
407 + // It is possible that group update is
408 + // in progress while we got a stale info from switch
409 + if (!storedGroupEntries.remove(store.getGroup(
410 + group.deviceId(), group.id()))) {
411 + log.warn("Group AUDIT: Inconsistent state:"
412 + + "Group exists in ID based table while "
413 + + "not present in key based table");
414 + }
415 + } else {
391 // there are groups in the switch that aren't in the store 416 // there are groups in the switch that aren't in the store
392 log.trace("Group AUDIT: extraneous group {} exists " 417 log.trace("Group AUDIT: extraneous group {} exists "
393 + "in data plane for device {}", 418 + "in data plane for device {}",
...@@ -395,6 +420,7 @@ public class GroupManager ...@@ -395,6 +420,7 @@ public class GroupManager
395 extraneousStoredEntries.remove(group); 420 extraneousStoredEntries.remove(group);
396 extraneousGroup(group); 421 extraneousGroup(group);
397 } 422 }
423 + }
398 for (Group group : storedGroupEntries) { 424 for (Group group : storedGroupEntries) {
399 // there are groups in the store that aren't in the switch 425 // there are groups in the store that aren't in the switch
400 log.trace("Group AUDIT: group {} missing " 426 log.trace("Group AUDIT: group {} missing "
......
...@@ -15,6 +15,12 @@ ...@@ -15,6 +15,12 @@
15 */ 15 */
16 package org.onosproject.net.group.impl; 16 package org.onosproject.net.group.impl;
17 17
18 +import static org.junit.Assert.assertEquals;
19 +import static org.junit.Assert.assertFalse;
20 +import static org.junit.Assert.assertNotEquals;
21 +import static org.junit.Assert.assertNotNull;
22 +import static org.junit.Assert.assertTrue;
23 +
18 import java.util.ArrayList; 24 import java.util.ArrayList;
19 import java.util.Arrays; 25 import java.util.Arrays;
20 import java.util.Collections; 26 import java.util.Collections;
...@@ -38,6 +44,7 @@ import org.onosproject.net.flow.TrafficTreatment; ...@@ -38,6 +44,7 @@ import org.onosproject.net.flow.TrafficTreatment;
38 import org.onosproject.net.group.DefaultGroup; 44 import org.onosproject.net.group.DefaultGroup;
39 import org.onosproject.net.group.DefaultGroupBucket; 45 import org.onosproject.net.group.DefaultGroupBucket;
40 import org.onosproject.net.group.DefaultGroupDescription; 46 import org.onosproject.net.group.DefaultGroupDescription;
47 +import org.onosproject.net.group.DefaultGroupKey;
41 import org.onosproject.net.group.Group; 48 import org.onosproject.net.group.Group;
42 import org.onosproject.net.group.GroupBucket; 49 import org.onosproject.net.group.GroupBucket;
43 import org.onosproject.net.group.GroupBuckets; 50 import org.onosproject.net.group.GroupBuckets;
...@@ -58,8 +65,6 @@ import org.onosproject.store.trivial.impl.SimpleGroupStore; ...@@ -58,8 +65,6 @@ import org.onosproject.store.trivial.impl.SimpleGroupStore;
58 65
59 import com.google.common.collect.Iterables; 66 import com.google.common.collect.Iterables;
60 67
61 -import static org.junit.Assert.*;
62 -
63 /** 68 /**
64 * Test codifying the group service & group provider service contracts. 69 * Test codifying the group service & group provider service contracts.
65 */ 70 */
...@@ -108,31 +113,6 @@ public class GroupManagerTest { ...@@ -108,31 +113,6 @@ public class GroupManagerTest {
108 mgr.eventDispatcher = null; 113 mgr.eventDispatcher = null;
109 } 114 }
110 115
111 - private class TestGroupKey implements GroupKey {
112 - private String groupId;
113 -
114 - public TestGroupKey(String id) {
115 - this.groupId = id;
116 - }
117 -
118 - public String id() {
119 - return this.groupId;
120 - }
121 -
122 - @Override
123 - public int hashCode() {
124 - return groupId.hashCode();
125 - }
126 -
127 - @Override
128 - public boolean equals(Object obj) {
129 - if (obj instanceof TestGroupKey) {
130 - return this.groupId.equals(((TestGroupKey) obj).id());
131 - }
132 - return false;
133 - }
134 - }
135 -
136 /** 116 /**
137 * Tests group service north bound and south bound interfaces. 117 * Tests group service north bound and south bound interfaces.
138 * The following operations are tested: 118 * The following operations are tested:
...@@ -177,7 +157,7 @@ public class GroupManagerTest { ...@@ -177,7 +157,7 @@ public class GroupManagerTest {
177 PortNumber.portNumber(32)}; 157 PortNumber.portNumber(32)};
178 PortNumber[] ports2 = {PortNumber.portNumber(41), 158 PortNumber[] ports2 = {PortNumber.portNumber(41),
179 PortNumber.portNumber(42)}; 159 PortNumber.portNumber(42)};
180 - TestGroupKey key = new TestGroupKey("group1BeforeAudit"); 160 + GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
181 List<GroupBucket> buckets = new ArrayList<GroupBucket>(); 161 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
182 List<PortNumber> outPorts = new ArrayList<PortNumber>(); 162 List<PortNumber> outPorts = new ArrayList<PortNumber>();
183 outPorts.addAll(Arrays.asList(ports1)); 163 outPorts.addAll(Arrays.asList(ports1));
...@@ -224,7 +204,7 @@ public class GroupManagerTest { ...@@ -224,7 +204,7 @@ public class GroupManagerTest {
224 providerService.pushGroupMetrics(DID, groupEntries); 204 providerService.pushGroupMetrics(DID, groupEntries);
225 // First group metrics would trigger the device audit completion 205 // First group metrics would trigger the device audit completion
226 // post which all pending group requests are also executed. 206 // post which all pending group requests are also executed.
227 - TestGroupKey key = new TestGroupKey("group1BeforeAudit"); 207 + GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
228 Group createdGroup = groupService.getGroup(DID, key); 208 Group createdGroup = groupService.getGroup(DID, key);
229 int createdGroupId = createdGroup.id().id(); 209 int createdGroupId = createdGroup.id().id();
230 assertNotEquals(gId1.id(), createdGroupId); 210 assertNotEquals(gId1.id(), createdGroupId);
...@@ -256,7 +236,7 @@ public class GroupManagerTest { ...@@ -256,7 +236,7 @@ public class GroupManagerTest {
256 0); 236 0);
257 List<Group> groupEntries = Arrays.asList(group1, group2); 237 List<Group> groupEntries = Arrays.asList(group1, group2);
258 providerService.pushGroupMetrics(DID, groupEntries); 238 providerService.pushGroupMetrics(DID, groupEntries);
259 - TestGroupKey key = new TestGroupKey("group1BeforeAudit"); 239 + GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
260 Group createdGroup = groupService.getGroup(DID, key); 240 Group createdGroup = groupService.getGroup(DID, key);
261 List<GroupOperation> expectedGroupOps = Arrays.asList( 241 List<GroupOperation> expectedGroupOps = Arrays.asList(
262 GroupOperation.createDeleteGroupOperation(gId1, 242 GroupOperation.createDeleteGroupOperation(gId1,
...@@ -271,7 +251,7 @@ public class GroupManagerTest { ...@@ -271,7 +251,7 @@ public class GroupManagerTest {
271 251
272 // Test AUDIT with confirmed groups 252 // Test AUDIT with confirmed groups
273 private void testAuditWithConfirmedGroups() { 253 private void testAuditWithConfirmedGroups() {
274 - TestGroupKey key = new TestGroupKey("group1BeforeAudit"); 254 + GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
275 Group createdGroup = groupService.getGroup(DID, key); 255 Group createdGroup = groupService.getGroup(DID, key);
276 createdGroup = new DefaultGroup(createdGroup.id(), 256 createdGroup = new DefaultGroup(createdGroup.id(),
277 DID, 257 DID,
...@@ -284,9 +264,9 @@ public class GroupManagerTest { ...@@ -284,9 +264,9 @@ public class GroupManagerTest {
284 264
285 // Test group add bucket operations 265 // Test group add bucket operations
286 private void testAddBuckets() { 266 private void testAddBuckets() {
287 - TestGroupKey addKey = new TestGroupKey("group1AddBuckets"); 267 + GroupKey addKey = new DefaultGroupKey("group1AddBuckets".getBytes());
288 268
289 - TestGroupKey prevKey = new TestGroupKey("group1BeforeAudit"); 269 + GroupKey prevKey = new DefaultGroupKey("group1BeforeAudit".getBytes());
290 Group createdGroup = groupService.getGroup(DID, prevKey); 270 Group createdGroup = groupService.getGroup(DID, prevKey);
291 List<GroupBucket> buckets = new ArrayList<GroupBucket>(); 271 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
292 buckets.addAll(createdGroup.buckets().buckets()); 272 buckets.addAll(createdGroup.buckets().buckets());
...@@ -328,9 +308,9 @@ public class GroupManagerTest { ...@@ -328,9 +308,9 @@ public class GroupManagerTest {
328 308
329 // Test group remove bucket operations 309 // Test group remove bucket operations
330 private void testRemoveBuckets() { 310 private void testRemoveBuckets() {
331 - TestGroupKey removeKey = new TestGroupKey("group1RemoveBuckets"); 311 + GroupKey removeKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
332 312
333 - TestGroupKey prevKey = new TestGroupKey("group1AddBuckets"); 313 + GroupKey prevKey = new DefaultGroupKey("group1AddBuckets".getBytes());
334 Group createdGroup = groupService.getGroup(DID, prevKey); 314 Group createdGroup = groupService.getGroup(DID, prevKey);
335 List<GroupBucket> buckets = new ArrayList<GroupBucket>(); 315 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
336 buckets.addAll(createdGroup.buckets().buckets()); 316 buckets.addAll(createdGroup.buckets().buckets());
...@@ -372,7 +352,7 @@ public class GroupManagerTest { ...@@ -372,7 +352,7 @@ public class GroupManagerTest {
372 352
373 // Test group remove operations 353 // Test group remove operations
374 private void testRemoveGroup() { 354 private void testRemoveGroup() {
375 - TestGroupKey currKey = new TestGroupKey("group1RemoveBuckets"); 355 + GroupKey currKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
376 Group existingGroup = groupService.getGroup(DID, currKey); 356 Group existingGroup = groupService.getGroup(DID, currKey);
377 groupService.removeGroup(DID, currKey, appId); 357 groupService.removeGroup(DID, currKey, appId);
378 List<GroupOperation> expectedGroupOps = Arrays.asList( 358 List<GroupOperation> expectedGroupOps = Arrays.asList(
...@@ -397,7 +377,7 @@ public class GroupManagerTest { ...@@ -397,7 +377,7 @@ public class GroupManagerTest {
397 PortNumber[] ports2 = {PortNumber.portNumber(41), 377 PortNumber[] ports2 = {PortNumber.portNumber(41),
398 PortNumber.portNumber(42)}; 378 PortNumber.portNumber(42)};
399 // Test Group creation before AUDIT process 379 // Test Group creation before AUDIT process
400 - TestGroupKey key = new TestGroupKey("group1BeforeAudit"); 380 + GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
401 List<GroupBucket> buckets = new ArrayList<GroupBucket>(); 381 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
402 List<PortNumber> outPorts = new ArrayList<PortNumber>(); 382 List<PortNumber> outPorts = new ArrayList<PortNumber>();
403 outPorts.addAll(Arrays.asList(ports1)); 383 outPorts.addAll(Arrays.asList(ports1));
......
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.group.impl;
17 +
18 +import org.onosproject.net.DeviceId;
19 +import org.onosproject.net.group.GroupBuckets;
20 +import org.onosproject.net.group.GroupDescription;
21 +import org.onosproject.net.group.GroupKey;
22 +import org.onosproject.net.group.GroupStore.UpdateType;
23 +
24 +/**
25 + * Format of the Group store message that is used to
26 + * communicate with the peer nodes in the cluster.
27 + */
28 +public final class GroupStoreMessage {
29 + private final DeviceId deviceId;
30 + private final GroupKey appCookie;
31 + private final GroupDescription groupDesc;
32 + private final UpdateType updateType;
33 + private final GroupBuckets updateBuckets;
34 + private final GroupKey newAppCookie;
35 + private final Type type;
36 +
37 + /**
38 + * Type of group store request.
39 + */
40 + public enum Type {
41 + ADD,
42 + UPDATE,
43 + DELETE
44 + }
45 +
46 + private GroupStoreMessage(Type type,
47 + DeviceId deviceId,
48 + GroupKey appCookie,
49 + GroupDescription groupDesc,
50 + UpdateType updateType,
51 + GroupBuckets updateBuckets,
52 + GroupKey newAppCookie) {
53 + this.type = type;
54 + this.deviceId = deviceId;
55 + this.appCookie = appCookie;
56 + this.groupDesc = groupDesc;
57 + this.updateType = updateType;
58 + this.updateBuckets = updateBuckets;
59 + this.newAppCookie = newAppCookie;
60 + }
61 +
62 + /**
63 + * Creates a group store message for group ADD request.
64 + *
65 + * @param deviceId device identifier in which group to be added
66 + * @param desc group creation parameters
67 + * @return constructed group store message
68 + */
69 + public static GroupStoreMessage createGroupAddRequestMsg(DeviceId deviceId,
70 + GroupDescription desc) {
71 + return new GroupStoreMessage(Type.ADD,
72 + deviceId,
73 + null,
74 + desc,
75 + null,
76 + null,
77 + null);
78 + }
79 +
80 + /**
81 + * Creates a group store message for group UPDATE request.
82 + *
83 + * @param deviceId the device ID
84 + * @param appCookie the current group key
85 + * @param updateType update (add or delete) type
86 + * @param updateBuckets group buckets for updates
87 + * @param newAppCookie optional new group key
88 + * @return constructed group store message
89 + */
90 + public static GroupStoreMessage createGroupUpdateRequestMsg(DeviceId deviceId,
91 + GroupKey appCookie,
92 + UpdateType updateType,
93 + GroupBuckets updateBuckets,
94 + GroupKey newAppCookie) {
95 + return new GroupStoreMessage(Type.UPDATE,
96 + deviceId,
97 + appCookie,
98 + null,
99 + updateType,
100 + updateBuckets,
101 + newAppCookie);
102 + }
103 +
104 + /**
105 + * Creates a group store message for group DELETE request.
106 + *
107 + * @param deviceId the device ID
108 + * @param appCookie the group key
109 + * @return constructed group store message
110 + */
111 + public static GroupStoreMessage createGroupDeleteRequestMsg(DeviceId deviceId,
112 + GroupKey appCookie) {
113 + return new GroupStoreMessage(Type.DELETE,
114 + deviceId,
115 + appCookie,
116 + null,
117 + null,
118 + null,
119 + null);
120 + }
121 +
122 + /**
123 + * Returns the device identifier of this group request.
124 + *
125 + * @return device identifier
126 + */
127 + public DeviceId deviceId() {
128 + return deviceId;
129 + }
130 +
131 + /**
132 + * Returns the application cookie associated with this group request.
133 + *
134 + * @return application cookie
135 + */
136 + public GroupKey appCookie() {
137 + return appCookie;
138 + }
139 +
140 + /**
141 + * Returns the group create parameters associated with this group request.
142 + *
143 + * @return group create parameters
144 + */
145 + public GroupDescription groupDesc() {
146 + return groupDesc;
147 + }
148 +
149 + /**
150 + * Returns the group buckets to be updated as part of this group request.
151 + *
152 + * @return group buckets to be updated
153 + */
154 + public GroupBuckets updateBuckets() {
155 + return updateBuckets;
156 + }
157 +
158 + /**
159 + * Returns the update group operation type.
160 + *
161 + * @return update operation type
162 + */
163 + public UpdateType updateType() {
164 + return updateType;
165 + }
166 +
167 + /**
168 + * Returns the new application cookie associated with this group operation.
169 + *
170 + * @return new application cookie
171 + */
172 + public GroupKey newAppCookie() {
173 + return newAppCookie;
174 + }
175 +
176 + /**
177 + * Returns the type of this group operation.
178 + *
179 + * @return group message type
180 + */
181 + public Type type() {
182 + return type;
183 + }
184 +}
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.group.impl;
17 +
18 +import org.onosproject.store.cluster.messaging.MessageSubject;
19 +
20 +/**
21 + * MessageSubjects used by DistributedGroupRuleStore peer-peer communication.
22 + */
23 +public final class GroupStoreMessageSubjects {
24 + private GroupStoreMessageSubjects() {}
25 +
26 + public static final MessageSubject REMOTE_GROUP_OP_REQUEST
27 + = new MessageSubject("peer-forward-group-op-req");
28 +}
...@@ -209,6 +209,13 @@ public class SimpleGroupStore ...@@ -209,6 +209,13 @@ public class SimpleGroupStore
209 null; 209 null;
210 } 210 }
211 211
212 + @Override
213 + public Group getGroup(DeviceId deviceId, GroupId groupId) {
214 + return (groupEntriesById.get(deviceId) != null) ?
215 + groupEntriesById.get(deviceId).get(groupId) :
216 + null;
217 + }
218 +
212 private int getFreeGroupIdValue(DeviceId deviceId) { 219 private int getFreeGroupIdValue(DeviceId deviceId) {
213 int freeId = groupIdGen.incrementAndGet(); 220 int freeId = groupIdGen.incrementAndGet();
214 221
...@@ -551,5 +558,4 @@ public class SimpleGroupStore ...@@ -551,5 +558,4 @@ public class SimpleGroupStore
551 getExtraneousGroupIdTable(deviceId).values()); 558 getExtraneousGroupIdTable(deviceId).values());
552 } 559 }
553 560
554 -
555 } 561 }
......
...@@ -36,6 +36,7 @@ import org.onosproject.net.flow.DefaultTrafficTreatment; ...@@ -36,6 +36,7 @@ import org.onosproject.net.flow.DefaultTrafficTreatment;
36 import org.onosproject.net.flow.TrafficTreatment; 36 import org.onosproject.net.flow.TrafficTreatment;
37 import org.onosproject.net.group.DefaultGroupBucket; 37 import org.onosproject.net.group.DefaultGroupBucket;
38 import org.onosproject.net.group.DefaultGroupDescription; 38 import org.onosproject.net.group.DefaultGroupDescription;
39 +import org.onosproject.net.group.DefaultGroupKey;
39 import org.onosproject.net.group.Group; 40 import org.onosproject.net.group.Group;
40 import org.onosproject.net.group.GroupBucket; 41 import org.onosproject.net.group.GroupBucket;
41 import org.onosproject.net.group.GroupBuckets; 42 import org.onosproject.net.group.GroupBuckets;
...@@ -70,31 +71,6 @@ public class SimpleGroupStoreTest { ...@@ -70,31 +71,6 @@ public class SimpleGroupStoreTest {
70 simpleGroupStore.deactivate(); 71 simpleGroupStore.deactivate();
71 } 72 }
72 73
73 - public class TestGroupKey implements GroupKey {
74 - private String groupId;
75 -
76 - public TestGroupKey(String id) {
77 - this.groupId = id;
78 - }
79 -
80 - public String id() {
81 - return this.groupId;
82 - }
83 -
84 - @Override
85 - public int hashCode() {
86 - return groupId.hashCode();
87 - }
88 -
89 - @Override
90 - public boolean equals(Object obj) {
91 - if (obj instanceof TestGroupKey) {
92 - return this.groupId.equals(((TestGroupKey) obj).id());
93 - }
94 - return false;
95 - }
96 - }
97 -
98 private class InternalGroupStoreDelegate 74 private class InternalGroupStoreDelegate
99 implements GroupStoreDelegate { 75 implements GroupStoreDelegate {
100 private GroupId createdGroupId = null; 76 private GroupId createdGroupId = null;
...@@ -173,20 +149,20 @@ public class SimpleGroupStoreTest { ...@@ -173,20 +149,20 @@ public class SimpleGroupStoreTest {
173 simpleGroupStore.deviceInitialAuditCompleted(D1, true); 149 simpleGroupStore.deviceInitialAuditCompleted(D1, true);
174 150
175 // Testing storeGroup operation 151 // Testing storeGroup operation
176 - TestGroupKey newKey = new TestGroupKey("group1"); 152 + GroupKey newKey = new DefaultGroupKey("group1".getBytes());
177 testStoreAndGetGroup(newKey); 153 testStoreAndGetGroup(newKey);
178 154
179 // Testing addOrUpdateGroupEntry operation from southbound 155 // Testing addOrUpdateGroupEntry operation from southbound
180 - TestGroupKey currKey = newKey; 156 + GroupKey currKey = newKey;
181 testAddGroupEntryFromSB(currKey); 157 testAddGroupEntryFromSB(currKey);
182 158
183 // Testing updateGroupDescription for ADD operation from northbound 159 // Testing updateGroupDescription for ADD operation from northbound
184 - newKey = new TestGroupKey("group1AddBuckets"); 160 + newKey = new DefaultGroupKey("group1AddBuckets".getBytes());
185 testAddBuckets(currKey, newKey); 161 testAddBuckets(currKey, newKey);
186 162
187 // Testing updateGroupDescription for REMOVE operation from northbound 163 // Testing updateGroupDescription for REMOVE operation from northbound
188 currKey = newKey; 164 currKey = newKey;
189 - newKey = new TestGroupKey("group1RemoveBuckets"); 165 + newKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
190 testRemoveBuckets(currKey, newKey); 166 testRemoveBuckets(currKey, newKey);
191 167
192 // Testing addOrUpdateGroupEntry operation from southbound 168 // Testing addOrUpdateGroupEntry operation from southbound
...@@ -201,7 +177,7 @@ public class SimpleGroupStoreTest { ...@@ -201,7 +177,7 @@ public class SimpleGroupStoreTest {
201 } 177 }
202 178
203 // Testing storeGroup operation 179 // Testing storeGroup operation
204 - private void testStoreAndGetGroup(TestGroupKey key) { 180 + private void testStoreAndGetGroup(GroupKey key) {
205 PortNumber[] ports = {PortNumber.portNumber(31), 181 PortNumber[] ports = {PortNumber.portNumber(31),
206 PortNumber.portNumber(32)}; 182 PortNumber.portNumber(32)};
207 List<PortNumber> outPorts = new ArrayList<PortNumber>(); 183 List<PortNumber> outPorts = new ArrayList<PortNumber>();
...@@ -252,7 +228,7 @@ public class SimpleGroupStoreTest { ...@@ -252,7 +228,7 @@ public class SimpleGroupStoreTest {
252 } 228 }
253 229
254 // Testing addOrUpdateGroupEntry operation from southbound 230 // Testing addOrUpdateGroupEntry operation from southbound
255 - private void testAddGroupEntryFromSB(TestGroupKey currKey) { 231 + private void testAddGroupEntryFromSB(GroupKey currKey) {
256 Group existingGroup = simpleGroupStore.getGroup(D1, currKey); 232 Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
257 233
258 InternalGroupStoreDelegate addGroupEntryDelegate = 234 InternalGroupStoreDelegate addGroupEntryDelegate =
...@@ -265,7 +241,7 @@ public class SimpleGroupStoreTest { ...@@ -265,7 +241,7 @@ public class SimpleGroupStoreTest {
265 } 241 }
266 242
267 // Testing addOrUpdateGroupEntry operation from southbound 243 // Testing addOrUpdateGroupEntry operation from southbound
268 - private void testUpdateGroupEntryFromSB(TestGroupKey currKey) { 244 + private void testUpdateGroupEntryFromSB(GroupKey currKey) {
269 Group existingGroup = simpleGroupStore.getGroup(D1, currKey); 245 Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
270 246
271 InternalGroupStoreDelegate updateGroupEntryDelegate = 247 InternalGroupStoreDelegate updateGroupEntryDelegate =
...@@ -278,7 +254,7 @@ public class SimpleGroupStoreTest { ...@@ -278,7 +254,7 @@ public class SimpleGroupStoreTest {
278 } 254 }
279 255
280 // Testing updateGroupDescription for ADD operation from northbound 256 // Testing updateGroupDescription for ADD operation from northbound
281 - private void testAddBuckets(TestGroupKey currKey, TestGroupKey addKey) { 257 + private void testAddBuckets(GroupKey currKey, GroupKey addKey) {
282 Group existingGroup = simpleGroupStore.getGroup(D1, currKey); 258 Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
283 List<GroupBucket> buckets = new ArrayList<GroupBucket>(); 259 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
284 buckets.addAll(existingGroup.buckets().buckets()); 260 buckets.addAll(existingGroup.buckets().buckets());
...@@ -316,7 +292,7 @@ public class SimpleGroupStoreTest { ...@@ -316,7 +292,7 @@ public class SimpleGroupStoreTest {
316 } 292 }
317 293
318 // Testing updateGroupDescription for REMOVE operation from northbound 294 // Testing updateGroupDescription for REMOVE operation from northbound
319 - private void testRemoveBuckets(TestGroupKey currKey, TestGroupKey removeKey) { 295 + private void testRemoveBuckets(GroupKey currKey, GroupKey removeKey) {
320 Group existingGroup = simpleGroupStore.getGroup(D1, currKey); 296 Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
321 List<GroupBucket> buckets = new ArrayList<GroupBucket>(); 297 List<GroupBucket> buckets = new ArrayList<GroupBucket>();
322 buckets.addAll(existingGroup.buckets().buckets()); 298 buckets.addAll(existingGroup.buckets().buckets());
...@@ -343,7 +319,7 @@ public class SimpleGroupStoreTest { ...@@ -343,7 +319,7 @@ public class SimpleGroupStoreTest {
343 } 319 }
344 320
345 // Testing deleteGroupDescription operation from northbound 321 // Testing deleteGroupDescription operation from northbound
346 - private void testDeleteGroup(TestGroupKey currKey) { 322 + private void testDeleteGroup(GroupKey currKey) {
347 Group existingGroup = simpleGroupStore.getGroup(D1, currKey); 323 Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
348 InternalGroupStoreDelegate deleteGroupDescDelegate = 324 InternalGroupStoreDelegate deleteGroupDescDelegate =
349 new InternalGroupStoreDelegate(currKey, 325 new InternalGroupStoreDelegate(currKey,
...@@ -355,7 +331,7 @@ public class SimpleGroupStoreTest { ...@@ -355,7 +331,7 @@ public class SimpleGroupStoreTest {
355 } 331 }
356 332
357 // Testing removeGroupEntry operation from southbound 333 // Testing removeGroupEntry operation from southbound
358 - private void testRemoveGroupFromSB(TestGroupKey currKey) { 334 + private void testRemoveGroupFromSB(GroupKey currKey) {
359 Group existingGroup = simpleGroupStore.getGroup(D1, currKey); 335 Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
360 InternalGroupStoreDelegate removeGroupEntryDelegate = 336 InternalGroupStoreDelegate removeGroupEntryDelegate =
361 new InternalGroupStoreDelegate(currKey, 337 new InternalGroupStoreDelegate(currKey,
...@@ -380,7 +356,7 @@ public class SimpleGroupStoreTest { ...@@ -380,7 +356,7 @@ public class SimpleGroupStoreTest {
380 356
381 ApplicationId appId = 357 ApplicationId appId =
382 new DefaultApplicationId(2, "org.groupstore.test"); 358 new DefaultApplicationId(2, "org.groupstore.test");
383 - TestGroupKey key = new TestGroupKey("group1"); 359 + GroupKey key = new DefaultGroupKey("group1".getBytes());
384 PortNumber[] ports = {PortNumber.portNumber(31), 360 PortNumber[] ports = {PortNumber.portNumber(31),
385 PortNumber.portNumber(32)}; 361 PortNumber.portNumber(32)};
386 List<PortNumber> outPorts = new ArrayList<PortNumber>(); 362 List<PortNumber> outPorts = new ArrayList<PortNumber>();
......