BUG-8202: Fix Conflict Modification on odl-programming 37/54837/3
authorClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Wed, 12 Apr 2017 06:58:46 +0000 (08:58 +0200)
committerRobert Varga <nite@hq.sk>
Sat, 22 Apr 2017 13:12:46 +0000 (13:12 +0000)
Instruction DS configuration only should be written
on Leader when instatiateService.

Change-Id: I9acf17c8a19d8b22d83e62b315fdadf9494783f2
Signed-off-by: Claudio D. Gasparini <claudio.gasparini@pantheon.tech>
programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/InstructionDeployerImpl.java
programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/IntructionDeployer.java
programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/ProgrammingServiceImpl.java
programming/impl/src/main/java/org/opendaylight/controller/config/yang/programming/impl/InstructionSchedulerImplModule.java
programming/impl/src/test/java/org/opendaylight/bgpcep/programming/impl/AbstractProgrammingTest.java [new file with mode: 0644]
programming/impl/src/test/java/org/opendaylight/bgpcep/programming/impl/InstructionDeployerImplTest.java
programming/impl/src/test/java/org/opendaylight/bgpcep/programming/impl/ProgrammingServiceImplTest.java

index f7469b7bf80384a07f42610d6c9963952f444bb0..12c52dd5a2fccd3bfff6222d065dfd56af475a88 100644 (file)
@@ -13,7 +13,6 @@ import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 import io.netty.util.Timer;
@@ -68,6 +67,53 @@ public final class InstructionDeployerImpl implements IntructionDeployer,
     private final InstanceIdentifier<OdlProgramming> iid;
     private final ClusterSingletonServiceProvider cssp;
 
+
+    class WriteConfiguration {
+        private final String instructionId;
+
+        WriteConfiguration(final String instructionId) {
+            this.instructionId = instructionId;
+        }
+
+        void create() {
+            final OdlProgrammingConfig instruction = new OdlProgrammingConfigBuilder()
+                .setInstructionQueueId(this.instructionId).build();
+            final WriteTransaction wTx = InstructionDeployerImpl.this.dataProvider.newWriteOnlyTransaction();
+            wTx.put(LogicalDatastoreType.CONFIGURATION, InstructionDeployerImpl.this.iid.child(
+                OdlProgrammingConfig.class, new OdlProgrammingConfigKey(this.instructionId)), instruction, true);
+            final CheckedFuture<Void, TransactionCommitFailedException> future = wTx.submit();
+            Futures.addCallback(future, new FutureCallback<Void>() {
+                @Override
+                public void onSuccess(final Void result) {
+                    LOG.debug("Instruction Instance {} initialized successfully.", WriteConfiguration.this.instructionId);
+                }
+
+                @Override
+                public void onFailure(final Throwable t) {
+                    LOG.error("Failed to initialize Instruction Instance {}.", WriteConfiguration.this.instructionId, t);
+                }
+            });
+        }
+
+        void remove() {
+            final WriteTransaction wTx = InstructionDeployerImpl.this.dataProvider.newWriteOnlyTransaction();
+            wTx.delete(LogicalDatastoreType.CONFIGURATION, InstructionDeployerImpl.this.iid.child(
+                OdlProgrammingConfig.class, new OdlProgrammingConfigKey(this.instructionId)));
+            final CheckedFuture<Void, TransactionCommitFailedException> future = wTx.submit();
+            Futures.addCallback(future, new FutureCallback<Void>() {
+                @Override
+                public void onSuccess(final Void result) {
+                    LOG.debug("Instruction Instance {} removed successfully.", WriteConfiguration.this.instructionId);
+                }
+
+                @Override
+                public void onFailure(final Throwable t) {
+                    LOG.error("Failed to remove Instruction Instance {}.", WriteConfiguration.this.instructionId, t);
+                }
+            });
+        }
+    }
+
     public InstructionDeployerImpl(final DataBroker dataProvider, final RpcProviderRegistry rpcProviderRegistry,
         final NotificationPublishService notifs, final Timer timer, final ClusterSingletonServiceProvider cssp,
         final BundleContext bundleContext) {
@@ -104,7 +150,8 @@ public final class InstructionDeployerImpl implements IntructionDeployer,
     }
 
 
-    private synchronized void createInstruction(final String instructionId) {
+    private synchronized void createInstruction(final String instructionId,
+        final WriteConfiguration writeConfiguration) {
         if (this.programmingServices.containsKey(instructionId)) {
             LOG.warn("Instruction Scheduler {} already exist. New instance won't be created", instructionId);
             return;
@@ -113,7 +160,7 @@ public final class InstructionDeployerImpl implements IntructionDeployer,
 
         final ProgrammingServiceImpl programmingInst =
             new ProgrammingServiceImpl(this.dataProvider, this.notifs, this.exec, this.rpcProviderRegistry, this.cssp,
-                this.timer, instructionId);
+                this.timer, instructionId, writeConfiguration);
         this.programmingServices.put(instructionId, programmingInst);
         final Dictionary<String, String> properties = new Hashtable<>();
         properties.put(InstructionScheduler.class.getName(), instructionId);
@@ -131,45 +178,13 @@ public final class InstructionDeployerImpl implements IntructionDeployer,
     }
 
     @Override
-    public ListenableFuture<Void> writeConfiguration(final String instructionId) {
-        final OdlProgrammingConfig instruction = new OdlProgrammingConfigBuilder()
-            .setInstructionQueueId(instructionId).build();
-        final WriteTransaction wTx = this.dataProvider.newWriteOnlyTransaction();
-        wTx.put(LogicalDatastoreType.CONFIGURATION, this.iid.child(OdlProgrammingConfig.class,
-            new OdlProgrammingConfigKey(instructionId)), instruction, true);
-        final CheckedFuture<Void, TransactionCommitFailedException> future = wTx.submit();
-        Futures.addCallback(future, new FutureCallback<Void>() {
-            @Override
-            public void onSuccess(final Void result) {
-                LOG.debug("Instruction Instance {} initialized successfully.", instructionId);
-            }
-
-            @Override
-            public void onFailure(final Throwable t) {
-                LOG.error("Failed to initialize Instruction Instance {}.", instructionId, t);
-            }
-        });
-        return future;
+    public void writeConfiguration(final String instructionId) {
+        createInstruction(instructionId, new WriteConfiguration(instructionId));
     }
 
     @Override
-    public ListenableFuture<Void> removeConfiguration(final String instructionId) {
-        final WriteTransaction wTx = this.dataProvider.newWriteOnlyTransaction();
-        wTx.delete(LogicalDatastoreType.CONFIGURATION, this.iid.child(OdlProgrammingConfig.class,
-            new OdlProgrammingConfigKey(instructionId)));
-        final CheckedFuture<Void, TransactionCommitFailedException> future = wTx.submit();
-        Futures.addCallback(future, new FutureCallback<Void>() {
-            @Override
-            public void onSuccess(final Void result) {
-                LOG.debug("Instruction Instance {} removed successfully.", instructionId);
-            }
-
-            @Override
-            public void onFailure(final Throwable t) {
-                LOG.error("Failed to remove Instruction Instance {}.", instructionId, t);
-            }
-        });
-        return future;
+    public void removeConfiguration(final String instructionId) {
+        removeInstruction(instructionId);
     }
 
     @Override
@@ -199,7 +214,7 @@ public final class InstructionDeployerImpl implements IntructionDeployer,
                 break;
             case SUBTREE_MODIFIED:
             case WRITE:
-                createInstruction(config.getDataAfter().getInstructionQueueId());
+                createInstruction(config.getDataAfter().getInstructionQueueId(), null);
                 break;
             default:
                 break;
index e6fb575f24f4637fbb8c807d94ede566b9792af0..029cfb75d695d69084e5995188a2a04e7eb2fd2b 100644 (file)
@@ -7,8 +7,6 @@
  */
 package org.opendaylight.bgpcep.programming.impl;
 
-import com.google.common.util.concurrent.ListenableFuture;
-
 /**
  * Instruction Scheduler Deployer
  */
@@ -17,11 +15,11 @@ public interface IntructionDeployer {
      * Write instruction configuration on DS
      * @param instructionId Instruction Scheduler Id
      */
-    ListenableFuture<Void> writeConfiguration(String instructionId);
+    void writeConfiguration(String instructionId);
 
     /**
      * Remove instruction configuration on DS
      * @param instructionId Instruction Scheduler Id
      */
-    ListenableFuture<Void> removeConfiguration(String instructionId);
+    void removeConfiguration(String instructionId);
 }
index 5e8e0dea19151df7de17b804faa2678400239fdb..1d5f8130705fc6b8c0a4983128f6e3e4ae45d115 100644 (file)
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import org.opendaylight.bgpcep.programming.NanotimeUtil;
+import org.opendaylight.bgpcep.programming.impl.InstructionDeployerImpl.WriteConfiguration;
 import org.opendaylight.bgpcep.programming.spi.ExecutionResult;
 import org.opendaylight.bgpcep.programming.spi.Instruction;
 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
@@ -85,6 +86,7 @@ public final class ProgrammingServiceImpl implements AutoCloseable, ClusterSingl
     private final ServiceGroupIdentifier sgi;
     private final ClusterSingletonServiceRegistration csspReg;
     private final RpcProviderRegistry rpcProviderRegistry;
+    private final WriteConfiguration writeConfiguration;
     private RpcRegistration<ProgrammingService> reg;
     private ServiceRegistration<?> serviceRegistration;
 
@@ -151,7 +153,8 @@ public final class ProgrammingServiceImpl implements AutoCloseable, ClusterSingl
 
     ProgrammingServiceImpl(final DataBroker dataProvider, final NotificationPublishService notifs,
         final ListeningExecutorService executor, final RpcProviderRegistry rpcProviderRegistry,
-        final ClusterSingletonServiceProvider cssp, final Timer timer, final String instructionId) {
+        final ClusterSingletonServiceProvider cssp, final Timer timer, final String instructionId,
+        final WriteConfiguration writeConfiguration) {
         this.dataProvider = Preconditions.checkNotNull(dataProvider);
         this.instructionId = Preconditions.checkNotNull(instructionId);
         this.notifs = Preconditions.checkNotNull(notifs);
@@ -159,6 +162,7 @@ public final class ProgrammingServiceImpl implements AutoCloseable, ClusterSingl
         this.rpcProviderRegistry = Preconditions.checkNotNull(rpcProviderRegistry);
         this.timer = Preconditions.checkNotNull(timer);
         this.qid = KeyedInstanceIdentifier.builder(InstructionsQueue.class,  new InstructionsQueueKey(this.instructionId)).build();
+        this.writeConfiguration = writeConfiguration;
         this.sgi = ServiceGroupIdentifier.create("programming-"+ this.instructionId + "-service-group");
         this.csspReg = cssp.registerClusterSingletonService(this);
     }
@@ -167,6 +171,9 @@ public final class ProgrammingServiceImpl implements AutoCloseable, ClusterSingl
     public void instantiateServiceInstance() {
         LOG.info("Instruction Queue service {} instantiated", this.sgi.getValue());
 
+        if (this.writeConfiguration != null) {
+            this.writeConfiguration.create();
+        }
         this.reg = this.rpcProviderRegistry.addRpcImplementation(ProgrammingService.class, this);
 
         final WriteTransaction t = this.dataProvider.newWriteOnlyTransaction();
@@ -398,6 +405,9 @@ public final class ProgrammingServiceImpl implements AutoCloseable, ClusterSingl
     public ListenableFuture<Void> closeServiceInstance() {
         LOG.info("Closing Instruction Queue service {}", this.sgi.getValue());
 
+        if (this.writeConfiguration != null) {
+            this.writeConfiguration.remove();
+        }
         this.reg.close();
         for (final InstructionImpl i : this.insns.values()) {
             i.tryCancel(null);
index 70c8db0c503cfa156e4948a4b88d694b064a7f56..bef5105286ead36c0a53798721bab9bcf08074ca 100644 (file)
@@ -60,12 +60,7 @@ public final class InstructionSchedulerImplModule extends
 
         final String instructionId = getInstructionQueueId() != null ? getInstructionQueueId() :
             getIdentifier().getInstanceName();
-        try {
-            intructionDeployer.writeConfiguration(instructionId).get();
-        } catch (final Exception e) {
-            LOG.error("Failed to instantiate Instruction at {}", instructionId, e);
-            throw new IllegalStateException("Failed to instantiate provider", e);
-        }
+        intructionDeployer.writeConfiguration(instructionId);
         final WaitingServiceTracker<InstructionScheduler> instructionSchedulerTracker = WaitingServiceTracker
             .create(InstructionScheduler.class,
                 this.bundleContext, "(" + InstructionScheduler.class.getName() + "=" + instructionId + ")");
diff --git a/programming/impl/src/test/java/org/opendaylight/bgpcep/programming/impl/AbstractProgrammingTest.java b/programming/impl/src/test/java/org/opendaylight/bgpcep/programming/impl/AbstractProgrammingTest.java
new file mode 100644 (file)
index 0000000..81146b9
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.bgpcep.programming.impl;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import org.junit.Before;
+import org.mockito.Mock;
+import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.ProgrammingService;
+
+abstract class AbstractProgrammingTest extends AbstractConcurrentDataBrokerTest {
+    @Mock
+    RpcProviderRegistry rpcRegistry;
+    @Mock
+    ClusterSingletonServiceProvider cssp;
+    @Mock
+    ClusterSingletonServiceRegistration singletonServiceRegistration;
+    @Mock
+    private RoutedRpcRegistration<ProgrammingService> registration;
+    ClusterSingletonService singletonService;
+
+    @Before
+    public void setUp() throws Exception {
+        initMocks(this);
+        doAnswer(invocationOnMock -> {
+            this.singletonService = (ClusterSingletonService) invocationOnMock.getArguments()[0];
+            return this.singletonServiceRegistration;
+        }).when(this.cssp).registerClusterSingletonService(any(ClusterSingletonService.class));
+        doAnswer(invocationOnMock -> {
+            this.singletonService.closeServiceInstance();
+            return null;
+        }).when(this.singletonServiceRegistration).close();
+
+        doReturn(this.registration).when(this.rpcRegistry).addRpcImplementation(any(), any(ProgrammingService.class));
+
+        doNothing().when(this.registration).close();
+    }
+}
index 3291c79e8a4e5b09532367c0f824d1c32cdd4339..01ac378b9a4f08d1894bfeff14157582ec2abda5 100644 (file)
@@ -8,11 +8,10 @@
 package org.opendaylight.bgpcep.programming.impl;
 
 import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
-import static org.mockito.MockitoAnnotations.initMocks;
 import static org.opendaylight.protocol.util.CheckUtil.checkNotPresentConfiguration;
 import static org.opendaylight.protocol.util.CheckUtil.checkPresentConfiguration;
 
@@ -21,51 +20,39 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
-import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
-import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.programming.config.rev170301.odl.programming.OdlProgrammingConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.programming.config.rev170301.odl.programming.OdlProgrammingConfigKey;
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
-public class InstructionDeployerImplTest extends AbstractConcurrentDataBrokerTest {
-    @Mock
-    private RpcProviderRegistry rpcRegistry;
+public class InstructionDeployerImplTest extends AbstractProgrammingTest {
     @Mock
     private NotificationPublishService notifs;
     @Mock
     private Timer timer;
     @Mock
-    private ClusterSingletonServiceProvider cssp;
-    @Mock
-    private ClusterSingletonServiceRegistration singletonServiceRegistration;
-    @Mock
     private BundleContext bundleContext;
     @Mock
     private ServiceRegistration serviceRegistration;
 
     @Before
+    @Override
     public void setUp() throws Exception {
-        initMocks(this);
-        doAnswer(invocationOnMock -> this.singletonServiceRegistration).when(this.cssp)
-            .registerClusterSingletonService(any(ClusterSingletonService.class));
-
+        super.setUp();
         doReturn(this.serviceRegistration).when(this.bundleContext).registerService(any(String.class), any(), any());
+        doNothing().when(this.serviceRegistration).unregister();
     }
 
     @Test
     public void testInstructionDeployer() throws Exception {
         final InstructionDeployerImpl deployer = new InstructionDeployerImpl(getDataBroker(), this.rpcRegistry,
             this.notifs, this.timer, this.cssp, this.bundleContext);
-
         checkPresentConfiguration(getDataBroker(), deployer.getInstructionIID());
 
         final String instructionId = "newInstruction";
         deployer.writeConfiguration(instructionId);
+        this.singletonService.instantiateServiceInstance();
         final KeyedInstanceIdentifier<OdlProgrammingConfig, OdlProgrammingConfigKey> intructionIID =
             deployer.getInstructionIID().child(OdlProgrammingConfig.class, new OdlProgrammingConfigKey(instructionId));
         checkPresentConfiguration(getDataBroker(), intructionIID);
index 889b400b51c5b2318dd0df0c59a2247247aef014..43629a3b9cdcdc61ec1ba00a52b6ec8c8b394f13 100644 (file)
@@ -12,12 +12,8 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
-import static org.mockito.MockitoAnnotations.initMocks;
 import static org.opendaylight.protocol.util.CheckUtil.checkNotPresentOperational;
 import static org.opendaylight.protocol.util.CheckUtil.checkPresentOperational;
 
@@ -31,17 +27,9 @@ import java.util.Optional;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.opendaylight.bgpcep.programming.NanotimeUtil;
 import org.opendaylight.bgpcep.programming.spi.Instruction;
 import org.opendaylight.bgpcep.programming.spi.SchedulerException;
-import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
-import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.CancelInstructionInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.CancelInstructionInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.CleanInstructionsInput;
@@ -52,7 +40,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programm
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.InstructionsQueue;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.InstructionsQueueKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.Nanotime;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.ProgrammingService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.SubmitInstructionInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.instruction.queue.InstructionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.instruction.status.changed.Details;
@@ -62,7 +49,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
-public class ProgrammingServiceImplTest extends AbstractConcurrentDataBrokerTest {
+public class ProgrammingServiceImplTest extends AbstractProgrammingTest {
 
     private static final int INSTRUCTION_DEADLINE_OFFSET_IN_SECONDS = 3;
     private static final String INSTRUCTIONS_QUEUE_KEY = "test-instraction-queue";
@@ -70,38 +57,18 @@ public class ProgrammingServiceImplTest extends AbstractConcurrentDataBrokerTest
     private MockedExecutorWrapper mockedExecutorWrapper;
     private MockedNotificationServiceWrapper mockedNotificationServiceWrapper;
     private ProgrammingServiceImpl testedProgrammingService;
-    @Mock
-    private ClusterSingletonServiceProvider cssp;
-    @Mock
-    private ClusterSingletonServiceRegistration singletonServiceRegistration;
-    @Mock
-    private RpcProviderRegistry rpcRegistry;
-    @Mock
-    private RoutedRpcRegistration<ProgrammingService> registration;
-    private ClusterSingletonService singletonService;
 
     @Before
+    @Override
     public void setUp() throws Exception {
-        initMocks(this);
-        doAnswer(invocationOnMock -> {
-            this.singletonService = (ClusterSingletonService) invocationOnMock.getArguments()[0];
-            return this.singletonServiceRegistration;
-        }).when(this.cssp).registerClusterSingletonService(any(ClusterSingletonService.class));
-
-        doAnswer(invocationOnMock -> {
-            this.singletonService.closeServiceInstance();
-            return null;
-        }).when(this.singletonServiceRegistration).close();
-        doReturn(this.registration).when(this.rpcRegistry).addRpcImplementation(Mockito.any(),
-            Mockito.any(ProgrammingService.class));
-        doNothing().when(this.registration).close();
+        super.setUp();
         this.mockedExecutorWrapper = new MockedExecutorWrapper();
         this.mockedNotificationServiceWrapper = new MockedNotificationServiceWrapper();
 
         this.testedProgrammingService = new ProgrammingServiceImpl(getDataBroker(),
             this.mockedNotificationServiceWrapper.getMockedNotificationService(),
             this.mockedExecutorWrapper.getMockedExecutor(), this.rpcRegistry, this.cssp, this.timer,
-            INSTRUCTIONS_QUEUE_KEY);
+            INSTRUCTIONS_QUEUE_KEY, null);
         this.singletonService.instantiateServiceInstance();
     }