Committed by
Gerrit Code Review
Added events for the Interface subsytem
Change-Id: I9adcc2caa2a98625173c9b9c6d15bbd1a0706eaa
Showing
5 changed files
with
162 additions
and
74 deletions
... | @@ -31,6 +31,9 @@ import org.onosproject.net.host.InterfaceIpAddress; | ... | @@ -31,6 +31,9 @@ import org.onosproject.net.host.InterfaceIpAddress; |
31 | import java.util.Iterator; | 31 | import java.util.Iterator; |
32 | import java.util.Set; | 32 | import java.util.Set; |
33 | 33 | ||
34 | +import static com.google.common.base.Preconditions.checkArgument; | ||
35 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
36 | + | ||
34 | /** | 37 | /** |
35 | * Configuration for interfaces. | 38 | * Configuration for interfaces. |
36 | */ | 39 | */ |
... | @@ -41,7 +44,9 @@ public class InterfaceConfig extends Config<ConnectPoint> { | ... | @@ -41,7 +44,9 @@ public class InterfaceConfig extends Config<ConnectPoint> { |
41 | public static final String MAC = "mac"; | 44 | public static final String MAC = "mac"; |
42 | public static final String VLAN = "vlan"; | 45 | public static final String VLAN = "vlan"; |
43 | 46 | ||
44 | - public static final String CONFIG_VALUE_ERROR = "Error parsing config value"; | 47 | + private static final String CONFIG_VALUE_ERROR = "Error parsing config value"; |
48 | + private static final String INTF_NULL_ERROR = "Interface cannot be null"; | ||
49 | + private static final String INTF_NAME_ERROR = "Interface must have a valid name"; | ||
45 | 50 | ||
46 | /** | 51 | /** |
47 | * Retrieves all interfaces configured on this port. | 52 | * Retrieves all interfaces configured on this port. |
... | @@ -78,6 +83,12 @@ public class InterfaceConfig extends Config<ConnectPoint> { | ... | @@ -78,6 +83,12 @@ public class InterfaceConfig extends Config<ConnectPoint> { |
78 | * @param intf interface to add | 83 | * @param intf interface to add |
79 | */ | 84 | */ |
80 | public void addInterface(Interface intf) { | 85 | public void addInterface(Interface intf) { |
86 | + checkNotNull(intf, INTF_NULL_ERROR); | ||
87 | + checkArgument(!intf.name().equals(Interface.NO_INTERFACE_NAME), INTF_NAME_ERROR); | ||
88 | + | ||
89 | + // Remove old interface with this name if it exists | ||
90 | + removeInterface(intf.name()); | ||
91 | + | ||
81 | ObjectNode intfNode = array.addObject(); | 92 | ObjectNode intfNode = array.addObject(); |
82 | 93 | ||
83 | intfNode.put(NAME, intf.name()); | 94 | intfNode.put(NAME, intf.name()); |
... | @@ -101,6 +112,9 @@ public class InterfaceConfig extends Config<ConnectPoint> { | ... | @@ -101,6 +112,9 @@ public class InterfaceConfig extends Config<ConnectPoint> { |
101 | * @param name name of the interface to remove | 112 | * @param name name of the interface to remove |
102 | */ | 113 | */ |
103 | public void removeInterface(String name) { | 114 | public void removeInterface(String name) { |
115 | + checkNotNull(name, INTF_NULL_ERROR); | ||
116 | + checkArgument(!name.equals(Interface.NO_INTERFACE_NAME), INTF_NAME_ERROR); | ||
117 | + | ||
104 | Iterator<JsonNode> it = array.iterator(); | 118 | Iterator<JsonNode> it = array.iterator(); |
105 | while (it.hasNext()) { | 119 | while (it.hasNext()) { |
106 | JsonNode node = it.next(); | 120 | JsonNode node = it.next(); | ... | ... |
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.incubator.net.intf; | ||
18 | + | ||
19 | +import org.onosproject.event.AbstractEvent; | ||
20 | + | ||
21 | +/** | ||
22 | + * Describes an interface event. | ||
23 | + */ | ||
24 | +public class InterfaceEvent extends AbstractEvent<InterfaceEvent.Type, Interface> { | ||
25 | + | ||
26 | + public enum Type { | ||
27 | + /** | ||
28 | + * Indicates a new interface has been added. | ||
29 | + */ | ||
30 | + INTERFACE_ADDED, | ||
31 | + | ||
32 | + /** | ||
33 | + * Indicates an interface has been updated. | ||
34 | + */ | ||
35 | + INTERFACE_UPDATED, | ||
36 | + | ||
37 | + /** | ||
38 | + * Indicates an interface has been removed. | ||
39 | + */ | ||
40 | + INTERFACE_REMOVED | ||
41 | + } | ||
42 | + | ||
43 | + /** | ||
44 | + * Creates an interface event with type and subject. | ||
45 | + * | ||
46 | + * @param type event type | ||
47 | + * @param subject subject interface | ||
48 | + */ | ||
49 | + public InterfaceEvent(Type type, Interface subject) { | ||
50 | + super(type, subject); | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * Creates an interface event with type, subject and time. | ||
55 | + * | ||
56 | + * @param type event type | ||
57 | + * @param subject subject interface | ||
58 | + * @param time time of event | ||
59 | + */ | ||
60 | + public InterfaceEvent(Type type, Interface subject, long time) { | ||
61 | + super(type, subject, time); | ||
62 | + } | ||
63 | + | ||
64 | +} |
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.incubator.net.intf; | ||
18 | + | ||
19 | +import org.onosproject.event.EventListener; | ||
20 | + | ||
21 | +/** | ||
22 | + * Listener for interface events. | ||
23 | + */ | ||
24 | +public interface InterfaceListener extends EventListener<InterfaceEvent> { | ||
25 | +} |
... | @@ -19,6 +19,7 @@ package org.onosproject.incubator.net.intf; | ... | @@ -19,6 +19,7 @@ package org.onosproject.incubator.net.intf; |
19 | import com.google.common.annotations.Beta; | 19 | import com.google.common.annotations.Beta; |
20 | import org.onlab.packet.IpAddress; | 20 | import org.onlab.packet.IpAddress; |
21 | import org.onlab.packet.VlanId; | 21 | import org.onlab.packet.VlanId; |
22 | +import org.onosproject.event.ListenerService; | ||
22 | import org.onosproject.net.ConnectPoint; | 23 | import org.onosproject.net.ConnectPoint; |
23 | 24 | ||
24 | import java.util.Set; | 25 | import java.util.Set; |
... | @@ -27,7 +28,8 @@ import java.util.Set; | ... | @@ -27,7 +28,8 @@ import java.util.Set; |
27 | * Service for interacting with interfaces. | 28 | * Service for interacting with interfaces. |
28 | */ | 29 | */ |
29 | @Beta | 30 | @Beta |
30 | -public interface InterfaceService { | 31 | +public interface InterfaceService |
32 | + extends ListenerService<InterfaceEvent, InterfaceListener> { | ||
31 | 33 | ||
32 | /** | 34 | /** |
33 | * Returns the set of all interfaces in the system. | 35 | * Returns the set of all interfaces in the system. | ... | ... |
... | @@ -27,10 +27,13 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -27,10 +27,13 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
27 | import org.apache.felix.scr.annotations.Service; | 27 | import org.apache.felix.scr.annotations.Service; |
28 | import org.onlab.packet.IpAddress; | 28 | import org.onlab.packet.IpAddress; |
29 | import org.onlab.packet.VlanId; | 29 | import org.onlab.packet.VlanId; |
30 | +import org.onosproject.event.ListenerRegistry; | ||
30 | import org.onosproject.incubator.net.config.basics.ConfigException; | 31 | import org.onosproject.incubator.net.config.basics.ConfigException; |
31 | import org.onosproject.incubator.net.config.basics.InterfaceConfig; | 32 | import org.onosproject.incubator.net.config.basics.InterfaceConfig; |
32 | import org.onosproject.incubator.net.intf.Interface; | 33 | import org.onosproject.incubator.net.intf.Interface; |
33 | import org.onosproject.incubator.net.intf.InterfaceAdminService; | 34 | import org.onosproject.incubator.net.intf.InterfaceAdminService; |
35 | +import org.onosproject.incubator.net.intf.InterfaceEvent; | ||
36 | +import org.onosproject.incubator.net.intf.InterfaceListener; | ||
34 | import org.onosproject.incubator.net.intf.InterfaceService; | 37 | import org.onosproject.incubator.net.intf.InterfaceService; |
35 | import org.onosproject.net.ConnectPoint; | 38 | import org.onosproject.net.ConnectPoint; |
36 | import org.onosproject.net.config.NetworkConfigEvent; | 39 | import org.onosproject.net.config.NetworkConfigEvent; |
... | @@ -40,11 +43,9 @@ import org.slf4j.Logger; | ... | @@ -40,11 +43,9 @@ import org.slf4j.Logger; |
40 | import org.slf4j.LoggerFactory; | 43 | import org.slf4j.LoggerFactory; |
41 | 44 | ||
42 | import java.util.Collections; | 45 | import java.util.Collections; |
43 | -import java.util.Iterator; | ||
44 | import java.util.Map; | 46 | import java.util.Map; |
45 | import java.util.Optional; | 47 | import java.util.Optional; |
46 | import java.util.Set; | 48 | import java.util.Set; |
47 | -import java.util.concurrent.atomic.AtomicBoolean; | ||
48 | 49 | ||
49 | import static java.util.stream.Collectors.collectingAndThen; | 50 | import static java.util.stream.Collectors.collectingAndThen; |
50 | import static java.util.stream.Collectors.toSet; | 51 | import static java.util.stream.Collectors.toSet; |
... | @@ -54,8 +55,8 @@ import static java.util.stream.Collectors.toSet; | ... | @@ -54,8 +55,8 @@ import static java.util.stream.Collectors.toSet; |
54 | */ | 55 | */ |
55 | @Service | 56 | @Service |
56 | @Component(immediate = true) | 57 | @Component(immediate = true) |
57 | -public class InterfaceManager implements InterfaceService, | 58 | +public class InterfaceManager extends ListenerRegistry<InterfaceEvent, InterfaceListener> |
58 | - InterfaceAdminService { | 59 | + implements InterfaceService, InterfaceAdminService { |
59 | 60 | ||
60 | private final Logger log = LoggerFactory.getLogger(getClass()); | 61 | private final Logger log = LoggerFactory.getLogger(getClass()); |
61 | 62 | ||
... | @@ -148,20 +149,53 @@ public class InterfaceManager implements InterfaceService, | ... | @@ -148,20 +149,53 @@ public class InterfaceManager implements InterfaceService, |
148 | 149 | ||
149 | private void updateInterfaces(InterfaceConfig intfConfig) { | 150 | private void updateInterfaces(InterfaceConfig intfConfig) { |
150 | try { | 151 | try { |
151 | - interfaces.put(intfConfig.subject(), Sets.newHashSet(intfConfig.getInterfaces())); | 152 | + Set<Interface> old = interfaces.put(intfConfig.subject(), |
153 | + Sets.newHashSet(intfConfig.getInterfaces())); | ||
154 | + | ||
155 | + if (old == null) { | ||
156 | + old = Collections.emptySet(); | ||
157 | + } | ||
158 | + | ||
159 | + for (Interface intf : intfConfig.getInterfaces()) { | ||
160 | + if (intf.name().equals(Interface.NO_INTERFACE_NAME)) { | ||
161 | + process(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_ADDED, intf)); | ||
162 | + } else { | ||
163 | + Optional<Interface> oldIntf = findInterface(intf, old); | ||
164 | + if (oldIntf.isPresent()) { | ||
165 | + old.remove(oldIntf.get()); | ||
166 | + if (!oldIntf.get().equals(intf)) { | ||
167 | + process(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_UPDATED, intf)); | ||
168 | + } | ||
169 | + } else { | ||
170 | + process(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_ADDED, intf)); | ||
171 | + } | ||
172 | + } | ||
173 | + } | ||
174 | + | ||
175 | + for (Interface intf : old) { | ||
176 | + if (!intf.name().equals(Interface.NO_INTERFACE_NAME)) { | ||
177 | + process(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, intf)); | ||
178 | + } | ||
179 | + } | ||
152 | } catch (ConfigException e) { | 180 | } catch (ConfigException e) { |
153 | log.error("Error in interface config", e); | 181 | log.error("Error in interface config", e); |
154 | } | 182 | } |
155 | } | 183 | } |
156 | 184 | ||
185 | + private Optional<Interface> findInterface(Interface intf, Set<Interface> set) { | ||
186 | + return set.stream().filter(i -> i.name().equals(intf.name())).findAny(); | ||
187 | + } | ||
188 | + | ||
157 | private void removeInterfaces(ConnectPoint port) { | 189 | private void removeInterfaces(ConnectPoint port) { |
158 | - interfaces.remove(port); | 190 | + Set<Interface> old = interfaces.remove(port); |
191 | + | ||
192 | + old.stream() | ||
193 | + .filter(i -> !i.name().equals(Interface.NO_INTERFACE_NAME)) | ||
194 | + .forEach(i -> process(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, i))); | ||
159 | } | 195 | } |
160 | 196 | ||
161 | @Override | 197 | @Override |
162 | public void add(Interface intf) { | 198 | public void add(Interface intf) { |
163 | - addInternal(intf); | ||
164 | - | ||
165 | InterfaceConfig config = | 199 | InterfaceConfig config = |
166 | configService.addConfig(intf.connectPoint(), CONFIG_CLASS); | 200 | configService.addConfig(intf.connectPoint(), CONFIG_CLASS); |
167 | 201 | ||
... | @@ -170,30 +204,8 @@ public class InterfaceManager implements InterfaceService, | ... | @@ -170,30 +204,8 @@ public class InterfaceManager implements InterfaceService, |
170 | configService.applyConfig(intf.connectPoint(), CONFIG_CLASS, config.node()); | 204 | configService.applyConfig(intf.connectPoint(), CONFIG_CLASS, config.node()); |
171 | } | 205 | } |
172 | 206 | ||
173 | - private void addInternal(Interface intf) { | ||
174 | - interfaces.compute(intf.connectPoint(), (cp, current) -> { | ||
175 | - if (current == null) { | ||
176 | - return Sets.newHashSet(intf); | ||
177 | - } | ||
178 | - | ||
179 | - Iterator<Interface> it = current.iterator(); | ||
180 | - while (it.hasNext()) { | ||
181 | - Interface i = it.next(); | ||
182 | - if (i.name().equals(intf.name())) { | ||
183 | - it.remove(); | ||
184 | - break; | ||
185 | - } | ||
186 | - } | ||
187 | - | ||
188 | - current.add(intf); | ||
189 | - return current; | ||
190 | - }); | ||
191 | - } | ||
192 | - | ||
193 | @Override | 207 | @Override |
194 | public boolean remove(ConnectPoint connectPoint, String name) { | 208 | public boolean remove(ConnectPoint connectPoint, String name) { |
195 | - boolean success = removeInternal(name, connectPoint); | ||
196 | - | ||
197 | InterfaceConfig config = configService.addConfig(connectPoint, CONFIG_CLASS); | 209 | InterfaceConfig config = configService.addConfig(connectPoint, CONFIG_CLASS); |
198 | config.removeInterface(name); | 210 | config.removeInterface(name); |
199 | 211 | ||
... | @@ -205,37 +217,10 @@ public class InterfaceManager implements InterfaceService, | ... | @@ -205,37 +217,10 @@ public class InterfaceManager implements InterfaceService, |
205 | } | 217 | } |
206 | } catch (ConfigException e) { | 218 | } catch (ConfigException e) { |
207 | log.error("Error reading interfaces JSON", e); | 219 | log.error("Error reading interfaces JSON", e); |
220 | + return false; | ||
208 | } | 221 | } |
209 | 222 | ||
210 | - return success; | 223 | + return true; |
211 | - } | ||
212 | - | ||
213 | - public boolean removeInternal(String name, ConnectPoint connectPoint) { | ||
214 | - AtomicBoolean removed = new AtomicBoolean(false); | ||
215 | - | ||
216 | - interfaces.compute(connectPoint, (cp, current) -> { | ||
217 | - if (current == null) { | ||
218 | - return null; | ||
219 | - } | ||
220 | - | ||
221 | - Iterator<Interface> it = current.iterator(); | ||
222 | - while (it.hasNext()) { | ||
223 | - Interface i = it.next(); | ||
224 | - if (i.name().equals(name)) { | ||
225 | - it.remove(); | ||
226 | - removed.set(true); | ||
227 | - break; | ||
228 | - } | ||
229 | - } | ||
230 | - | ||
231 | - if (current.isEmpty()) { | ||
232 | - return null; | ||
233 | - } else { | ||
234 | - return current; | ||
235 | - } | ||
236 | - }); | ||
237 | - | ||
238 | - return removed.get(); | ||
239 | } | 224 | } |
240 | 225 | ||
241 | /** | 226 | /** |
... | @@ -245,24 +230,22 @@ public class InterfaceManager implements InterfaceService, | ... | @@ -245,24 +230,22 @@ public class InterfaceManager implements InterfaceService, |
245 | 230 | ||
246 | @Override | 231 | @Override |
247 | public void event(NetworkConfigEvent event) { | 232 | public void event(NetworkConfigEvent event) { |
248 | - switch (event.type()) { | 233 | + if (event.configClass() == CONFIG_CLASS) { |
249 | - case CONFIG_ADDED: | 234 | + switch (event.type()) { |
250 | - case CONFIG_UPDATED: | 235 | + case CONFIG_ADDED: |
251 | - if (event.configClass() == InterfaceConfig.class) { | 236 | + case CONFIG_UPDATED: |
252 | InterfaceConfig config = | 237 | InterfaceConfig config = |
253 | configService.getConfig((ConnectPoint) event.subject(), InterfaceConfig.class); | 238 | configService.getConfig((ConnectPoint) event.subject(), InterfaceConfig.class); |
254 | updateInterfaces(config); | 239 | updateInterfaces(config); |
255 | - } | 240 | + break; |
256 | - break; | 241 | + case CONFIG_REMOVED: |
257 | - case CONFIG_REMOVED: | ||
258 | - if (event.configClass() == InterfaceConfig.class) { | ||
259 | removeInterfaces((ConnectPoint) event.subject()); | 242 | removeInterfaces((ConnectPoint) event.subject()); |
243 | + break; | ||
244 | + case CONFIG_REGISTERED: | ||
245 | + case CONFIG_UNREGISTERED: | ||
246 | + default: | ||
247 | + break; | ||
260 | } | 248 | } |
261 | - break; | ||
262 | - case CONFIG_REGISTERED: | ||
263 | - case CONFIG_UNREGISTERED: | ||
264 | - default: | ||
265 | - break; | ||
266 | } | 249 | } |
267 | } | 250 | } |
268 | } | 251 | } | ... | ... |
-
Please register or login to post a comment