Search in sources :

Example 6 with MasterClient

use of org.neo4j.kernel.ha.com.slave.MasterClient in project neo4j by neo4j.

the class HighAvailabilityMemberStateMachineTest method whenHAModeSwitcherSwitchesToSlaveTheOtherModeSwitcherDoNotGetTheOldMasterClient.

@Test
public void whenHAModeSwitcherSwitchesToSlaveTheOtherModeSwitcherDoNotGetTheOldMasterClient() throws Throwable {
    InstanceId me = new InstanceId(1);
    StoreId storeId = newStoreIdForCurrentVersion();
    HighAvailabilityMemberContext context = mock(HighAvailabilityMemberContext.class);
    when(context.getMyId()).thenReturn(me);
    AvailabilityGuard guard = mock(AvailabilityGuard.class);
    ObservedClusterMembers members = mock(ObservedClusterMembers.class);
    ClusterMember masterMember = mock(ClusterMember.class);
    when(masterMember.getHARole()).thenReturn("master");
    when(masterMember.hasRole("master")).thenReturn(true);
    when(masterMember.getInstanceId()).thenReturn(new InstanceId(2));
    when(masterMember.getStoreId()).thenReturn(storeId);
    ClusterMember self = new ClusterMember(me);
    when(members.getMembers()).thenReturn(Arrays.asList(self, masterMember));
    when(members.getCurrentMember()).thenReturn(self);
    DependencyResolver dependencyResolver = mock(DependencyResolver.class);
    FileSystemAbstraction fs = mock(FileSystemAbstraction.class);
    when(fs.fileExists(any(File.class))).thenReturn(true);
    when(dependencyResolver.resolveDependency(FileSystemAbstraction.class)).thenReturn(fs);
    when(dependencyResolver.resolveDependency(Monitors.class)).thenReturn(new Monitors());
    NeoStoreDataSource dataSource = mock(NeoStoreDataSource.class);
    when(dataSource.getDependencyResolver()).thenReturn(dependencyResolver);
    when(dataSource.getStoreId()).thenReturn(storeId);
    when(dependencyResolver.resolveDependency(NeoStoreDataSource.class)).thenReturn(dataSource);
    when(dependencyResolver.resolveDependency(TransactionIdStore.class)).thenReturn(new DeadSimpleTransactionIdStore());
    when(dependencyResolver.resolveDependency(ObservedClusterMembers.class)).thenReturn(members);
    UpdatePuller updatePuller = mock(UpdatePuller.class);
    when(updatePuller.tryPullUpdates()).thenReturn(true);
    when(dependencyResolver.resolveDependency(UpdatePuller.class)).thenReturn(updatePuller);
    ClusterMemberAvailability clusterMemberAvailability = mock(ClusterMemberAvailability.class);
    final TriggerableClusterMemberEvents events = new TriggerableClusterMemberEvents();
    Election election = mock(Election.class);
    HighAvailabilityMemberStateMachine stateMachine = new HighAvailabilityMemberStateMachine(context, guard, members, events, election, NullLogProvider.getInstance());
    ClusterMembers clusterMembers = new ClusterMembers(members, stateMachine);
    when(dependencyResolver.resolveDependency(ClusterMembers.class)).thenReturn(clusterMembers);
    stateMachine.init();
    stateMachine.start();
    final DelegateInvocationHandler<Master> handler = new DelegateInvocationHandler<>(Master.class);
    MasterClientResolver masterClientResolver = mock(MasterClientResolver.class);
    MasterClient masterClient = mock(MasterClient.class);
    when(masterClient.getProtocolVersion()).thenReturn(MasterClient214.PROTOCOL_VERSION);
    when(masterClient.handshake(anyLong(), any(StoreId.class))).thenReturn(new Response<HandshakeResult>(new HandshakeResult(0, 42), storeId, mock(ResourceReleaser.class)) {

        @Override
        public void accept(Handler handler) throws IOException {
        }

        @Override
        public boolean hasTransactionsToBeApplied() {
            return false;
        }
    });
    when(masterClient.toString()).thenReturn("TheExpectedMasterClient!");
    when(masterClientResolver.instantiate(anyString(), anyInt(), anyString(), any(Monitors.class), any(StoreId.class), any(LifeSupport.class))).thenReturn(masterClient);
    final CountDownLatch latch = new CountDownLatch(2);
    final AtomicBoolean switchedSuccessfully = new AtomicBoolean();
    SwitchToSlave.Monitor monitor = new SwitchToSlave.Monitor() {

        @Override
        public void switchToSlaveCompleted(boolean wasSuccessful) {
            switchedSuccessfully.set(wasSuccessful);
            latch.countDown();
        }
    };
    Config config = Config.embeddedDefaults(Collections.singletonMap(ClusterSettings.server_id.name(), me.toString()));
    TransactionStats transactionCounters = mock(TransactionStats.class);
    when(transactionCounters.getNumberOfActiveTransactions()).thenReturn(0L);
    PageCache pageCacheMock = mock(PageCache.class);
    PagedFile pagedFileMock = mock(PagedFile.class);
    when(pagedFileMock.getLastPageId()).thenReturn(1L);
    when(pageCacheMock.map(any(File.class), anyInt())).thenReturn(pagedFileMock);
    TransactionIdStore transactionIdStoreMock = mock(TransactionIdStore.class);
    when(transactionIdStoreMock.getLastCommittedTransaction()).thenReturn(new TransactionId(0, 0, 0));
    SwitchToSlaveCopyThenBranch switchToSlave = new SwitchToSlaveCopyThenBranch(new File(""), NullLogService.getInstance(), mock(FileSystemAbstraction.class), config, dependencyResolver, mock(HaIdGeneratorFactory.class), handler, mock(ClusterMemberAvailability.class), mock(RequestContextFactory.class), mock(PullerFactory.class, RETURNS_MOCKS), Iterables.empty(), masterClientResolver, monitor, new StoreCopyClient.Monitor.Adapter(), Suppliers.singleton(dataSource), Suppliers.singleton(transactionIdStoreMock), slave -> {
        SlaveServer mock = mock(SlaveServer.class);
        when(mock.getSocketAddress()).thenReturn(new InetSocketAddress("localhost", 123));
        return mock;
    }, updatePuller, pageCacheMock, mock(Monitors.class), transactionCounters);
    ComponentSwitcherContainer switcherContainer = new ComponentSwitcherContainer();
    HighAvailabilityModeSwitcher haModeSwitcher = new HighAvailabilityModeSwitcher(switchToSlave, mock(SwitchToMaster.class), election, clusterMemberAvailability, mock(ClusterClient.class), storeSupplierMock(), me, switcherContainer, neoStoreDataSourceSupplierMock(), NullLogService.getInstance());
    haModeSwitcher.init();
    haModeSwitcher.start();
    haModeSwitcher.listeningAt(URI.create("http://localhost:12345"));
    stateMachine.addHighAvailabilityMemberListener(haModeSwitcher);
    final AtomicReference<Master> ref = new AtomicReference<>(null);
    //noinspection unchecked
    AbstractComponentSwitcher<Object> otherModeSwitcher = new AbstractComponentSwitcher<Object>(mock(DelegateInvocationHandler.class)) {

        @Override
        protected Object getSlaveImpl() {
            Master master = handler.cement();
            ref.set(master);
            latch.countDown();
            return null;
        }

        @Override
        protected Object getMasterImpl() {
            return null;
        }
    };
    switcherContainer.add(otherModeSwitcher);
    // When
    events.switchToSlave(me);
    // Then
    latch.await();
    assertTrue("mode switch failed", switchedSuccessfully.get());
    Master actual = ref.get();
    // let's test the toString()s since there are too many wrappers of proxies
    assertEquals(masterClient.toString(), actual.toString());
    stateMachine.stop();
    stateMachine.shutdown();
    haModeSwitcher.stop();
    haModeSwitcher.shutdown();
}
Also used : FileSystemAbstraction(org.neo4j.io.fs.FileSystemAbstraction) MasterClient(org.neo4j.kernel.ha.com.slave.MasterClient) InetSocketAddress(java.net.InetSocketAddress) DeadSimpleTransactionIdStore(org.neo4j.kernel.impl.transaction.DeadSimpleTransactionIdStore) AvailabilityGuard(org.neo4j.kernel.AvailabilityGuard) ObservedClusterMembers(org.neo4j.kernel.ha.cluster.member.ObservedClusterMembers) RequestContextFactory(org.neo4j.kernel.ha.com.RequestContextFactory) PageCache(org.neo4j.io.pagecache.PageCache) HighAvailabilityModeSwitcher(org.neo4j.kernel.ha.cluster.modeswitch.HighAvailabilityModeSwitcher) DeadSimpleTransactionIdStore(org.neo4j.kernel.impl.transaction.DeadSimpleTransactionIdStore) TransactionIdStore(org.neo4j.kernel.impl.transaction.log.TransactionIdStore) InstanceId(org.neo4j.cluster.InstanceId) NeoStoreDataSource(org.neo4j.kernel.NeoStoreDataSource) DelegateInvocationHandler(org.neo4j.kernel.ha.DelegateInvocationHandler) DelegateInvocationHandler(org.neo4j.kernel.ha.DelegateInvocationHandler) DependencyResolver(org.neo4j.graphdb.DependencyResolver) TransactionId(org.neo4j.kernel.impl.store.TransactionId) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Monitors(org.neo4j.kernel.monitoring.Monitors) PagedFile(org.neo4j.io.pagecache.PagedFile) File(java.io.File) HaIdGeneratorFactory(org.neo4j.kernel.ha.id.HaIdGeneratorFactory) HandshakeResult(org.neo4j.kernel.ha.com.master.HandshakeResult) Config(org.neo4j.kernel.configuration.Config) ClusterMemberAvailability(org.neo4j.cluster.member.ClusterMemberAvailability) ClusterMembers(org.neo4j.kernel.ha.cluster.member.ClusterMembers) ObservedClusterMembers(org.neo4j.kernel.ha.cluster.member.ObservedClusterMembers) SlaveServer(org.neo4j.kernel.ha.com.slave.SlaveServer) ClusterMember(org.neo4j.kernel.ha.cluster.member.ClusterMember) ClusterClient(org.neo4j.cluster.client.ClusterClient) StoreId(org.neo4j.kernel.impl.store.StoreId) AbstractComponentSwitcher(org.neo4j.kernel.ha.cluster.modeswitch.AbstractComponentSwitcher) UpdatePuller(org.neo4j.kernel.ha.UpdatePuller) LifeSupport(org.neo4j.kernel.lifecycle.LifeSupport) PullerFactory(org.neo4j.kernel.ha.PullerFactory) PagedFile(org.neo4j.io.pagecache.PagedFile) ComponentSwitcherContainer(org.neo4j.kernel.ha.cluster.modeswitch.ComponentSwitcherContainer) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) Election(org.neo4j.cluster.protocol.election.Election) MasterClientResolver(org.neo4j.kernel.ha.com.slave.MasterClientResolver) Master(org.neo4j.kernel.ha.com.master.Master) TransactionStats(org.neo4j.kernel.impl.transaction.TransactionStats) Test(org.junit.Test)

Example 7 with MasterClient

use of org.neo4j.kernel.ha.com.slave.MasterClient in project neo4j by neo4j.

the class SwitchToSlave method startHaCommunication.

private URI startHaCommunication(LifeSupport haCommunicationLife, NeoStoreDataSource neoDataSource, URI me, URI masterUri, StoreId storeId, CancellationRequest cancellationRequest) throws IllegalArgumentException, InterruptedException {
    MasterClient master = newMasterClient(masterUri, me, neoDataSource.getStoreId(), haCommunicationLife);
    TransactionObligationFulfiller obligationFulfiller = resolver.resolveDependency(TransactionObligationFulfiller.class);
    UpdatePullerScheduler updatePullerScheduler = updatePullerFactory.createUpdatePullerScheduler(updatePuller);
    Slave slaveImpl = new SlaveImpl(obligationFulfiller);
    SlaveServer server = slaveServerFactory.apply(slaveImpl);
    if (cancellationRequest.cancellationRequested()) {
        msgLog.info("Switch to slave cancelled, unable to start HA-communication");
        return null;
    }
    masterDelegateHandler.setDelegate(master);
    haCommunicationLife.add(updatePullerScheduler);
    haCommunicationLife.add(server);
    haCommunicationLife.start();
    /*
         * Take the opportunity to catch up with master, now that we're alone here, right before we
         * drop the availability guard, so that other transactions might start.
         */
    if (!catchUpWithMaster(updatePuller)) {
        return null;
    }
    URI slaveHaURI = createHaURI(me, server);
    clusterMemberAvailability.memberIsAvailable(HighAvailabilityModeSwitcher.SLAVE, slaveHaURI, storeId);
    return slaveHaURI;
}
Also used : Slave(org.neo4j.kernel.ha.com.master.Slave) TransactionObligationFulfiller(org.neo4j.com.storecopy.TransactionObligationFulfiller) UpdatePullerScheduler(org.neo4j.kernel.ha.UpdatePullerScheduler) MasterClient(org.neo4j.kernel.ha.com.slave.MasterClient) SlaveServer(org.neo4j.kernel.ha.com.slave.SlaveServer) URI(java.net.URI) SlaveImpl(org.neo4j.kernel.ha.com.slave.SlaveImpl)

Example 8 with MasterClient

use of org.neo4j.kernel.ha.com.slave.MasterClient in project neo4j by neo4j.

the class SwitchToSlave method copyStoreFromMasterIfNeeded.

private void copyStoreFromMasterIfNeeded(URI masterUri, URI me, CancellationRequest cancellationRequest) throws Throwable {
    if (!isStorePresent(pageCache, storeDir)) {
        boolean success = false;
        monitor.storeCopyStarted();
        LifeSupport copyLife = new LifeSupport();
        try {
            MasterClient masterClient = newMasterClient(masterUri, me, null, copyLife);
            copyLife.start();
            boolean masterIsOld = MasterClient.CURRENT.compareTo(masterClient.getProtocolVersion()) > 0;
            if (masterIsOld) {
                throw new UnableToCopyStoreFromOldMasterException(MasterClient.CURRENT.getApplicationProtocol(), masterClient.getProtocolVersion().getApplicationProtocol());
            } else {
                copyStoreFromMaster(masterClient, cancellationRequest, MoveAfterCopy.moveReplaceExisting());
                success = true;
            }
        } finally {
            monitor.storeCopyCompleted(success);
            copyLife.shutdown();
        }
    }
}
Also used : UnableToCopyStoreFromOldMasterException(org.neo4j.kernel.ha.store.UnableToCopyStoreFromOldMasterException) MasterClient(org.neo4j.kernel.ha.com.slave.MasterClient) LifeSupport(org.neo4j.kernel.lifecycle.LifeSupport)

Example 9 with MasterClient

use of org.neo4j.kernel.ha.com.slave.MasterClient in project neo4j by neo4j.

the class SwitchToSlaveCopyThenBranch method copyStore.

private void copyStore(URI masterUri, URI me, CancellationRequest cancellationRequest, MoveAfterCopy moveAfterCopy) throws Throwable {
    boolean success = false;
    monitor.storeCopyStarted();
    LifeSupport copyLife = new LifeSupport();
    try {
        MasterClient masterClient = newMasterClient(masterUri, me, null, copyLife);
        copyLife.start();
        boolean masterIsOld = MasterClient.CURRENT.compareTo(masterClient.getProtocolVersion()) > 0;
        if (masterIsOld) {
            throw new UnableToCopyStoreFromOldMasterException(MasterClient.CURRENT.getApplicationProtocol(), masterClient.getProtocolVersion().getApplicationProtocol());
        } else {
            copyStoreFromMaster(masterClient, cancellationRequest, moveAfterCopy);
            success = true;
        }
    } finally {
        monitor.storeCopyCompleted(success);
        copyLife.shutdown();
    }
}
Also used : UnableToCopyStoreFromOldMasterException(org.neo4j.kernel.ha.store.UnableToCopyStoreFromOldMasterException) MasterClient(org.neo4j.kernel.ha.com.slave.MasterClient) LifeSupport(org.neo4j.kernel.lifecycle.LifeSupport)

Example 10 with MasterClient

use of org.neo4j.kernel.ha.com.slave.MasterClient in project neo4j by neo4j.

the class SwitchToSlaveBranchThenCopyTest method shouldHandleBranchedStoreWhenMyStoreIdDiffersFromMasterStoreId.

@Test
@SuppressWarnings("unchecked")
public void shouldHandleBranchedStoreWhenMyStoreIdDiffersFromMasterStoreId() throws Throwable {
    // Given
    SwitchToSlaveBranchThenCopy switchToSlave = newSwitchToSlaveSpy();
    URI me = new URI("cluster://localhost?serverId=2");
    MasterClient masterClient = mock(MasterClient.class);
    Response<HandshakeResult> response = mock(Response.class);
    when(response.response()).thenReturn(new HandshakeResult(1, 2));
    when(masterClient.handshake(anyLong(), any(StoreId.class))).thenReturn(response);
    StoreId storeId = newStoreIdForCurrentVersion(1, 2, 3, 4);
    TransactionIdStore transactionIdStore = mock(TransactionIdStore.class);
    when(transactionIdStore.getLastCommittedTransaction()).thenReturn(new TransactionId(42, 42, 42));
    when(transactionIdStore.getLastCommittedTransactionId()).thenReturn(TransactionIdStore.BASE_TX_ID);
    // When
    try {
        switchToSlave.checkDataConsistency(masterClient, transactionIdStore, storeId, new URI("cluster://localhost?serverId=1"), me, CancellationRequest.NEVER_CANCELLED);
        fail("Should have thrown " + MismatchingStoreIdException.class.getSimpleName() + " exception");
    } catch (MismatchingStoreIdException e) {
    // good we got the expected exception
    }
    // Then
    verify(switchToSlave).stopServicesAndHandleBranchedStore(any(BranchedDataPolicy.class));
}
Also used : HandshakeResult(org.neo4j.kernel.ha.com.master.HandshakeResult) TransactionIdStore(org.neo4j.kernel.impl.transaction.log.TransactionIdStore) StoreId(org.neo4j.kernel.impl.store.StoreId) MasterClient(org.neo4j.kernel.ha.com.slave.MasterClient) MismatchingStoreIdException(org.neo4j.kernel.impl.store.MismatchingStoreIdException) BranchedDataPolicy(org.neo4j.kernel.ha.BranchedDataPolicy) URI(java.net.URI) TransactionId(org.neo4j.kernel.impl.store.TransactionId) Test(org.junit.Test)

Aggregations

MasterClient (org.neo4j.kernel.ha.com.slave.MasterClient)16 Test (org.junit.Test)11 StoreId (org.neo4j.kernel.impl.store.StoreId)11 URI (java.net.URI)9 TransactionId (org.neo4j.kernel.impl.store.TransactionId)9 TransactionIdStore (org.neo4j.kernel.impl.transaction.log.TransactionIdStore)9 BranchedDataPolicy (org.neo4j.kernel.ha.BranchedDataPolicy)7 HandshakeResult (org.neo4j.kernel.ha.com.master.HandshakeResult)7 LifeSupport (org.neo4j.kernel.lifecycle.LifeSupport)7 CancellationRequest (org.neo4j.helpers.CancellationRequest)6 BranchedDataException (org.neo4j.kernel.ha.BranchedDataException)6 File (java.io.File)5 PageCache (org.neo4j.io.pagecache.PageCache)5 SlaveServer (org.neo4j.kernel.ha.com.slave.SlaveServer)5 MismatchingStoreIdException (org.neo4j.kernel.impl.store.MismatchingStoreIdException)5 IOException (java.io.IOException)4 InstanceId (org.neo4j.cluster.InstanceId)4 ClusterMemberAvailability (org.neo4j.cluster.member.ClusterMemberAvailability)4 MoveAfterCopy (org.neo4j.com.storecopy.MoveAfterCopy)4 StoreCopyClient (org.neo4j.com.storecopy.StoreCopyClient)4