Committed by
Gerrit Code Review
ONOS-985: Sample integration test application for group subsystem
Change-Id: I68352f922e5c7a0800fcc4fa839955769bf925a6
Showing
20 changed files
with
1203 additions
and
19 deletions
apps/grouphandler/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!-- | ||
3 | + ~ Copyright 2014 Open Networking Laboratory | ||
4 | + ~ | ||
5 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + ~ you may not use this file except in compliance with the License. | ||
7 | + ~ You may obtain a copy of the License at | ||
8 | + ~ | ||
9 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + ~ | ||
11 | + ~ Unless required by applicable law or agreed to in writing, software | ||
12 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + ~ See the License for the specific language governing permissions and | ||
15 | + ~ limitations under the License. | ||
16 | + --> | ||
17 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
18 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
19 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
20 | + <modelVersion>4.0.0</modelVersion> | ||
21 | + | ||
22 | + <parent> | ||
23 | + <groupId>org.onosproject</groupId> | ||
24 | + <artifactId>onos-apps</artifactId> | ||
25 | + <version>1.1.0-SNAPSHOT</version> | ||
26 | + <relativePath>../pom.xml</relativePath> | ||
27 | + </parent> | ||
28 | + | ||
29 | + <artifactId>onos-app-grouphandler</artifactId> | ||
30 | + <packaging>bundle</packaging> | ||
31 | + | ||
32 | + <description>ONOS sample application using group service</description> | ||
33 | + | ||
34 | + <dependencies> | ||
35 | + <dependency> | ||
36 | + <groupId>org.onosproject</groupId> | ||
37 | + <artifactId>onos-api</artifactId> | ||
38 | + <version>${project.version}</version> | ||
39 | + </dependency> | ||
40 | + <dependency> | ||
41 | + <groupId>org.onosproject</groupId> | ||
42 | + <artifactId>onlab-osgi</artifactId> | ||
43 | + <version>${project.version}</version> | ||
44 | + </dependency> | ||
45 | + <dependency> | ||
46 | + <groupId>org.onosproject</groupId> | ||
47 | + <artifactId>onlab-nio</artifactId> | ||
48 | + <version>${project.version}</version> | ||
49 | + </dependency> | ||
50 | + <dependency> | ||
51 | + <groupId>org.onosproject</groupId> | ||
52 | + <artifactId>onlab-netty</artifactId> | ||
53 | + <version>${project.version}</version> | ||
54 | + </dependency> | ||
55 | + <dependency> | ||
56 | + <groupId>org.apache.karaf.shell</groupId> | ||
57 | + <artifactId>org.apache.karaf.shell.console</artifactId> | ||
58 | + </dependency> | ||
59 | + <dependency> | ||
60 | + <groupId>org.onosproject</groupId> | ||
61 | + <artifactId>onlab-misc</artifactId> | ||
62 | + </dependency> | ||
63 | + <dependency> | ||
64 | + <groupId>com.google.guava</groupId> | ||
65 | + <artifactId>guava</artifactId> | ||
66 | + </dependency> | ||
67 | + <dependency> | ||
68 | + <groupId>org.osgi</groupId> | ||
69 | + <artifactId>org.osgi.core</artifactId> | ||
70 | + </dependency> | ||
71 | + </dependencies> | ||
72 | +</project> |
apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultEdgeGroupHandler.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.grouphandler; | ||
17 | + | ||
18 | +import java.util.Arrays; | ||
19 | +import java.util.HashSet; | ||
20 | +import java.util.List; | ||
21 | +import java.util.Set; | ||
22 | + | ||
23 | +import org.onosproject.core.ApplicationId; | ||
24 | +import org.onosproject.net.DeviceId; | ||
25 | +import org.onosproject.net.Link; | ||
26 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
27 | +import org.onosproject.net.flow.TrafficTreatment; | ||
28 | +import org.onosproject.net.group.DefaultGroupBucket; | ||
29 | +import org.onosproject.net.group.GroupBucket; | ||
30 | +import org.onosproject.net.group.GroupBuckets; | ||
31 | +import org.onosproject.net.group.GroupService; | ||
32 | +import org.onosproject.net.link.LinkService; | ||
33 | + | ||
34 | +/** | ||
35 | + * Default ECMP group handler creation module for an edge device. | ||
36 | + * This component creates a set of ECMP groups for every neighbor | ||
37 | + * that this device is connected to. | ||
38 | + * For example, consider a network of 4 devices: D0 (Segment ID: 100), | ||
39 | + * D1 (Segment ID: 101), D2 (Segment ID: 102) and D3 (Segment ID: 103), | ||
40 | + * where D0 and D3 are edge devices and D1 and D2 are transit devices. | ||
41 | + * Assume device D0 is connected to 2 neighbors (D1 and D2 ). | ||
42 | + * The following groups will be created in D0: | ||
43 | + * 1) all ports to D1 + with no label push, | ||
44 | + * 2) all ports to D1 + with label 102 pushed, | ||
45 | + * 3) all ports to D1 + with label 103 pushed, | ||
46 | + * 4) all ports to D2 + with no label push, | ||
47 | + * 5) all ports to D2 + with label 101 pushed, | ||
48 | + * 6) all ports to D2 + with label 103 pushed, | ||
49 | + * 7) all ports to D1 and D2 + with label 103 pushed | ||
50 | + */ | ||
51 | +public class DefaultEdgeGroupHandler extends DefaultGroupHandler { | ||
52 | + | ||
53 | + protected DefaultEdgeGroupHandler(DeviceId deviceId, | ||
54 | + ApplicationId appId, | ||
55 | + DeviceProperties config, | ||
56 | + LinkService linkService, | ||
57 | + GroupService groupService) { | ||
58 | + super(deviceId, appId, config, linkService, groupService); | ||
59 | + } | ||
60 | + | ||
61 | + @Override | ||
62 | + public void createGroups() { | ||
63 | + log.debug("Creating default groups " | ||
64 | + + "for edge device {}", deviceId); | ||
65 | + Set<DeviceId> neighbors = devicePortMap.keySet(); | ||
66 | + if (neighbors == null || neighbors.isEmpty()) { | ||
67 | + return; | ||
68 | + } | ||
69 | + | ||
70 | + // Create all possible Neighbor sets from this router | ||
71 | + Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(neighbors); | ||
72 | + log.trace("createGroupsAtEdgeRouter: The size of neighbor powerset " | ||
73 | + + "for sw {} is {}", deviceId, powerSet.size()); | ||
74 | + Set<NeighborSet> nsSet = new HashSet<NeighborSet>(); | ||
75 | + for (Set<DeviceId> combo : powerSet) { | ||
76 | + if (combo.isEmpty()) { | ||
77 | + continue; | ||
78 | + } | ||
79 | + List<Integer> groupSegmentIds = | ||
80 | + getSegmentIdsTobePairedWithNeighborSet(combo); | ||
81 | + for (Integer sId : groupSegmentIds) { | ||
82 | + NeighborSet ns = new NeighborSet(combo, sId); | ||
83 | + log.trace("createGroupsAtEdgeRouter: sw {} " | ||
84 | + + "combo {} sId {} ns {}", | ||
85 | + deviceId, combo, sId, ns); | ||
86 | + nsSet.add(ns); | ||
87 | + } | ||
88 | + } | ||
89 | + log.trace("createGroupsAtEdgeRouter: The neighborset " | ||
90 | + + "with label for sw {} is {}", | ||
91 | + deviceId, nsSet); | ||
92 | + | ||
93 | + createGroupsFromNeighborsets(nsSet); | ||
94 | + } | ||
95 | + | ||
96 | + @Override | ||
97 | + protected void newNeighbor(Link newNeighborLink) { | ||
98 | + log.debug("New Neighbor: Updating groups " | ||
99 | + + "for edge device {}", deviceId); | ||
100 | + // Recompute neighbor power set | ||
101 | + addNeighborAtPort(newNeighborLink.dst().deviceId(), | ||
102 | + newNeighborLink.src().port()); | ||
103 | + // Compute new neighbor sets due to the addition of new neighbor | ||
104 | + Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent( | ||
105 | + newNeighborLink.dst().deviceId(), | ||
106 | + devicePortMap.keySet()); | ||
107 | + createGroupsFromNeighborsets(nsSet); | ||
108 | + } | ||
109 | + | ||
110 | + @Override | ||
111 | + protected void newPortToExistingNeighbor(Link newNeighborLink) { | ||
112 | + log.debug("New port to existing neighbor: Updating " | ||
113 | + + "groups for edge device {}", deviceId); | ||
114 | + addNeighborAtPort(newNeighborLink.dst().deviceId(), | ||
115 | + newNeighborLink.src().port()); | ||
116 | + Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent( | ||
117 | + newNeighborLink.dst().deviceId(), | ||
118 | + devicePortMap.keySet()); | ||
119 | + for (NeighborSet ns : nsSet) { | ||
120 | + // Create the new bucket to be updated | ||
121 | + TrafficTreatment.Builder tBuilder = | ||
122 | + DefaultTrafficTreatment.builder(); | ||
123 | + tBuilder.setOutput(newNeighborLink.src().port()) | ||
124 | + .setEthDst(deviceConfig.getDeviceMac( | ||
125 | + newNeighborLink.dst().deviceId())) | ||
126 | + .setEthSrc(nodeMacAddr) | ||
127 | + .pushMpls() | ||
128 | + .setMpls(ns.getEdgeLabel()); | ||
129 | + GroupBucket updatedBucket = DefaultGroupBucket. | ||
130 | + createSelectGroupBucket(tBuilder.build()); | ||
131 | + GroupBuckets updatedBuckets = new GroupBuckets( | ||
132 | + Arrays.asList(updatedBucket)); | ||
133 | + log.debug("newPortToExistingNeighborAtEdgeRouter: " | ||
134 | + + "groupService.addBucketsToGroup for neighborset{}", ns); | ||
135 | + groupService.addBucketsToGroup(deviceId, ns, updatedBuckets, ns, appId); | ||
136 | + } | ||
137 | + } | ||
138 | + | ||
139 | + @Override | ||
140 | + protected Set<NeighborSet> computeImpactedNeighborsetForPortEvent( | ||
141 | + DeviceId impactedNeighbor, | ||
142 | + Set<DeviceId> updatedNeighbors) { | ||
143 | + Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(updatedNeighbors); | ||
144 | + | ||
145 | + Set<DeviceId> tmp = new HashSet<DeviceId>(); | ||
146 | + tmp.addAll(updatedNeighbors); | ||
147 | + tmp.remove(impactedNeighbor); | ||
148 | + Set<Set<DeviceId>> tmpPowerSet = getPowerSetOfNeighbors(tmp); | ||
149 | + | ||
150 | + // Compute the impacted neighbor sets | ||
151 | + powerSet.removeAll(tmpPowerSet); | ||
152 | + | ||
153 | + Set<NeighborSet> nsSet = new HashSet<NeighborSet>(); | ||
154 | + for (Set<DeviceId> combo : powerSet) { | ||
155 | + if (combo.isEmpty()) { | ||
156 | + continue; | ||
157 | + } | ||
158 | + List<Integer> groupSegmentIds = | ||
159 | + getSegmentIdsTobePairedWithNeighborSet(combo); | ||
160 | + for (Integer sId : groupSegmentIds) { | ||
161 | + NeighborSet ns = new NeighborSet(combo, sId); | ||
162 | + log.trace("computeImpactedNeighborsetForPortEvent: sw {} " | ||
163 | + + "combo {} sId {} ns {}", | ||
164 | + deviceId, combo, sId, ns); | ||
165 | + nsSet.add(ns); | ||
166 | + } | ||
167 | + } | ||
168 | + log.trace("computeImpactedNeighborsetForPortEvent: The neighborset " | ||
169 | + + "with label for sw {} is {}", | ||
170 | + deviceId, nsSet); | ||
171 | + return nsSet; | ||
172 | + } | ||
173 | + | ||
174 | +} |
This diff is collapsed. Click to expand it.
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.grouphandler; | ||
17 | + | ||
18 | +import static org.slf4j.LoggerFactory.getLogger; | ||
19 | + | ||
20 | +import java.util.Arrays; | ||
21 | +import java.util.HashMap; | ||
22 | +import java.util.List; | ||
23 | + | ||
24 | +import org.apache.felix.scr.annotations.Activate; | ||
25 | +import org.apache.felix.scr.annotations.Component; | ||
26 | +import org.apache.felix.scr.annotations.Deactivate; | ||
27 | +import org.apache.felix.scr.annotations.Reference; | ||
28 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
29 | +import org.onlab.packet.MacAddress; | ||
30 | +import org.onosproject.core.ApplicationId; | ||
31 | +import org.onosproject.core.CoreService; | ||
32 | +import org.onosproject.net.Device; | ||
33 | +import org.onosproject.net.DeviceId; | ||
34 | +import org.onosproject.net.device.DeviceEvent; | ||
35 | +import org.onosproject.net.device.DeviceListener; | ||
36 | +import org.onosproject.net.device.DeviceService; | ||
37 | +import org.onosproject.net.group.GroupService; | ||
38 | +import org.onosproject.net.link.LinkEvent; | ||
39 | +import org.onosproject.net.link.LinkListener; | ||
40 | +import org.onosproject.net.link.LinkService; | ||
41 | +import org.onosproject.net.topology.TopologyService; | ||
42 | +import org.slf4j.Logger; | ||
43 | + | ||
44 | +/** | ||
45 | + * Sample application to verify group subsystem end to end. | ||
46 | + * This application expects a network of maximum of six connected | ||
47 | + * devices for the test to work. For every device in the network, | ||
48 | + * this test application launches a default group handler function | ||
49 | + * that creates ECMP groups for every neighbor the device is | ||
50 | + * connected to. | ||
51 | + */ | ||
52 | +@Component(immediate = true) | ||
53 | +public class DefaultGroupHandlerApp { | ||
54 | + | ||
55 | + private final Logger log = getLogger(getClass()); | ||
56 | + | ||
57 | + private final DeviceProperties config = new DeviceConfiguration(); | ||
58 | + private ApplicationId appId; | ||
59 | + private HashMap<DeviceId, DefaultGroupHandler> dghMap = | ||
60 | + new HashMap<DeviceId, DefaultGroupHandler>(); | ||
61 | + | ||
62 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
63 | + protected TopologyService topologyService; | ||
64 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
65 | + protected DeviceService deviceService; | ||
66 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
67 | + protected LinkService linkService; | ||
68 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
69 | + protected GroupService groupService; | ||
70 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
71 | + protected CoreService coreService; | ||
72 | + | ||
73 | + private DeviceListener deviceListener = new InternalDeviceListener(); | ||
74 | + private LinkListener linkListener = new InternalLinkListener(); | ||
75 | + | ||
76 | + @Activate | ||
77 | + public void activate() { | ||
78 | + appId = coreService.registerApplication("org.onosproject.defaultgrouphandler"); | ||
79 | + log.info("DefaultGroupHandlerApp Activating"); | ||
80 | + deviceService.addListener(deviceListener); | ||
81 | + linkService.addListener(linkListener); | ||
82 | + for (Device device: deviceService.getDevices()) { | ||
83 | + log.debug("Initiating default group handling for {}", device.id()); | ||
84 | + DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler(device.id(), | ||
85 | + appId, | ||
86 | + config, | ||
87 | + linkService, | ||
88 | + groupService); | ||
89 | + dgh.createGroups(); | ||
90 | + dghMap.put(device.id(), dgh); | ||
91 | + } | ||
92 | + log.info("Activated"); | ||
93 | + } | ||
94 | + | ||
95 | + @Deactivate | ||
96 | + public void deactivate() { | ||
97 | + dghMap.clear(); | ||
98 | + } | ||
99 | + | ||
100 | + public class DeviceConfiguration implements DeviceProperties { | ||
101 | + private final List<Integer> allSegmentIds = | ||
102 | + Arrays.asList(101, 102, 103, 104, 105, 106); | ||
103 | + private HashMap<DeviceId, Integer> deviceSegmentIdMap = | ||
104 | + new HashMap<DeviceId, Integer>() { | ||
105 | + { | ||
106 | + put(DeviceId.deviceId("of:0000000000000001"), 101); | ||
107 | + put(DeviceId.deviceId("of:0000000000000002"), 102); | ||
108 | + put(DeviceId.deviceId("of:0000000000000003"), 103); | ||
109 | + put(DeviceId.deviceId("of:0000000000000004"), 104); | ||
110 | + put(DeviceId.deviceId("of:0000000000000005"), 105); | ||
111 | + put(DeviceId.deviceId("of:0000000000000006"), 106); | ||
112 | + } | ||
113 | + }; | ||
114 | + private final HashMap<DeviceId, MacAddress> deviceMacMap = | ||
115 | + new HashMap<DeviceId, MacAddress>() { | ||
116 | + { | ||
117 | + put(DeviceId.deviceId("of:0000000000000001"), | ||
118 | + MacAddress.valueOf("00:00:00:00:00:01")); | ||
119 | + put(DeviceId.deviceId("of:0000000000000002"), | ||
120 | + MacAddress.valueOf("00:00:00:00:00:02")); | ||
121 | + put(DeviceId.deviceId("of:0000000000000003"), | ||
122 | + MacAddress.valueOf("00:00:00:00:00:03")); | ||
123 | + put(DeviceId.deviceId("of:0000000000000004"), | ||
124 | + MacAddress.valueOf("00:00:00:00:00:04")); | ||
125 | + put(DeviceId.deviceId("of:0000000000000005"), | ||
126 | + MacAddress.valueOf("00:00:00:00:00:05")); | ||
127 | + put(DeviceId.deviceId("of:0000000000000006"), | ||
128 | + MacAddress.valueOf("00:00:00:00:00:06")); | ||
129 | + } | ||
130 | + }; | ||
131 | + | ||
132 | + @Override | ||
133 | + public int getSegmentId(DeviceId deviceId) { | ||
134 | + if (deviceSegmentIdMap.get(deviceId) != null) { | ||
135 | + log.debug("getSegmentId for device{} is {}", | ||
136 | + deviceId, | ||
137 | + deviceSegmentIdMap.get(deviceId)); | ||
138 | + return deviceSegmentIdMap.get(deviceId); | ||
139 | + } else { | ||
140 | + throw new IllegalStateException(); | ||
141 | + } | ||
142 | + } | ||
143 | + @Override | ||
144 | + public MacAddress getDeviceMac(DeviceId deviceId) { | ||
145 | + if (deviceMacMap.get(deviceId) != null) { | ||
146 | + log.debug("getDeviceMac for device{} is {}", | ||
147 | + deviceId, | ||
148 | + deviceMacMap.get(deviceId)); | ||
149 | + return deviceMacMap.get(deviceId); | ||
150 | + } else { | ||
151 | + throw new IllegalStateException(); | ||
152 | + } | ||
153 | + } | ||
154 | + @Override | ||
155 | + public boolean isEdgeDevice(DeviceId deviceId) { | ||
156 | + return true; | ||
157 | + } | ||
158 | + @Override | ||
159 | + public List<Integer> getAllDeviceSegmentIds() { | ||
160 | + return allSegmentIds; | ||
161 | + } | ||
162 | + } | ||
163 | + | ||
164 | + private class InternalDeviceListener implements DeviceListener { | ||
165 | + | ||
166 | + @Override | ||
167 | + public void event(DeviceEvent event) { | ||
168 | + switch (event.type()) { | ||
169 | + case DEVICE_ADDED: | ||
170 | + log.debug("Initiating default group handling for {}", event.subject().id()); | ||
171 | + DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler( | ||
172 | + event.subject().id(), | ||
173 | + appId, | ||
174 | + config, | ||
175 | + linkService, | ||
176 | + groupService); | ||
177 | + dgh.createGroups(); | ||
178 | + dghMap.put(event.subject().id(), dgh); | ||
179 | + break; | ||
180 | + case PORT_REMOVED: | ||
181 | + if (dghMap.get(event.subject().id()) != null) { | ||
182 | + dghMap.get(event.subject().id()).portDown(event.port().number()); | ||
183 | + } | ||
184 | + break; | ||
185 | + default: | ||
186 | + break; | ||
187 | + } | ||
188 | + | ||
189 | + } | ||
190 | + } | ||
191 | + | ||
192 | + private class InternalLinkListener implements LinkListener { | ||
193 | + | ||
194 | + @Override | ||
195 | + public void event(LinkEvent event) { | ||
196 | + switch (event.type()) { | ||
197 | + case LINK_ADDED: | ||
198 | + if (dghMap.get(event.subject().src().deviceId()) != null) { | ||
199 | + dghMap.get(event.subject().src().deviceId()).linkUp(event.subject()); | ||
200 | + } | ||
201 | + break; | ||
202 | + default: | ||
203 | + break; | ||
204 | + } | ||
205 | + } | ||
206 | + | ||
207 | + } | ||
208 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultTransitGroupHandler.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.grouphandler; | ||
17 | + | ||
18 | +import java.util.Arrays; | ||
19 | +import java.util.HashSet; | ||
20 | +import java.util.Set; | ||
21 | + | ||
22 | +import org.onosproject.core.ApplicationId; | ||
23 | +import org.onosproject.net.DeviceId; | ||
24 | +import org.onosproject.net.Link; | ||
25 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
26 | +import org.onosproject.net.flow.TrafficTreatment; | ||
27 | +import org.onosproject.net.group.DefaultGroupBucket; | ||
28 | +import org.onosproject.net.group.GroupBucket; | ||
29 | +import org.onosproject.net.group.GroupBuckets; | ||
30 | +import org.onosproject.net.group.GroupService; | ||
31 | +import org.onosproject.net.link.LinkService; | ||
32 | + | ||
33 | +/** | ||
34 | + * Default ECMP group handler creation module for a transit device. | ||
35 | + * This component creates a set of ECMP groups for every neighbor | ||
36 | + * that this device is connected to. | ||
37 | + * For example, consider a network of 4 devices: D0 (Segment ID: 100), | ||
38 | + * D1 (Segment ID: 101), D2 (Segment ID: 102) and D3 (Segment ID: 103), | ||
39 | + * where D0 and D3 are edge devices and D1 and D2 are transit devices. | ||
40 | + * Assume transit device D1 is connected to 2 neighbors (D0 and D3 ). | ||
41 | + * The following groups will be created in D1: | ||
42 | + * 1) all ports to D0 + with no label push, | ||
43 | + * 2) all ports to D3 + with no label push, | ||
44 | + */ | ||
45 | +public class DefaultTransitGroupHandler extends DefaultGroupHandler { | ||
46 | + | ||
47 | + protected DefaultTransitGroupHandler(DeviceId deviceId, | ||
48 | + ApplicationId appId, | ||
49 | + DeviceProperties config, | ||
50 | + LinkService linkService, | ||
51 | + GroupService groupService) { | ||
52 | + super(deviceId, appId, config, linkService, groupService); | ||
53 | + } | ||
54 | + | ||
55 | + @Override | ||
56 | + public void createGroups() { | ||
57 | + Set<DeviceId> neighbors = devicePortMap.keySet(); | ||
58 | + if (neighbors == null || neighbors.isEmpty()) { | ||
59 | + return; | ||
60 | + } | ||
61 | + | ||
62 | + // Create all possible Neighbor sets from this router | ||
63 | + // NOTE: Avoid any pairings of edge routers only | ||
64 | + Set<Set<DeviceId>> sets = getPowerSetOfNeighbors(neighbors); | ||
65 | + sets = filterEdgeRouterOnlyPairings(sets); | ||
66 | + log.debug("createGroupsAtTransitRouter: The size of neighbor powerset " | ||
67 | + + "for sw {} is {}", deviceId, sets.size()); | ||
68 | + Set<NeighborSet> nsSet = new HashSet<NeighborSet>(); | ||
69 | + for (Set<DeviceId> combo : sets) { | ||
70 | + if (combo.isEmpty()) { | ||
71 | + continue; | ||
72 | + } | ||
73 | + NeighborSet ns = new NeighborSet(combo); | ||
74 | + log.debug("createGroupsAtTransitRouter: sw {} combo {} ns {}", | ||
75 | + deviceId, combo, ns); | ||
76 | + nsSet.add(ns); | ||
77 | + } | ||
78 | + log.debug("createGroupsAtTransitRouter: The neighborset with label " | ||
79 | + + "for sw {} is {}", deviceId, nsSet); | ||
80 | + | ||
81 | + createGroupsFromNeighborsets(nsSet); | ||
82 | + } | ||
83 | + | ||
84 | + @Override | ||
85 | + protected void newNeighbor(Link newNeighborLink) { | ||
86 | + log.debug("New Neighbor: Updating groups for " | ||
87 | + + "transit device {}", deviceId); | ||
88 | + // Recompute neighbor power set | ||
89 | + addNeighborAtPort(newNeighborLink.dst().deviceId(), | ||
90 | + newNeighborLink.src().port()); | ||
91 | + // Compute new neighbor sets due to the addition of new neighbor | ||
92 | + Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent( | ||
93 | + newNeighborLink.dst().deviceId(), | ||
94 | + devicePortMap.keySet()); | ||
95 | + createGroupsFromNeighborsets(nsSet); | ||
96 | + } | ||
97 | + | ||
98 | + @Override | ||
99 | + protected void newPortToExistingNeighbor(Link newNeighborLink) { | ||
100 | + log.debug("New port to existing neighbor: Updating " | ||
101 | + + "groups for transit device {}", deviceId); | ||
102 | + addNeighborAtPort(newNeighborLink.dst().deviceId(), | ||
103 | + newNeighborLink.src().port()); | ||
104 | + Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent( | ||
105 | + newNeighborLink.dst().deviceId(), | ||
106 | + devicePortMap.keySet()); | ||
107 | + for (NeighborSet ns : nsSet) { | ||
108 | + // Create the new bucket to be updated | ||
109 | + TrafficTreatment.Builder tBuilder = | ||
110 | + DefaultTrafficTreatment.builder(); | ||
111 | + tBuilder.setOutput(newNeighborLink.src().port()) | ||
112 | + .setEthDst(deviceConfig.getDeviceMac( | ||
113 | + newNeighborLink.dst().deviceId())) | ||
114 | + .setEthSrc(nodeMacAddr) | ||
115 | + .pushMpls() | ||
116 | + .setMpls(ns.getEdgeLabel()); | ||
117 | + GroupBucket updatedBucket = DefaultGroupBucket. | ||
118 | + createSelectGroupBucket(tBuilder.build()); | ||
119 | + GroupBuckets updatedBuckets = new GroupBuckets( | ||
120 | + Arrays.asList(updatedBucket)); | ||
121 | + log.debug("newPortToExistingNeighborAtEdgeRouter: " | ||
122 | + + "groupService.addBucketsToGroup for neighborset{}", ns); | ||
123 | + groupService.addBucketsToGroup(deviceId, ns, updatedBuckets, ns, appId); | ||
124 | + } | ||
125 | + } | ||
126 | + | ||
127 | + @Override | ||
128 | + protected Set<NeighborSet> computeImpactedNeighborsetForPortEvent( | ||
129 | + DeviceId impactedNeighbor, | ||
130 | + Set<DeviceId> updatedNeighbors) { | ||
131 | + Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(updatedNeighbors); | ||
132 | + | ||
133 | + Set<DeviceId> tmp = updatedNeighbors; | ||
134 | + tmp.remove(impactedNeighbor); | ||
135 | + Set<Set<DeviceId>> tmpPowerSet = getPowerSetOfNeighbors(tmp); | ||
136 | + | ||
137 | + // Compute the impacted neighbor sets | ||
138 | + powerSet.removeAll(tmpPowerSet); | ||
139 | + | ||
140 | + powerSet = filterEdgeRouterOnlyPairings(powerSet); | ||
141 | + Set<NeighborSet> nsSet = new HashSet<NeighborSet>(); | ||
142 | + for (Set<DeviceId> combo : powerSet) { | ||
143 | + if (combo.isEmpty()) { | ||
144 | + continue; | ||
145 | + } | ||
146 | + NeighborSet ns = new NeighborSet(combo); | ||
147 | + log.debug("createGroupsAtTransitRouter: sw {} combo {} ns {}", | ||
148 | + deviceId, combo, ns); | ||
149 | + nsSet.add(ns); | ||
150 | + } | ||
151 | + log.debug("computeImpactedNeighborsetForPortEvent: The neighborset with label " | ||
152 | + + "for sw {} is {}", deviceId, nsSet); | ||
153 | + | ||
154 | + return nsSet; | ||
155 | + } | ||
156 | + | ||
157 | + private Set<Set<DeviceId>> filterEdgeRouterOnlyPairings(Set<Set<DeviceId>> sets) { | ||
158 | + Set<Set<DeviceId>> fiteredSets = new HashSet<Set<DeviceId>>(); | ||
159 | + for (Set<DeviceId> deviceSubSet : sets) { | ||
160 | + if (deviceSubSet.size() > 1) { | ||
161 | + boolean avoidEdgeRouterPairing = true; | ||
162 | + for (DeviceId device : deviceSubSet) { | ||
163 | + if (!deviceConfig.isEdgeDevice(device)) { | ||
164 | + avoidEdgeRouterPairing = false; | ||
165 | + break; | ||
166 | + } | ||
167 | + } | ||
168 | + if (!avoidEdgeRouterPairing) { | ||
169 | + fiteredSets.add(deviceSubSet); | ||
170 | + } | ||
171 | + } else { | ||
172 | + fiteredSets.add(deviceSubSet); | ||
173 | + } | ||
174 | + } | ||
175 | + return fiteredSets; | ||
176 | + } | ||
177 | +} |
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.grouphandler; | ||
17 | + | ||
18 | +import java.util.List; | ||
19 | + | ||
20 | +import org.onlab.packet.MacAddress; | ||
21 | +import org.onosproject.net.DeviceId; | ||
22 | + | ||
23 | +/** | ||
24 | + * Mechanism through which group handler module retrieves | ||
25 | + * the device specific attributes such as segment ID, | ||
26 | + * Mac address...etc from group handler applications. | ||
27 | + */ | ||
28 | +public interface DeviceProperties { | ||
29 | + /** | ||
30 | + * Returns the segment id of a device to be used in group creation. | ||
31 | + * | ||
32 | + * @param deviceId device identifier | ||
33 | + * @return segment id of a device | ||
34 | + */ | ||
35 | + int getSegmentId(DeviceId deviceId); | ||
36 | + /** | ||
37 | + * Returns the Mac address of a device to be used in group creation. | ||
38 | + * | ||
39 | + * @param deviceId device identifier | ||
40 | + * @return mac address of a device | ||
41 | + */ | ||
42 | + MacAddress getDeviceMac(DeviceId deviceId); | ||
43 | + /** | ||
44 | + * Indicates whether a device is edge device or transit/core device. | ||
45 | + * | ||
46 | + * @param deviceId device identifier | ||
47 | + * @return boolean | ||
48 | + */ | ||
49 | + boolean isEdgeDevice(DeviceId deviceId); | ||
50 | + /** | ||
51 | + * Returns all segment IDs to be considered in building auto | ||
52 | + * | ||
53 | + * created groups. | ||
54 | + * @return list of segment IDs | ||
55 | + */ | ||
56 | + List<Integer> getAllDeviceSegmentIds(); | ||
57 | +} |
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.grouphandler; | ||
17 | + | ||
18 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
19 | + | ||
20 | +import org.onosproject.net.PortNumber; | ||
21 | +import org.onosproject.net.group.GroupKey; | ||
22 | + | ||
23 | +/** | ||
24 | + * Representation of policy group bucket identifier. Not exposed to | ||
25 | + * the application and only to be used internally. | ||
26 | + */ | ||
27 | +public class GroupBucketIdentifier { | ||
28 | + private int label; | ||
29 | + private BucketOutputType type; | ||
30 | + private PortNumber outPort; | ||
31 | + private GroupKey outGroup; | ||
32 | + | ||
33 | + protected enum BucketOutputType { | ||
34 | + PORT, | ||
35 | + GROUP | ||
36 | + } | ||
37 | + | ||
38 | + protected GroupBucketIdentifier(int label, | ||
39 | + PortNumber outPort) { | ||
40 | + this.label = label; | ||
41 | + this.type = BucketOutputType.PORT; | ||
42 | + this.outPort = checkNotNull(outPort); | ||
43 | + this.outGroup = null; | ||
44 | + } | ||
45 | + | ||
46 | + protected GroupBucketIdentifier(int label, | ||
47 | + GroupKey outGroup) { | ||
48 | + this.label = label; | ||
49 | + this.type = BucketOutputType.GROUP; | ||
50 | + this.outPort = null; | ||
51 | + this.outGroup = checkNotNull(outGroup); | ||
52 | + } | ||
53 | + | ||
54 | + protected int label() { | ||
55 | + return this.label; | ||
56 | + } | ||
57 | + | ||
58 | + protected BucketOutputType type() { | ||
59 | + return this.type; | ||
60 | + } | ||
61 | + | ||
62 | + protected PortNumber outPort() { | ||
63 | + return this.outPort; | ||
64 | + } | ||
65 | + | ||
66 | + protected GroupKey outGroup() { | ||
67 | + return this.outGroup; | ||
68 | + } | ||
69 | +} | ||
70 | + |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.grouphandler; | ||
18 | + | ||
19 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
20 | + | ||
21 | +import java.util.HashSet; | ||
22 | +import java.util.Objects; | ||
23 | +import java.util.Set; | ||
24 | + | ||
25 | +import org.onosproject.net.DeviceId; | ||
26 | +import org.onosproject.net.group.GroupKey; | ||
27 | + | ||
28 | +/** | ||
29 | + * Representation of a set of neighbor switch dpids along with edge node | ||
30 | + * label. Meant to be used as a lookup-key in a hash-map to retrieve an | ||
31 | + * ECMP-group that hashes packets to a set of ports connecting to the | ||
32 | + * neighbors in this set. | ||
33 | + */ | ||
34 | +public class NeighborSet implements GroupKey { | ||
35 | + private final Set<DeviceId> neighbors; | ||
36 | + private final int edgeLabel; | ||
37 | + | ||
38 | + /** | ||
39 | + * Constructor with set of neighbors. Edge label is | ||
40 | + * default to -1. | ||
41 | + * | ||
42 | + * @param neighbors set of neighbors to be part of neighbor set | ||
43 | + */ | ||
44 | + public NeighborSet(Set<DeviceId> neighbors) { | ||
45 | + checkNotNull(neighbors); | ||
46 | + this.edgeLabel = -1; | ||
47 | + this.neighbors = new HashSet<DeviceId>(); | ||
48 | + this.neighbors.addAll(neighbors); | ||
49 | + } | ||
50 | + | ||
51 | + /** | ||
52 | + * Constructor with set of neighbors and edge label. | ||
53 | + * | ||
54 | + * @param neighbors set of neighbors to be part of neighbor set | ||
55 | + * @param edgeLabel label to be pushed as part of group operation | ||
56 | + */ | ||
57 | + public NeighborSet(Set<DeviceId> neighbors, int edgeLabel) { | ||
58 | + checkNotNull(neighbors); | ||
59 | + this.edgeLabel = edgeLabel; | ||
60 | + this.neighbors = new HashSet<DeviceId>(); | ||
61 | + this.neighbors.addAll(neighbors); | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * Default constructor for kryo serialization. | ||
66 | + */ | ||
67 | + public NeighborSet() { | ||
68 | + this.edgeLabel = -1; | ||
69 | + this.neighbors = new HashSet<DeviceId>(); | ||
70 | + } | ||
71 | + | ||
72 | + /** | ||
73 | + * Gets the neighbors part of neighbor set. | ||
74 | + * | ||
75 | + * @return set of neighbor identifiers | ||
76 | + */ | ||
77 | + public Set<DeviceId> getDeviceIds() { | ||
78 | + return neighbors; | ||
79 | + } | ||
80 | + | ||
81 | + /** | ||
82 | + * Gets the label associated with neighbor set. | ||
83 | + * | ||
84 | + * @return integer | ||
85 | + */ | ||
86 | + public int getEdgeLabel() { | ||
87 | + return edgeLabel; | ||
88 | + } | ||
89 | + | ||
90 | + // The list of neighbor ids and label are used for comparison. | ||
91 | + @Override | ||
92 | + public boolean equals(Object o) { | ||
93 | + if (this == o) { | ||
94 | + return true; | ||
95 | + } | ||
96 | + if (!(o instanceof NeighborSet)) { | ||
97 | + return false; | ||
98 | + } | ||
99 | + NeighborSet that = (NeighborSet) o; | ||
100 | + return (this.neighbors.containsAll(that.neighbors) && | ||
101 | + that.neighbors.containsAll(this.neighbors) && | ||
102 | + (this.edgeLabel == that.edgeLabel)); | ||
103 | + } | ||
104 | + | ||
105 | + // The list of neighbor ids and label are used for comparison. | ||
106 | + @Override | ||
107 | + public int hashCode() { | ||
108 | + int result = 17; | ||
109 | + int combinedHash = 0; | ||
110 | + for (DeviceId d : neighbors) { | ||
111 | + combinedHash = combinedHash + Objects.hash(d); | ||
112 | + } | ||
113 | + result = 31 * result + combinedHash + Objects.hash(edgeLabel); | ||
114 | + | ||
115 | + return result; | ||
116 | + } | ||
117 | + | ||
118 | + @Override | ||
119 | + public String toString() { | ||
120 | + return " Neighborset Sw: " + neighbors | ||
121 | + + " and Label: " + edgeLabel; | ||
122 | + } | ||
123 | +} |
This diff is collapsed. Click to expand it.
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.grouphandler; | ||
17 | + | ||
18 | +import java.util.List; | ||
19 | + | ||
20 | +import org.onosproject.net.group.GroupKey; | ||
21 | + | ||
22 | +/** | ||
23 | + * Representation of policy based group identifiers. | ||
24 | + * Opaque to group handler applications and only the outermost | ||
25 | + * policy group identifier in a chain is visible to the applications. | ||
26 | + */ | ||
27 | +public class PolicyGroupIdentifier implements GroupKey { | ||
28 | + private String id; | ||
29 | + private List<PolicyGroupParams> inputParams; | ||
30 | + private List<GroupBucketIdentifier> bucketIds; | ||
31 | + | ||
32 | + /** | ||
33 | + * Constructor. | ||
34 | + * | ||
35 | + * @param id unique identifier associated with the policy group | ||
36 | + * @param input policy group params associated with this group | ||
37 | + * @param bucketIds buckets associated with this group | ||
38 | + */ | ||
39 | + protected PolicyGroupIdentifier(String id, | ||
40 | + List<PolicyGroupParams> input, | ||
41 | + List<GroupBucketIdentifier> bucketIds) { | ||
42 | + this.id = id; | ||
43 | + this.inputParams = input; | ||
44 | + this.bucketIds = bucketIds; | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Returns the bucket identifier list associated with the policy | ||
49 | + * group identifier. | ||
50 | + * | ||
51 | + * @return list of bucket identifier | ||
52 | + */ | ||
53 | + protected List<GroupBucketIdentifier> bucketIds() { | ||
54 | + return this.bucketIds; | ||
55 | + } | ||
56 | + | ||
57 | + @Override | ||
58 | + public int hashCode() { | ||
59 | + int result = 17; | ||
60 | + int combinedHash = 0; | ||
61 | + for (PolicyGroupParams input:inputParams) { | ||
62 | + combinedHash = combinedHash + input.hashCode(); | ||
63 | + } | ||
64 | + for (GroupBucketIdentifier bucketId:bucketIds) { | ||
65 | + combinedHash = combinedHash + bucketId.hashCode(); | ||
66 | + } | ||
67 | + result = 31 * result + combinedHash; | ||
68 | + | ||
69 | + return result; | ||
70 | + } | ||
71 | + | ||
72 | + @Override | ||
73 | + public boolean equals(Object obj) { | ||
74 | + if (this == obj) { | ||
75 | + return true; | ||
76 | + } | ||
77 | + | ||
78 | + if (obj instanceof PolicyGroupIdentifier) { | ||
79 | + PolicyGroupIdentifier that = (PolicyGroupIdentifier) obj; | ||
80 | + boolean result = this.id.equals(that.id); | ||
81 | + result = result && | ||
82 | + this.inputParams.containsAll(that.inputParams) && | ||
83 | + that.inputParams.containsAll(this.inputParams); | ||
84 | + result = result && | ||
85 | + this.bucketIds.containsAll(that.bucketIds) && | ||
86 | + that.bucketIds.containsAll(this.bucketIds); | ||
87 | + return result; | ||
88 | + } | ||
89 | + | ||
90 | + return false; | ||
91 | + } | ||
92 | +} |
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.grouphandler; | ||
17 | + | ||
18 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
19 | + | ||
20 | +import java.util.List; | ||
21 | +import java.util.Objects; | ||
22 | + | ||
23 | +import org.onosproject.net.PortNumber; | ||
24 | + | ||
25 | +/** | ||
26 | + * Representation of parameters used to create policy based groups. | ||
27 | + */ | ||
28 | +public class PolicyGroupParams { | ||
29 | + private final List<PortNumber> ports; | ||
30 | + private final List<Integer> labelStack; | ||
31 | + | ||
32 | + /** | ||
33 | + * Constructor. | ||
34 | + * | ||
35 | + * @param labelStack mpls label stack to be applied on the ports | ||
36 | + * @param ports ports to be part of the policy group | ||
37 | + */ | ||
38 | + public PolicyGroupParams(List<Integer> labelStack, | ||
39 | + List<PortNumber> ports) { | ||
40 | + this.ports = checkNotNull(ports); | ||
41 | + this.labelStack = checkNotNull(labelStack); | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Returns the ports associated with the policy group params. | ||
46 | + * | ||
47 | + * @return list of port numbers | ||
48 | + */ | ||
49 | + public List<PortNumber> getPorts() { | ||
50 | + return ports; | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * Returns the label stack associated with the policy group params. | ||
55 | + * | ||
56 | + * @return list of integers | ||
57 | + */ | ||
58 | + public List<Integer> getLabelStack() { | ||
59 | + return labelStack; | ||
60 | + } | ||
61 | + | ||
62 | + @Override | ||
63 | + public int hashCode() { | ||
64 | + int result = 17; | ||
65 | + int combinedHash = 0; | ||
66 | + for (PortNumber port:ports) { | ||
67 | + combinedHash = combinedHash + port.hashCode(); | ||
68 | + } | ||
69 | + combinedHash = combinedHash + Objects.hash(labelStack); | ||
70 | + result = 31 * result + combinedHash; | ||
71 | + | ||
72 | + return result; | ||
73 | + } | ||
74 | + | ||
75 | + @Override | ||
76 | + public boolean equals(Object obj) { | ||
77 | + if (this == obj) { | ||
78 | + return true; | ||
79 | + } | ||
80 | + | ||
81 | + if (obj instanceof PolicyGroupParams) { | ||
82 | + PolicyGroupParams that = (PolicyGroupParams) obj; | ||
83 | + boolean result = this.labelStack.equals(that.labelStack); | ||
84 | + result = result && | ||
85 | + this.ports.containsAll(that.ports) && | ||
86 | + that.ports.containsAll(this.ports); | ||
87 | + return result; | ||
88 | + } | ||
89 | + | ||
90 | + return false; | ||
91 | + } | ||
92 | +} |
... | @@ -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 static com.google.common.base.MoreObjects.toStringHelper; | ||
18 | import static org.slf4j.LoggerFactory.getLogger; | 19 | import static org.slf4j.LoggerFactory.getLogger; |
19 | 20 | ||
20 | import java.util.Objects; | 21 | import java.util.Objects; |
... | @@ -205,4 +206,13 @@ public class DefaultGroup extends DefaultGroupDescription | ... | @@ -205,4 +206,13 @@ public class DefaultGroup extends DefaultGroupDescription |
205 | } | 206 | } |
206 | return false; | 207 | return false; |
207 | } | 208 | } |
209 | + | ||
210 | + @Override | ||
211 | + public String toString() { | ||
212 | + return toStringHelper(this) | ||
213 | + .add("description", super.toString()) | ||
214 | + .add("groupid", id) | ||
215 | + .add("state", state) | ||
216 | + .toString(); | ||
217 | + } | ||
208 | } | 218 | } | ... | ... |
... | @@ -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 static com.google.common.base.MoreObjects.toStringHelper; | ||
18 | import static com.google.common.base.Preconditions.checkArgument; | 19 | import static com.google.common.base.Preconditions.checkArgument; |
19 | import static com.google.common.base.Preconditions.checkNotNull; | 20 | import static com.google.common.base.Preconditions.checkNotNull; |
20 | 21 | ||
... | @@ -212,4 +213,11 @@ public final class DefaultGroupBucket implements GroupBucket { | ... | @@ -212,4 +213,11 @@ public final class DefaultGroupBucket implements GroupBucket { |
212 | return false; | 213 | return false; |
213 | } | 214 | } |
214 | 215 | ||
216 | + @Override | ||
217 | + public String toString() { | ||
218 | + return toStringHelper(this) | ||
219 | + .add("type", type) | ||
220 | + .add("treatment", treatment) | ||
221 | + .toString(); | ||
222 | + } | ||
215 | } | 223 | } | ... | ... |
... | @@ -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 static com.google.common.base.MoreObjects.toStringHelper; | ||
18 | import static com.google.common.base.Preconditions.checkNotNull; | 19 | import static com.google.common.base.Preconditions.checkNotNull; |
19 | 20 | ||
20 | import java.util.Objects; | 21 | import java.util.Objects; |
... | @@ -168,4 +169,13 @@ public class DefaultGroupDescription implements GroupDescription { | ... | @@ -168,4 +169,13 @@ public class DefaultGroupDescription implements GroupDescription { |
168 | return false; | 169 | return false; |
169 | } | 170 | } |
170 | 171 | ||
172 | + @Override | ||
173 | + public String toString() { | ||
174 | + return toStringHelper(this) | ||
175 | + .add("deviceId", deviceId) | ||
176 | + .add("type", type) | ||
177 | + .add("buckets", buckets) | ||
178 | + .add("appId", appId) | ||
179 | + .toString(); | ||
180 | + } | ||
171 | } | 181 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -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 static com.google.common.base.MoreObjects.toStringHelper; | ||
18 | import static com.google.common.base.Preconditions.checkNotNull; | 19 | import static com.google.common.base.Preconditions.checkNotNull; |
19 | 20 | ||
20 | import java.util.List; | 21 | import java.util.List; |
... | @@ -66,4 +67,10 @@ public final class GroupBuckets { | ... | @@ -66,4 +67,10 @@ public final class GroupBuckets { |
66 | return false; | 67 | return false; |
67 | } | 68 | } |
68 | 69 | ||
70 | + @Override | ||
71 | + public String toString() { | ||
72 | + return toStringHelper(this) | ||
73 | + .add("buckets", buckets) | ||
74 | + .toString(); | ||
75 | + } | ||
69 | } | 76 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -132,8 +132,9 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> { | ... | @@ -132,8 +132,9 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> { |
132 | * Indicates the first group audit is completed. | 132 | * Indicates the first group audit is completed. |
133 | * | 133 | * |
134 | * @param deviceId the device ID | 134 | * @param deviceId the device ID |
135 | + * @param completed initial audit status | ||
135 | */ | 136 | */ |
136 | - void deviceInitialAuditCompleted(DeviceId deviceId); | 137 | + void deviceInitialAuditCompleted(DeviceId deviceId, boolean completed); |
137 | 138 | ||
138 | /** | 139 | /** |
139 | * Retrieves the initial group audit status for a device. | 140 | * Retrieves the initial group audit status for a device. | ... | ... |
... | @@ -32,6 +32,9 @@ import org.onosproject.core.ApplicationId; | ... | @@ -32,6 +32,9 @@ import org.onosproject.core.ApplicationId; |
32 | import org.onosproject.event.AbstractListenerRegistry; | 32 | import org.onosproject.event.AbstractListenerRegistry; |
33 | import org.onosproject.event.EventDeliveryService; | 33 | import org.onosproject.event.EventDeliveryService; |
34 | import org.onosproject.net.DeviceId; | 34 | import org.onosproject.net.DeviceId; |
35 | +import org.onosproject.net.device.DeviceEvent; | ||
36 | +import org.onosproject.net.device.DeviceListener; | ||
37 | +import org.onosproject.net.device.DeviceService; | ||
35 | import org.onosproject.net.group.Group; | 38 | import org.onosproject.net.group.Group; |
36 | import org.onosproject.net.group.GroupBuckets; | 39 | import org.onosproject.net.group.GroupBuckets; |
37 | import org.onosproject.net.group.GroupDescription; | 40 | import org.onosproject.net.group.GroupDescription; |
... | @@ -67,17 +70,22 @@ public class GroupManager | ... | @@ -67,17 +70,22 @@ public class GroupManager |
67 | private final AbstractListenerRegistry<GroupEvent, GroupListener> | 70 | private final AbstractListenerRegistry<GroupEvent, GroupListener> |
68 | listenerRegistry = new AbstractListenerRegistry<>(); | 71 | listenerRegistry = new AbstractListenerRegistry<>(); |
69 | private final GroupStoreDelegate delegate = new InternalGroupStoreDelegate(); | 72 | private final GroupStoreDelegate delegate = new InternalGroupStoreDelegate(); |
73 | + private final DeviceListener deviceListener = new InternalDeviceListener(); | ||
70 | 74 | ||
71 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 75 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
72 | protected GroupStore store; | 76 | protected GroupStore store; |
73 | 77 | ||
74 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 78 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
79 | + protected DeviceService deviceService; | ||
80 | + | ||
81 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
75 | protected EventDeliveryService eventDispatcher; | 82 | protected EventDeliveryService eventDispatcher; |
76 | 83 | ||
77 | @Activate | 84 | @Activate |
78 | public void activate() { | 85 | public void activate() { |
79 | store.setDelegate(delegate); | 86 | store.setDelegate(delegate); |
80 | eventDispatcher.addSink(GroupEvent.class, listenerRegistry); | 87 | eventDispatcher.addSink(GroupEvent.class, listenerRegistry); |
88 | + deviceService.addListener(deviceListener); | ||
81 | log.info("Started"); | 89 | log.info("Started"); |
82 | } | 90 | } |
83 | 91 | ||
... | @@ -232,6 +240,8 @@ public class GroupManager | ... | @@ -232,6 +240,8 @@ public class GroupManager |
232 | GroupOperations groupOps = null; | 240 | GroupOperations groupOps = null; |
233 | switch (event.type()) { | 241 | switch (event.type()) { |
234 | case GROUP_ADD_REQUESTED: | 242 | case GROUP_ADD_REQUESTED: |
243 | + log.debug("GROUP_ADD_REQUESTED for Group {} on device {}", | ||
244 | + group.id(), group.deviceId()); | ||
235 | GroupOperation groupAddOp = GroupOperation. | 245 | GroupOperation groupAddOp = GroupOperation. |
236 | createAddGroupOperation(group.id(), | 246 | createAddGroupOperation(group.id(), |
237 | group.type(), | 247 | group.type(), |
... | @@ -242,6 +252,8 @@ public class GroupManager | ... | @@ -242,6 +252,8 @@ public class GroupManager |
242 | break; | 252 | break; |
243 | 253 | ||
244 | case GROUP_UPDATE_REQUESTED: | 254 | case GROUP_UPDATE_REQUESTED: |
255 | + log.debug("GROUP_UPDATE_REQUESTED for Group {} on device {}", | ||
256 | + group.id(), group.deviceId()); | ||
245 | GroupOperation groupModifyOp = GroupOperation. | 257 | GroupOperation groupModifyOp = GroupOperation. |
246 | createModifyGroupOperation(group.id(), | 258 | createModifyGroupOperation(group.id(), |
247 | group.type(), | 259 | group.type(), |
... | @@ -252,6 +264,8 @@ public class GroupManager | ... | @@ -252,6 +264,8 @@ public class GroupManager |
252 | break; | 264 | break; |
253 | 265 | ||
254 | case GROUP_REMOVE_REQUESTED: | 266 | case GROUP_REMOVE_REQUESTED: |
267 | + log.debug("GROUP_REMOVE_REQUESTED for Group {} on device {}", | ||
268 | + group.id(), group.deviceId()); | ||
255 | GroupOperation groupDeleteOp = GroupOperation. | 269 | GroupOperation groupDeleteOp = GroupOperation. |
256 | createDeleteGroupOperation(group.id(), | 270 | createDeleteGroupOperation(group.id(), |
257 | group.type()); | 271 | group.type()); |
... | @@ -294,10 +308,14 @@ public class GroupManager | ... | @@ -294,10 +308,14 @@ public class GroupManager |
294 | GroupProvider gp = getProvider(group.deviceId()); | 308 | GroupProvider gp = getProvider(group.deviceId()); |
295 | switch (group.state()) { | 309 | switch (group.state()) { |
296 | case PENDING_DELETE: | 310 | case PENDING_DELETE: |
311 | + log.debug("Group {} delete confirmation from device {}", | ||
312 | + group, group.deviceId()); | ||
297 | store.removeGroupEntry(group); | 313 | store.removeGroupEntry(group); |
298 | break; | 314 | break; |
299 | case ADDED: | 315 | case ADDED: |
300 | case PENDING_ADD: | 316 | case PENDING_ADD: |
317 | + log.debug("Group {} is in store but not on device {}", | ||
318 | + group, group.deviceId()); | ||
301 | GroupOperation groupAddOp = GroupOperation. | 319 | GroupOperation groupAddOp = GroupOperation. |
302 | createAddGroupOperation(group.id(), | 320 | createAddGroupOperation(group.id(), |
303 | group.type(), | 321 | group.type(), |
... | @@ -314,7 +332,8 @@ public class GroupManager | ... | @@ -314,7 +332,8 @@ public class GroupManager |
314 | 332 | ||
315 | 333 | ||
316 | private void extraneousGroup(Group group) { | 334 | private void extraneousGroup(Group group) { |
317 | - log.debug("Group {} is on switch but not in store.", group); | 335 | + log.debug("Group {} is on device {} but not in store.", |
336 | + group, group.deviceId()); | ||
318 | checkValidity(); | 337 | checkValidity(); |
319 | store.addOrUpdateExtraneousGroupEntry(group); | 338 | store.addOrUpdateExtraneousGroupEntry(group); |
320 | } | 339 | } |
... | @@ -322,13 +341,16 @@ public class GroupManager | ... | @@ -322,13 +341,16 @@ public class GroupManager |
322 | private void groupAdded(Group group) { | 341 | private void groupAdded(Group group) { |
323 | checkValidity(); | 342 | checkValidity(); |
324 | 343 | ||
325 | - log.trace("Group {}", group); | 344 | + log.trace("Group {} Added or Updated in device {}", |
345 | + group, group.deviceId()); | ||
326 | store.addOrUpdateGroupEntry(group); | 346 | store.addOrUpdateGroupEntry(group); |
327 | } | 347 | } |
328 | 348 | ||
329 | @Override | 349 | @Override |
330 | public void pushGroupMetrics(DeviceId deviceId, | 350 | public void pushGroupMetrics(DeviceId deviceId, |
331 | Collection<Group> groupEntries) { | 351 | Collection<Group> groupEntries) { |
352 | + log.trace("Received group metrics from device {}", | ||
353 | + deviceId); | ||
332 | boolean deviceInitialAuditStatus = | 354 | boolean deviceInitialAuditStatus = |
333 | store.deviceInitialAuditStatus(deviceId); | 355 | store.deviceInitialAuditStatus(deviceId); |
334 | Set<Group> southboundGroupEntries = | 356 | Set<Group> southboundGroupEntries = |
... | @@ -338,31 +360,75 @@ public class GroupManager | ... | @@ -338,31 +360,75 @@ public class GroupManager |
338 | Set<Group> extraneousStoredEntries = | 360 | Set<Group> extraneousStoredEntries = |
339 | Sets.newHashSet(store.getExtraneousGroups(deviceId)); | 361 | Sets.newHashSet(store.getExtraneousGroups(deviceId)); |
340 | 362 | ||
363 | + log.trace("Displaying all southboundGroupEntries for device {}", deviceId); | ||
364 | + for (Iterator<Group> it = southboundGroupEntries.iterator(); it.hasNext();) { | ||
365 | + Group group = it.next(); | ||
366 | + log.trace("Group {} in device {}", group, deviceId); | ||
367 | + } | ||
368 | + | ||
369 | + log.trace("Displaying all stored group entries for device {}", deviceId); | ||
370 | + for (Iterator<Group> it = storedGroupEntries.iterator(); it.hasNext();) { | ||
371 | + Group group = it.next(); | ||
372 | + log.trace("Stored Group {} for device {}", group, deviceId); | ||
373 | + } | ||
374 | + | ||
341 | for (Iterator<Group> it = southboundGroupEntries.iterator(); it.hasNext();) { | 375 | for (Iterator<Group> it = southboundGroupEntries.iterator(); it.hasNext();) { |
342 | Group group = it.next(); | 376 | Group group = it.next(); |
343 | if (storedGroupEntries.remove(group)) { | 377 | if (storedGroupEntries.remove(group)) { |
344 | // we both have the group, let's update some info then. | 378 | // we both have the group, let's update some info then. |
379 | + log.trace("Group AUDIT: group {} exists " | ||
380 | + + "in both planes for device {}", | ||
381 | + group.id(), deviceId); | ||
345 | groupAdded(group); | 382 | groupAdded(group); |
346 | it.remove(); | 383 | it.remove(); |
347 | } | 384 | } |
348 | } | 385 | } |
349 | for (Group group : southboundGroupEntries) { | 386 | for (Group group : southboundGroupEntries) { |
350 | // there are groups in the switch that aren't in the store | 387 | // there are groups in the switch that aren't in the store |
388 | + log.trace("Group AUDIT: extraneous group {} exists " | ||
389 | + + "in data plane for device {}", | ||
390 | + group.id(), deviceId); | ||
351 | extraneousStoredEntries.remove(group); | 391 | extraneousStoredEntries.remove(group); |
352 | extraneousGroup(group); | 392 | extraneousGroup(group); |
353 | } | 393 | } |
354 | for (Group group : storedGroupEntries) { | 394 | for (Group group : storedGroupEntries) { |
355 | // there are groups in the store that aren't in the switch | 395 | // there are groups in the store that aren't in the switch |
396 | + log.trace("Group AUDIT: group {} missing " | ||
397 | + + "in data plane for device {}", | ||
398 | + group.id(), deviceId); | ||
356 | groupMissing(group); | 399 | groupMissing(group); |
357 | } | 400 | } |
358 | for (Group group : extraneousStoredEntries) { | 401 | for (Group group : extraneousStoredEntries) { |
359 | // there are groups in the extraneous store that | 402 | // there are groups in the extraneous store that |
360 | // aren't in the switch | 403 | // aren't in the switch |
404 | + log.trace("Group AUDIT: clearing extransoeus group {} " | ||
405 | + + "from store for device {}", | ||
406 | + group.id(), deviceId); | ||
361 | store.removeExtraneousGroupEntry(group); | 407 | store.removeExtraneousGroupEntry(group); |
362 | } | 408 | } |
363 | 409 | ||
364 | if (!deviceInitialAuditStatus) { | 410 | if (!deviceInitialAuditStatus) { |
365 | - store.deviceInitialAuditCompleted(deviceId); | 411 | + log.debug("Group AUDIT: Setting device {} initial " |
412 | + + "AUDIT completed", deviceId); | ||
413 | + store.deviceInitialAuditCompleted(deviceId, true); | ||
414 | + } | ||
415 | + } | ||
416 | + } | ||
417 | + | ||
418 | + private class InternalDeviceListener implements DeviceListener { | ||
419 | + | ||
420 | + @Override | ||
421 | + public void event(DeviceEvent event) { | ||
422 | + switch (event.type()) { | ||
423 | + case DEVICE_REMOVED: | ||
424 | + log.debug("Clearing device {} initial " | ||
425 | + + "AUDIT completed status as device is going down", | ||
426 | + event.subject().id()); | ||
427 | + store.deviceInitialAuditCompleted(event.subject().id(), false); | ||
428 | + break; | ||
429 | + | ||
430 | + default: | ||
431 | + break; | ||
366 | } | 432 | } |
367 | } | 433 | } |
368 | } | 434 | } | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -261,6 +261,11 @@ public class SimpleGroupStore | ... | @@ -261,6 +261,11 @@ public class SimpleGroupStore |
261 | } | 261 | } |
262 | 262 | ||
263 | private void storeGroupDescriptionInternal(GroupDescription groupDesc) { | 263 | private void storeGroupDescriptionInternal(GroupDescription groupDesc) { |
264 | + // Check if a group is existing with the same key | ||
265 | + if (getGroup(groupDesc.deviceId(), groupDesc.appCookie()) != null) { | ||
266 | + return; | ||
267 | + } | ||
268 | + | ||
264 | // Get a new group identifier | 269 | // Get a new group identifier |
265 | GroupId id = new DefaultGroupId(getFreeGroupIdValue(groupDesc.deviceId())); | 270 | GroupId id = new DefaultGroupId(getFreeGroupIdValue(groupDesc.deviceId())); |
266 | // Create a group entry object | 271 | // Create a group entry object |
... | @@ -448,29 +453,41 @@ public class SimpleGroupStore | ... | @@ -448,29 +453,41 @@ public class SimpleGroupStore |
448 | } | 453 | } |
449 | 454 | ||
450 | @Override | 455 | @Override |
451 | - public void deviceInitialAuditCompleted(DeviceId deviceId) { | 456 | + public void deviceInitialAuditCompleted(DeviceId deviceId, |
457 | + boolean completed) { | ||
452 | synchronized (deviceAuditStatus) { | 458 | synchronized (deviceAuditStatus) { |
453 | - deviceAuditStatus.putIfAbsent(deviceId, true); | 459 | + if (completed) { |
454 | - // Execute all pending group requests | 460 | + log.debug("deviceInitialAuditCompleted: AUDIT " |
455 | - ConcurrentMap<GroupKey, StoredGroupEntry> pendingGroupRequests = | 461 | + + "completed for device {}", deviceId); |
456 | - getPendingGroupKeyTable(deviceId); | 462 | + deviceAuditStatus.put(deviceId, true); |
457 | - for (Group group:pendingGroupRequests.values()) { | 463 | + // Execute all pending group requests |
458 | - GroupDescription tmp = new DefaultGroupDescription( | 464 | + ConcurrentMap<GroupKey, StoredGroupEntry> pendingGroupRequests = |
459 | - group.deviceId(), | 465 | + getPendingGroupKeyTable(deviceId); |
460 | - group.type(), | 466 | + for (Group group:pendingGroupRequests.values()) { |
461 | - group.buckets(), | 467 | + GroupDescription tmp = new DefaultGroupDescription( |
462 | - group.appCookie(), | 468 | + group.deviceId(), |
463 | - group.appId()); | 469 | + group.type(), |
464 | - storeGroupDescriptionInternal(tmp); | 470 | + group.buckets(), |
471 | + group.appCookie(), | ||
472 | + group.appId()); | ||
473 | + storeGroupDescriptionInternal(tmp); | ||
474 | + } | ||
475 | + getPendingGroupKeyTable(deviceId).clear(); | ||
476 | + } else { | ||
477 | + if (deviceAuditStatus.get(deviceId)) { | ||
478 | + log.debug("deviceInitialAuditCompleted: Clearing AUDIT " | ||
479 | + + "status for device {}", deviceId); | ||
480 | + deviceAuditStatus.put(deviceId, false); | ||
481 | + } | ||
465 | } | 482 | } |
466 | - getPendingGroupKeyTable(deviceId).clear(); | ||
467 | } | 483 | } |
468 | } | 484 | } |
469 | 485 | ||
470 | @Override | 486 | @Override |
471 | public boolean deviceInitialAuditStatus(DeviceId deviceId) { | 487 | public boolean deviceInitialAuditStatus(DeviceId deviceId) { |
472 | synchronized (deviceAuditStatus) { | 488 | synchronized (deviceAuditStatus) { |
473 | - return (deviceAuditStatus.get(deviceId) != null) ? true : false; | 489 | + return (deviceAuditStatus.get(deviceId) != null) |
490 | + ? deviceAuditStatus.get(deviceId) : false; | ||
474 | } | 491 | } |
475 | } | 492 | } |
476 | 493 | ... | ... |
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment