2 * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.controller.clustering.it.provider;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.SettableFuture;
13 import java.util.HashMap;
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.WriteTransactionsHandler;
22 import org.opendaylight.controller.clustering.it.provider.impl.YnlListener;
23 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
24 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
25 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
26 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationRegistration;
27 import org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService;
28 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
29 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
30 import org.opendaylight.controller.sal.core.api.model.SchemaService;
31 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
32 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
33 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
34 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.AddShardReplicaInput;
35 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.BecomeModuleLeaderInput;
36 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.BecomePrefixLeaderInput;
37 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.IsClientAbortedOutput;
38 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.OdlMdsalLowlevelControlService;
39 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ProduceTransactionsInput;
40 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.PublishNotificationsInput;
41 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterBoundConstantInput;
42 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterConstantInput;
43 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterDefaultConstantInput;
44 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterSingletonConstantInput;
45 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RemoveShardReplicaInput;
46 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeYnlInput;
47 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterBoundConstantInput;
48 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterFlappingSingletonOutput;
49 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterFlappingSingletonOutputBuilder;
50 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDdtlOutput;
51 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDtclOutput;
52 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeYnlInput;
53 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeYnlOutput;
54 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.WriteTransactionsInput;
55 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.WriteTransactionsOutput;
56 import org.opendaylight.yangtools.concepts.ListenerRegistration;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import org.opendaylight.yangtools.yang.common.RpcError;
59 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
60 import org.opendaylight.yangtools.yang.common.RpcResult;
61 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
65 public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService {
67 private static final Logger LOG = LoggerFactory.getLogger(MdsalLowLevelTestProvider.class);
69 private final RpcProviderRegistry rpcRegistry;
70 private final BindingAwareBroker.RpcRegistration<OdlMdsalLowlevelControlService> registration;
71 private final BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer;
72 private final DOMDataBroker domDataBroker;
73 private final NotificationPublishService notificationPublishService;
74 private final NotificationService notificationService;
75 private final SchemaService schemaService;
76 private final ClusterSingletonServiceProvider singletonService;
77 private final DOMRpcProviderService domRpcService;
79 private Map<InstanceIdentifier<?>, DOMRpcImplementationRegistration<RoutedGetConstantService>> routedRegistrations =
82 private Map<String, ListenerRegistration<YnlListener>> ynlRegistrations = new HashMap<>();
84 private DOMRpcImplementationRegistration<GetConstantService> globalGetConstantRegistration = null;
85 private ClusterSingletonServiceRegistration getSingletonConstantRegistration;
86 private FlappingSingletonService flappingSingletonService;
88 public MdsalLowLevelTestProvider(final RpcProviderRegistry rpcRegistry,
89 final DOMRpcProviderService domRpcService,
90 final ClusterSingletonServiceProvider singletonService,
91 final SchemaService schemaService,
92 final BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer,
93 final NotificationPublishService notificationPublishService,
94 final NotificationService notificationService,
95 final DOMDataBroker domDataBroker) {
96 this.rpcRegistry = rpcRegistry;
97 this.domRpcService = domRpcService;
98 this.singletonService = singletonService;
99 this.schemaService = schemaService;
100 this.bindingNormalizedNodeSerializer = bindingNormalizedNodeSerializer;
101 this.notificationPublishService = notificationPublishService;
102 this.notificationService = notificationService;
103 this.domDataBroker = domDataBroker;
105 registration = rpcRegistry.addRpcImplementation(OdlMdsalLowlevelControlService.class, this);
109 public Future<RpcResult<Void>> unregisterSingletonConstant() {
110 LOG.debug("unregister-singleton-constant");
112 if (getSingletonConstantRegistration == null) {
113 LOG.debug("No get-singleton-constant registration present.");
114 final RpcError rpcError = RpcResultBuilder
115 .newError(ErrorType.APPLICATION, "missing-registration", "No get-singleton-constant rpc registration present.");
116 final RpcResult<Void> result = RpcResultBuilder.<Void>failed().withRpcError(rpcError).build();
117 return Futures.immediateFuture(result);
121 getSingletonConstantRegistration.close();
122 getSingletonConstantRegistration = null;
124 return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
125 } catch (final Exception e) {
126 LOG.debug("There was a problem closing the singleton constant service", e);
127 final RpcError rpcError = RpcResultBuilder
128 .newError(ErrorType.APPLICATION, "error-closing", "There was a problem closing get-singleton-constant");
129 final RpcResult<Void> result = RpcResultBuilder.<Void>failed().withRpcError(rpcError).build();
130 return Futures.immediateFuture(result);
135 public Future<RpcResult<Void>> publishNotifications(final PublishNotificationsInput input) {
136 LOG.debug("publish-notifications, input: {}", input);
138 final PublishNotificationsTask task = new PublishNotificationsTask(notificationPublishService, input.getId(),
139 input.getSeconds(), input.getNotificationsPerSecond());
141 final SettableFuture<RpcResult<Void>> settableFuture = SettableFuture.create();
142 task.start(settableFuture);
144 return settableFuture;
148 public Future<RpcResult<Void>> subscribeDtcl() {
153 public Future<RpcResult<WriteTransactionsOutput>> writeTransactions(final WriteTransactionsInput input) {
154 LOG.debug("write-transactions, input: {}", input);
156 final WriteTransactionsHandler writeTransactionsHandler = new WriteTransactionsHandler(domDataBroker, input);
158 final SettableFuture<RpcResult<WriteTransactionsOutput>> settableFuture = SettableFuture.create();
159 writeTransactionsHandler.start(settableFuture);
161 return settableFuture;
165 public Future<RpcResult<IsClientAbortedOutput>> isClientAborted() {
170 public Future<RpcResult<Void>> becomeModuleLeader(BecomeModuleLeaderInput input) {
175 public Future<RpcResult<Void>> removeShardReplica(RemoveShardReplicaInput input) {
180 public Future<RpcResult<Void>> subscribeYnl(final SubscribeYnlInput input) {
182 LOG.debug("subscribe-ynl, input: {}", input);
184 if (ynlRegistrations.containsKey(input.getId())) {
185 final RpcError error = RpcResultBuilder.newError(ErrorType.RPC, "Registration present.",
186 "There is already ynl listener registered for this id: " + input.getId());
187 return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
190 ynlRegistrations.put(input.getId(),
191 notificationService.registerNotificationListener(new YnlListener(input.getId())));
193 return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
197 public Future<RpcResult<Void>> becomePrefixLeader(BecomePrefixLeaderInput input) {
202 public Future<RpcResult<Void>> unregisterBoundConstant(final UnregisterBoundConstantInput input) {
203 LOG.debug("unregister-bound-constant, {}", input);
205 final DOMRpcImplementationRegistration<RoutedGetConstantService> registration =
206 routedRegistrations.remove(input.getContext());
208 if (registration == null) {
209 LOG.debug("No get-contexted-constant registration for context: {}", input.getContext());
210 final RpcError rpcError = RpcResultBuilder
211 .newError(ErrorType.APPLICATION, "missing-registration", "No get-constant rpc registration present.");
212 final RpcResult<Void> result = RpcResultBuilder.<Void>failed().withRpcError(rpcError).build();
213 return Futures.immediateFuture(result);
216 registration.close();
217 return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
221 public Future<RpcResult<Void>> registerSingletonConstant(final RegisterSingletonConstantInput input) {
223 LOG.debug("Received register-singleton-constant rpc, input: {}", input);
225 if (input.getConstant() == null) {
226 final RpcError error = RpcResultBuilder.newError(
227 ErrorType.RPC, "Invalid input.", "Constant value is null");
228 return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
231 getSingletonConstantRegistration =
232 SingletonGetConstantService.registerNew(singletonService, domRpcService, input.getConstant());
234 return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
238 public Future<RpcResult<Void>> registerDefaultConstant(RegisterDefaultConstantInput input) {
243 public Future<RpcResult<Void>> unregisterConstant() {
245 if (globalGetConstantRegistration == null) {
246 final RpcError rpcError = RpcResultBuilder
247 .newError(ErrorType.APPLICATION, "missing-registration", "No get-constant rpc registration present.");
248 final RpcResult<Void> result = RpcResultBuilder.<Void>failed().withRpcError(rpcError).build();
249 return Futures.immediateFuture(result);
252 globalGetConstantRegistration.close();
253 globalGetConstantRegistration = null;
255 return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
259 public Future<RpcResult<UnregisterFlappingSingletonOutput>> unregisterFlappingSingleton() {
260 LOG.debug("unregister-flapping-singleton received.");
262 if (flappingSingletonService == null) {
263 final RpcError rpcError = RpcResultBuilder
264 .newError(ErrorType.APPLICATION, "missing-registration", "No flapping-singleton registration present.");
265 final RpcResult<UnregisterFlappingSingletonOutput> result =
266 RpcResultBuilder.<UnregisterFlappingSingletonOutput>failed().withRpcError(rpcError).build();
267 return Futures.immediateFuture(result);
270 final long flapCount = flappingSingletonService.setInactive();
271 flappingSingletonService = null;
273 final UnregisterFlappingSingletonOutput output =
274 new UnregisterFlappingSingletonOutputBuilder().setFlapCount(flapCount).build();
276 return Futures.immediateFuture(RpcResultBuilder.success(output).build());
280 public Future<RpcResult<Void>> addShardReplica(AddShardReplicaInput input) {
285 public Future<RpcResult<Void>> subscribeDdtl() {
290 public Future<RpcResult<Void>> registerBoundConstant(final RegisterBoundConstantInput input) {
291 LOG.debug("register-bound-constant: {}", input);
293 if (input.getContext() == null) {
294 final RpcError error = RpcResultBuilder.newError(
295 ErrorType.RPC, "Invalid input.", "Context value is null");
296 return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
299 if (input.getConstant() == null) {
300 final RpcError error = RpcResultBuilder.newError(
301 ErrorType.RPC, "Invalid input.", "Constant value is null");
302 return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
305 if (routedRegistrations.containsKey(input.getContext())) {
306 final RpcError error = RpcResultBuilder.newError(ErrorType.RPC, "Registration present.",
307 "There is already a rpc registered for context: " + input.getContext());
308 return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
311 final DOMRpcImplementationRegistration<RoutedGetConstantService> registration =
312 RoutedGetConstantService.registerNew(bindingNormalizedNodeSerializer, domRpcService,
313 input.getConstant(), input.getContext());
315 routedRegistrations.put(input.getContext(), registration);
316 return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
320 public Future<RpcResult<Void>> registerFlappingSingleton() {
321 LOG.debug("Received register-flapping-singleton.");
323 if (flappingSingletonService != null) {
324 final RpcError error = RpcResultBuilder.newError(
325 ErrorType.RPC, "Registration present.", "flappin-singleton already registered");
326 return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
329 flappingSingletonService = new FlappingSingletonService(singletonService);
331 return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
335 public Future<RpcResult<UnsubscribeDtclOutput>> unsubscribeDtcl() {
340 public Future<RpcResult<Void>> deconfigureIdIntsShard() {
345 public Future<RpcResult<UnsubscribeYnlOutput>> unsubscribeYnl(final UnsubscribeYnlInput input) {
346 LOG.debug("Received unsubscribe-ynl, input: {}", input);
348 if (!ynlRegistrations.containsKey(input.getId())) {
349 final RpcError rpcError = RpcResultBuilder
350 .newError(ErrorType.APPLICATION, "missing-registration", "No ynl listener with this id registered.");
351 final RpcResult<UnsubscribeYnlOutput> result =
352 RpcResultBuilder.<UnsubscribeYnlOutput>failed().withRpcError(rpcError).build();
353 return Futures.immediateFuture(result);
356 final ListenerRegistration<YnlListener> registration = ynlRegistrations.remove(input.getId());
357 final UnsubscribeYnlOutput output = registration.getInstance().getOutput();
359 registration.close();
361 return Futures.immediateFuture(RpcResultBuilder.<UnsubscribeYnlOutput>success().withResult(output).build());
365 public Future<RpcResult<Void>> produceTransactions(ProduceTransactionsInput input) {
370 public Future<RpcResult<Void>> registerConstant(final RegisterConstantInput input) {
372 LOG.debug("Received register-constant rpc, input: {}", input);
374 if (input.getConstant() == null) {
375 final RpcError error = RpcResultBuilder.newError(
376 ErrorType.RPC, "Invalid input.", "Constant value is null");
377 return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
380 if (globalGetConstantRegistration != null) {
381 final RpcError error = RpcResultBuilder.newError(ErrorType.RPC, "Registration present.",
382 "There is already a get-constant rpc registered.");
383 return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
386 globalGetConstantRegistration = GetConstantService.registerNew(domRpcService, input.getConstant());
387 return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
391 public Future<RpcResult<Void>> unregisterDefaultConstant() {
396 public Future<RpcResult<UnsubscribeDdtlOutput>> unsubscribeDdtl() {