Fabric leader clean up 8 (#1650)
This commit is contained in:
@@ -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.
|
||||
@@ -17,30 +17,34 @@
|
||||
package org.springframework.cloud.kubernetes.fabric8.leader;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMap;
|
||||
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.KubernetesClientException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.cloud.kubernetes.commons.leader.Leader;
|
||||
import org.springframework.cloud.kubernetes.commons.leader.LeaderProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.leader.LeadershipController;
|
||||
import org.springframework.cloud.kubernetes.commons.leader.PodReadinessWatcher;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.leader.Candidate;
|
||||
import org.springframework.integration.leader.event.LeaderEventPublisher;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.commons.leader.LeaderUtils.guarded;
|
||||
|
||||
/**
|
||||
* @author Gytis Trikleris
|
||||
*/
|
||||
public class Fabric8LeadershipController extends LeadershipController {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(Fabric8LeadershipController.class);
|
||||
private static final LogAccessor LOGGER = new LogAccessor(Fabric8LeadershipController.class);
|
||||
|
||||
private final KubernetesClient kubernetesClient;
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
public Fabric8LeadershipController(Candidate candidate, LeaderProperties leaderProperties,
|
||||
LeaderEventPublisher leaderEventPublisher, KubernetesClient kubernetesClient) {
|
||||
super(candidate, leaderProperties, leaderEventPublisher);
|
||||
@@ -48,41 +52,47 @@ public class Fabric8LeadershipController extends LeadershipController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void update() {
|
||||
LOGGER.debug("Checking leader state");
|
||||
ConfigMap configMap = getConfigMap();
|
||||
if (configMap == null && !leaderProperties.isCreateConfigMap()) {
|
||||
LOGGER.warn("ConfigMap '{}' does not exist and leaderProperties.isCreateConfigMap() "
|
||||
+ "is false, cannot acquire leadership", leaderProperties.getConfigMapName());
|
||||
notifyOnFailedToAcquire();
|
||||
return;
|
||||
}
|
||||
Leader leader = extractLeader(configMap);
|
||||
public void update() {
|
||||
guarded(lock, () -> {
|
||||
LOGGER.debug(() -> "Checking leader state");
|
||||
ConfigMap configMap = getConfigMap();
|
||||
if (configMap == null && !leaderProperties.isCreateConfigMap()) {
|
||||
LOGGER.warn("ConfigMap '" + leaderProperties.getConfigMapName()
|
||||
+ "' does not exist and leaderProperties.isCreateConfigMap() "
|
||||
+ "is false, cannot acquire leadership");
|
||||
notifyOnFailedToAcquire();
|
||||
return;
|
||||
}
|
||||
Leader leader = extractLeader(configMap);
|
||||
|
||||
if (leader != null && isPodReady(leader.getId())) {
|
||||
handleLeaderChange(leader);
|
||||
return;
|
||||
}
|
||||
if (leader != null && isPodReady(leader.getId())) {
|
||||
handleLeaderChange(leader);
|
||||
return;
|
||||
}
|
||||
|
||||
if (leader != null && leader.isCandidate(candidate)) {
|
||||
revoke(configMap);
|
||||
}
|
||||
else {
|
||||
acquire(configMap);
|
||||
}
|
||||
});
|
||||
|
||||
if (leader != null && leader.isCandidate(this.candidate)) {
|
||||
revoke(configMap);
|
||||
}
|
||||
else {
|
||||
acquire(configMap);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void revoke() {
|
||||
ConfigMap configMap = getConfigMap();
|
||||
Leader leader = extractLeader(configMap);
|
||||
public void revoke() {
|
||||
guarded(lock, () -> {
|
||||
ConfigMap configMap = getConfigMap();
|
||||
Leader leader = extractLeader(configMap);
|
||||
|
||||
if (leader != null && leader.isCandidate(this.candidate)) {
|
||||
revoke(configMap);
|
||||
}
|
||||
if (leader != null && leader.isCandidate(candidate)) {
|
||||
revoke(configMap);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void revoke(ConfigMap configMap) {
|
||||
LOGGER.debug("Trying to revoke leadership for '{}'", this.candidate);
|
||||
LOGGER.debug(() -> "Trying to revoke leadership for :" + candidate);
|
||||
|
||||
try {
|
||||
String leaderKey = getLeaderKey();
|
||||
@@ -90,20 +100,20 @@ public class Fabric8LeadershipController extends LeadershipController {
|
||||
handleLeaderChange(null);
|
||||
}
|
||||
catch (KubernetesClientException e) {
|
||||
LOGGER.warn("Failure when revoking leadership for '{}': {}", this.candidate, e.getMessage());
|
||||
LOGGER.warn("Failure when revoking leadership for : " + candidate + "because : " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void acquire(ConfigMap configMap) {
|
||||
LOGGER.debug("Trying to acquire leadership for '{}'", this.candidate);
|
||||
LOGGER.debug(() -> "Trying to acquire leadership for :" + this.candidate);
|
||||
|
||||
if (!isPodReady(this.candidate.getId())) {
|
||||
LOGGER.debug("Pod of '{}' is not ready at the moment, cannot acquire leadership", this.candidate);
|
||||
if (!isPodReady(candidate.getId())) {
|
||||
LOGGER.debug("Pod : " + candidate + "is not ready at the moment, cannot acquire leadership");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Map<String, String> data = getLeaderData(this.candidate);
|
||||
Map<String, String> data = getLeaderData(candidate);
|
||||
|
||||
if (configMap == null) {
|
||||
createConfigMap(data);
|
||||
@@ -112,11 +122,11 @@ public class Fabric8LeadershipController extends LeadershipController {
|
||||
updateConfigMapEntry(configMap, data);
|
||||
}
|
||||
|
||||
Leader newLeader = new Leader(this.candidate.getRole(), this.candidate.getId());
|
||||
Leader newLeader = new Leader(candidate.getRole(), candidate.getId());
|
||||
handleLeaderChange(newLeader);
|
||||
}
|
||||
catch (KubernetesClientException e) {
|
||||
LOGGER.warn("Failure when acquiring leadership for '{}': {}", this.candidate, e.getMessage());
|
||||
LOGGER.warn(() -> "Failure when acquiring leadership for : " + candidate + " because : " + e.getMessage());
|
||||
notifyOnFailedToAcquire();
|
||||
}
|
||||
}
|
||||
@@ -135,47 +145,39 @@ public class Fabric8LeadershipController extends LeadershipController {
|
||||
}
|
||||
|
||||
private boolean isPodReady(String name) {
|
||||
return this.kubernetesClient.pods().withName(name).isReady();
|
||||
return kubernetesClient.pods().withName(name).isReady();
|
||||
}
|
||||
|
||||
private ConfigMap getConfigMap() {
|
||||
return this.kubernetesClient.configMaps()
|
||||
.inNamespace(this.leaderProperties.getNamespace(this.kubernetesClient.getNamespace()))
|
||||
.withName(this.leaderProperties.getConfigMapName()).get();
|
||||
return kubernetesClient.configMaps().inNamespace(leaderProperties.getNamespace(kubernetesClient.getNamespace()))
|
||||
.withName(leaderProperties.getConfigMapName()).get();
|
||||
}
|
||||
|
||||
private void createConfigMap(Map<String, String> data) {
|
||||
LOGGER.debug("Creating new config map with data: {}", data);
|
||||
LOGGER.debug(() -> "Creating new config map with data: " + data);
|
||||
|
||||
ConfigMap newConfigMap = new ConfigMapBuilder().withNewMetadata()
|
||||
.withName(this.leaderProperties.getConfigMapName()).addToLabels(PROVIDER_KEY, PROVIDER)
|
||||
.addToLabels(KIND_KEY, KIND).endMetadata().addToData(data).build();
|
||||
ConfigMap newConfigMap = new ConfigMapBuilder().withNewMetadata().withName(leaderProperties.getConfigMapName())
|
||||
.addToLabels(PROVIDER_KEY, PROVIDER).addToLabels(KIND_KEY, KIND).endMetadata().addToData(data).build();
|
||||
|
||||
this.kubernetesClient.configMaps()
|
||||
.inNamespace(this.leaderProperties.getNamespace(this.kubernetesClient.getNamespace()))
|
||||
kubernetesClient.configMaps().inNamespace(leaderProperties.getNamespace(kubernetesClient.getNamespace()))
|
||||
.resource(newConfigMap).create();
|
||||
}
|
||||
|
||||
private void updateConfigMapEntry(ConfigMap configMap, Map<String, String> newData) {
|
||||
LOGGER.debug("Adding new data to config map: {}", newData);
|
||||
|
||||
LOGGER.debug(() -> "Adding new data to config map: " + newData);
|
||||
ConfigMap newConfigMap = new ConfigMapBuilder(configMap).addToData(newData).build();
|
||||
|
||||
updateConfigMap(configMap, newConfigMap);
|
||||
}
|
||||
|
||||
private void removeConfigMapEntry(ConfigMap configMap, String key) {
|
||||
LOGGER.debug("Removing config map entry '{}'", key);
|
||||
|
||||
LOGGER.debug(() -> "Removing config map entry: " + key);
|
||||
ConfigMap newConfigMap = new ConfigMapBuilder(configMap).removeFromData(key).build();
|
||||
|
||||
updateConfigMap(configMap, newConfigMap);
|
||||
}
|
||||
|
||||
private void updateConfigMap(ConfigMap oldConfigMap, ConfigMap newConfigMap) {
|
||||
this.kubernetesClient.configMaps()
|
||||
.inNamespace(this.leaderProperties.getNamespace(this.kubernetesClient.getNamespace()))
|
||||
.resource(newConfigMap).lockResourceVersion(oldConfigMap.getMetadata().getResourceVersion()).replace();
|
||||
kubernetesClient.configMaps().inNamespace(leaderProperties.getNamespace(kubernetesClient.getNamespace()))
|
||||
.resource(newConfigMap).lockResourceVersion(oldConfigMap.getMetadata().getResourceVersion()).update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -94,8 +94,7 @@ public class Fabric8LeadershipControllerTest {
|
||||
fabric8LeadershipController.update();
|
||||
|
||||
// then
|
||||
assertThat(output).contains("ConfigMap '" + testConfigmap + "' does not exist "
|
||||
+ "and leaderProperties.isCreateConfigMap() is false, cannot acquire leadership");
|
||||
assertThat(output).contains("ConfigMap 'test-configmap' does not exist and leaderProperties.isCreateConfigMap() is false, cannot acquire leadership");
|
||||
verify(mockLeaderEventPublisher).publishOnFailedToAcquire(any(), any(), any());
|
||||
|
||||
verify(mockKubernetesClient, never()).pods();
|
||||
|
||||
Reference in New Issue
Block a user