Search in sources :

Example 1 with CoordinatedRepairResult

use of org.apache.cassandra.repair.CoordinatedRepairResult in project cassandra by apache.

the class CoordinatorMessagingTest method testMockedMessagingHappyPath.

@Test
public void testMockedMessagingHappyPath() throws InterruptedException, ExecutionException, TimeoutException, NoSuchRepairSessionException {
    CountDownLatch prepareLatch = createLatch();
    CountDownLatch finalizeLatch = createLatch();
    MockMessagingSpy spyPrepare = createPrepareSpy(Collections.emptySet(), Collections.emptySet(), prepareLatch);
    MockMessagingSpy spyFinalize = createFinalizeSpy(Collections.emptySet(), Collections.emptySet(), finalizeLatch);
    MockMessagingSpy spyCommit = createCommitSpy();
    UUID uuid = registerSession(cfs, true, true);
    CoordinatorSession coordinator = ActiveRepairService.instance.consistent.coordinated.registerSession(uuid, PARTICIPANTS, false);
    AtomicBoolean repairSubmitted = new AtomicBoolean(false);
    Promise<CoordinatedRepairResult> repairFuture = AsyncPromise.uncancellable();
    Supplier<Future<CoordinatedRepairResult>> sessionSupplier = () -> {
        repairSubmitted.set(true);
        return repairFuture;
    };
    // coordinator sends prepare requests to create local session and perform anticompaction
    Assert.assertFalse(repairSubmitted.get());
    // execute repair and start prepare phase
    Future<CoordinatedRepairResult> sessionResult = coordinator.execute(sessionSupplier);
    Assert.assertFalse(sessionResult.isDone());
    // prepare completed
    prepareLatch.countDown();
    spyPrepare.interceptMessageOut(3).get(1, TimeUnit.SECONDS);
    Assert.assertFalse(sessionResult.isDone());
    // set result from local repair session
    repairFuture.trySuccess(CoordinatedRepairResult.success(Lists.newArrayList(createResult(coordinator), createResult(coordinator), createResult(coordinator))));
    // finalize phase
    finalizeLatch.countDown();
    spyFinalize.interceptMessageOut(3).get(1, TimeUnit.SECONDS);
    // commit phase
    spyCommit.interceptMessageOut(3).get(1, TimeUnit.SECONDS);
    Assert.assertFalse(sessionResult.get().hasFailed());
    // expect no other messages except from intercepted so far
    spyPrepare.interceptNoMsg(100, TimeUnit.MILLISECONDS);
    spyFinalize.interceptNoMsg(100, TimeUnit.MILLISECONDS);
    spyCommit.interceptNoMsg(100, TimeUnit.MILLISECONDS);
    Assert.assertEquals(ConsistentSession.State.FINALIZED, coordinator.getState());
    Assert.assertFalse(ActiveRepairService.instance.consistent.local.isSessionInProgress(uuid));
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CoordinatedRepairResult(org.apache.cassandra.repair.CoordinatedRepairResult) Future(org.apache.cassandra.utils.concurrent.Future) CountDownLatch(java.util.concurrent.CountDownLatch) UUID(java.util.UUID) MockMessagingSpy(org.apache.cassandra.net.MockMessagingSpy) AbstractRepairTest(org.apache.cassandra.repair.AbstractRepairTest) Test(org.junit.Test)

Example 2 with CoordinatedRepairResult

use of org.apache.cassandra.repair.CoordinatedRepairResult in project cassandra by apache.

the class CoordinatorSessionTest method successCase.

/**
 * Tests the complete coordinator side consistent repair cycle
 */
@Test
public void successCase() {
    InstrumentedCoordinatorSession coordinator = createInstrumentedSession();
    AtomicBoolean repairSubmitted = new AtomicBoolean(false);
    Promise<CoordinatedRepairResult> repairFuture = AsyncPromise.uncancellable();
    Supplier<Future<CoordinatedRepairResult>> sessionSupplier = () -> {
        repairSubmitted.set(true);
        return repairFuture;
    };
    // coordinator sends prepare requests to create local session and perform anticompaction
    Assert.assertFalse(repairSubmitted.get());
    Assert.assertTrue(coordinator.sentMessages.isEmpty());
    Future<CoordinatedRepairResult> sessionResult = coordinator.execute(sessionSupplier);
    for (InetAddressAndPort participant : PARTICIPANTS) {
        RepairMessage expected = new PrepareConsistentRequest(coordinator.sessionID, COORDINATOR, new HashSet<>(PARTICIPANTS));
        assertMessageSent(coordinator, participant, expected);
    }
    // participants respond to coordinator, and repair begins once all participants have responded with success
    Assert.assertEquals(ConsistentSession.State.PREPARING, coordinator.getState());
    coordinator.handlePrepareResponse(PARTICIPANT1, true);
    Assert.assertEquals(ConsistentSession.State.PREPARING, coordinator.getState());
    coordinator.handlePrepareResponse(PARTICIPANT2, true);
    Assert.assertEquals(ConsistentSession.State.PREPARING, coordinator.getState());
    // set the setRepairing callback to verify the correct state when it's called
    Assert.assertFalse(coordinator.setRepairingCalled);
    coordinator.onSetRepairing = () -> Assert.assertEquals(PREPARED, coordinator.getState());
    coordinator.handlePrepareResponse(PARTICIPANT3, true);
    Assert.assertTrue(coordinator.setRepairingCalled);
    Assert.assertTrue(repairSubmitted.get());
    Assert.assertEquals(ConsistentSession.State.REPAIRING, coordinator.getState());
    ArrayList<RepairSessionResult> results = Lists.newArrayList(createResult(coordinator), createResult(coordinator), createResult(coordinator));
    coordinator.sentMessages.clear();
    repairFuture.trySuccess(CoordinatedRepairResult.success(results));
    // propose messages should have been sent once all repair sessions completed successfully
    for (InetAddressAndPort participant : PARTICIPANTS) {
        RepairMessage expected = new FinalizePropose(coordinator.sessionID);
        assertMessageSent(coordinator, participant, expected);
    }
    // finalize commit messages will be sent once all participants respond with a promize to finalize
    coordinator.sentMessages.clear();
    Assert.assertEquals(ConsistentSession.State.REPAIRING, coordinator.getState());
    coordinator.handleFinalizePromise(PARTICIPANT1, true);
    Assert.assertEquals(ConsistentSession.State.REPAIRING, coordinator.getState());
    coordinator.handleFinalizePromise(PARTICIPANT2, true);
    Assert.assertEquals(ConsistentSession.State.REPAIRING, coordinator.getState());
    // set the finalizeCommit callback so we can verify the state when it's called
    Assert.assertFalse(coordinator.finalizeCommitCalled);
    coordinator.onFinalizeCommit = () -> Assert.assertEquals(FINALIZE_PROMISED, coordinator.getState());
    coordinator.handleFinalizePromise(PARTICIPANT3, true);
    Assert.assertTrue(coordinator.finalizeCommitCalled);
    Assert.assertEquals(ConsistentSession.State.FINALIZED, coordinator.getState());
    for (InetAddressAndPort participant : PARTICIPANTS) {
        RepairMessage expected = new FinalizeCommit(coordinator.sessionID);
        assertMessageSent(coordinator, participant, expected);
    }
    Assert.assertTrue(sessionResult.isDone());
    sessionResult.syncUninterruptibly();
}
Also used : FinalizeCommit(org.apache.cassandra.repair.messages.FinalizeCommit) InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) PrepareConsistentRequest(org.apache.cassandra.repair.messages.PrepareConsistentRequest) FinalizePropose(org.apache.cassandra.repair.messages.FinalizePropose) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RepairMessage(org.apache.cassandra.repair.messages.RepairMessage) CoordinatedRepairResult(org.apache.cassandra.repair.CoordinatedRepairResult) Future(org.apache.cassandra.utils.concurrent.Future) RepairSessionResult(org.apache.cassandra.repair.RepairSessionResult) AbstractRepairTest(org.apache.cassandra.repair.AbstractRepairTest) Test(org.junit.Test)

Example 3 with CoordinatedRepairResult

use of org.apache.cassandra.repair.CoordinatedRepairResult in project cassandra by apache.

the class CoordinatorSessionTest method failedPropose.

@Test
public void failedPropose() {
    InstrumentedCoordinatorSession coordinator = createInstrumentedSession();
    AtomicBoolean repairSubmitted = new AtomicBoolean(false);
    Promise<CoordinatedRepairResult> repairFuture = AsyncPromise.uncancellable();
    Supplier<Future<CoordinatedRepairResult>> sessionSupplier = () -> {
        repairSubmitted.set(true);
        return repairFuture;
    };
    // coordinator sends prepare requests to create local session and perform anticompaction
    Assert.assertFalse(repairSubmitted.get());
    Assert.assertTrue(coordinator.sentMessages.isEmpty());
    Future<CoordinatedRepairResult> sessionResult = coordinator.execute(sessionSupplier);
    for (InetAddressAndPort participant : PARTICIPANTS) {
        RepairMessage expected = new PrepareConsistentRequest(coordinator.sessionID, COORDINATOR, new HashSet<>(PARTICIPANTS));
        assertMessageSent(coordinator, participant, expected);
    }
    // participants respond to coordinator, and repair begins once all participants have responded with success
    Assert.assertEquals(ConsistentSession.State.PREPARING, coordinator.getState());
    coordinator.handlePrepareResponse(PARTICIPANT1, true);
    Assert.assertEquals(ConsistentSession.State.PREPARING, coordinator.getState());
    coordinator.handlePrepareResponse(PARTICIPANT2, true);
    Assert.assertEquals(ConsistentSession.State.PREPARING, coordinator.getState());
    // set the setRepairing callback to verify the correct state when it's called
    Assert.assertFalse(coordinator.setRepairingCalled);
    coordinator.onSetRepairing = () -> Assert.assertEquals(PREPARED, coordinator.getState());
    coordinator.handlePrepareResponse(PARTICIPANT3, true);
    Assert.assertTrue(coordinator.setRepairingCalled);
    Assert.assertTrue(repairSubmitted.get());
    Assert.assertEquals(ConsistentSession.State.REPAIRING, coordinator.getState());
    ArrayList<RepairSessionResult> results = Lists.newArrayList(createResult(coordinator), createResult(coordinator), createResult(coordinator));
    coordinator.sentMessages.clear();
    repairFuture.trySuccess(CoordinatedRepairResult.success(results));
    // propose messages should have been sent once all repair sessions completed successfully
    for (InetAddressAndPort participant : PARTICIPANTS) {
        RepairMessage expected = new FinalizePropose(coordinator.sessionID);
        assertMessageSent(coordinator, participant, expected);
    }
    // finalize commit messages will be sent once all participants respond with a promize to finalize
    coordinator.sentMessages.clear();
    Assert.assertEquals(ConsistentSession.State.REPAIRING, coordinator.getState());
    coordinator.handleFinalizePromise(PARTICIPANT1, true);
    Assert.assertEquals(ConsistentSession.State.REPAIRING, coordinator.getState());
    Assert.assertFalse(coordinator.failCalled);
    coordinator.handleFinalizePromise(PARTICIPANT2, false);
    Assert.assertEquals(ConsistentSession.State.FAILED, coordinator.getState());
    Assert.assertTrue(coordinator.failCalled);
    // additional success messages should be ignored
    Assert.assertFalse(coordinator.finalizeCommitCalled);
    coordinator.onFinalizeCommit = Assert::fail;
    coordinator.handleFinalizePromise(PARTICIPANT3, true);
    Assert.assertFalse(coordinator.finalizeCommitCalled);
    Assert.assertEquals(ConsistentSession.State.FAILED, coordinator.getState());
    // failure messages should have been sent to all participants
    for (InetAddressAndPort participant : PARTICIPANTS) {
        RepairMessage expected = new FailSession(coordinator.sessionID);
        assertMessageSent(coordinator, participant, expected);
    }
    Assert.assertTrue(sessionResult.isDone());
    Assert.assertNotNull(sessionResult.cause());
}
Also used : InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) PrepareConsistentRequest(org.apache.cassandra.repair.messages.PrepareConsistentRequest) FinalizePropose(org.apache.cassandra.repair.messages.FinalizePropose) FailSession(org.apache.cassandra.repair.messages.FailSession) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RepairMessage(org.apache.cassandra.repair.messages.RepairMessage) Assert(org.junit.Assert) CoordinatedRepairResult(org.apache.cassandra.repair.CoordinatedRepairResult) Future(org.apache.cassandra.utils.concurrent.Future) RepairSessionResult(org.apache.cassandra.repair.RepairSessionResult) AbstractRepairTest(org.apache.cassandra.repair.AbstractRepairTest) Test(org.junit.Test)

Example 4 with CoordinatedRepairResult

use of org.apache.cassandra.repair.CoordinatedRepairResult in project cassandra by apache.

the class CoordinatorSessionTest method failedRepairs.

@Test
public void failedRepairs() {
    InstrumentedCoordinatorSession coordinator = createInstrumentedSession();
    AtomicBoolean repairSubmitted = new AtomicBoolean(false);
    Promise<CoordinatedRepairResult> repairFuture = AsyncPromise.uncancellable();
    Supplier<Future<CoordinatedRepairResult>> sessionSupplier = () -> {
        repairSubmitted.set(true);
        return repairFuture;
    };
    // coordinator sends prepare requests to create local session and perform anticompaction
    Assert.assertFalse(repairSubmitted.get());
    Assert.assertTrue(coordinator.sentMessages.isEmpty());
    Future<CoordinatedRepairResult> sessionResult = coordinator.execute(sessionSupplier);
    for (InetAddressAndPort participant : PARTICIPANTS) {
        PrepareConsistentRequest expected = new PrepareConsistentRequest(coordinator.sessionID, COORDINATOR, new HashSet<>(PARTICIPANTS));
        assertMessageSent(coordinator, participant, expected);
    }
    // participants respond to coordinator, and repair begins once all participants have responded with success
    Assert.assertEquals(ConsistentSession.State.PREPARING, coordinator.getState());
    coordinator.handlePrepareResponse(PARTICIPANT1, true);
    Assert.assertEquals(ConsistentSession.State.PREPARING, coordinator.getState());
    coordinator.handlePrepareResponse(PARTICIPANT2, true);
    Assert.assertEquals(ConsistentSession.State.PREPARING, coordinator.getState());
    // set the setRepairing callback to verify the correct state when it's called
    Assert.assertFalse(coordinator.setRepairingCalled);
    coordinator.onSetRepairing = () -> Assert.assertEquals(PREPARED, coordinator.getState());
    coordinator.handlePrepareResponse(PARTICIPANT3, true);
    Assert.assertTrue(coordinator.setRepairingCalled);
    Assert.assertTrue(repairSubmitted.get());
    Assert.assertEquals(ConsistentSession.State.REPAIRING, coordinator.getState());
    List<Collection<Range<Token>>> ranges = Arrays.asList(coordinator.ranges, coordinator.ranges, coordinator.ranges);
    ArrayList<RepairSessionResult> results = Lists.newArrayList(createResult(coordinator), null, createResult(coordinator));
    coordinator.sentMessages.clear();
    Assert.assertFalse(coordinator.failCalled);
    coordinator.onFail = () -> Assert.assertEquals(REPAIRING, coordinator.getState());
    repairFuture.trySuccess(CoordinatedRepairResult.create(ranges, results));
    Assert.assertTrue(coordinator.failCalled);
    // all participants should have been notified of session failure
    for (InetAddressAndPort participant : PARTICIPANTS) {
        RepairMessage expected = new FailSession(coordinator.sessionID);
        assertMessageSent(coordinator, participant, expected);
    }
    Assert.assertTrue(sessionResult.isDone());
    Assert.assertNotNull(sessionResult.cause());
}
Also used : InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) Token(org.apache.cassandra.dht.Token) PrepareConsistentRequest(org.apache.cassandra.repair.messages.PrepareConsistentRequest) FailSession(org.apache.cassandra.repair.messages.FailSession) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RepairMessage(org.apache.cassandra.repair.messages.RepairMessage) CoordinatedRepairResult(org.apache.cassandra.repair.CoordinatedRepairResult) Future(org.apache.cassandra.utils.concurrent.Future) Collection(java.util.Collection) RepairSessionResult(org.apache.cassandra.repair.RepairSessionResult) AbstractRepairTest(org.apache.cassandra.repair.AbstractRepairTest) Test(org.junit.Test)

Example 5 with CoordinatedRepairResult

use of org.apache.cassandra.repair.CoordinatedRepairResult in project cassandra by apache.

the class CoordinatorSessionTest method failedPrepare.

@Test
public void failedPrepare() {
    InstrumentedCoordinatorSession coordinator = createInstrumentedSession();
    AtomicBoolean repairSubmitted = new AtomicBoolean(false);
    Promise<CoordinatedRepairResult> repairFuture = AsyncPromise.uncancellable();
    Supplier<Future<CoordinatedRepairResult>> sessionSupplier = () -> {
        repairSubmitted.set(true);
        return repairFuture;
    };
    // coordinator sends prepare requests to create local session and perform anticompaction
    Assert.assertFalse(repairSubmitted.get());
    Assert.assertTrue(coordinator.sentMessages.isEmpty());
    Future<CoordinatedRepairResult> sessionResult = coordinator.execute(sessionSupplier);
    for (InetAddressAndPort participant : PARTICIPANTS) {
        PrepareConsistentRequest expected = new PrepareConsistentRequest(coordinator.sessionID, COORDINATOR, new HashSet<>(PARTICIPANTS));
        assertMessageSent(coordinator, participant, expected);
    }
    coordinator.sentMessages.clear();
    // participants respond to coordinator, and repair begins once all participants have responded
    Assert.assertEquals(ConsistentSession.State.PREPARING, coordinator.getState());
    coordinator.handlePrepareResponse(PARTICIPANT1, true);
    Assert.assertEquals(ConsistentSession.State.PREPARING, coordinator.getState());
    Assert.assertEquals(PREPARED, coordinator.getParticipantState(PARTICIPANT1));
    Assert.assertFalse(sessionResult.isDone());
    // participant 2 fails to prepare for consistent repair
    Assert.assertFalse(coordinator.failCalled);
    coordinator.handlePrepareResponse(PARTICIPANT2, false);
    Assert.assertEquals(ConsistentSession.State.PREPARING, coordinator.getState());
    // we should have sent failure messages to the other participants, but not yet marked them failed internally
    assertMessageSent(coordinator, PARTICIPANT1, new FailSession(coordinator.sessionID));
    assertMessageSent(coordinator, PARTICIPANT2, new FailSession(coordinator.sessionID));
    assertMessageSent(coordinator, PARTICIPANT3, new FailSession(coordinator.sessionID));
    Assert.assertEquals(FAILED, coordinator.getParticipantState(PARTICIPANT2));
    Assert.assertEquals(PREPARED, coordinator.getParticipantState(PARTICIPANT1));
    Assert.assertEquals(PREPARING, coordinator.getParticipantState(PARTICIPANT3));
    Assert.assertFalse(sessionResult.isDone());
    Assert.assertFalse(coordinator.failCalled);
    coordinator.sentMessages.clear();
    // last outstanding response should cause repair to complete in failed state
    Assert.assertFalse(coordinator.setRepairingCalled);
    coordinator.onSetRepairing = Assert::fail;
    coordinator.handlePrepareResponse(PARTICIPANT3, true);
    Assert.assertTrue(coordinator.failCalled);
    Assert.assertFalse(coordinator.setRepairingCalled);
    Assert.assertFalse(repairSubmitted.get());
    // all participants that did not fail should have been notified of session failure
    RepairMessage expected = new FailSession(coordinator.sessionID);
    assertMessageSent(coordinator, PARTICIPANT1, expected);
    assertMessageSent(coordinator, PARTICIPANT3, expected);
    Assert.assertFalse(coordinator.sentMessages.containsKey(PARTICIPANT2));
    Assert.assertTrue(sessionResult.isDone());
    Assert.assertNotNull(sessionResult.cause());
}
Also used : InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) PrepareConsistentRequest(org.apache.cassandra.repair.messages.PrepareConsistentRequest) FailSession(org.apache.cassandra.repair.messages.FailSession) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RepairMessage(org.apache.cassandra.repair.messages.RepairMessage) Assert(org.junit.Assert) CoordinatedRepairResult(org.apache.cassandra.repair.CoordinatedRepairResult) Future(org.apache.cassandra.utils.concurrent.Future) AbstractRepairTest(org.apache.cassandra.repair.AbstractRepairTest) Test(org.junit.Test)

Aggregations

AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)7 CoordinatedRepairResult (org.apache.cassandra.repair.CoordinatedRepairResult)7 Future (org.apache.cassandra.utils.concurrent.Future)7 AbstractRepairTest (org.apache.cassandra.repair.AbstractRepairTest)6 Test (org.junit.Test)6 InetAddressAndPort (org.apache.cassandra.locator.InetAddressAndPort)4 PrepareConsistentRequest (org.apache.cassandra.repair.messages.PrepareConsistentRequest)4 RepairMessage (org.apache.cassandra.repair.messages.RepairMessage)4 UUID (java.util.UUID)3 MockMessagingSpy (org.apache.cassandra.net.MockMessagingSpy)3 RepairSessionResult (org.apache.cassandra.repair.RepairSessionResult)3 FailSession (org.apache.cassandra.repair.messages.FailSession)3 CountDownLatch (java.util.concurrent.CountDownLatch)2 ExecutionException (java.util.concurrent.ExecutionException)2 FinalizePropose (org.apache.cassandra.repair.messages.FinalizePropose)2 Assert (org.junit.Assert)2 Collection (java.util.Collection)1 TimeoutException (java.util.concurrent.TimeoutException)1 Token (org.apache.cassandra.dht.Token)1 FinalizeCommit (org.apache.cassandra.repair.messages.FinalizeCommit)1