blob: 39820b49b959e8f17133b4ed3396aab4eff150ed [file] [log] [blame]
Sithara Punnassery9306e6b2017-02-06 15:38:19 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Sithara Punnassery9306e6b2017-02-06 15:38:19 -08003 *
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.config.impl;
17
18import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.apache.felix.scr.annotations.Service;
Sithara Punnassery9d464a32017-07-23 16:14:02 -070024import org.onosproject.config.ResourceIdParser;
25import org.onosproject.config.RpcExecutor;
26import org.onosproject.config.RpcMessageId;
Sithara Punnassery7b0c15e2017-07-07 15:08:19 -070027import org.onosproject.event.AbstractListenerManager;
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080028import org.onosproject.config.DynamicConfigEvent;
29import org.onosproject.config.DynamicConfigListener;
30import org.onosproject.config.DynamicConfigService;
31import org.onosproject.config.DynamicConfigStore;
32import org.onosproject.config.DynamicConfigStoreDelegate;
33import org.onosproject.config.FailedException;
34import org.onosproject.config.Filter;
Gaurav Agrawal02dbee32017-05-11 19:04:52 +053035import org.onosproject.yang.model.RpcInput;
36import org.onosproject.yang.model.RpcOutput;
Sithara Punnassery4b091dc2017-03-02 17:22:40 -080037import org.onosproject.yang.model.DataNode;
38import org.onosproject.yang.model.ResourceId;
Sithara Punnassery9d464a32017-07-23 16:14:02 -070039import org.onosproject.yang.model.RpcRegistry;
40import org.onosproject.yang.model.RpcService;
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080041
Sithara Punnassery9d464a32017-07-23 16:14:02 -070042import java.util.HashSet;
43import java.util.Map;
44import java.util.Set;
Sithara Punnassery7b0c15e2017-07-07 15:08:19 -070045import java.util.concurrent.CompletableFuture;
Sithara Punnassery9d464a32017-07-23 16:14:02 -070046import java.util.concurrent.ConcurrentHashMap;
47import java.util.concurrent.Executors;
Sithara Punnassery7b0c15e2017-07-07 15:08:19 -070048
49import org.slf4j.Logger;
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080050import static org.slf4j.LoggerFactory.getLogger;
51
52/**
Sithara Punnassery7b0c15e2017-07-07 15:08:19 -070053 * Implementation of the Dynamic Config Service.
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080054 *
55 */
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080056@Component(immediate = true)
57@Service
58public class DynamicConfigManager
59 extends AbstractListenerManager<DynamicConfigEvent, DynamicConfigListener>
Sithara Punnassery9d464a32017-07-23 16:14:02 -070060 implements DynamicConfigService, RpcRegistry {
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080061 private final Logger log = getLogger(getClass());
62 private final DynamicConfigStoreDelegate storeDelegate = new InternalStoreDelegate();
63 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080064 protected DynamicConfigStore store;
Sithara Punnassery9d464a32017-07-23 16:14:02 -070065 private ConcurrentHashMap<String, RpcService> handlerRegistry = new ConcurrentHashMap<>();
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080066
67 @Activate
68 public void activate() {
69 store.setDelegate(storeDelegate);
Sithara Punnassery43833e12017-03-14 16:29:19 -070070 eventDispatcher.addSink(DynamicConfigEvent.class, listenerRegistry);
Sithara Punnassery644a2662017-06-09 02:02:57 -070071 log.info("Started");
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080072 }
73
74 @Deactivate
75 public void deactivate() {
76 store.unsetDelegate(storeDelegate);
Sithara Punnassery43833e12017-03-14 16:29:19 -070077 eventDispatcher.removeSink(DynamicConfigEvent.class);
Sithara Punnassery9d464a32017-07-23 16:14:02 -070078 handlerRegistry.clear();
Sithara Punnassery644a2662017-06-09 02:02:57 -070079 log.info("Stopped");
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080080 }
81
Sithara Punnassery7b0c15e2017-07-07 15:08:19 -070082 public void createNode(ResourceId path, DataNode node) {
Sithara Punnassery0da1a9c2017-05-17 16:16:22 -070083 store.addNode(path, node).join();
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080084 }
85
86 public DataNode readNode(ResourceId path, Filter filter) {
87 return store.readNode(path, filter).join();
88 }
89
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080090 public void updateNode(ResourceId path, DataNode node) {
Sithara Punnassery0da1a9c2017-05-17 16:16:22 -070091 store.updateNode(path, node).join();
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080092 }
93
94 public void deleteNode(ResourceId path) {
Sithara Punnassery4b091dc2017-03-02 17:22:40 -080095 store.deleteNodeRecursive(path).join();
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080096 }
97
Sithara Punnassery9306e6b2017-02-06 15:38:19 -080098 public void replaceNode(ResourceId path, DataNode node) {
99 throw new FailedException("Not yet implemented");
100 }
Sithara Punnassery43833e12017-03-14 16:29:19 -0700101
Sithara Punnassery18ffcc72017-05-18 14:24:30 -0700102 public Boolean nodeExist(ResourceId path) {
103 return store.nodeExist(path).join();
104 }
105
Sithara Punnassery9d464a32017-07-23 16:14:02 -0700106 public Set<RpcService> getRpcServices() {
107 Set<RpcService> res = new HashSet();
108 for (Map.Entry<String, RpcService> e : handlerRegistry.entrySet()) {
109 res.add(e.getValue());
110 }
111 return res;
Sithara Punnassery9306e6b2017-02-06 15:38:19 -0800112 }
113
Sithara Punnassery9d464a32017-07-23 16:14:02 -0700114 public RpcService getRpcService(Class<? extends RpcService> intfc) {
115 return handlerRegistry.get(intfc.getSimpleName());
116 }
117
118 public void registerRpcService(RpcService handler) {
119 for (Class<?> intfc : handler.getClass().getInterfaces()) {
120 if (RpcService.class.isAssignableFrom(intfc)) {
121 handlerRegistry.put(intfc.getSimpleName(), handler);
122 }
Sithara Punnassery644a2662017-06-09 02:02:57 -0700123 }
Sithara Punnassery9d464a32017-07-23 16:14:02 -0700124 }
125
126 public void unregisterRpcService(RpcService handler) {
127 for (Class<?> intfc : handler.getClass().getInterfaces()) {
128 if (RpcService.class.isAssignableFrom(intfc)) {
129 String key = intfc.getSimpleName();
130 if (handlerRegistry.get(key) == null) {
131 throw new FailedException("No registered handler found, cannot unregister");
132 }
133 handlerRegistry.remove(key);
134 }
135 }
136 }
137
138 private int getSvcId(RpcService handler, String srvc) {
139 Class<?>[] intfcs = handler.getClass().getInterfaces();
140 for (int i = 0; i < intfcs.length; i++) {
141 if (intfcs[i].getSimpleName().compareTo(srvc) == 0) {
142 return i;
143 }
144 }
145 throw new FailedException("No handler found, cannot invoke");
146 }
Sithara Punnassery7b0c15e2017-07-07 15:08:19 -0700147
148 public CompletableFuture<RpcOutput> invokeRpc(ResourceId id, RpcInput input) {
Sithara Punnassery9d464a32017-07-23 16:14:02 -0700149 String[] ctxt = ResourceIdParser.getService(id);
150 RpcService handler = handlerRegistry.get(ctxt[0]);
151 if (handler == null) {
152 throw new FailedException("No registered handler found, cannot invoke");
153 }
154 return CompletableFuture.supplyAsync(
155 new RpcExecutor(handler, getSvcId(handler, ctxt[0]), ctxt[1], RpcMessageId.generate(), input),
156 Executors.newSingleThreadExecutor());
Sithara Punnassery9306e6b2017-02-06 15:38:19 -0800157 }
158
Sithara Punnassery9306e6b2017-02-06 15:38:19 -0800159 /**
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800160 * Auxiliary store delegate to receive notification about changes in the store.
Sithara Punnassery9306e6b2017-02-06 15:38:19 -0800161 */
162 private class InternalStoreDelegate implements DynamicConfigStoreDelegate {
163 public void notify(DynamicConfigEvent event) {
Sithara Punnassery43833e12017-03-14 16:29:19 -0700164 post(event);
Sithara Punnassery9306e6b2017-02-06 15:38:19 -0800165 }
166 }
167}