blob: a9771024092d3746c37ad6d82fbc34a4c8320310 [file] [log] [blame]
Thomas Vachuska96d55b12015-05-11 08:52:03 -07001/*
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 */
16package org.onosproject.incubator.net.config.impl;
17
18import com.fasterxml.jackson.databind.node.ObjectNode;
19import com.google.common.collect.ImmutableSet;
20import com.google.common.collect.Maps;
21import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
24import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
26import org.apache.felix.scr.annotations.Service;
27import org.onosproject.event.EventDeliveryService;
28import org.onosproject.event.ListenerRegistry;
29import org.onosproject.incubator.net.config.Config;
30import org.onosproject.incubator.net.config.ConfigFactory;
31import org.onosproject.incubator.net.config.NetworkConfigEvent;
32import org.onosproject.incubator.net.config.NetworkConfigListener;
33import org.onosproject.incubator.net.config.NetworkConfigRegistry;
34import org.onosproject.incubator.net.config.NetworkConfigService;
35import org.onosproject.incubator.net.config.NetworkConfigStore;
36import org.onosproject.incubator.net.config.NetworkConfigStoreDelegate;
37import org.onosproject.incubator.net.config.SubjectFactory;
38import org.slf4j.Logger;
39import org.slf4j.LoggerFactory;
40
41import java.util.Map;
42import java.util.Objects;
43import java.util.Set;
44
45import static com.google.common.base.Preconditions.checkNotNull;
46
47/**
48 * Implementation of the network configuration subsystem.
49 */
50@Component(immediate = true)
51@Service
52public class NetworkConfigManager implements NetworkConfigRegistry, NetworkConfigService {
53
54 private final Logger log = LoggerFactory.getLogger(getClass());
55
56 private static final String NULL_FACTORY_MSG = "Factory cannot be null";
57 private static final String NULL_SCLASS_MSG = "Subject class cannot be null";
58 private static final String NULL_CCLASS_MSG = "Config class cannot be null";
59 private static final String NULL_SUBJECT_MSG = "Subject cannot be null";
60
61 // Inventory of configuration factories
62 private final Map<ConfigKey, ConfigFactory> factories = Maps.newConcurrentMap();
63
64 // Secondary indeces to retrieve subject and config classes by keys
65 private final Map<String, SubjectFactory> subjectClasses = Maps.newConcurrentMap();
66 private final Map<Class, SubjectFactory> subjectClassKeys = Maps.newConcurrentMap();
67 private final Map<String, Class<? extends Config>> configClasses = Maps.newConcurrentMap();
68
69 private final ListenerRegistry<NetworkConfigEvent, NetworkConfigListener>
70 listenerRegistry = new ListenerRegistry<>();
71
72 private final NetworkConfigStoreDelegate storeDelegate = new InternalStoreDelegate();
73
74 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
75 protected NetworkConfigStore store;
76
77 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
78 protected EventDeliveryService eventDispatcher;
79
80
81 @Activate
82 public void activate() {
83 eventDispatcher.addSink(NetworkConfigEvent.class, listenerRegistry);
84 store.setDelegate(storeDelegate);
85 log.info("Started");
86 }
87
88 @Deactivate
89 public void deactivate() {
90 eventDispatcher.removeSink(NetworkConfigEvent.class);
91 store.unsetDelegate(storeDelegate);
92 log.info("Stopped");
93 }
94
95
96 @Override
97 @SuppressWarnings("unchecked")
98 public void registerConfigFactory(ConfigFactory configFactory) {
99 checkNotNull(configFactory, NULL_FACTORY_MSG);
100 factories.put(key(configFactory), configFactory);
101 configClasses.put(configFactory.configKey(), configFactory.configClass());
102
103 SubjectFactory subjectFactory = configFactory.subjectFactory();
104 subjectClasses.putIfAbsent(subjectFactory.subjectKey(), subjectFactory);
105 subjectClassKeys.putIfAbsent(subjectFactory.subjectClass(), subjectFactory);
106
107 store.addConfigFactory(configFactory);
108 }
109
110 @Override
111 public void unregisterConfigFactory(ConfigFactory configFactory) {
112 checkNotNull(configFactory, NULL_FACTORY_MSG);
113 factories.remove(key(configFactory));
114 configClasses.remove(configFactory.configKey());
115
116 // Note that we are deliberately not removing subject factory key bindings.
117 store.removeConfigFactory(configFactory);
118 }
119
120 @Override
121 public Set<ConfigFactory> getConfigFactories() {
122 return ImmutableSet.copyOf(factories.values());
123 }
124
125
126 @Override
127 @SuppressWarnings("unchecked")
128 public <S, C extends Config<S>> Set<ConfigFactory<S, C>> getConfigFactories(Class<S> subjectClass) {
129 ImmutableSet.Builder<ConfigFactory<S, C>> builder = ImmutableSet.builder();
130 factories.forEach((key, factory) -> {
131 if (factory.subjectFactory().subjectClass().equals(subjectClass)) {
132 builder.add(factory);
133 }
134 });
135 return builder.build();
136 }
137
138 @Override
139 public <S, C extends Config<S>> ConfigFactory<S, C> getConfigFactory(Class<C> configClass) {
140 checkNotNull(configClass, NULL_CCLASS_MSG);
141 return store.getConfigFactory(configClass);
142 }
143
144
145 @Override
146 public Set<Class> getSubjectClasses() {
147 ImmutableSet.Builder<Class> builder = ImmutableSet.builder();
148 factories.forEach((k, v) -> builder.add(k.subjectClass));
149 return builder.build();
150 }
151
152 @Override
153 public SubjectFactory getSubjectFactory(String subjectKey) {
154 return subjectClasses.get(subjectKey);
155 }
156
157 @Override
158 public SubjectFactory getSubjectFactory(Class subjectClass) {
159 return subjectClassKeys.get(subjectClass);
160 }
161
162 @Override
163 public Class<? extends Config> getConfigClass(String configKey) {
164 return configClasses.get(configKey);
165 }
166
167 @Override
168 public <S> Set<S> getSubjects(Class<S> subjectClass) {
169 checkNotNull(subjectClass, NULL_SCLASS_MSG);
170 return store.getSubjects(subjectClass);
171 }
172
173 @Override
174 public <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass, Class<C> configClass) {
175 checkNotNull(subjectClass, NULL_SCLASS_MSG);
176 checkNotNull(configClass, NULL_CCLASS_MSG);
177 return store.getSubjects(subjectClass, configClass);
178 }
179
180 @Override
181 public <S> Set<Config<S>> getConfigs(S subject) {
182 checkNotNull(subject, NULL_SUBJECT_MSG);
183 Set<Class<? extends Config<S>>> configClasses = store.getConfigClasses(subject);
184 ImmutableSet.Builder<Config<S>> cfg = ImmutableSet.builder();
185 configClasses.forEach(cc -> cfg.add(store.getConfig(subject, cc)));
186 return cfg.build();
187 }
188
189 @Override
190 public <S, T extends Config<S>> T getConfig(S subject, Class<T> configClass) {
191 checkNotNull(subject, NULL_SUBJECT_MSG);
192 checkNotNull(configClass, NULL_CCLASS_MSG);
193 return store.getConfig(subject, configClass);
194 }
195
196
197 @Override
198 public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) {
199 checkNotNull(subject, NULL_SUBJECT_MSG);
200 checkNotNull(configClass, NULL_CCLASS_MSG);
201 return store.createConfig(subject, configClass);
202 }
203
204 @Override
205 public <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass, ObjectNode json) {
206 checkNotNull(subject, NULL_SUBJECT_MSG);
207 checkNotNull(configClass, NULL_CCLASS_MSG);
208 return store.applyConfig(subject, configClass, json);
209 }
210
211 @Override
212 public <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass) {
213 checkNotNull(subject, NULL_SUBJECT_MSG);
214 checkNotNull(configClass, NULL_CCLASS_MSG);
215 store.clearConfig(subject, configClass);
216 }
217
218 @Override
219 public void addListener(NetworkConfigListener listener) {
220 listenerRegistry.addListener(listener);
221 }
222
223 @Override
224 public void removeListener(NetworkConfigListener listener) {
225 listenerRegistry.removeListener(listener);
226 }
227
228
229 // Auxiliary store delegate to receive notification about changes in
230 // the network configuration store state - by the store itself.
231 private class InternalStoreDelegate implements NetworkConfigStoreDelegate {
232 @Override
233 public void notify(NetworkConfigEvent event) {
234 eventDispatcher.post(event);
235 }
236 }
237
238
239 // Produces a key for uniquely tracking a config factory.
240 private static ConfigKey key(ConfigFactory factory) {
241 return new ConfigKey(factory.subjectFactory().subjectClass(), factory.configClass());
242 }
243
244 // Auxiliary key to track config factories.
245 private static final class ConfigKey {
246 final Class subjectClass;
247 final Class configClass;
248
249 private ConfigKey(Class subjectClass, Class configClass) {
250 this.subjectClass = subjectClass;
251 this.configClass = configClass;
252 }
253
254 @Override
255 public int hashCode() {
256 return Objects.hash(subjectClass, configClass);
257 }
258
259 @Override
260 public boolean equals(Object obj) {
261 if (this == obj) {
262 return true;
263 }
264 if (obj instanceof ConfigKey) {
265 final ConfigKey other = (ConfigKey) obj;
266 return Objects.equals(this.subjectClass, other.subjectClass)
267 && Objects.equals(this.configClass, other.configClass);
268 }
269 return false;
270 }
271 }
272
273}