f82cdbf2ed4690fdf2e5c5cf58c49dd9ed9d08a4
[onosfw.git] /
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.impl;
18
19 import com.google.common.collect.ImmutableSet;
20 import com.google.common.collect.Maps;
21 import org.apache.felix.scr.annotations.Activate;
22 import org.apache.felix.scr.annotations.Component;
23 import org.apache.felix.scr.annotations.Deactivate;
24 import org.apache.felix.scr.annotations.Reference;
25 import org.apache.felix.scr.annotations.ReferenceCardinality;
26 import org.apache.felix.scr.annotations.Service;
27 import org.onlab.packet.IpAddress;
28 import org.onlab.packet.VlanId;
29 import org.onosproject.incubator.net.config.basics.ConfigException;
30 import org.onosproject.incubator.net.config.basics.InterfaceConfig;
31 import org.onosproject.incubator.net.intf.Interface;
32 import org.onosproject.incubator.net.intf.InterfaceService;
33 import org.onosproject.net.ConnectPoint;
34 import org.onosproject.net.config.NetworkConfigEvent;
35 import org.onosproject.net.config.NetworkConfigListener;
36 import org.onosproject.net.config.NetworkConfigService;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import java.util.Collections;
41 import java.util.Map;
42 import java.util.Optional;
43 import java.util.Set;
44
45 import static java.util.stream.Collectors.collectingAndThen;
46 import static java.util.stream.Collectors.toSet;
47
48 /**
49  * Manages the inventory of interfaces in the system.
50  */
51 @Service
52 @Component(immediate = true)
53 public class InterfaceManager implements InterfaceService {
54
55     private final Logger log = LoggerFactory.getLogger(getClass());
56
57     private static final Class<ConnectPoint> SUBJECT_CLASS = ConnectPoint.class;
58     private static final Class<InterfaceConfig> CONFIG_CLASS = InterfaceConfig.class;
59
60     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61     protected NetworkConfigService configService;
62
63     private final InternalConfigListener listener = new InternalConfigListener();
64
65     private final Map<ConnectPoint, Set<Interface>> interfaces = Maps.newConcurrentMap();
66
67     @Activate
68     public void activate() {
69         configService.addListener(listener);
70
71         // TODO address concurrency issues here
72         for (ConnectPoint subject : configService.getSubjects(SUBJECT_CLASS, CONFIG_CLASS)) {
73             InterfaceConfig config = configService.getConfig(subject, CONFIG_CLASS);
74
75             if (config != null) {
76                 updateInterfaces(config);
77             }
78         }
79
80         log.info("Started");
81     }
82
83     @Deactivate
84     public void deactivate() {
85         configService.removeListener(listener);
86
87         log.info("Stopped");
88     }
89
90     @Override
91     public Set<Interface> getInterfaces() {
92         return interfaces.values()
93                 .stream()
94                 .flatMap(set -> set.stream())
95                 .collect(collectingAndThen(toSet(), ImmutableSet::copyOf));
96     }
97
98     @Override
99     public Set<Interface> getInterfacesByPort(ConnectPoint port) {
100         Set<Interface> intfs = interfaces.get(port);
101         if (intfs == null) {
102             return Collections.emptySet();
103         }
104         return ImmutableSet.copyOf(intfs);
105     }
106
107     @Override
108     public Set<Interface> getInterfacesByIp(IpAddress ip) {
109         return interfaces.values()
110                 .stream()
111                 .flatMap(set -> set.stream())
112                 .filter(intf -> intf.ipAddresses()
113                         .stream()
114                         .anyMatch(ia -> ia.ipAddress().equals(ip)))
115                 .collect(collectingAndThen(toSet(), ImmutableSet::copyOf));
116     }
117
118     @Override
119     public Interface getMatchingInterface(IpAddress ip) {
120         Optional<Interface> match = interfaces.values()
121                 .stream()
122                 .flatMap(set -> set.stream())
123                 .filter(intf -> intf.ipAddresses()
124                         .stream()
125                         .anyMatch(intfIp -> intfIp.subnetAddress().contains(ip)))
126                 .findFirst();
127
128         if (match.isPresent()) {
129             return match.get();
130         }
131
132         return null;
133     }
134
135     @Override
136     public Set<Interface> getInterfacesByVlan(VlanId vlan) {
137         return interfaces.values()
138                 .stream()
139                 .flatMap(set -> set.stream())
140                 .filter(intf -> intf.vlan().equals(vlan))
141                 .collect(collectingAndThen(toSet(), ImmutableSet::copyOf));
142     }
143
144     private void updateInterfaces(InterfaceConfig intfConfig) {
145         try {
146             interfaces.put(intfConfig.subject(), intfConfig.getInterfaces());
147         } catch (ConfigException e) {
148             log.error("Error in interface config", e);
149         }
150     }
151
152     private void removeInterfaces(ConnectPoint port) {
153         interfaces.remove(port);
154     }
155
156     /**
157      * Listener for network config events.
158      */
159     private class InternalConfigListener implements NetworkConfigListener {
160
161         @Override
162         public void event(NetworkConfigEvent event) {
163             switch (event.type()) {
164             case CONFIG_ADDED:
165             case CONFIG_UPDATED:
166                 if (event.configClass() == InterfaceConfig.class) {
167                     InterfaceConfig config =
168                             configService.getConfig((ConnectPoint) event.subject(), InterfaceConfig.class);
169                     updateInterfaces(config);
170                 }
171                 break;
172             case CONFIG_REMOVED:
173                 if (event.configClass() == InterfaceConfig.class) {
174                     removeInterfaces((ConnectPoint) event.subject());
175                 }
176                 break;
177             case CONFIG_REGISTERED:
178             case CONFIG_UNREGISTERED:
179             default:
180                 break;
181             }
182         }
183     }
184 }