Bump versions 9.0.4-SNAPSHOT
[controller.git] / opendaylight / md-sal / samples / clustering-test-app / provider / src / main / java / org / opendaylight / controller / clustering / it / provider / MdsalLowLevelTestProvider.java
index 8e26cb6f957470edd036b537cd601275c84a5298..10dafba452be749dbafd447f93c70b65ccd2f1e3 100644 (file)
@@ -8,11 +8,10 @@
 package org.opendaylight.controller.clustering.it.provider;
 
 import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
+import akka.dispatch.Futures;
 import akka.dispatch.OnComplete;
 import akka.pattern.Patterns;
 import com.google.common.base.Strings;
-import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.SettableFuture;
 import java.util.HashMap;
@@ -21,7 +20,9 @@ import java.util.Optional;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import org.opendaylight.controller.cluster.ActorSystemProvider;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Singleton;
 import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
 import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
 import org.opendaylight.controller.cluster.raft.client.messages.Shutdown;
@@ -39,150 +40,201 @@ import org.opendaylight.mdsal.binding.api.RpcProviderService;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService;
+import org.opendaylight.mdsal.dom.api.DOMDataBroker.DataTreeChangeExtension;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
-import org.opendaylight.mdsal.dom.api.DOMRpcImplementationRegistration;
 import org.opendaylight.mdsal.dom.api.DOMRpcProviderService;
 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+import org.opendaylight.mdsal.singleton.api.ClusterSingletonServiceProvider;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.AddShardReplica;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.AddShardReplicaInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.AddShardReplicaOutput;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.CheckPublishNotifications;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.CheckPublishNotificationsInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.CheckPublishNotificationsOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.CheckPublishNotificationsOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.IsClientAborted;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.IsClientAbortedInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.IsClientAbortedOutput;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.OdlMdsalLowlevelControlService;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterBoundConstant;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterBoundConstantInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterBoundConstantOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterBoundConstantOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterConstant;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterConstantInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterConstantOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterConstantOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterDefaultConstant;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterDefaultConstantInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterDefaultConstantOutput;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterFlappingSingleton;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterFlappingSingletonInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterFlappingSingletonOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterFlappingSingletonOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterSingletonConstant;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterSingletonConstantInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterSingletonConstantOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterSingletonConstantOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RemoveShardReplica;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RemoveShardReplicaInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RemoveShardReplicaOutput;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ShutdownShardReplica;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ShutdownShardReplicaInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ShutdownShardReplicaOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ShutdownShardReplicaOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.StartPublishNotifications;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.StartPublishNotificationsInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.StartPublishNotificationsOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.StartPublishNotificationsOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeDdtl;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeDdtlInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeDdtlOutput;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeDtcl;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeDtclInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeDtclOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeDtclOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeYnl;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeYnlInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeYnlOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeYnlOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterBoundConstant;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterBoundConstantInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterBoundConstantOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterBoundConstantOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterConstant;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterConstantInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterConstantOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterConstantOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterDefaultConstant;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterDefaultConstantInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterDefaultConstantOutput;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterFlappingSingleton;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterFlappingSingletonInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterFlappingSingletonOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterFlappingSingletonOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterSingletonConstant;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterSingletonConstantInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterSingletonConstantOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterSingletonConstantOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDdtl;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDdtlInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDdtlOutput;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDtcl;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDtclInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDtclOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDtclOutputBuilder;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeYnl;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeYnlInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeYnlOutput;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.WriteTransactions;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.WriteTransactionsInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.WriteTransactionsOutput;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.target.rev170215.IdSequence;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
 import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
+import org.opendaylight.yangtools.yang.common.ErrorType;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import scala.concurrent.duration.FiniteDuration;
 
-public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService {
+@Singleton
+@Component(service = {})
+public final class MdsalLowLevelTestProvider {
     private static final Logger LOG = LoggerFactory.getLogger(MdsalLowLevelTestProvider.class);
 
-    private final RpcProviderService rpcRegistry;
-    private final ObjectRegistration<OdlMdsalLowlevelControlService> registration;
+    private final Registration registration;
     private final DistributedDataStoreInterface configDataStore;
     private final BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer;
     private final DOMDataBroker domDataBroker;
     private final NotificationPublishService notificationPublishService;
     private final NotificationService notificationService;
-    private final DOMSchemaService schemaService;
     private final ClusterSingletonServiceProvider singletonService;
     private final DOMRpcProviderService domRpcService;
-    private final DOMDataTreeChangeService domDataTreeChangeService;
-    private final ActorSystem actorSystem;
+    private final DataTreeChangeExtension dataTreeChangeExtension;
 
-    private final Map<InstanceIdentifier<?>, DOMRpcImplementationRegistration<RoutedGetConstantService>>
-            routedRegistrations = new HashMap<>();
-
-    private final Map<String, ListenerRegistration<YnlListener>> ynlRegistrations = new HashMap<>();
+    private final Map<InstanceIdentifier<?>, Registration> routedRegistrations = new HashMap<>();
+    private final Map<String, ObjectRegistration<YnlListener>> ynlRegistrations = new HashMap<>();
+    private final Map<String, PublishNotificationsTask> publishNotificationsTasks = new HashMap<>();
 
-    private DOMRpcImplementationRegistration<GetConstantService> globalGetConstantRegistration = null;
-    private ClusterSingletonServiceRegistration getSingletonConstantRegistration;
+    private Registration globalGetConstantRegistration = null;
+    private Registration getSingletonConstantRegistration;
     private FlappingSingletonService flappingSingletonService;
-    private ListenerRegistration<DOMDataTreeChangeListener> dtclReg;
+    private Registration dtclReg;
     private IdIntsListener idIntsListener;
-    private final Map<String, PublishNotificationsTask> publishNotificationsTasks = new HashMap<>();
 
-    public MdsalLowLevelTestProvider(final RpcProviderService rpcRegistry,
-                                     final DOMRpcProviderService domRpcService,
-                                     final ClusterSingletonServiceProvider singletonService,
-                                     final DOMSchemaService schemaService,
-                                     final BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer,
-                                     final NotificationPublishService notificationPublishService,
-                                     final NotificationService notificationService,
-                                     final DOMDataBroker domDataBroker,
-                                     final DistributedDataStoreInterface configDataStore,
-                                     final ActorSystemProvider actorSystemProvider) {
-        this.rpcRegistry = rpcRegistry;
+    @Inject
+    @Activate
+    public MdsalLowLevelTestProvider(
+            @Reference final RpcProviderService rpcRegistry,
+            @Reference final DOMRpcProviderService domRpcService,
+            @Reference final ClusterSingletonServiceProvider singletonService,
+            @Reference final DOMSchemaService schemaService,
+            @Reference final BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer,
+            @Reference final NotificationPublishService notificationPublishService,
+            @Reference final NotificationService notificationService,
+            @Reference final DOMDataBroker domDataBroker,
+            @Reference final DistributedDataStoreInterface configDataStore) {
         this.domRpcService = domRpcService;
         this.singletonService = singletonService;
-        this.schemaService = schemaService;
         this.bindingNormalizedNodeSerializer = bindingNormalizedNodeSerializer;
         this.notificationPublishService = notificationPublishService;
         this.notificationService = notificationService;
         this.domDataBroker = domDataBroker;
         this.configDataStore = configDataStore;
-        this.actorSystem = actorSystemProvider.getActorSystem();
 
-        domDataTreeChangeService = domDataBroker.getExtensions().getInstance(DOMDataTreeChangeService.class);
+        dataTreeChangeExtension = domDataBroker.extension(DataTreeChangeExtension.class);
+
+        registration = rpcRegistry.registerRpcImplementations(
+            (UnregisterSingletonConstant) this::unregisterSingletonConstant,
+            (StartPublishNotifications) this::startPublishNotifications,
+            (SubscribeDdtl) this::subscribeDdtl,
+            (WriteTransactions) this::writeTransactions,
+            (IsClientAborted) this::isClientAborted,
+            (RemoveShardReplica) this::removeShardReplica,
+            (SubscribeYnl) this::subscribeYnl,
+            (UnregisterBoundConstant) this::unregisterBoundConstant,
+            (RegisterSingletonConstant) this::registerSingletonConstant,
+            (RegisterDefaultConstant) this::registerDefaultConstant,
+            (UnregisterConstant) this::unregisterConstant,
+            (UnregisterFlappingSingleton) this::unregisterFlappingSingleton,
+            (AddShardReplica) this::addShardReplica,
+            (RegisterBoundConstant) this::registerBoundConstant,
+            (RegisterFlappingSingleton) this::registerFlappingSingleton,
+            (UnsubscribeDdtl) this::unsubscribeDdtl,
+            (UnsubscribeYnl) this::unsubscribeYnl,
+            (CheckPublishNotifications) this::checkPublishNotifications,
+            (ShutdownShardReplica) this::shutdownShardReplica,
+            (RegisterConstant) this::registerConstant,
+            (UnregisterDefaultConstant) this::unregisterDefaultConstant,
+            (SubscribeDtcl) this::subscribeDtcl,
+            (UnsubscribeDtcl) this::unsubscribeDtcl);
+    }
 
-        registration = rpcRegistry.registerRpcImplementation(OdlMdsalLowlevelControlService.class, this);
+    @PreDestroy
+    @Deactivate
+    public void close() {
+        registration.close();
     }
 
-    @Override
     @SuppressWarnings("checkstyle:IllegalCatch")
-    public ListenableFuture<RpcResult<UnregisterSingletonConstantOutput>> unregisterSingletonConstant(
+    private ListenableFuture<RpcResult<UnregisterSingletonConstantOutput>> unregisterSingletonConstant(
             final UnregisterSingletonConstantInput input) {
         LOG.info("In unregisterSingletonConstant");
 
         if (getSingletonConstantRegistration == null) {
-            return RpcResultBuilder.<UnregisterSingletonConstantOutput>failed().withError(ErrorType.RPC, "data-missing",
-                    "No prior RPC was registered").buildFuture();
+            return RpcResultBuilder.<UnregisterSingletonConstantOutput>failed()
+                .withError(ErrorType.RPC, ErrorTag.DATA_MISSING, "No prior RPC was registered")
+                .buildFuture();
         }
 
         try {
@@ -198,8 +250,7 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
         }
     }
 
-    @Override
-    public ListenableFuture<RpcResult<StartPublishNotificationsOutput>> startPublishNotifications(
+    private ListenableFuture<RpcResult<StartPublishNotificationsOutput>> startPublishNotifications(
             final StartPublishNotificationsInput input) {
         LOG.info("In startPublishNotifications - input: {}", input);
 
@@ -213,81 +264,85 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
         return RpcResultBuilder.success(new StartPublishNotificationsOutputBuilder().build()).buildFuture();
     }
 
-    @Override
-    public ListenableFuture<RpcResult<SubscribeDtclOutput>> subscribeDtcl(final SubscribeDtclInput input) {
+    private ListenableFuture<RpcResult<SubscribeDtclOutput>> subscribeDtcl(final SubscribeDtclInput input) {
         LOG.info("In subscribeDtcl - input: {}", input);
 
         if (dtclReg != null) {
-            return RpcResultBuilder.<SubscribeDtclOutput>failed().withError(ErrorType.RPC,
-                "data-exists", "There is already a DataTreeChangeListener registered for id-ints").buildFuture();
+            return RpcResultBuilder.<SubscribeDtclOutput>failed().withError(ErrorType.RPC, ErrorTag.DATA_EXISTS,
+                "There is already a DataTreeChangeListener registered for id-ints")
+                .buildFuture();
         }
 
         idIntsListener = new IdIntsListener();
 
-        dtclReg = domDataTreeChangeService.registerDataTreeChangeListener(
-            new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, WriteTransactionsHandler.ID_INT_YID),
+        dtclReg = dataTreeChangeExtension.registerTreeChangeListener(
+            DOMDataTreeIdentifier.of(LogicalDatastoreType.CONFIGURATION, WriteTransactionsHandler.ID_INT_YID),
             idIntsListener);
 
         return RpcResultBuilder.success(new SubscribeDtclOutputBuilder().build()).buildFuture();
     }
 
-    @Override
-    public ListenableFuture<RpcResult<WriteTransactionsOutput>> writeTransactions(final WriteTransactionsInput input) {
+    private ListenableFuture<RpcResult<WriteTransactionsOutput>> writeTransactions(final WriteTransactionsInput input) {
         return WriteTransactionsHandler.start(domDataBroker, input);
     }
 
-    @Override
-    public ListenableFuture<RpcResult<IsClientAbortedOutput>> isClientAborted(final IsClientAbortedInput input) {
+    private ListenableFuture<RpcResult<IsClientAbortedOutput>> isClientAborted(final IsClientAbortedInput input) {
         return null;
     }
 
-    @Override
-    public ListenableFuture<RpcResult<RemoveShardReplicaOutput>> removeShardReplica(
+    private ListenableFuture<RpcResult<RemoveShardReplicaOutput>> removeShardReplica(
             final RemoveShardReplicaInput input) {
         return null;
     }
 
-    @Override
-    public ListenableFuture<RpcResult<SubscribeYnlOutput>> subscribeYnl(final SubscribeYnlInput input) {
+    private ListenableFuture<RpcResult<SubscribeYnlOutput>> subscribeYnl(final SubscribeYnlInput input) {
         LOG.info("In subscribeYnl - input: {}", input);
 
         if (ynlRegistrations.containsKey(input.getId())) {
-            return RpcResultBuilder.<SubscribeYnlOutput>failed().withError(ErrorType.RPC,
-                "data-exists", "There is already a listener registered for id: " + input.getId()).buildFuture();
+            return RpcResultBuilder.<SubscribeYnlOutput>failed()
+                .withError(ErrorType.RPC, ErrorTag.DATA_EXISTS,
+                    "There is already a listener registered for id: " + input.getId())
+                .buildFuture();
         }
 
-        ynlRegistrations.put(input.getId(),
-                notificationService.registerNotificationListener(new YnlListener(input.getId())));
+        final var id = input.getId();
+        final var listener = new YnlListener(id);
+        final var reg = notificationService.registerListener(IdSequence.class, listener);
+        ynlRegistrations.put(id, new AbstractObjectRegistration<>(listener) {
+            @Override
+            protected void removeRegistration() {
+                reg.close();
+            }
+        });
 
         return RpcResultBuilder.success(new SubscribeYnlOutputBuilder().build()).buildFuture();
     }
 
 
-    @Override
-    public ListenableFuture<RpcResult<UnregisterBoundConstantOutput>> unregisterBoundConstant(
+    private ListenableFuture<RpcResult<UnregisterBoundConstantOutput>> unregisterBoundConstant(
             final UnregisterBoundConstantInput input) {
         LOG.info("In unregisterBoundConstant - {}", input);
 
-        final DOMRpcImplementationRegistration<RoutedGetConstantService> rpcRegistration =
-                routedRegistrations.remove(input.getContext());
-
+        final var rpcRegistration = routedRegistrations.remove(input.getContext());
         if (rpcRegistration == null) {
-            return RpcResultBuilder.<UnregisterBoundConstantOutput>failed().withError(
-                ErrorType.RPC, "data-missing", "No prior RPC was registered for " + input.getContext()).buildFuture();
+            return RpcResultBuilder.<UnregisterBoundConstantOutput>failed()
+                .withError(ErrorType.RPC, ErrorTag.DATA_MISSING,
+                    "No prior RPC was registered for " + input.getContext())
+                .buildFuture();
         }
 
         rpcRegistration.close();
         return RpcResultBuilder.success(new UnregisterBoundConstantOutputBuilder().build()).buildFuture();
     }
 
-    @Override
-    public ListenableFuture<RpcResult<RegisterSingletonConstantOutput>> registerSingletonConstant(
+    private ListenableFuture<RpcResult<RegisterSingletonConstantOutput>> registerSingletonConstant(
             final RegisterSingletonConstantInput input) {
         LOG.info("In registerSingletonConstant - input: {}", input);
 
         if (input.getConstant() == null) {
-            return RpcResultBuilder.<RegisterSingletonConstantOutput>failed().withError(
-                    ErrorType.RPC, "invalid-value", "Constant value is null").buildFuture();
+            return RpcResultBuilder.<RegisterSingletonConstantOutput>failed()
+                .withError(ErrorType.RPC, ErrorTag.INVALID_VALUE, "Constant value is null")
+                .buildFuture();
         }
 
         getSingletonConstantRegistration =
@@ -296,36 +351,35 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
         return RpcResultBuilder.success(new RegisterSingletonConstantOutputBuilder().build()).buildFuture();
     }
 
-    @Override
-    public ListenableFuture<RpcResult<RegisterDefaultConstantOutput>> registerDefaultConstant(
+    private ListenableFuture<RpcResult<RegisterDefaultConstantOutput>> registerDefaultConstant(
             final RegisterDefaultConstantInput input) {
         return null;
     }
 
-    @Override
-    public ListenableFuture<RpcResult<UnregisterConstantOutput>> unregisterConstant(
+    private ListenableFuture<RpcResult<UnregisterConstantOutput>> unregisterConstant(
             final UnregisterConstantInput input) {
         LOG.info("In unregisterConstant");
 
         if (globalGetConstantRegistration == null) {
-            return RpcResultBuilder.<UnregisterConstantOutput>failed().withError(
-                ErrorType.RPC, "data-missing", "No prior RPC was registered").buildFuture();
+            return RpcResultBuilder.<UnregisterConstantOutput>failed()
+                .withError(ErrorType.RPC, ErrorTag.DATA_MISSING, "No prior RPC was registered")
+                .buildFuture();
         }
 
         globalGetConstantRegistration.close();
         globalGetConstantRegistration = null;
 
-        return Futures.immediateFuture(RpcResultBuilder.success(new UnregisterConstantOutputBuilder().build()).build());
+        return RpcResultBuilder.success(new UnregisterConstantOutputBuilder().build()).buildFuture();
     }
 
-    @Override
-    public ListenableFuture<RpcResult<UnregisterFlappingSingletonOutput>> unregisterFlappingSingleton(
+    private ListenableFuture<RpcResult<UnregisterFlappingSingletonOutput>> unregisterFlappingSingleton(
             final UnregisterFlappingSingletonInput input) {
         LOG.info("In unregisterFlappingSingleton");
 
         if (flappingSingletonService == null) {
-            return RpcResultBuilder.<UnregisterFlappingSingletonOutput>failed().withError(
-                ErrorType.RPC, "data-missing", "No prior RPC was registered").buildFuture();
+            return RpcResultBuilder.<UnregisterFlappingSingletonOutput>failed()
+                .withError(ErrorType.RPC, ErrorTag.DATA_MISSING, "No prior RPC was registered")
+                .buildFuture();
         }
 
         final long flapCount = flappingSingletonService.setInactive();
@@ -335,52 +389,49 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
                 .buildFuture();
     }
 
-    @Override
-    public ListenableFuture<RpcResult<AddShardReplicaOutput>> addShardReplica(final AddShardReplicaInput input) {
+    private ListenableFuture<RpcResult<AddShardReplicaOutput>> addShardReplica(final AddShardReplicaInput input) {
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public ListenableFuture<RpcResult<SubscribeDdtlOutput>> subscribeDdtl(final SubscribeDdtlInput input) {
+    private ListenableFuture<RpcResult<SubscribeDdtlOutput>> subscribeDdtl(final SubscribeDdtlInput input) {
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public ListenableFuture<RpcResult<RegisterBoundConstantOutput>> registerBoundConstant(
+    private ListenableFuture<RpcResult<RegisterBoundConstantOutput>> registerBoundConstant(
             final RegisterBoundConstantInput input) {
         LOG.info("In registerBoundConstant - input: {}", input);
 
         if (input.getContext() == null) {
             return RpcResultBuilder.<RegisterBoundConstantOutput>failed().withError(
-                    ErrorType.RPC, "invalid-value", "Context value is null").buildFuture();
+                    ErrorType.RPC, ErrorTag.INVALID_VALUE, "Context value is null").buildFuture();
         }
 
         if (input.getConstant() == null) {
             return RpcResultBuilder.<RegisterBoundConstantOutput>failed().withError(
-                    ErrorType.RPC, "invalid-value", "Constant value is null").buildFuture();
+                    ErrorType.RPC, ErrorTag.INVALID_VALUE, "Constant value is null").buildFuture();
         }
 
         if (routedRegistrations.containsKey(input.getContext())) {
             return RpcResultBuilder.<RegisterBoundConstantOutput>failed().withError(ErrorType.RPC,
-                "data-exists", "There is already an rpc registered for context: " + input.getContext()).buildFuture();
+                ErrorTag.DATA_EXISTS, "There is already an rpc registered for context: " + input.getContext())
+                .buildFuture();
         }
 
-        final DOMRpcImplementationRegistration<RoutedGetConstantService> rpcRegistration =
-                RoutedGetConstantService.registerNew(bindingNormalizedNodeSerializer, domRpcService,
-                        input.getConstant(), input.getContext());
+        final var rpcRegistration = RoutedGetConstantService.registerNew(bindingNormalizedNodeSerializer, domRpcService,
+            input.getConstant(), input.getContext());
 
         routedRegistrations.put(input.getContext(), rpcRegistration);
         return RpcResultBuilder.success(new RegisterBoundConstantOutputBuilder().build()).buildFuture();
     }
 
-    @Override
-    public ListenableFuture<RpcResult<RegisterFlappingSingletonOutput>> registerFlappingSingleton(
+    private ListenableFuture<RpcResult<RegisterFlappingSingletonOutput>> registerFlappingSingleton(
             final RegisterFlappingSingletonInput input) {
         LOG.info("In registerFlappingSingleton");
 
         if (flappingSingletonService != null) {
-            return RpcResultBuilder.<RegisterFlappingSingletonOutput>failed().withError(ErrorType.RPC,
-                "data-exists", "There is already an rpc registered").buildFuture();
+            return RpcResultBuilder.<RegisterFlappingSingletonOutput>failed()
+                .withError(ErrorType.RPC, ErrorTag.DATA_EXISTS, "There is already an rpc registered")
+                .buildFuture();
         }
 
         flappingSingletonService = new FlappingSingletonService(singletonService);
@@ -388,13 +439,13 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
         return RpcResultBuilder.success(new RegisterFlappingSingletonOutputBuilder().build()).buildFuture();
     }
 
-    @Override
-    public ListenableFuture<RpcResult<UnsubscribeDtclOutput>> unsubscribeDtcl(final UnsubscribeDtclInput input) {
+    private ListenableFuture<RpcResult<UnsubscribeDtclOutput>> unsubscribeDtcl(final UnsubscribeDtclInput input) {
         LOG.info("In unsubscribeDtcl");
 
         if (idIntsListener == null || dtclReg == null) {
-            return RpcResultBuilder.<UnsubscribeDtclOutput>failed().withError(
-                    ErrorType.RPC, "data-missing", "No prior listener was registered").buildFuture();
+            return RpcResultBuilder.<UnsubscribeDtclOutput>failed()
+                .withError(ErrorType.RPC, ErrorTag.DATA_MISSING, "No prior listener was registered")
+                .buildFuture();
         }
 
         long timeout = 120L;
@@ -410,8 +461,10 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
         dtclReg = null;
 
         if (!idIntsListener.hasTriggered()) {
-            return RpcResultBuilder.<UnsubscribeDtclOutput>failed().withError(ErrorType.APPLICATION, "operation-failed",
-                    "id-ints listener has not received any notifications.").buildFuture();
+            return RpcResultBuilder.<UnsubscribeDtclOutput>failed()
+                .withError(ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED,
+                    "id-ints listener has not received any notifications.")
+                .buildFuture();
         }
 
         try (DOMDataTreeReadTransaction rTx = domDataBroker.newReadOnlyTransaction()) {
@@ -419,17 +472,18 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
                 WriteTransactionsHandler.ID_INT_YID).get();
 
             if (!readResult.isPresent()) {
-                return RpcResultBuilder.<UnsubscribeDtclOutput>failed().withError(ErrorType.APPLICATION, "data-missing",
-                        "No data read from id-ints list").buildFuture();
+                return RpcResultBuilder.<UnsubscribeDtclOutput>failed()
+                    .withError(ErrorType.APPLICATION, ErrorTag.DATA_MISSING, "No data read from id-ints list")
+                    .buildFuture();
             }
 
-            final boolean nodesEqual = idIntsListener.checkEqual(readResult.get());
+            final boolean nodesEqual = idIntsListener.checkEqual(readResult.orElseThrow());
             if (!nodesEqual) {
                 LOG.error("Final read of id-int does not match IdIntsListener's copy. {}",
-                        idIntsListener.diffWithLocalCopy(readResult.get()));
+                        idIntsListener.diffWithLocalCopy(readResult.orElseThrow()));
             }
 
-            return RpcResultBuilder.success(new UnsubscribeDtclOutputBuilder().setCopyMatches(nodesEqual))
+            return RpcResultBuilder.success(new UnsubscribeDtclOutputBuilder().setCopyMatches(nodesEqual).build())
                     .buildFuture();
 
         } catch (final InterruptedException | ExecutionException e) {
@@ -439,33 +493,32 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
         }
     }
 
-    @Override
-    public ListenableFuture<RpcResult<UnsubscribeYnlOutput>> unsubscribeYnl(final UnsubscribeYnlInput input) {
+    private ListenableFuture<RpcResult<UnsubscribeYnlOutput>> unsubscribeYnl(final UnsubscribeYnlInput input) {
         LOG.info("In unsubscribeYnl - input: {}", input);
 
         if (!ynlRegistrations.containsKey(input.getId())) {
-            return RpcResultBuilder.<UnsubscribeYnlOutput>failed().withError(
-                ErrorType.RPC, "data-missing", "No prior listener was registered for " + input.getId()).buildFuture();
+            return RpcResultBuilder.<UnsubscribeYnlOutput>failed()
+                .withError(ErrorType.RPC, ErrorTag.DATA_MISSING,
+                    "No prior listener was registered for " + input.getId())
+                .buildFuture();
         }
 
-        final ListenerRegistration<YnlListener> reg = ynlRegistrations.remove(input.getId());
-        final UnsubscribeYnlOutput output = reg.getInstance().getOutput();
-
-        reg.close();
-
-        return RpcResultBuilder.<UnsubscribeYnlOutput>success().withResult(output).buildFuture();
+        try (var reg = ynlRegistrations.remove(input.getId())) {
+            return RpcResultBuilder.<UnsubscribeYnlOutput>success()
+                .withResult(reg.getInstance().getOutput())
+                .buildFuture();
+        }
     }
 
-    @Override
-    public ListenableFuture<RpcResult<CheckPublishNotificationsOutput>> checkPublishNotifications(
+    private ListenableFuture<RpcResult<CheckPublishNotificationsOutput>> checkPublishNotifications(
             final CheckPublishNotificationsInput input) {
         LOG.info("In checkPublishNotifications - input: {}", input);
 
         final PublishNotificationsTask task = publishNotificationsTasks.get(input.getId());
 
         if (task == null) {
-            return Futures.immediateFuture(RpcResultBuilder.success(
-                    new CheckPublishNotificationsOutputBuilder().setActive(false)).build());
+            return RpcResultBuilder.success(new CheckPublishNotificationsOutputBuilder().setActive(false).build())
+                .buildFuture();
         }
 
         final CheckPublishNotificationsOutputBuilder checkPublishNotificationsOutputBuilder =
@@ -482,15 +535,15 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
         return RpcResultBuilder.success(output).buildFuture();
     }
 
-    @Override
-    public ListenableFuture<RpcResult<ShutdownShardReplicaOutput>> shutdownShardReplica(
+    private ListenableFuture<RpcResult<ShutdownShardReplicaOutput>> shutdownShardReplica(
             final ShutdownShardReplicaInput input) {
         LOG.info("In shutdownShardReplica - input: {}", input);
 
         final String shardName = input.getShardName();
         if (Strings.isNullOrEmpty(shardName)) {
-            return RpcResultBuilder.<ShutdownShardReplicaOutput>failed().withError(ErrorType.RPC, "bad-element",
-                shardName + "is not a valid shard name").buildFuture();
+            return RpcResultBuilder.<ShutdownShardReplicaOutput>failed()
+                .withError(ErrorType.RPC, ErrorTag.BAD_ELEMENT, shardName + "is not a valid shard name")
+                .buildFuture();
         }
 
         return shutdownShardGracefully(shardName, new ShutdownShardReplicaOutputBuilder().build());
@@ -503,7 +556,7 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
         long timeoutInMS = Math.max(context.getDatastoreContext().getShardRaftConfig()
                 .getElectionTimeOutInterval().$times(3).toMillis(), 10000);
         final FiniteDuration duration = FiniteDuration.apply(timeoutInMS, TimeUnit.MILLISECONDS);
-        final scala.concurrent.Promise<Boolean> shutdownShardAsk = akka.dispatch.Futures.promise();
+        final scala.concurrent.Promise<Boolean> shutdownShardAsk = Futures.promise();
 
         context.findLocalShardAsync(shardName).onComplete(new OnComplete<ActorRef>() {
             @Override
@@ -533,33 +586,32 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
         return rpcResult;
     }
 
-    @Override
-    public ListenableFuture<RpcResult<RegisterConstantOutput>> registerConstant(final RegisterConstantInput input) {
+    private ListenableFuture<RpcResult<RegisterConstantOutput>> registerConstant(final RegisterConstantInput input) {
         LOG.info("In registerConstant - input: {}", input);
 
         if (input.getConstant() == null) {
-            return RpcResultBuilder.<RegisterConstantOutput>failed().withError(
-                    ErrorType.RPC, "invalid-value", "Constant value is null").buildFuture();
+            return RpcResultBuilder.<RegisterConstantOutput>failed()
+                .withError(ErrorType.RPC, ErrorTag.INVALID_VALUE, "Constant value is null")
+                .buildFuture();
         }
 
         if (globalGetConstantRegistration != null) {
-            return RpcResultBuilder.<RegisterConstantOutput>failed().withError(ErrorType.RPC,
-                    "data-exists", "There is already an rpc registered").buildFuture();
+            return RpcResultBuilder.<RegisterConstantOutput>failed()
+                .withError(ErrorType.RPC, ErrorTag.DATA_EXISTS, "There is already an rpc registered")
+                .buildFuture();
         }
 
         globalGetConstantRegistration = GetConstantService.registerNew(domRpcService, input.getConstant());
         return RpcResultBuilder.success(new RegisterConstantOutputBuilder().build()).buildFuture();
     }
 
-    @Override
-    public ListenableFuture<RpcResult<UnregisterDefaultConstantOutput>> unregisterDefaultConstant(
+    private ListenableFuture<RpcResult<UnregisterDefaultConstantOutput>> unregisterDefaultConstant(
             final UnregisterDefaultConstantInput input) {
         throw new UnsupportedOperationException();
     }
 
-    @Override
     @SuppressWarnings("checkstyle:IllegalCatch")
-    public ListenableFuture<RpcResult<UnsubscribeDdtlOutput>> unsubscribeDdtl(final UnsubscribeDdtlInput input) {
+    private ListenableFuture<RpcResult<UnsubscribeDdtlOutput>> unsubscribeDdtl(final UnsubscribeDdtlInput input) {
         throw new UnsupportedOperationException();
     }
 }