ConfigMapLockRepository
This commit is contained in:
committed by
Ioannis Canellos
parent
e50eb097f0
commit
561bc9d00c
1
pom.xml
1
pom.xml
@@ -87,6 +87,7 @@
|
||||
<module>spring-cloud-starter-kubernetes-zipkin</module>
|
||||
<module>spring-cloud-starter-kubernetes-all</module>
|
||||
<module>spring-cloud-kubernetes-examples</module>
|
||||
<module>spring-cloud-kubernetes-lock</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
|
||||
74
spring-cloud-kubernetes-lock/pom.xml
Normal file
74
spring-cloud-kubernetes-lock/pom.xml
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 2018 to the original 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
|
||||
|
||||
http://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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes</artifactId>
|
||||
<version>0.3.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-cloud-kubernetes-lock</artifactId>
|
||||
<name>Spring Cloud Kubernetes :: Lock</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.arquillian.junit</groupId>
|
||||
<artifactId>arquillian-junit-standalone</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.arquillian.cube</groupId>
|
||||
<artifactId>arquillian-cube-kubernetes</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.arquillian.cube</groupId>
|
||||
<artifactId>arquillian-cube-requirement</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${maven-failsafe-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2018 to the original 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
|
||||
*
|
||||
* http://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.lock;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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;
|
||||
|
||||
public class ConfigMapLockRepository {
|
||||
|
||||
static final String CONFIG_MAP_PREFIX = "lock";
|
||||
|
||||
static final String HOLDER_KEY = "holder";
|
||||
|
||||
static final String EXPIRATION_KEY = "expiration";
|
||||
|
||||
private static final String PROVIDER_LABEL = "provider";
|
||||
|
||||
private static final String PROVIDER_LABEL_VALUE = "spring-cloud-kubernetes";
|
||||
|
||||
private static final String KIND_LABEL = "kind";
|
||||
|
||||
private static final String KIND_LABEL_VALUE = "lock";
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigMapLockRepository.class);
|
||||
|
||||
private KubernetesClient kubernetesClient;
|
||||
|
||||
private String namespace;
|
||||
|
||||
public ConfigMapLockRepository(KubernetesClient kubernetesClient, String namespace) {
|
||||
this.kubernetesClient = kubernetesClient;
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
public ConfigMap get(String name) {
|
||||
return kubernetesClient.configMaps()
|
||||
.inNamespace(namespace)
|
||||
.withName(getConfigMapName(name))
|
||||
.get();
|
||||
}
|
||||
|
||||
public boolean create(String name, String holder, long expiration) {
|
||||
ConfigMap configMap = new ConfigMapBuilder().withNewMetadata()
|
||||
.withName(getConfigMapName(name))
|
||||
.addToLabels(PROVIDER_LABEL, PROVIDER_LABEL_VALUE)
|
||||
.addToLabels(KIND_LABEL, KIND_LABEL_VALUE)
|
||||
.endMetadata()
|
||||
.addToData(HOLDER_KEY, holder)
|
||||
.addToData(EXPIRATION_KEY, String.valueOf(expiration))
|
||||
// TODO add information about the creator
|
||||
.build();
|
||||
|
||||
try {
|
||||
kubernetesClient.configMaps()
|
||||
.inNamespace(namespace)
|
||||
.create(configMap);
|
||||
} catch (KubernetesClientException e) {
|
||||
LOGGER.warn("Failed to create ConfigMap for name '{}': ", name, e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void deleteAll() {
|
||||
kubernetesClient.configMaps()
|
||||
.inNamespace(namespace)
|
||||
.withLabel(PROVIDER_LABEL, PROVIDER_LABEL_VALUE)
|
||||
.withLabel(KIND_LABEL, KIND_LABEL_VALUE)
|
||||
.delete();
|
||||
}
|
||||
|
||||
public void deleteExpired() {
|
||||
long now = System.currentTimeMillis();
|
||||
// TODO check that it was created by this process
|
||||
List<ConfigMap> configMaps = kubernetesClient.configMaps()
|
||||
.inNamespace(namespace)
|
||||
.withLabel(PROVIDER_LABEL, PROVIDER_LABEL_VALUE)
|
||||
.withLabel(KIND_LABEL, KIND_LABEL_VALUE)
|
||||
.list()
|
||||
.getItems()
|
||||
.stream()
|
||||
.filter(c -> Long.valueOf(c.getData().get("expiration")) < now)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
kubernetesClient.configMaps()
|
||||
.inNamespace(namespace)
|
||||
.delete(configMaps);
|
||||
}
|
||||
|
||||
private String getConfigMapName(String name) {
|
||||
return String.format("%s-%s", CONFIG_MAP_PREFIX, name);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package org.springframework.cloud.kubernetes.lock;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMap;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import org.arquillian.cube.kubernetes.api.Session;
|
||||
import org.arquillian.cube.kubernetes.impl.requirement.RequiresKubernetes;
|
||||
import org.jboss.arquillian.junit.Arquillian;
|
||||
import org.jboss.arquillian.test.api.ArquillianResource;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@RunWith(Arquillian.class)
|
||||
@RequiresKubernetes
|
||||
public class ConfigMapLockRepositoryIT {
|
||||
|
||||
@ArquillianResource
|
||||
private KubernetesClient kubernetesClient;
|
||||
|
||||
@ArquillianResource
|
||||
private Session session;
|
||||
|
||||
private ConfigMapLockRepository repository;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
repository = new ConfigMapLockRepository(kubernetesClient, session.getNamespace());
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
deleteConfigMap("test-name");
|
||||
deleteConfigMap("test-name-2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateConfigMap() {
|
||||
long expiration = System.currentTimeMillis();
|
||||
boolean result = repository.create("test-name", "test-holder", expiration);
|
||||
assertThat(result).isTrue();
|
||||
|
||||
ConfigMap configMap = repository.get("test-name");
|
||||
Map<String, String> data = configMap.getData();
|
||||
assertThat(data).containsEntry(ConfigMapLockRepository.HOLDER_KEY, "test-holder");
|
||||
assertThat(data).containsEntry(ConfigMapLockRepository.EXPIRATION_KEY, String.valueOf(expiration));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotOverwriteConfigMap() {
|
||||
boolean firstResult = repository.create("test-name", "test-holder", 0);
|
||||
assertThat(firstResult).isTrue();
|
||||
|
||||
boolean secondResult = repository.create("test-name", "test-holder", 0);
|
||||
assertThat(secondResult).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeleteAllConfigMaps() {
|
||||
repository.create("test-name", "test-holder", 0);
|
||||
repository.create("test-name-2", "test-holder-2", 0);
|
||||
repository.deleteAll();
|
||||
assertThat(repository.get("test-name")).isNull();
|
||||
assertThat(repository.get("test-name-2")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeleteExpiredConfigMaps() {
|
||||
repository.create("test-name", "test-holder", System.currentTimeMillis() - 1);
|
||||
repository.create("test-name-2", "test-holder-2", System.currentTimeMillis() + 10000);
|
||||
repository.deleteExpired();
|
||||
assertThat(repository.get("test-name")).isNull();
|
||||
assertThat(repository.get("test-name-2")).isNotNull();
|
||||
}
|
||||
|
||||
private void deleteConfigMap(String name) {
|
||||
kubernetesClient.configMaps()
|
||||
.inNamespace(session.getNamespace())
|
||||
.withName(String.format("%s-%s", ConfigMapLockRepository.CONFIG_MAP_PREFIX, name))
|
||||
.delete();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user