GH-4008: ZK: Add leader and participants support

Fixes https://github.com/spring-projects/spring-integration/issues/4008

Impossible to retrieve current leader id from ZK `LeaderInitiator`

* change return type of `LeaderInitiator.getContext()` from `Context` to `CuratorContext`
* add `getLeader()` method to `CuratorContext`
* add `getParticipants()` method to `CuratorContext`
This commit is contained in:
Ivan Zaitsev
2023-02-07 17:36:29 +02:00
committed by GitHub
parent 6a2ff0cd99
commit e6d0a4f826
2 changed files with 57 additions and 16 deletions

View File

@@ -16,12 +16,16 @@
package org.springframework.integration.zookeeper.leader;
import java.util.Collection;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.imps.CuratorFrameworkState;
import org.apache.curator.framework.recipes.leader.LeaderSelector;
import org.apache.curator.framework.recipes.leader.LeaderSelectorListenerAdapter;
import org.apache.curator.framework.recipes.leader.Participant;
import org.springframework.context.SmartLifecycle;
import org.springframework.integration.leader.Candidate;
@@ -38,6 +42,7 @@ import org.springframework.util.StringUtils;
* @author Janne Valkealahti
* @author Gary Russell
* @author Artem Bilan
* @author Ivan Zaitsev
*
* @since 4.2
*/
@@ -49,6 +54,8 @@ public class LeaderInitiator implements SmartLifecycle {
private final CuratorContext context = new CuratorContext();
private final CuratorContext nullContext = new NullCuratorContext();
/**
* Curator client.
*/
@@ -59,20 +66,6 @@ public class LeaderInitiator implements SmartLifecycle {
*/
private final Candidate candidate;
private final Context nullContext = new Context() {
@Override
public boolean isLeader() {
return false;
}
@Override
public String getRole() {
return LeaderInitiator.this.candidate.getRole();
}
};
private final Object lifecycleMonitor = new Object();
/**
@@ -214,7 +207,7 @@ public class LeaderInitiator implements SmartLifecycle {
* @return the context.
* @since 5.0
*/
public Context getContext() {
public CuratorContext getContext() {
if (this.leaderSelector == null) {
return this.nullContext;
}
@@ -283,7 +276,7 @@ public class LeaderInitiator implements SmartLifecycle {
/**
* Implementation of leadership context backed by Curator.
*/
private class CuratorContext implements Context {
public class CuratorContext implements Context {
CuratorContext() {
}
@@ -303,6 +296,24 @@ public class LeaderInitiator implements SmartLifecycle {
return LeaderInitiator.this.candidate.getRole();
}
/**
* Get the leader
* @return the leader.
* @since 6.0.3
*/
public Participant getLeader() throws Exception {
return LeaderInitiator.this.leaderSelector.getLeader();
}
/**
* Get the list of participants
* @return list of participants.
* @since 6.0.3
*/
public Collection<Participant> getParticipants() throws Exception {
return LeaderInitiator.this.leaderSelector.getParticipants();
}
@Override
public String toString() {
return "CuratorContext{role=" + LeaderInitiator.this.candidate.getRole() +
@@ -312,4 +323,28 @@ public class LeaderInitiator implements SmartLifecycle {
}
private class NullCuratorContext extends CuratorContext {
@Override
public boolean isLeader() {
return false;
}
@Override
public String getRole() {
return LeaderInitiator.this.candidate.getRole();
}
@Override
public Participant getLeader() throws Exception {
return null;
}
@Override
public Collection<Participant> getParticipants() throws Exception {
return List.of();
}
}
}

View File

@@ -23,6 +23,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.leader.Participant;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -47,6 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Gary Russell
* @author Artem Bilan
* @author Ivan Zaitsev
*
* @since 4.2
*
@@ -88,6 +90,8 @@ public class LeaderInitiatorFactoryBeanTests extends ZookeeperTestSupport {
public void testExceptionFromEvent() throws Exception {
CountDownLatch onGranted = new CountDownLatch(1);
Participant participant = new Participant("foo", true);
LeaderInitiator initiator = new LeaderInitiator(client, new DefaultCandidate("foo", "bar"));
initiator.setLeaderEventPublisher(new DefaultLeaderEventPublisher() {
@@ -110,6 +114,8 @@ public class LeaderInitiatorFactoryBeanTests extends ZookeeperTestSupport {
assertThat(onGranted.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(initiator.getContext().isLeader()).isTrue();
assertThat(initiator.getContext().getRole()).isEqualTo("bar");
assertThat(initiator.getContext().getLeader()).isEqualTo(participant);
assertThat(initiator.getContext().getParticipants()).contains(participant);
initiator.stop();
}