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;
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) {
}
- 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;
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);
}
@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
break;
case SUBTREE_MODIFIED:
case WRITE:
- createInstruction(config.getDataAfter().getInstructionQueueId());
+ createInstruction(config.getDataAfter().getInstructionQueueId(), null);
break;
default:
break;
*/
package org.opendaylight.bgpcep.programming.impl;
-import com.google.common.util.concurrent.ListenableFuture;
-
/**
* Instruction Scheduler Deployer
*/
* 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);
}
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;
private final ServiceGroupIdentifier sgi;
private final ClusterSingletonServiceRegistration csspReg;
private final RpcProviderRegistry rpcProviderRegistry;
+ private final WriteConfiguration writeConfiguration;
private RpcRegistration<ProgrammingService> reg;
private ServiceRegistration<?> serviceRegistration;
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);
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);
}
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();
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);
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 + ")");
--- /dev/null
+/*
+ * 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.AbstractDataBrokerTest;
+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 AbstractDataBrokerTest {
+ @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();
+ }
+}
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;
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.AbstractDataBrokerTest;
-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 AbstractDataBrokerTest {
- @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);
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;
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.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.controller.md.sal.binding.test.AbstractDataBrokerTest;
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;
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;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
-public class ProgrammingServiceImplTest extends AbstractDataBrokerTest {
+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";
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();
}