7ada4bea61090c1aa31c384de9a66c92e34c17c9
[controller.git] / opendaylight / md-sal / samples / clustering-test-app / provider / src / main / java / org / opendaylight / controller / clustering / it / provider / MdsalLowLevelTestProvider.java
1 /*
2  * Copyright (c) 2017 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.clustering.it.provider;
10
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.SettableFuture;
13 import java.util.HashMap;
14 import java.util.Map;
15 import java.util.concurrent.Future;
16 import org.opendaylight.controller.clustering.it.provider.impl.FlappingSingletonService;
17 import org.opendaylight.controller.clustering.it.provider.impl.GetConstantService;
18 import org.opendaylight.controller.clustering.it.provider.impl.PublishNotificationsTask;
19 import org.opendaylight.controller.clustering.it.provider.impl.RoutedGetConstantService;
20 import org.opendaylight.controller.clustering.it.provider.impl.SingletonGetConstantService;
21 import org.opendaylight.controller.clustering.it.provider.impl.YnlListener;
22 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
23 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
24 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationRegistration;
25 import org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService;
26 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
27 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
28 import org.opendaylight.controller.sal.core.api.model.SchemaService;
29 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
30 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
31 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
32 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.AddShardReplicaInput;
33 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.BecomeModuleLeaderInput;
34 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.BecomePrefixLeaderInput;
35 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.IsClientAbortedOutput;
36 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.OdlMdsalLowlevelControlService;
37 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ProduceTransactionsInput;
38 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.PublishNotificationsInput;
39 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterBoundConstantInput;
40 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterConstantInput;
41 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterDefaultConstantInput;
42 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterSingletonConstantInput;
43 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RemoveShardReplicaInput;
44 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeYnlInput;
45 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterBoundConstantInput;
46 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterFlappingSingletonOutput;
47 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterFlappingSingletonOutputBuilder;
48 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDdtlOutput;
49 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDtclOutput;
50 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeYnlInput;
51 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeYnlOutput;
52 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.WriteTransactionsInput;
53 import org.opendaylight.yangtools.concepts.ListenerRegistration;
54 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
55 import org.opendaylight.yangtools.yang.common.RpcError;
56 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
57 import org.opendaylight.yangtools.yang.common.RpcResult;
58 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62 public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService {
63
64     private static final Logger LOG = LoggerFactory.getLogger(MdsalLowLevelTestProvider.class);
65
66     private final RpcProviderRegistry rpcRegistry;
67     private final BindingAwareBroker.RpcRegistration<OdlMdsalLowlevelControlService> registration;
68     private final BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer;
69     private final NotificationPublishService notificationPublishService;
70     private final NotificationService notificationService;
71     private final SchemaService schemaService;
72     private final ClusterSingletonServiceProvider singletonService;
73     private final DOMRpcProviderService domRpcService;
74
75     private Map<InstanceIdentifier<?>, DOMRpcImplementationRegistration<RoutedGetConstantService>> routedRegistrations =
76             new HashMap<>();
77
78     private Map<String, ListenerRegistration<YnlListener>> ynlRegistrations = new HashMap<>();
79
80     private DOMRpcImplementationRegistration<GetConstantService> globalGetConstantRegistration = null;
81     private ClusterSingletonServiceRegistration getSingletonConstantRegistration;
82     private FlappingSingletonService flappingSingletonService;
83
84     public MdsalLowLevelTestProvider(final RpcProviderRegistry rpcRegistry,
85                                      final DOMRpcProviderService domRpcService,
86                                      final ClusterSingletonServiceProvider singletonService,
87                                      final SchemaService schemaService,
88                                      final BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer,
89                                      final NotificationPublishService notificationPublishService,
90                                      final NotificationService notificationService) {
91         this.rpcRegistry = rpcRegistry;
92         this.domRpcService = domRpcService;
93         this.singletonService = singletonService;
94         this.schemaService = schemaService;
95         this.bindingNormalizedNodeSerializer = bindingNormalizedNodeSerializer;
96         this.notificationPublishService = notificationPublishService;
97         this.notificationService = notificationService;
98
99         registration = rpcRegistry.addRpcImplementation(OdlMdsalLowlevelControlService.class, this);
100     }
101
102     @Override
103     public Future<RpcResult<Void>> unregisterSingletonConstant() {
104         LOG.debug("unregister-singleton-constant");
105
106         if (getSingletonConstantRegistration == null) {
107             LOG.debug("No get-singleton-constant registration present.");
108             final RpcError rpcError = RpcResultBuilder
109                     .newError(ErrorType.APPLICATION, "missing-registration", "No get-singleton-constant rpc registration present.");
110             final RpcResult<Void> result = RpcResultBuilder.<Void>failed().withRpcError(rpcError).build();
111             return Futures.immediateFuture(result);
112         }
113
114         try {
115             getSingletonConstantRegistration.close();
116             getSingletonConstantRegistration = null;
117
118             return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
119         } catch (final Exception e) {
120             LOG.debug("There was a problem closing the singleton constant service", e);
121             final RpcError rpcError = RpcResultBuilder
122                     .newError(ErrorType.APPLICATION, "error-closing", "There was a problem closing get-singleton-constant");
123             final RpcResult<Void> result = RpcResultBuilder.<Void>failed().withRpcError(rpcError).build();
124             return Futures.immediateFuture(result);
125         }
126     }
127
128     @Override
129     public Future<RpcResult<Void>> publishNotifications(final PublishNotificationsInput input) {
130         LOG.debug("publish-notifications, input: {}", input);
131
132         final PublishNotificationsTask task = new PublishNotificationsTask(notificationPublishService, input.getId(),
133                 input.getSeconds(), input.getNotificationsPerSecond());
134
135         final SettableFuture<RpcResult<Void>> settableFuture = SettableFuture.create();
136         task.start(settableFuture);
137
138         return settableFuture;
139     }
140
141     @Override
142     public Future<RpcResult<Void>> subscribeDtcl() {
143         return null;
144     }
145
146     @Override
147     public Future<RpcResult<Void>> writeTransactions(WriteTransactionsInput input) {
148         return null;
149     }
150
151     @Override
152     public Future<RpcResult<IsClientAbortedOutput>> isClientAborted() {
153         return null;
154     }
155
156     @Override
157     public Future<RpcResult<Void>> becomeModuleLeader(BecomeModuleLeaderInput input) {
158         return null;
159     }
160
161     @Override
162     public Future<RpcResult<Void>> removeShardReplica(RemoveShardReplicaInput input) {
163         return null;
164     }
165
166     @Override
167     public Future<RpcResult<Void>> subscribeYnl(final SubscribeYnlInput input) {
168
169         LOG.debug("subscribe-ynl, input: {}", input);
170
171         if (ynlRegistrations.containsKey(input.getId())) {
172             final RpcError error = RpcResultBuilder.newError(ErrorType.RPC, "Registration present.",
173                     "There is already ynl listener registered for this id: " + input.getId());
174             return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
175         }
176
177         ynlRegistrations.put(input.getId(),
178                 notificationService.registerNotificationListener(new YnlListener(input.getId())));
179
180         return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
181     }
182
183     @Override
184     public Future<RpcResult<Void>> becomePrefixLeader(BecomePrefixLeaderInput input) {
185         return null;
186     }
187
188     @Override
189     public Future<RpcResult<Void>> unregisterBoundConstant(final UnregisterBoundConstantInput input) {
190         LOG.debug("unregister-bound-constant, {}", input);
191
192         final DOMRpcImplementationRegistration<RoutedGetConstantService> registration =
193                 routedRegistrations.remove(input.getContext());
194
195         if (registration == null) {
196             LOG.debug("No get-contexted-constant registration for context: {}", input.getContext());
197             final RpcError rpcError = RpcResultBuilder
198                     .newError(ErrorType.APPLICATION, "missing-registration", "No get-constant rpc registration present.");
199             final RpcResult<Void> result = RpcResultBuilder.<Void>failed().withRpcError(rpcError).build();
200             return Futures.immediateFuture(result);
201         }
202
203         registration.close();
204         return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
205     }
206
207     @Override
208     public Future<RpcResult<Void>> registerSingletonConstant(final RegisterSingletonConstantInput input) {
209
210         LOG.debug("Received register-singleton-constant rpc, input: {}", input);
211
212         if (input.getConstant() == null) {
213             final RpcError error = RpcResultBuilder.newError(
214                     ErrorType.RPC, "Invalid input.", "Constant value is null");
215             return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
216         }
217
218         getSingletonConstantRegistration =
219                 SingletonGetConstantService.registerNew(singletonService, domRpcService, input.getConstant());
220
221         return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
222     }
223
224     @Override
225     public Future<RpcResult<Void>> registerDefaultConstant(RegisterDefaultConstantInput input) {
226         return null;
227     }
228
229     @Override
230     public Future<RpcResult<Void>> unregisterConstant() {
231
232         if (globalGetConstantRegistration == null) {
233             final RpcError rpcError = RpcResultBuilder
234                     .newError(ErrorType.APPLICATION, "missing-registration", "No get-constant rpc registration present.");
235             final RpcResult<Void> result = RpcResultBuilder.<Void>failed().withRpcError(rpcError).build();
236             return Futures.immediateFuture(result);
237         }
238
239         globalGetConstantRegistration.close();
240         globalGetConstantRegistration = null;
241
242         return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
243     }
244
245     @Override
246     public Future<RpcResult<UnregisterFlappingSingletonOutput>> unregisterFlappingSingleton() {
247         LOG.debug("unregister-flapping-singleton received.");
248
249         if (flappingSingletonService == null) {
250             final RpcError rpcError = RpcResultBuilder
251                     .newError(ErrorType.APPLICATION, "missing-registration", "No flapping-singleton registration present.");
252             final RpcResult<UnregisterFlappingSingletonOutput> result =
253                     RpcResultBuilder.<UnregisterFlappingSingletonOutput>failed().withRpcError(rpcError).build();
254             return Futures.immediateFuture(result);
255         }
256
257         final long flapCount = flappingSingletonService.setInactive();
258         flappingSingletonService = null;
259
260         final UnregisterFlappingSingletonOutput output =
261                 new UnregisterFlappingSingletonOutputBuilder().setFlapCount(flapCount).build();
262
263         return Futures.immediateFuture(RpcResultBuilder.success(output).build());
264     }
265
266     @Override
267     public Future<RpcResult<Void>> addShardReplica(AddShardReplicaInput input) {
268         return null;
269     }
270
271     @Override
272     public Future<RpcResult<Void>> subscribeDdtl() {
273         return null;
274     }
275
276     @Override
277     public Future<RpcResult<Void>> registerBoundConstant(final RegisterBoundConstantInput input) {
278         LOG.debug("register-bound-constant: {}", input);
279
280         if (input.getContext() == null) {
281             final RpcError error = RpcResultBuilder.newError(
282                     ErrorType.RPC, "Invalid input.", "Context value is null");
283             return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
284         }
285
286         if (input.getConstant() == null) {
287             final RpcError error = RpcResultBuilder.newError(
288                     ErrorType.RPC, "Invalid input.", "Constant value is null");
289             return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
290         }
291
292         if (routedRegistrations.containsKey(input.getContext())) {
293             final RpcError error = RpcResultBuilder.newError(ErrorType.RPC, "Registration present.",
294                     "There is already a rpc registered for context: " + input.getContext());
295             return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
296         }
297
298         final DOMRpcImplementationRegistration<RoutedGetConstantService> registration =
299                 RoutedGetConstantService.registerNew(bindingNormalizedNodeSerializer, domRpcService,
300                         input.getConstant(), input.getContext());
301
302         routedRegistrations.put(input.getContext(), registration);
303         return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
304     }
305
306     @Override
307     public Future<RpcResult<Void>> registerFlappingSingleton() {
308         LOG.debug("Received register-flapping-singleton.");
309
310         if (flappingSingletonService != null) {
311             final RpcError error = RpcResultBuilder.newError(
312                     ErrorType.RPC, "Registration present.", "flappin-singleton already registered");
313             return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
314         }
315
316         flappingSingletonService = new FlappingSingletonService(singletonService);
317
318         return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
319     }
320
321     @Override
322     public Future<RpcResult<UnsubscribeDtclOutput>> unsubscribeDtcl() {
323         return null;
324     }
325
326     @Override
327     public Future<RpcResult<Void>> deconfigureIdIntsShard() {
328         return null;
329     }
330
331     @Override
332     public Future<RpcResult<UnsubscribeYnlOutput>> unsubscribeYnl(final UnsubscribeYnlInput input) {
333         LOG.debug("Received unsubscribe-ynl, input: {}", input);
334
335         if (!ynlRegistrations.containsKey(input.getId())) {
336             final RpcError rpcError = RpcResultBuilder
337                     .newError(ErrorType.APPLICATION, "missing-registration", "No ynl listener with this id registered.");
338             final RpcResult<UnsubscribeYnlOutput> result =
339                     RpcResultBuilder.<UnsubscribeYnlOutput>failed().withRpcError(rpcError).build();
340             return Futures.immediateFuture(result);
341         }
342
343         final ListenerRegistration<YnlListener> registration = ynlRegistrations.remove(input.getId());
344         final UnsubscribeYnlOutput output = registration.getInstance().getOutput();
345
346         registration.close();
347
348         return Futures.immediateFuture(RpcResultBuilder.<UnsubscribeYnlOutput>success().withResult(output).build());
349     }
350
351     @Override
352     public Future<RpcResult<Void>> produceTransactions(ProduceTransactionsInput input) {
353         return null;
354     }
355
356     @Override
357     public Future<RpcResult<Void>> registerConstant(final RegisterConstantInput input) {
358
359         LOG.debug("Received register-constant rpc, input: {}", input);
360
361         if (input.getConstant() == null) {
362             final RpcError error = RpcResultBuilder.newError(
363                     ErrorType.RPC, "Invalid input.", "Constant value is null");
364             return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
365         }
366
367         if (globalGetConstantRegistration != null) {
368             final RpcError error = RpcResultBuilder.newError(ErrorType.RPC, "Registration present.",
369                     "There is already a get-constant rpc registered.");
370             return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
371         }
372
373         globalGetConstantRegistration = GetConstantService.registerNew(domRpcService, input.getConstant());
374         return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
375     }
376
377     @Override
378     public Future<RpcResult<Void>> unregisterDefaultConstant() {
379         return null;
380     }
381
382     @Override
383     public Future<RpcResult<UnsubscribeDdtlOutput>> unsubscribeDdtl() {
384         return null;
385     }
386 }