Skip to content

Commit 933b7d2

Browse files
committed
wip
Signed-off-by: wind57 <[email protected]>
1 parent 6c8db4c commit 933b7d2

File tree

27 files changed

+745
-288
lines changed

27 files changed

+745
-288
lines changed

spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/leader/election/LeaderElectionCallbacks.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class LeaderElectionCallbacks {
3838
private static final LogAccessor LOG = new LogAccessor(LeaderElectionCallbacks.class);
3939

4040
@Bean
41-
public final String holderIdentity() throws UnknownHostException {
41+
public final String candidateIdentity() throws UnknownHostException {
4242
String podHostName = LeaderUtils.hostName();
4343
LOG.debug(() -> "using pod hostname : " + podHostName);
4444
return podHostName;
@@ -53,33 +53,33 @@ public final String podNamespace() {
5353

5454
@Bean
5555
public final Runnable onStartLeadingCallback(ApplicationEventPublisher applicationEventPublisher,
56-
String holderIdentity, LeaderElectionProperties properties) {
56+
String candidateIdentity, LeaderElectionProperties properties) {
5757
return () -> {
58-
LOG.info(() -> holderIdentity + " is now a leader");
58+
LOG.info(() -> candidateIdentity + " is now a leader");
5959
if (properties.publishEvents()) {
60-
applicationEventPublisher.publishEvent(new StartLeadingEvent(holderIdentity));
60+
applicationEventPublisher.publishEvent(new StartLeadingEvent(candidateIdentity));
6161
}
6262
};
6363
}
6464

6565
@Bean
6666
public final Runnable onStopLeadingCallback(ApplicationEventPublisher applicationEventPublisher,
67-
String holderIdentity, LeaderElectionProperties properties) {
67+
String candidateIdentity, LeaderElectionProperties properties) {
6868
return () -> {
69-
LOG.info(() -> "id : " + holderIdentity + " stopped being a leader");
69+
LOG.info(() -> "id : " + candidateIdentity + " stopped being a leader");
7070
if (properties.publishEvents()) {
71-
applicationEventPublisher.publishEvent(new StopLeadingEvent(holderIdentity));
71+
applicationEventPublisher.publishEvent(new StopLeadingEvent(candidateIdentity));
7272
}
7373
};
7474
}
7575

7676
@Bean
7777
public final Consumer<String> onNewLeaderCallback(ApplicationEventPublisher applicationEventPublisher,
7878
LeaderElectionProperties properties) {
79-
return holderIdentity -> {
80-
LOG.info(() -> "id : " + holderIdentity + " is the new leader");
79+
return candidateIdentity -> {
80+
LOG.info(() -> "id : " + candidateIdentity + " is the new leader");
8181
if (properties.publishEvents()) {
82-
applicationEventPublisher.publishEvent(new NewLeaderEvent(holderIdentity));
82+
applicationEventPublisher.publishEvent(new NewLeaderEvent(candidateIdentity));
8383
}
8484
};
8585
}

spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/leader/election/PodReadyRunner.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ public CompletableFuture<Void> podReady(BooleanSupplier podReadySupplier) {
6868
}
6969
}
7070
catch (Exception e) {
71-
LOG.error(() -> "exception waiting for pod : " + e.getMessage());
72-
LOG.error(() -> "leader election for : " + candidateIdentity + " was not successful");
71+
LOG.error(() -> "exception waiting for pod : " + candidateIdentity);
72+
LOG.error(() -> "pod readiness for : " + candidateIdentity + " failed with : " + e.getMessage());
7373
podReadyFuture.completeExceptionally(e);
7474
}
7575

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2013-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.kubernetes.commons.leader.election.events;
18+
19+
import org.springframework.context.ApplicationEvent;
20+
21+
/**
22+
* @author wind57
23+
*/
24+
abstract class LeaderElectionEvent extends ApplicationEvent {
25+
26+
private final String candidateIdentity;
27+
28+
LeaderElectionEvent(Object source) {
29+
super(source);
30+
candidateIdentity = (String) source;
31+
}
32+
33+
public String candidateIdentity() {
34+
return candidateIdentity;
35+
}
36+
37+
}

spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/leader/election/events/NewLeaderEvent.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,10 @@
1616

1717
package org.springframework.cloud.kubernetes.commons.leader.election.events;
1818

19-
import org.springframework.context.ApplicationEvent;
20-
21-
public final class NewLeaderEvent extends ApplicationEvent {
22-
23-
private final String holderIdentity;
19+
public final class NewLeaderEvent extends LeaderElectionEvent {
2420

2521
public NewLeaderEvent(Object source) {
2622
super(source);
27-
holderIdentity = (String) source;
28-
}
29-
30-
public String holderIdentity() {
31-
return holderIdentity;
3223
}
3324

3425
}

spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/leader/election/events/StartLeadingEvent.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,13 @@
1616

1717
package org.springframework.cloud.kubernetes.commons.leader.election.events;
1818

19-
import org.springframework.context.ApplicationEvent;
20-
2119
/**
2220
* @author wind57
2321
*/
24-
public final class StartLeadingEvent extends ApplicationEvent {
25-
26-
private final String holderIdentity;
22+
public final class StartLeadingEvent extends LeaderElectionEvent {
2723

2824
public StartLeadingEvent(Object source) {
2925
super(source);
30-
holderIdentity = (String) source;
31-
}
32-
33-
public String holderIdentity() {
34-
return holderIdentity;
3526
}
3627

3728
}

spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/leader/election/events/StopLeadingEvent.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,13 @@
1616

1717
package org.springframework.cloud.kubernetes.commons.leader.election.events;
1818

19-
import org.springframework.context.ApplicationEvent;
20-
2119
/**
2220
* @author wind57
2321
*/
24-
public final class StopLeadingEvent extends ApplicationEvent {
25-
26-
private final String holderIdentity;
22+
public final class StopLeadingEvent extends LeaderElectionEvent {
2723

2824
public StopLeadingEvent(Object source) {
2925
super(source);
30-
holderIdentity = (String) source;
31-
}
32-
33-
public String holderIdentity() {
34-
return holderIdentity;
3526
}
3627

3728
}

spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/leader/election/PodReadyRunnerTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ void readinessFailsOnTheSecondCycle(CapturedOutput output) {
117117
caught = true;
118118
assertThat(output.getOut())
119119
.contains("Pod : identity in namespace : namespace is not ready, will retry in one second");
120-
assertThat(output.getOut()).contains("exception waiting for pod : fail on the second cycle");
121-
assertThat(output.getOut()).contains("leader election for : identity was not successful");
120+
assertThat(output.getOut()).contains("exception waiting for pod : identity");
121+
assertThat(output.getOut()).contains("pod readiness for : identity failed with : fail on the second cycle");
122122
assertThat(output.getOut()).contains("canceling scheduled future because readiness failed");
123123

124124
await().atMost(Duration.ofSeconds(3))
@@ -164,8 +164,8 @@ void readinessFailsOnTheSecondCycleAttachNewPipeline(CapturedOutput output) {
164164
caught = true;
165165
assertThat(output.getOut())
166166
.contains("Pod : identity in namespace : namespace is not ready, will retry in one second");
167-
assertThat(output.getOut()).contains("exception waiting for pod : fail on the second cycle");
168-
assertThat(output.getOut()).contains("leader election for : identity was not successful");
167+
assertThat(output.getOut()).contains("exception waiting for pod : identity");
168+
assertThat(output.getOut()).contains("pod readiness for : identity failed with : fail on the second cycle");
169169
assertThat(output.getOut()).contains("readiness failed and we caught that");
170170
assertThat(output.getOut()).contains("canceling scheduled future because readiness failed");
171171

spring-cloud-kubernetes-fabric8-leader/src/main/java/org/springframework/cloud/kubernetes/fabric8/leader/election/Fabric8LeaderElectionAutoConfiguration.java

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,19 @@
1616

1717
package org.springframework.cloud.kubernetes.fabric8.leader.election;
1818

19+
import java.util.function.BooleanSupplier;
20+
1921
import io.fabric8.kubernetes.api.model.APIResource;
2022
import io.fabric8.kubernetes.api.model.APIResourceList;
2123
import io.fabric8.kubernetes.api.model.GroupVersionForDiscovery;
24+
import io.fabric8.kubernetes.api.model.Pod;
2225
import io.fabric8.kubernetes.client.KubernetesClient;
2326
import io.fabric8.kubernetes.client.extended.leaderelection.LeaderElectionConfig;
2427
import io.fabric8.kubernetes.client.extended.leaderelection.LeaderElectionConfigBuilder;
2528
import io.fabric8.kubernetes.client.extended.leaderelection.resourcelock.ConfigMapLock;
2629
import io.fabric8.kubernetes.client.extended.leaderelection.resourcelock.LeaseLock;
2730
import io.fabric8.kubernetes.client.extended.leaderelection.resourcelock.Lock;
31+
import io.fabric8.kubernetes.client.readiness.Readiness;
2832

2933
import org.springframework.boot.actuate.info.InfoContributor;
3034
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@@ -63,26 +67,35 @@ class Fabric8LeaderElectionAutoConfiguration {
6367
@Bean
6468
@ConditionalOnClass(InfoContributor.class)
6569
@ConditionalOnEnabledHealthIndicator("leader.election")
66-
Fabric8LeaderElectionInfoContributor leaderElectionInfoContributor(String holderIdentity,
67-
LeaderElectionConfig leaderElectionConfig, KubernetesClient fabric8KubernetesClient) {
68-
return new Fabric8LeaderElectionInfoContributor(holderIdentity, leaderElectionConfig, fabric8KubernetesClient);
70+
Fabric8LeaderElectionInfoContributor leaderElectionInfoContributor(String candidateIdentity,
71+
LeaderElectionConfig leaderElectionConfig, KubernetesClient fabric8KubernetesClient) {
72+
return new Fabric8LeaderElectionInfoContributor(candidateIdentity, leaderElectionConfig,
73+
fabric8KubernetesClient);
6974
}
7075

7176
@Bean
7277
@ConditionalOnMissingBean
73-
Fabric8LeaderElectionInitiator fabric8LeaderElectionInitiator(String holderIdentity, String podNamespace,
74-
KubernetesClient fabric8KubernetesClient, LeaderElectionConfig fabric8LeaderElectionConfig,
75-
LeaderElectionProperties leaderElectionProperties) {
76-
return new Fabric8LeaderElectionInitiator(holderIdentity, podNamespace, fabric8KubernetesClient,
77-
fabric8LeaderElectionConfig, leaderElectionProperties);
78+
Fabric8LeaderElectionInitiator fabric8LeaderElectionInitiator(String candidateIdentity, String podNamespace,
79+
KubernetesClient fabric8KubernetesClient, LeaderElectionConfig fabric8LeaderElectionConfig,
80+
LeaderElectionProperties leaderElectionProperties, BooleanSupplier podReadySupplier) {
81+
return new Fabric8LeaderElectionInitiator(candidateIdentity, podNamespace, fabric8KubernetesClient,
82+
fabric8LeaderElectionConfig, leaderElectionProperties, podReadySupplier);
83+
}
84+
85+
@Bean
86+
BooleanSupplier podReadySupplier(KubernetesClient fabric8KubernetesClient, String candidateIdentity,
87+
String podNamespace) {
88+
return () -> {
89+
Pod pod = fabric8KubernetesClient.pods().inNamespace(podNamespace).withName(candidateIdentity).get();
90+
return Readiness.isPodReady(pod);
91+
};
7892
}
7993

8094
@Bean
8195
@ConditionalOnMissingBean
8296
LeaderElectionConfig fabric8LeaderElectionConfig(LeaderElectionProperties properties, Lock lock,
83-
Fabric8LeaderElectionCallbacks fabric8LeaderElectionCallbacks) {
84-
return new LeaderElectionConfigBuilder()
85-
.withReleaseOnCancel()
97+
Fabric8LeaderElectionCallbacks fabric8LeaderElectionCallbacks) {
98+
return new LeaderElectionConfigBuilder().withReleaseOnCancel()
8699
.withName("Spring k8s leader election")
87100
.withLeaseDuration(properties.leaseDuration())
88101
.withLock(lock)
@@ -94,7 +107,7 @@ LeaderElectionConfig fabric8LeaderElectionConfig(LeaderElectionProperties proper
94107

95108
@Bean
96109
@ConditionalOnMissingBean
97-
Lock lock(KubernetesClient fabric8KubernetesClient, LeaderElectionProperties properties, String holderIdentity) {
110+
Lock lock(KubernetesClient fabric8KubernetesClient, LeaderElectionProperties properties, String candidateIdentity) {
98111
boolean leaseSupported = fabric8KubernetesClient.getApiGroups()
99112
.getGroups()
100113
.stream()
@@ -111,17 +124,17 @@ Lock lock(KubernetesClient fabric8KubernetesClient, LeaderElectionProperties pro
111124
if (leaseSupported) {
112125
if (properties.useConfigMapAsLock()) {
113126
LOG.info(() -> "leases are supported on the cluster, but config map will be used "
114-
+ "(because 'spring.cloud.kubernetes.leader.election.use-config-map-as-lock=true')");
115-
return new ConfigMapLock(properties.lockNamespace(), properties.lockName(), holderIdentity);
127+
+ "(because 'spring.cloud.kubernetes.leader.election.use-config-map-as-lock=true')");
128+
return new ConfigMapLock(properties.lockNamespace(), properties.lockName(), candidateIdentity);
116129
}
117130
else {
118131
LOG.info(() -> "will use lease as the lock for leader election");
119-
return new LeaseLock(properties.lockNamespace(), properties.lockName(), holderIdentity);
132+
return new LeaseLock(properties.lockNamespace(), properties.lockName(), candidateIdentity);
120133
}
121134
}
122135
else {
123136
LOG.info(() -> "will use configmap as the lock for leader election");
124-
return new ConfigMapLock(properties.lockNamespace(), properties.lockName(), holderIdentity);
137+
return new ConfigMapLock(properties.lockNamespace(), properties.lockName(), candidateIdentity);
125138
}
126139
}
127140

spring-cloud-kubernetes-fabric8-leader/src/main/java/org/springframework/cloud/kubernetes/fabric8/leader/election/Fabric8LeaderElectionCallbacks.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2024 the original author or authors.
2+
* Copyright 2013-present the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

spring-cloud-kubernetes-fabric8-leader/src/main/java/org/springframework/cloud/kubernetes/fabric8/leader/election/Fabric8LeaderElectionCallbacksAutoConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ final class Fabric8LeaderElectionCallbacksAutoConfiguration extends LeaderElecti
4545
@Bean
4646
@ConditionalOnMissingBean
4747
Fabric8LeaderElectionCallbacks fabric8LeaderElectionCallbacks(Runnable onStartLeadingCallback,
48-
Runnable onStopLeadingCallback, Consumer<String> onNewLeaderCallback) {
48+
Runnable onStopLeadingCallback, Consumer<String> onNewLeaderCallback) {
4949
return new Fabric8LeaderElectionCallbacks(onStartLeadingCallback, onStopLeadingCallback, onNewLeaderCallback);
5050
}
5151

0 commit comments

Comments
 (0)