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