Search in sources :

Example 1 with Context

use of org.springframework.integration.leader.Context in project spring-integration by spring-projects.

the class RedisLockRegistryLeaderInitiatorTests method testDistributedLeaderElection.

@Test
@RedisAvailable
public void testDistributedLeaderElection() throws Exception {
    CountDownLatch granted = new CountDownLatch(1);
    CountingPublisher countingPublisher = new CountingPublisher(granted);
    List<LockRegistryLeaderInitiator> initiators = new ArrayList<>();
    for (int i = 0; i < 2; i++) {
        RedisLockRegistry registry = new RedisLockRegistry(getConnectionFactoryForTest(), "LeaderInitiator");
        LockRegistryLeaderInitiator initiator = new LockRegistryLeaderInitiator(registry, new DefaultCandidate("foo", "bar"));
        initiator.setLeaderEventPublisher(countingPublisher);
        initiators.add(initiator);
    }
    for (LockRegistryLeaderInitiator initiator : initiators) {
        initiator.start();
    }
    assertThat(granted.await(10, TimeUnit.SECONDS), is(true));
    LockRegistryLeaderInitiator initiator1 = countingPublisher.initiator;
    LockRegistryLeaderInitiator initiator2 = null;
    for (LockRegistryLeaderInitiator initiator : initiators) {
        if (initiator != initiator1) {
            initiator2 = initiator;
            break;
        }
    }
    assertNotNull(initiator2);
    assertThat(initiator1.getContext().isLeader(), is(true));
    assertThat(initiator2.getContext().isLeader(), is(false));
    final CountDownLatch granted1 = new CountDownLatch(1);
    final CountDownLatch granted2 = new CountDownLatch(1);
    CountDownLatch revoked1 = new CountDownLatch(1);
    CountDownLatch revoked2 = new CountDownLatch(1);
    CountDownLatch acquireLockFailed1 = new CountDownLatch(1);
    CountDownLatch acquireLockFailed2 = new CountDownLatch(1);
    initiator1.setLeaderEventPublisher(new CountingPublisher(granted1, revoked1, acquireLockFailed1) {

        @Override
        public void publishOnRevoked(Object source, Context context, String role) {
            try {
                // It's difficult to see round-robin election, so block one initiator until the second is elected.
                assertThat(granted2.await(10, TimeUnit.SECONDS), is(true));
            } catch (InterruptedException e) {
            // No op
            }
            super.publishOnRevoked(source, context, role);
        }
    });
    initiator2.setLeaderEventPublisher(new CountingPublisher(granted2, revoked2, acquireLockFailed2) {

        @Override
        public void publishOnRevoked(Object source, Context context, String role) {
            try {
                // It's difficult to see round-robin election, so block one initiator until the second is elected.
                assertThat(granted1.await(10, TimeUnit.SECONDS), is(true));
            } catch (InterruptedException e) {
            // No op
            }
            super.publishOnRevoked(source, context, role);
        }
    });
    initiator1.getContext().yield();
    assertThat(revoked1.await(10, TimeUnit.SECONDS), is(true));
    assertThat(initiator2.getContext().isLeader(), is(true));
    assertThat(initiator1.getContext().isLeader(), is(false));
    initiator2.getContext().yield();
    assertThat(revoked2.await(10, TimeUnit.SECONDS), is(true));
    assertThat(initiator1.getContext().isLeader(), is(true));
    assertThat(initiator2.getContext().isLeader(), is(false));
    initiator2.stop();
    CountDownLatch revoked11 = new CountDownLatch(1);
    initiator1.setLeaderEventPublisher(new CountingPublisher(new CountDownLatch(1), revoked11, new CountDownLatch(1)));
    initiator1.getContext().yield();
    assertThat(revoked11.await(10, TimeUnit.SECONDS), is(true));
    assertThat(initiator1.getContext().isLeader(), is(false));
    initiator1.stop();
}
Also used : Context(org.springframework.integration.leader.Context) ArrayList(java.util.ArrayList) DefaultCandidate(org.springframework.integration.leader.DefaultCandidate) CountDownLatch(java.util.concurrent.CountDownLatch) LockRegistryLeaderInitiator(org.springframework.integration.support.leader.LockRegistryLeaderInitiator) RedisLockRegistry(org.springframework.integration.redis.util.RedisLockRegistry) RedisAvailable(org.springframework.integration.redis.rules.RedisAvailable) Test(org.junit.Test)

Example 2 with Context

use of org.springframework.integration.leader.Context in project spring-integration by spring-projects.

the class LockRegistryLeaderInitiatorTests method testExceptionFromEvent.

@Test
public void testExceptionFromEvent() throws Exception {
    CountDownLatch onGranted = new CountDownLatch(1);
    this.initiator.setLeaderEventPublisher(new DefaultLeaderEventPublisher() {

        @Override
        public void publishOnGranted(Object source, Context context, String role) {
            try {
                throw new RuntimeException("intentional");
            } finally {
                onGranted.countDown();
            }
        }
    });
    this.initiator.start();
    assertTrue(onGranted.await(10, TimeUnit.SECONDS));
    assertTrue(initiator.getContext().isLeader());
    this.initiator.stop();
}
Also used : Context(org.springframework.integration.leader.Context) DefaultLeaderEventPublisher(org.springframework.integration.leader.event.DefaultLeaderEventPublisher) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 3 with Context

use of org.springframework.integration.leader.Context in project spring-integration by spring-projects.

the class JdbcLockRegistryLeaderInitiatorTests method testDistributedLeaderElection.

@Test
public void testDistributedLeaderElection() throws Exception {
    CountDownLatch granted = new CountDownLatch(1);
    CountingPublisher countingPublisher = new CountingPublisher(granted);
    List<LockRegistryLeaderInitiator> initiators = new ArrayList<LockRegistryLeaderInitiator>();
    for (int i = 0; i < 2; i++) {
        DefaultLockRepository lockRepository = new DefaultLockRepository(dataSource);
        lockRepository.afterPropertiesSet();
        LockRegistryLeaderInitiator initiator = new LockRegistryLeaderInitiator(new JdbcLockRegistry(lockRepository), new DefaultCandidate("foo", "bar"));
        initiator.setLeaderEventPublisher(countingPublisher);
        initiators.add(initiator);
    }
    for (LockRegistryLeaderInitiator initiator : initiators) {
        initiator.start();
    }
    assertThat(granted.await(10, TimeUnit.SECONDS), is(true));
    LockRegistryLeaderInitiator initiator1 = countingPublisher.initiator;
    LockRegistryLeaderInitiator initiator2 = null;
    for (LockRegistryLeaderInitiator initiator : initiators) {
        if (initiator != initiator1) {
            initiator2 = initiator;
            break;
        }
    }
    assertNotNull(initiator2);
    assertThat(initiator1.getContext().isLeader(), is(true));
    assertThat(initiator2.getContext().isLeader(), is(false));
    final CountDownLatch granted1 = new CountDownLatch(1);
    final CountDownLatch granted2 = new CountDownLatch(1);
    CountDownLatch revoked1 = new CountDownLatch(1);
    CountDownLatch revoked2 = new CountDownLatch(1);
    final CountDownLatch acquireLockFailed1 = new CountDownLatch(1);
    final CountDownLatch acquireLockFailed2 = new CountDownLatch(1);
    initiator1.setLeaderEventPublisher(new CountingPublisher(granted1, revoked1, acquireLockFailed1) {

        @Override
        public void publishOnRevoked(Object source, Context context, String role) {
            try {
                // It's difficult to see round-robin election, so block one initiator until the second is elected.
                assertThat(granted2.await(20, TimeUnit.SECONDS), is(true));
            } catch (InterruptedException e) {
            // No op
            }
            super.publishOnRevoked(source, context, role);
        }
    });
    initiator2.setLeaderEventPublisher(new CountingPublisher(granted2, revoked2, acquireLockFailed2) {

        @Override
        public void publishOnRevoked(Object source, Context context, String role) {
            try {
                // It's difficult to see round-robin election, so block one initiator until the second is elected.
                assertThat(granted1.await(20, TimeUnit.SECONDS), is(true));
            } catch (InterruptedException e) {
            // No op
            }
            super.publishOnRevoked(source, context, role);
        }
    });
    initiator1.getContext().yield();
    assertThat(revoked1.await(20, TimeUnit.SECONDS), is(true));
    assertThat(initiator2.getContext().isLeader(), is(true));
    assertThat(initiator1.getContext().isLeader(), is(false));
    initiator2.getContext().yield();
    assertThat(revoked2.await(20, TimeUnit.SECONDS), is(true));
    assertThat(initiator1.getContext().isLeader(), is(true));
    assertThat(initiator2.getContext().isLeader(), is(false));
    // Stop second initiator, so the first one will be leader even after yield
    initiator2.stop();
    CountDownLatch granted11 = new CountDownLatch(1);
    initiator1.setLeaderEventPublisher(new CountingPublisher(granted11));
    initiator1.getContext().yield();
    assertThat(granted11.await(20, TimeUnit.SECONDS), is(true));
    assertThat(initiator1.getContext().isLeader(), is(true));
    initiator1.stop();
}
Also used : Context(org.springframework.integration.leader.Context) ArrayList(java.util.ArrayList) DefaultCandidate(org.springframework.integration.leader.DefaultCandidate) CountDownLatch(java.util.concurrent.CountDownLatch) DefaultLockRepository(org.springframework.integration.jdbc.lock.DefaultLockRepository) JdbcLockRegistry(org.springframework.integration.jdbc.lock.JdbcLockRegistry) LockRegistryLeaderInitiator(org.springframework.integration.support.leader.LockRegistryLeaderInitiator) Test(org.junit.Test)

Example 4 with Context

use of org.springframework.integration.leader.Context in project spring-integration by spring-projects.

the class LeaderInitiatorFactoryBeanTests method testExceptionFromEvent.

@Test
public void testExceptionFromEvent() throws Exception {
    CountDownLatch onGranted = new CountDownLatch(1);
    LeaderInitiator initiator = new LeaderInitiator(client, new DefaultCandidate());
    initiator.setLeaderEventPublisher(new DefaultLeaderEventPublisher() {

        @Override
        public void publishOnGranted(Object source, Context context, String role) {
            try {
                throw new RuntimeException("intentional");
            } finally {
                onGranted.countDown();
            }
        }
    });
    initiator.start();
    assertTrue(onGranted.await(10, TimeUnit.SECONDS));
    assertTrue(initiator.getContext().isLeader());
    initiator.stop();
}
Also used : DirtiesContext(org.springframework.test.annotation.DirtiesContext) Context(org.springframework.integration.leader.Context) LeaderInitiator(org.springframework.integration.zookeeper.leader.LeaderInitiator) DefaultLeaderEventPublisher(org.springframework.integration.leader.event.DefaultLeaderEventPublisher) DefaultCandidate(org.springframework.integration.leader.DefaultCandidate) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Aggregations

CountDownLatch (java.util.concurrent.CountDownLatch)4 Test (org.junit.Test)4 Context (org.springframework.integration.leader.Context)4 DefaultCandidate (org.springframework.integration.leader.DefaultCandidate)3 ArrayList (java.util.ArrayList)2 DefaultLeaderEventPublisher (org.springframework.integration.leader.event.DefaultLeaderEventPublisher)2 LockRegistryLeaderInitiator (org.springframework.integration.support.leader.LockRegistryLeaderInitiator)2 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)1 DefaultLockRepository (org.springframework.integration.jdbc.lock.DefaultLockRepository)1 JdbcLockRegistry (org.springframework.integration.jdbc.lock.JdbcLockRegistry)1 RedisAvailable (org.springframework.integration.redis.rules.RedisAvailable)1 RedisLockRegistry (org.springframework.integration.redis.util.RedisLockRegistry)1 LeaderInitiator (org.springframework.integration.zookeeper.leader.LeaderInitiator)1 DirtiesContext (org.springframework.test.annotation.DirtiesContext)1