Fabric leader clean up 3 (#1643)
This commit is contained in:
@@ -47,7 +47,7 @@ public class Leader {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Objects.equals(this.role, candidate.getRole()) && Objects.equals(this.id, candidate.getId());
|
||||
return Objects.equals(role, candidate.getRole()) && Objects.equals(id, candidate.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2019 the original author or authors.
|
||||
* Copyright 2019-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,6 @@ package org.springframework.cloud.kubernetes.commons.leader;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.boot.actuate.info.Info.Builder;
|
||||
import org.springframework.boot.actuate.info.InfoContributor;
|
||||
@@ -38,16 +37,12 @@ public class LeaderInfoContributor implements InfoContributor {
|
||||
@Override
|
||||
public void contribute(Builder builder) {
|
||||
Map<String, Object> details = new HashMap<>();
|
||||
Optional<Leader> leader = leadershipController.getLocalLeader();
|
||||
if (leader.isPresent()) {
|
||||
Leader l = leader.get();
|
||||
details.put("leaderId", l.getId());
|
||||
details.put("role", l.getRole());
|
||||
details.put("isLeader", l.isCandidate(candidate));
|
||||
}
|
||||
else {
|
||||
details.put("leaderId", "Unknown");
|
||||
}
|
||||
leadershipController.getLocalLeader().ifPresentOrElse(leader -> {
|
||||
details.put("leaderId", leader.getId());
|
||||
details.put("role", leader.getRole());
|
||||
details.put("isLeader", leader.isCandidate(candidate));
|
||||
}, () -> details.put("leaderId", "Unknown"));
|
||||
|
||||
builder.withDetail("leaderElection", details);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2013-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.commons.leader;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.boot.actuate.info.Info;
|
||||
import org.springframework.integration.leader.Candidate;
|
||||
import org.springframework.integration.leader.DefaultCandidate;
|
||||
import org.springframework.integration.leader.event.LeaderEventPublisher;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
class LeaderInfoContributorTests {
|
||||
|
||||
@Test
|
||||
void testLeaderMissing() {
|
||||
|
||||
Candidate candidate = new DefaultCandidate("id", "role");
|
||||
LeaderProperties leaderProperties = new LeaderProperties();
|
||||
LeaderEventPublisher leaderEventPublisher = Mockito.mock(LeaderEventPublisher.class);
|
||||
LeadershipController leadershipController = new LeadershipControllerStub(candidate, leaderProperties,
|
||||
leaderEventPublisher);
|
||||
|
||||
LeaderInfoContributor leaderInfoContributor = new LeaderInfoContributor(leadershipController, candidate);
|
||||
Info.Builder builder = new Info.Builder();
|
||||
leaderInfoContributor.contribute(builder);
|
||||
|
||||
Assertions.assertEquals(builder.build().getDetails().get("leaderElection"), Map.of("leaderId", "Unknown"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLeaderPresentIsLeader() {
|
||||
|
||||
Candidate candidate = new DefaultCandidate("leaderId", "leaderRole");
|
||||
LeaderProperties leaderProperties = new LeaderProperties();
|
||||
LeaderEventPublisher leaderEventPublisher = Mockito.mock(LeaderEventPublisher.class);
|
||||
LeadershipController leadershipController = new LeadershipControllerStub(candidate, leaderProperties,
|
||||
leaderEventPublisher);
|
||||
|
||||
Leader leader = new Leader("leaderRole", "leaderId");
|
||||
|
||||
leadershipController.handleLeaderChange(leader);
|
||||
|
||||
LeaderInfoContributor leaderInfoContributor = new LeaderInfoContributor(leadershipController, candidate);
|
||||
Info.Builder builder = new Info.Builder();
|
||||
leaderInfoContributor.contribute(builder);
|
||||
|
||||
Assertions.assertEquals(builder.build().getDetails().get("leaderElection"),
|
||||
Map.of("role", "leaderRole", "isLeader", true, "leaderId", "leaderId"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLeaderPresentIsNotLeader() {
|
||||
|
||||
Candidate candidate = new DefaultCandidate("leaderId", "notLeaderRole");
|
||||
LeaderProperties leaderProperties = new LeaderProperties();
|
||||
LeaderEventPublisher leaderEventPublisher = Mockito.mock(LeaderEventPublisher.class);
|
||||
LeadershipController leadershipController = new LeadershipControllerStub(candidate, leaderProperties,
|
||||
leaderEventPublisher);
|
||||
|
||||
Leader leader = new Leader("leaderRole", "leaderId");
|
||||
|
||||
leadershipController.handleLeaderChange(leader);
|
||||
|
||||
LeaderInfoContributor leaderInfoContributor = new LeaderInfoContributor(leadershipController, candidate);
|
||||
Info.Builder builder = new Info.Builder();
|
||||
leaderInfoContributor.contribute(builder);
|
||||
|
||||
Assertions.assertEquals(builder.build().getDetails().get("leaderElection"),
|
||||
Map.of("role", "leaderRole", "isLeader", false, "leaderId", "leaderId"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2013-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.commons.leader;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.integration.leader.Candidate;
|
||||
import org.springframework.integration.leader.event.LeaderEventPublisher;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
final class LeadershipControllerStub extends LeadershipController {
|
||||
|
||||
private Leader leader;
|
||||
|
||||
LeadershipControllerStub(Candidate candidate, LeaderProperties leaderProperties,
|
||||
LeaderEventPublisher leaderEventPublisher) {
|
||||
super(candidate, leaderProperties, leaderEventPublisher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revoke() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PodReadinessWatcher createPodReadinessWatcher(String localLeaderId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleLeaderChange(Leader leader) {
|
||||
this.leader = leader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Leader> getLocalLeader() {
|
||||
return Optional.ofNullable(leader);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,20 +47,38 @@ import org.springframework.integration.leader.event.LeaderEventPublisher;
|
||||
@ConditionalOnProperty(value = "spring.cloud.kubernetes.leader.enabled", matchIfMissing = true)
|
||||
public class Fabric8LeaderAutoConfiguration {
|
||||
|
||||
/*
|
||||
* Used for publishing application events that happen: granted, revoked or failed to
|
||||
* acquire mutex.
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(LeaderEventPublisher.class)
|
||||
public LeaderEventPublisher defaultLeaderEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
return new DefaultLeaderEventPublisher(applicationEventPublisher);
|
||||
}
|
||||
|
||||
/*
|
||||
* This can be thought as "self" or the pod that participates in leader election
|
||||
* process. The implementation that we return simply logs events that happen during
|
||||
* that process.
|
||||
*/
|
||||
@Bean
|
||||
public Candidate candidate(LeaderProperties leaderProperties) throws UnknownHostException {
|
||||
String id = LeaderUtils.hostName();
|
||||
String role = leaderProperties.getRole();
|
||||
|
||||
return new DefaultCandidate(id, role);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an info contributor with leader information.
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnClass(InfoContributor.class)
|
||||
public LeaderInfoContributor leaderInfoContributor(Fabric8LeadershipController fabric8LeadershipController,
|
||||
Candidate candidate) {
|
||||
return new LeaderInfoContributor(fabric8LeadershipController, candidate);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Fabric8LeadershipController leadershipController(Candidate candidate, LeaderProperties leaderProperties,
|
||||
LeaderEventPublisher leaderEventPublisher, KubernetesClient kubernetesClient) {
|
||||
@@ -87,11 +105,4 @@ public class Fabric8LeaderAutoConfiguration {
|
||||
hostPodWatcher);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(InfoContributor.class)
|
||||
public LeaderInfoContributor leaderInfoContributor(Fabric8LeadershipController fabric8LeadershipController,
|
||||
Candidate candidate) {
|
||||
return new LeaderInfoContributor(fabric8LeadershipController, candidate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.fabric8.leader;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import org.springframework.boot.actuate.info.Info;
|
||||
import org.springframework.cloud.kubernetes.commons.leader.Leader;
|
||||
import org.springframework.cloud.kubernetes.commons.leader.LeaderInfoContributor;
|
||||
import org.springframework.integration.leader.Candidate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class LeaderInfoContributorTest {
|
||||
|
||||
@Mock
|
||||
private Candidate mockCandidate;
|
||||
|
||||
@Mock
|
||||
private Fabric8LeadershipController mockFabric8LeadershipController;
|
||||
|
||||
@Mock
|
||||
private Leader mockLeader;
|
||||
|
||||
private LeaderInfoContributor leaderInfoContributor;
|
||||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
this.leaderInfoContributor = new LeaderInfoContributor(this.mockFabric8LeadershipController,
|
||||
this.mockCandidate);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void infoWithoutLeader() {
|
||||
Info.Builder builder = new Info.Builder();
|
||||
|
||||
leaderInfoContributor.contribute(builder);
|
||||
|
||||
Map<String, Object> details = (Map<String, Object>) builder.build().get("leaderElection");
|
||||
assertThat(details).containsEntry("leaderId", "Unknown");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void infoWhenLeader() {
|
||||
given(this.mockFabric8LeadershipController.getLocalLeader()).willReturn(Optional.of(this.mockLeader));
|
||||
given(this.mockLeader.isCandidate(this.mockCandidate)).willReturn(true);
|
||||
given(this.mockLeader.getRole()).willReturn("testRole");
|
||||
given(this.mockLeader.getId()).willReturn("id");
|
||||
Info.Builder builder = new Info.Builder();
|
||||
|
||||
leaderInfoContributor.contribute(builder);
|
||||
|
||||
Map<String, Object> details = (Map<String, Object>) builder.build().get("leaderElection");
|
||||
assertThat(details).containsEntry("isLeader", true);
|
||||
assertThat(details).containsEntry("leaderId", "id");
|
||||
assertThat(details).containsEntry("role", "testRole");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void infoWhenAnotherIsLeader() {
|
||||
given(this.mockFabric8LeadershipController.getLocalLeader()).willReturn(Optional.of(this.mockLeader));
|
||||
given(this.mockLeader.getRole()).willReturn("testRole");
|
||||
given(this.mockLeader.getId()).willReturn("id");
|
||||
Info.Builder builder = new Info.Builder();
|
||||
|
||||
leaderInfoContributor.contribute(builder);
|
||||
|
||||
Map<String, Object> details = (Map<String, Object>) builder.build().get("leaderElection");
|
||||
assertThat(details).containsEntry("isLeader", false);
|
||||
assertThat(details).containsEntry("leaderId", "id");
|
||||
assertThat(details).containsEntry("role", "testRole");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
* Copyright 2013-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,57 +18,48 @@ package org.springframework.cloud.kubernetes.fabric8.leader;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import org.springframework.cloud.kubernetes.commons.leader.Leader;
|
||||
import org.springframework.integration.leader.Candidate;
|
||||
import org.springframework.integration.leader.DefaultCandidate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* @author Gytis Trikleris
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class LeaderTest {
|
||||
class LeaderTest {
|
||||
|
||||
private static final String ROLE = "test-role";
|
||||
|
||||
private static final String ID = "test-id";
|
||||
|
||||
@Mock
|
||||
private Candidate mockCandidate;
|
||||
|
||||
private Leader leader;
|
||||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
this.leader = new Leader(ROLE, ID);
|
||||
void before() {
|
||||
leader = new Leader(ROLE, ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetRole() {
|
||||
assertThat(this.leader.getRole()).isEqualTo(ROLE);
|
||||
void shouldGetRole() {
|
||||
assertThat(leader.getRole()).isEqualTo(ROLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetId() {
|
||||
assertThat(this.leader.getId()).isEqualTo(ID);
|
||||
void shouldGetId() {
|
||||
assertThat(leader.getId()).isEqualTo(ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCheckWithNullCandidate() {
|
||||
assertThat(this.leader.isCandidate(null)).isEqualTo(false);
|
||||
void shouldCheckWithNullCandidate() {
|
||||
assertThat(leader.isCandidate(null)).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCheckCandidate() {
|
||||
given(this.mockCandidate.getId()).willReturn(ID);
|
||||
given(this.mockCandidate.getRole()).willReturn(ROLE);
|
||||
|
||||
assertThat(this.leader.isCandidate(this.mockCandidate)).isTrue();
|
||||
void shouldCheckCandidate() {
|
||||
Candidate candidate = new DefaultCandidate(ID, ROLE);
|
||||
assertThat(leader.isCandidate(candidate)).isTrue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user