Search in sources :

Example 1 with SwitchToMaster

use of org.neo4j.kernel.ha.cluster.SwitchToMaster in project neo4j by neo4j.

the class HighAvailabilityModeSwitcherTest method shouldUseProperServerIdWhenDemotingFromMasterOnException.

@Test
public void shouldUseProperServerIdWhenDemotingFromMasterOnException() throws Throwable {
    /*
         * This a test that acts as a driver to prove a bug which had an instance send out a demote message
         * with instance id -1, since it used HAMS#getServerId(URI) with a URI coming from the NetworkReceiver binding
         * which did not contain the serverId URI argument. This has been fixed by explicitly adding the instanceid
         * as a constructor argument of the HAMS.
         */
    // Given
    SwitchToSlaveCopyThenBranch sts = mock(SwitchToSlaveCopyThenBranch.class);
    SwitchToMaster stm = mock(SwitchToMaster.class);
    // this is necessary to trigger a revert which uses the serverId from the HAMS#me field
    when(stm.switchToMaster(any(LifeSupport.class), any(URI.class))).thenThrow(new RuntimeException());
    Election election = mock(Election.class);
    ClusterMemberAvailability cma = mock(ClusterMemberAvailability.class);
    InstanceId instanceId = new InstanceId(14);
    HighAvailabilityModeSwitcher theSwitcher = new HighAvailabilityModeSwitcher(sts, stm, election, cma, mock(ClusterClient.class), storeSupplierMock(), instanceId, new ComponentSwitcherContainer(), neoStoreDataSourceSupplierMock(), NullLogService.getInstance());
    theSwitcher.init();
    theSwitcher.start();
    /*
         * This is the trick, kind of. NetworkReceiver creates this and passes it on to NetworkReceiver#getURI() and
         * that
         * is what HAMS uses as the HAMS#me field value. But we should not be using this to extract the instanceId.
         * Note the lack of a serverId argument
         */
    URI listeningAt = URI.create("ha://0.0.0.0:5001?name=someName");
    theSwitcher.listeningAt(listeningAt);
    // When
    try {
        // the instance fails to switch to master
        theSwitcher.masterIsElected(new HighAvailabilityMemberChangeEvent(HighAvailabilityMemberState.PENDING, HighAvailabilityMemberState.TO_MASTER, instanceId, listeningAt));
    } finally {
        theSwitcher.stop();
        theSwitcher.shutdown();
    }
    // Then
    // The demotion message must have used the proper instance id
    verify(election).demote(instanceId);
}
Also used : ClusterClient(org.neo4j.cluster.client.ClusterClient) SwitchToSlaveCopyThenBranch(org.neo4j.kernel.ha.cluster.SwitchToSlaveCopyThenBranch) InstanceId(org.neo4j.cluster.InstanceId) HighAvailabilityMemberChangeEvent(org.neo4j.kernel.ha.cluster.HighAvailabilityMemberChangeEvent) ClusterMemberAvailability(org.neo4j.cluster.member.ClusterMemberAvailability) LifeSupport(org.neo4j.kernel.lifecycle.LifeSupport) SwitchToMaster(org.neo4j.kernel.ha.cluster.SwitchToMaster) URI(java.net.URI) Election(org.neo4j.cluster.protocol.election.Election) Test(org.junit.Test)

Example 2 with SwitchToMaster

use of org.neo4j.kernel.ha.cluster.SwitchToMaster in project neo4j by neo4j.

the class HighAvailabilityModeSwitcherTest method shouldSwitchToSlaveForNullMasterAndBeSilentWhenMovingToDetached.

@Test
public void shouldSwitchToSlaveForNullMasterAndBeSilentWhenMovingToDetached() throws Throwable {
    // Given
    SwitchToSlaveCopyThenBranch sts = mock(SwitchToSlaveCopyThenBranch.class);
    SwitchToMaster stm = mock(SwitchToMaster.class);
    Election election = mock(Election.class);
    ClusterMemberAvailability cma = mock(ClusterMemberAvailability.class);
    InstanceId instanceId = new InstanceId(14);
    ComponentSwitcher componentSwitcher = mock(ComponentSwitcher.class);
    HighAvailabilityModeSwitcher theSwitcher = new HighAvailabilityModeSwitcher(sts, stm, election, cma, mock(ClusterClient.class), storeSupplierMock(), instanceId, componentSwitcher, neoStoreDataSourceSupplierMock(), NullLogService.getInstance());
    // When
    theSwitcher.init();
    theSwitcher.start();
    theSwitcher.instanceDetached(new HighAvailabilityMemberChangeEvent(HighAvailabilityMemberState.MASTER, HighAvailabilityMemberState.PENDING, null, null));
    // Then
    verify(componentSwitcher).switchToSlave();
    verifyZeroInteractions(cma);
}
Also used : ClusterClient(org.neo4j.cluster.client.ClusterClient) SwitchToSlaveCopyThenBranch(org.neo4j.kernel.ha.cluster.SwitchToSlaveCopyThenBranch) InstanceId(org.neo4j.cluster.InstanceId) HighAvailabilityMemberChangeEvent(org.neo4j.kernel.ha.cluster.HighAvailabilityMemberChangeEvent) ClusterMemberAvailability(org.neo4j.cluster.member.ClusterMemberAvailability) SwitchToMaster(org.neo4j.kernel.ha.cluster.SwitchToMaster) Election(org.neo4j.cluster.protocol.election.Election) Test(org.junit.Test)

Example 3 with SwitchToMaster

use of org.neo4j.kernel.ha.cluster.SwitchToMaster in project neo4j by neo4j.

the class HighAvailabilityModeSwitcherTest method shouldReswitchToSlaveIfNewMasterBecameElectedAndAvailableDuringSwitch.

@Test
public void shouldReswitchToSlaveIfNewMasterBecameElectedAndAvailableDuringSwitch() throws Throwable {
    // Given
    final CountDownLatch switching = new CountDownLatch(1);
    final CountDownLatch slaveAvailable = new CountDownLatch(2);
    final AtomicBoolean firstSwitch = new AtomicBoolean(true);
    ClusterMemberAvailability availability = mock(ClusterMemberAvailability.class);
    SwitchToSlaveCopyThenBranch switchToSlave = mock(SwitchToSlaveCopyThenBranch.class);
    @SuppressWarnings("resource") SwitchToMaster switchToMaster = mock(SwitchToMaster.class);
    when(switchToSlave.switchToSlave(any(LifeSupport.class), any(URI.class), any(URI.class), any(CancellationRequest.class))).thenAnswer(invocationOnMock -> {
        switching.countDown();
        CancellationRequest cancel = (CancellationRequest) invocationOnMock.getArguments()[3];
        if (firstSwitch.get()) {
            while (!cancel.cancellationRequested()) {
                Thread.sleep(1);
            }
            firstSwitch.set(false);
        }
        slaveAvailable.countDown();
        return URI.create("ha://slave");
    });
    HighAvailabilityModeSwitcher toTest = new HighAvailabilityModeSwitcher(switchToSlave, switchToMaster, mock(Election.class), availability, mock(ClusterClient.class), storeSupplierMock(), mock(InstanceId.class), new ComponentSwitcherContainer(), neoStoreDataSourceSupplierMock(), NullLogService.getInstance());
    toTest.init();
    toTest.start();
    toTest.listeningAt(URI.create("ha://server3?serverId=3"));
    // When
    // This will start a switch to slave
    toTest.masterIsAvailable(new HighAvailabilityMemberChangeEvent(PENDING, TO_SLAVE, mock(InstanceId.class), URI.create("ha://server1")));
    // Wait until it starts and blocks on the cancellation request
    switching.await();
    // change the elected master, moving to pending, cancelling the previous change. This will block until the
    // previous switch is aborted
    toTest.masterIsElected(new HighAvailabilityMemberChangeEvent(TO_SLAVE, PENDING, new InstanceId(2), URI.create("ha://server2")));
    // Now move to the new master by switching to TO_SLAVE
    toTest.masterIsAvailable(new HighAvailabilityMemberChangeEvent(PENDING, TO_SLAVE, new InstanceId(2), URI.create("ha://server2")));
    // Then
    // The second switch must happen and this test won't block
    slaveAvailable.await();
}
Also used : InstanceId(org.neo4j.cluster.InstanceId) ClusterMemberAvailability(org.neo4j.cluster.member.ClusterMemberAvailability) CountDownLatch(java.util.concurrent.CountDownLatch) URI(java.net.URI) Election(org.neo4j.cluster.protocol.election.Election) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ClusterClient(org.neo4j.cluster.client.ClusterClient) SwitchToSlaveCopyThenBranch(org.neo4j.kernel.ha.cluster.SwitchToSlaveCopyThenBranch) HighAvailabilityMemberChangeEvent(org.neo4j.kernel.ha.cluster.HighAvailabilityMemberChangeEvent) LifeSupport(org.neo4j.kernel.lifecycle.LifeSupport) SwitchToMaster(org.neo4j.kernel.ha.cluster.SwitchToMaster) CancellationRequest(org.neo4j.helpers.CancellationRequest) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)3 InstanceId (org.neo4j.cluster.InstanceId)3 ClusterClient (org.neo4j.cluster.client.ClusterClient)3 ClusterMemberAvailability (org.neo4j.cluster.member.ClusterMemberAvailability)3 Election (org.neo4j.cluster.protocol.election.Election)3 HighAvailabilityMemberChangeEvent (org.neo4j.kernel.ha.cluster.HighAvailabilityMemberChangeEvent)3 SwitchToMaster (org.neo4j.kernel.ha.cluster.SwitchToMaster)3 SwitchToSlaveCopyThenBranch (org.neo4j.kernel.ha.cluster.SwitchToSlaveCopyThenBranch)3 URI (java.net.URI)2 LifeSupport (org.neo4j.kernel.lifecycle.LifeSupport)2 CountDownLatch (java.util.concurrent.CountDownLatch)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 CancellationRequest (org.neo4j.helpers.CancellationRequest)1