use of org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction in project controller by opendaylight.
the class DistributedDataStoreRemotingIntegrationTest method testTransactionForwardedToLeaderAfterRetry.
@Test
public void testTransactionForwardedToLeaderAfterRetry() throws Exception {
// TODO remove when test passes also for ClientBackedDataStore
Assume.assumeTrue(testParameter.equals(DistributedDataStore.class));
followerDatastoreContextBuilder.shardBatchedModificationCount(2);
leaderDatastoreContextBuilder.shardBatchedModificationCount(2);
initDatastoresWithCarsAndPeople("testTransactionForwardedToLeaderAfterRetry");
// Do an initial write to get the primary shard info cached.
final DOMStoreWriteTransaction initialWriteTx = followerDistributedDataStore.newWriteOnlyTransaction();
initialWriteTx.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
initialWriteTx.write(PeopleModel.BASE_PATH, PeopleModel.emptyContainer());
followerTestKit.doCommit(initialWriteTx.ready());
// Wait for the commit to be replicated to the follower.
MemberNode.verifyRaftState(followerDistributedDataStore, "cars", raftState -> assertEquals("getLastApplied", 1, raftState.getLastApplied()));
MemberNode.verifyRaftState(followerDistributedDataStore, "people", raftState -> assertEquals("getLastApplied", 1, raftState.getLastApplied()));
// Prepare, ready and canCommit a WO tx that writes to 2 shards. This will become the current tx in
// the leader shard.
final DOMStoreWriteTransaction writeTx1 = followerDistributedDataStore.newWriteOnlyTransaction();
writeTx1.write(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode());
writeTx1.write(PeopleModel.BASE_PATH, PeopleModel.emptyContainer());
final DOMStoreThreePhaseCommitCohort writeTx1Cohort = writeTx1.ready();
final ListenableFuture<Boolean> writeTx1CanCommit = writeTx1Cohort.canCommit();
writeTx1CanCommit.get(5, TimeUnit.SECONDS);
// Prepare and ready another WO tx that writes to 2 shards but don't canCommit yet. This will be queued
// in the leader shard.
final DOMStoreWriteTransaction writeTx2 = followerDistributedDataStore.newWriteOnlyTransaction();
final LinkedList<MapEntryNode> cars = new LinkedList<>();
int carIndex = 1;
cars.add(CarsModel.newCarEntry("car" + carIndex, BigInteger.valueOf(carIndex)));
writeTx2.write(CarsModel.newCarPath("car" + carIndex), cars.getLast());
carIndex++;
NormalizedNode<?, ?> people = PeopleModel.newPersonMapNode();
writeTx2.write(PeopleModel.PERSON_LIST_PATH, people);
final DOMStoreThreePhaseCommitCohort writeTx2Cohort = writeTx2.ready();
// Prepare another WO that writes to a single shard and thus will be directly committed on ready. This
// tx writes 5 cars so 2 BatchedModidifications messages will be sent initially and cached in the
// leader shard (with shardBatchedModificationCount set to 2). The 3rd BatchedModidifications will be
// sent on ready.
final DOMStoreWriteTransaction writeTx3 = followerDistributedDataStore.newWriteOnlyTransaction();
for (int i = 1; i <= 5; i++, carIndex++) {
cars.add(CarsModel.newCarEntry("car" + carIndex, BigInteger.valueOf(carIndex)));
writeTx3.write(CarsModel.newCarPath("car" + carIndex), cars.getLast());
}
// Prepare another WO that writes to a single shard. This will send a single BatchedModidifications
// message on ready.
final DOMStoreWriteTransaction writeTx4 = followerDistributedDataStore.newWriteOnlyTransaction();
cars.add(CarsModel.newCarEntry("car" + carIndex, BigInteger.valueOf(carIndex)));
writeTx4.write(CarsModel.newCarPath("car" + carIndex), cars.getLast());
carIndex++;
// Prepare a RW tx that will create a tx actor and send a ForwardedReadyTransaciton message to the
// leader shard on ready.
final DOMStoreReadWriteTransaction readWriteTx = followerDistributedDataStore.newReadWriteTransaction();
cars.add(CarsModel.newCarEntry("car" + carIndex, BigInteger.valueOf(carIndex)));
readWriteTx.write(CarsModel.newCarPath("car" + carIndex), cars.getLast());
IntegrationTestKit.verifyShardStats(leaderDistributedDataStore, "cars", stats -> assertEquals("getReadWriteTransactionCount", 1, stats.getReadWriteTransactionCount()));
// Disable elections on the leader so it switches to follower.
sendDatastoreContextUpdate(leaderDistributedDataStore, leaderDatastoreContextBuilder.customRaftPolicyImplementation(DisableElectionsRaftPolicy.class.getName()).shardElectionTimeoutFactor(10));
leaderTestKit.waitUntilNoLeader(leaderDistributedDataStore.getActorContext(), "cars");
// Submit all tx's - the messages should get queued for retry.
final ListenableFuture<Boolean> writeTx2CanCommit = writeTx2Cohort.canCommit();
final DOMStoreThreePhaseCommitCohort writeTx3Cohort = writeTx3.ready();
final DOMStoreThreePhaseCommitCohort writeTx4Cohort = writeTx4.ready();
final DOMStoreThreePhaseCommitCohort rwTxCohort = readWriteTx.ready();
// Enable elections on the other follower so it becomes the leader, at which point the
// tx's should get forwarded from the previous leader to the new leader to complete the commits.
sendDatastoreContextUpdate(followerDistributedDataStore, followerDatastoreContextBuilder.customRaftPolicyImplementation(null).shardElectionTimeoutFactor(1));
IntegrationTestKit.findLocalShard(followerDistributedDataStore.getActorContext(), "cars").tell(TimeoutNow.INSTANCE, ActorRef.noSender());
IntegrationTestKit.findLocalShard(followerDistributedDataStore.getActorContext(), "people").tell(TimeoutNow.INSTANCE, ActorRef.noSender());
followerTestKit.doCommit(writeTx1CanCommit, writeTx1Cohort);
followerTestKit.doCommit(writeTx2CanCommit, writeTx2Cohort);
followerTestKit.doCommit(writeTx3Cohort);
followerTestKit.doCommit(writeTx4Cohort);
followerTestKit.doCommit(rwTxCohort);
DOMStoreReadTransaction readTx = leaderDistributedDataStore.newReadOnlyTransaction();
verifyCars(readTx, cars.toArray(new MapEntryNode[cars.size()]));
verifyNode(readTx, PeopleModel.PERSON_LIST_PATH, people);
}
use of org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction in project controller by opendaylight.
the class ConcurrentDOMDataBrokerTest method testCreateTransactionOnChain.
@Test
public void testCreateTransactionOnChain() {
DOMStore domStore = mock(DOMStore.class);
try (ConcurrentDOMDataBroker dataBroker = new ConcurrentDOMDataBroker(ImmutableMap.of(LogicalDatastoreType.OPERATIONAL, domStore, LogicalDatastoreType.CONFIGURATION, domStore), futureExecutor)) {
DOMStoreReadWriteTransaction operationalTransaction = mock(DOMStoreReadWriteTransaction.class);
DOMStoreTransactionChain mockChain = mock(DOMStoreTransactionChain.class);
doReturn(mockChain).when(domStore).createTransactionChain();
doReturn(operationalTransaction).when(mockChain).newWriteOnlyTransaction();
DOMTransactionChain transactionChain = dataBroker.createTransactionChain(mock(TransactionChainListener.class));
DOMDataTreeWriteTransaction domDataWriteTransaction = transactionChain.newWriteOnlyTransaction();
verify(mockChain, never()).newWriteOnlyTransaction();
domDataWriteTransaction.put(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.EMPTY, mock(NormalizedNode.class));
}
}
use of org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction in project controller by opendaylight.
the class ConcurrentDOMDataBrokerTest method testSubmitWithOnlyTwoSubTransactions.
@Test
public void testSubmitWithOnlyTwoSubTransactions() throws InterruptedException {
DOMStore configDomStore = mock(DOMStore.class);
DOMStore operationalDomStore = mock(DOMStore.class);
DOMStoreReadWriteTransaction operationalTransaction = mock(DOMStoreReadWriteTransaction.class);
DOMStoreReadWriteTransaction configTransaction = mock(DOMStoreReadWriteTransaction.class);
DOMStoreThreePhaseCommitCohort mockCohortOperational = mock(DOMStoreThreePhaseCommitCohort.class);
DOMStoreThreePhaseCommitCohort mockCohortConfig = mock(DOMStoreThreePhaseCommitCohort.class);
doReturn(operationalTransaction).when(operationalDomStore).newReadWriteTransaction();
doReturn(configTransaction).when(configDomStore).newReadWriteTransaction();
doReturn(mockCohortOperational).when(operationalTransaction).ready();
doReturn(Futures.immediateFuture(false)).when(mockCohortOperational).canCommit();
doReturn(Futures.immediateFuture(null)).when(mockCohortOperational).abort();
doReturn(mockCohortConfig).when(configTransaction).ready();
doReturn(Futures.immediateFuture(false)).when(mockCohortConfig).canCommit();
doReturn(Futures.immediateFuture(null)).when(mockCohortConfig).abort();
final CountDownLatch latch = new CountDownLatch(1);
final List<DOMStoreThreePhaseCommitCohort> commitCohorts = new ArrayList<>();
try (ConcurrentDOMDataBroker dataBroker = new ConcurrentDOMDataBroker(ImmutableMap.of(LogicalDatastoreType.OPERATIONAL, operationalDomStore, LogicalDatastoreType.CONFIGURATION, configDomStore), futureExecutor) {
@Override
@SuppressWarnings("checkstyle:hiddenField")
public CheckedFuture<Void, TransactionCommitFailedException> submit(DOMDataTreeWriteTransaction writeTx, Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
commitCohorts.addAll(cohorts);
latch.countDown();
return super.submit(writeTx, cohorts);
}
}) {
DOMDataTreeReadWriteTransaction domDataReadWriteTransaction = dataBroker.newReadWriteTransaction();
domDataReadWriteTransaction.put(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.EMPTY, mock(NormalizedNode.class));
domDataReadWriteTransaction.merge(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.EMPTY, mock(NormalizedNode.class));
domDataReadWriteTransaction.submit();
assertTrue(latch.await(10, TimeUnit.SECONDS));
assertTrue(commitCohorts.size() == 2);
}
}
use of org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction in project controller by opendaylight.
the class ConcurrentDOMDataBrokerTest method testLazySubTransactionCreationForReadWriteTransactions.
@Test
public void testLazySubTransactionCreationForReadWriteTransactions() {
DOMStore configDomStore = mock(DOMStore.class);
DOMStore operationalDomStore = mock(DOMStore.class);
DOMStoreReadWriteTransaction storeTxn = mock(DOMStoreReadWriteTransaction.class);
doReturn(storeTxn).when(operationalDomStore).newReadWriteTransaction();
doReturn(storeTxn).when(configDomStore).newReadWriteTransaction();
try (ConcurrentDOMDataBroker dataBroker = new ConcurrentDOMDataBroker(ImmutableMap.of(LogicalDatastoreType.OPERATIONAL, operationalDomStore, LogicalDatastoreType.CONFIGURATION, configDomStore), futureExecutor)) {
DOMDataTreeReadWriteTransaction dataTxn = dataBroker.newReadWriteTransaction();
dataTxn.put(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.EMPTY, mock(NormalizedNode.class));
dataTxn.put(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.EMPTY, mock(NormalizedNode.class));
dataTxn.read(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.EMPTY);
verify(configDomStore, never()).newReadWriteTransaction();
verify(operationalDomStore, times(1)).newReadWriteTransaction();
dataTxn.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.EMPTY, mock(NormalizedNode.class));
verify(configDomStore, times(1)).newReadWriteTransaction();
verify(operationalDomStore, times(1)).newReadWriteTransaction();
}
}
use of org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction in project controller by opendaylight.
the class DistributedDataStoreIntegrationTest method testCreateChainedTransactionAfterEmptyTxReadied.
@Test
public void testCreateChainedTransactionAfterEmptyTxReadied() throws Exception {
new IntegrationTestKit(getSystem(), datastoreContextBuilder) {
{
try (AbstractDataStore dataStore = setupAbstractDataStore(testParameter, "testCreateChainedTransactionAfterEmptyTxReadied", "test-1")) {
final DOMStoreTransactionChain txChain = dataStore.createTransactionChain();
final DOMStoreReadWriteTransaction rwTx1 = txChain.newReadWriteTransaction();
rwTx1.ready();
final DOMStoreReadWriteTransaction rwTx2 = txChain.newReadWriteTransaction();
final Optional<NormalizedNode<?, ?>> optional = rwTx2.read(TestModel.TEST_PATH).get(5, TimeUnit.SECONDS);
assertEquals("isPresent", false, optional.isPresent());
txChain.close();
}
}
};
}
Aggregations