diff --git a/pom.xml b/pom.xml
index 217d83a9..7140f654 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,6 +22,7 @@
0.9.0
3.8.0
2.0.2
+ 3.14.9
@@ -40,6 +41,10 @@
org.springframework.boot
spring-boot-autoconfigure
+
+ org.springframework
+ spring-web
+
io.fabric8
kubernetes-client
@@ -78,6 +83,18 @@
2.23.4
test
+
+ com.squareup.okhttp3
+ okhttp
+ ${okhttp.version}
+ test
+
+
+ com.squareup.okhttp3
+ mockwebserver
+ ${okhttp.version}
+ test
+
diff --git a/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesActuatorTemplate.java b/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesActuatorTemplate.java
new file mode 100644
index 00000000..e0522d17
--- /dev/null
+++ b/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesActuatorTemplate.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2022 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.deployer.spi.kubernetes;
+
+import org.springframework.cloud.deployer.spi.app.AbstractActuatorTemplate;
+import org.springframework.cloud.deployer.spi.app.AppDeployer;
+import org.springframework.cloud.deployer.spi.app.AppInstanceStatus;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author David Turanski
+ */
+
+public class KubernetesActuatorTemplate extends AbstractActuatorTemplate {
+
+ public KubernetesActuatorTemplate(RestTemplate restTemplate, AppDeployer appDeployer) {
+ super(restTemplate, appDeployer);
+ }
+
+ protected String actuatorUrlForInstance(AppInstanceStatus appInstanceStatus) {
+ return String.format("http://%s:%d/actuator", appInstanceStatus.getAttributes().get("pod.ip"),
+ Integer.valueOf(appInstanceStatus.getAttributes().get("actuator.port")));
+ }
+}
diff --git a/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppInstanceStatus.java b/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppInstanceStatus.java
index 149fa39f..8299c957 100644
--- a/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppInstanceStatus.java
+++ b/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppInstanceStatus.java
@@ -19,8 +19,11 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
+import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.ContainerStatus;
+import io.fabric8.kubernetes.api.model.IntOrString;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.ServicePort;
@@ -127,6 +130,7 @@ public Map getAttributes() {
result.put("pod.name", pod.getMetadata().getName());
result.put("pod.startTime", pod.getStatus().getStartTime());
result.put("pod.ip", pod.getStatus().getPodIP());
+ result.put("actuator.port", determineActuatorPort(pod));
result.put("host.ip", pod.getStatus().getHostIP());
result.put("phase", pod.getStatus().getPhase());
result.put(AbstractKubernetesDeployer.SPRING_APP_KEY.replace('-', '.'),
@@ -175,6 +179,16 @@ public Map getAttributes() {
}
return result;
}
+
+ private String determineActuatorPort(Pod pod) {
+ return pod.getSpec().getContainers().stream().filter( (Container container) ->
+ container.getLivenessProbe() != null &&
+ container.getLivenessProbe().getHttpGet() != null &&
+ container.getLivenessProbe().getHttpGet().getPath().startsWith("/actuator"))
+ .findFirst()
+ .map(container -> container.getLivenessProbe().getHttpGet().getPort().getStrVal())
+ .orElse(new IntOrString("unknown").getStrVal());
+ }
}
diff --git a/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAutoConfiguration.java b/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAutoConfiguration.java
index 930159c2..1e1b312c 100644
--- a/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAutoConfiguration.java
+++ b/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAutoConfiguration.java
@@ -22,11 +22,13 @@
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.deployer.spi.app.ActuatorOperations;
import org.springframework.cloud.deployer.spi.app.AppDeployer;
import org.springframework.cloud.deployer.spi.task.TaskLauncher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
+import org.springframework.web.client.RestTemplate;
/**
* Spring Bean configuration for the {@link KubernetesAppDeployer}.
@@ -72,4 +74,15 @@ public ContainerFactory containerFactory() {
return new DefaultContainerFactory(deployerProperties);
}
+ @Bean
+ ActuatorOperations actuatorSupport(RestTemplate actuatorRestTemplate, AppDeployer appDeployer) {
+ return new KubernetesActuatorTemplate(actuatorRestTemplate, appDeployer);
+ }
+
+ @Bean
+ RestTemplate actuatorRestTemplate() {
+ //TODO: Configure security
+ return new RestTemplate();
+ }
+
}
diff --git a/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesActuatorTemplateTests.java b/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesActuatorTemplateTests.java
new file mode 100644
index 00000000..079d505c
--- /dev/null
+++ b/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesActuatorTemplateTests.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2022 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.deployer.spi.kubernetes;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import okhttp3.mockwebserver.Dispatcher;
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
+import okhttp3.mockwebserver.RecordedRequest;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.springframework.cloud.deployer.spi.app.ActuatorOperations;
+import org.springframework.cloud.deployer.spi.app.AppDeployer;
+import org.springframework.cloud.deployer.spi.app.AppInstanceStatus;
+import org.springframework.cloud.deployer.spi.app.AppStatus;
+import org.springframework.cloud.deployer.spi.app.DeploymentState;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.StreamUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.RestTemplate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class KubernetesActuatorTemplateTests {
+ private static MockWebServer mockActuator;
+
+ private final AppDeployer appDeployer = mock(AppDeployer.class);
+
+ private final ActuatorOperations actuatorOperations = new KubernetesActuatorTemplate(new RestTemplate(), appDeployer);
+
+ private AppInstanceStatus appInstanceStatus;
+
+ @BeforeAll
+ static void setupMockServer() throws IOException {
+ mockActuator = new MockWebServer();
+ mockActuator.start();
+ mockActuator.setDispatcher(new Dispatcher() {
+ @Override
+ public MockResponse dispatch(RecordedRequest recordedRequest) throws InterruptedException {
+ switch (recordedRequest.getPath()) {
+ case "/actuator/info":
+ return new MockResponse().setBody(resourceAsString("actuator-info.json"))
+ .addHeader("Content-Type", "application/json").setResponseCode(200);
+ case "/actuator/health":
+ return new MockResponse().setBody("\"status\":\"UP\"}")
+ .addHeader("Content-Type", "application/json").setResponseCode(200);
+ case "/actuator/bindings":
+ return new MockResponse().setBody(resourceAsString("actuator-bindings.json"))
+ .addHeader("Content-Type", "application/json").setResponseCode(200);
+ case "/actuator/bindings/input":
+ if (recordedRequest.getMethod().equals("GET")) {
+ return new MockResponse().setBody(resourceAsString("actuator-binding-input.json"))
+ .addHeader("Content-Type", "application/json")
+ .setResponseCode(200);
+ }
+ else if (recordedRequest.getMethod().equals("POST")) {
+ if (!StringUtils.hasText(recordedRequest.getBody().toString())) {
+ return new MockResponse().setResponseCode(HttpStatus.BAD_REQUEST.value());
+ }
+ else {
+ return new MockResponse().setBody(recordedRequest.getBody())
+ .addHeader("Content-Type", "application/json").setResponseCode(200);
+ }
+ }
+ else {
+ return new MockResponse().setResponseCode(HttpStatus.BAD_REQUEST.value());
+ }
+ default:
+ return new MockResponse().setResponseCode(HttpStatus.NOT_FOUND.value());
+ }
+ }
+ });
+ }
+
+ @AfterAll
+ static void tearDown() throws IOException {
+ mockActuator.shutdown();
+ }
+
+ @BeforeEach
+ void setUp() {
+ appInstanceStatus = mock(AppInstanceStatus.class);
+ Map attributes = new HashMap<>();
+ attributes.put("pod.ip", "127.0.0.1");
+ attributes.put("actuator.port", String.valueOf(mockActuator.getPort()));
+ attributes.put("guid", "test-application-0");
+ when(appInstanceStatus.getAttributes()).thenReturn(attributes);
+ when(appInstanceStatus.getState()).thenReturn(DeploymentState.deployed);
+ AppStatus appStatus = AppStatus.of("test-application-id")
+ .with(appInstanceStatus)
+ .build();
+ when(appDeployer.status(anyString())).thenReturn(appStatus);
+ }
+
+ @Test
+ void actuatorInfo() {
+ Map info = actuatorOperations
+ .getFromActuator("test-application-id", "test-application-0", "/info", Map.class);
+
+ assertThat(((Map, ?>) (info.get("app"))).get("name")).isEqualTo("log-sink-rabbit");
+ }
+
+ @Test
+ void actuatorBindings() {
+ List> bindings = actuatorOperations
+ .getFromActuator("test-application-id", "test-application-0", "/bindings", List.class);
+
+ assertThat(((Map, ?>) (bindings.get(0))).get("bindingName")).isEqualTo("input");
+ }
+
+ @Test
+ void actuatorBindingInput() {
+ Map binding = actuatorOperations
+ .getFromActuator("test-application-id", "test-application-0", "/bindings/input", Map.class);
+ assertThat(binding.get("bindingName")).isEqualTo("input");
+ }
+
+ @Test
+ void actuatorPostBindingInput() {
+ Map state = actuatorOperations
+ .postToActuator("test-application-id", "test-application-0", "/bindings/input",
+ Collections.singletonMap("state", "STOPPED"), Map.class);
+ assertThat(state.get("state")).isEqualTo("STOPPED");
+ }
+
+ @Test
+ void noInstanceDeployed() {
+ when(appInstanceStatus.getState()).thenReturn(DeploymentState.failed);
+ assertThatThrownBy(() -> {
+ actuatorOperations
+ .getFromActuator("test-application-id", "test-application-0", "/info", Map.class);
+
+ }).isInstanceOf(IllegalStateException.class).hasMessageContaining("not deployed");
+ }
+
+ private static String resourceAsString(String path) {
+ try {
+ return StreamUtils.copyToString(new ClassPathResource(path).getInputStream(), StandardCharsets.UTF_8);
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+}
diff --git a/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerIntegrationIT.java b/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerIntegrationIT.java
index efceebea..55031aef 100644
--- a/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerIntegrationIT.java
+++ b/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerIntegrationIT.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2021 the original author or authors.
+ * Copyright 2016-2022 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.
@@ -128,11 +128,7 @@ public void setup() {
@Test
public void testScaleStatefulSet() {
log.info("Testing {}...", "ScaleStatefulSet");
- KubernetesDeployerProperties deployProperties = new KubernetesDeployerProperties();
-
- ContainerFactory containerFactory = new DefaultContainerFactory(deployProperties);
- KubernetesAppDeployer appDeployer = new KubernetesAppDeployer(deployProperties, kubernetesClient,
- containerFactory);
+ KubernetesAppDeployer appDeployer = kubernetesAppDeployer();
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -193,11 +189,7 @@ public void testScaleStatefulSet() {
@Test
public void testScaleDeployment() {
log.info("Testing {}...", "ScaleDeployment");
- KubernetesDeployerProperties deployProperties = new KubernetesDeployerProperties();
-
- ContainerFactory containerFactory = new DefaultContainerFactory(deployProperties);
- KubernetesAppDeployer appDeployer = new KubernetesAppDeployer(deployProperties, kubernetesClient,
- containerFactory);
+ KubernetesAppDeployer appDeployer = kubernetesAppDeployer();
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -253,9 +245,7 @@ public void testFailedDeploymentWithLoadBalancer() {
deployProperties.setLivenessHttpProbePeriod(10);
deployProperties.setMaxTerminatedErrorRestarts(1);
deployProperties.setMaxCrashLoopBackOffRestarts(1);
- ContainerFactory containerFactory = new DefaultContainerFactory(deployProperties);
- KubernetesAppDeployer lbAppDeployer = new KubernetesAppDeployer(deployProperties, kubernetesClient,
- containerFactory);
+ KubernetesAppDeployer lbAppDeployer = kubernetesAppDeployer(deployProperties);
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -292,9 +282,7 @@ public void testGoodDeploymentWithLoadBalancer() {
KubernetesDeployerProperties deployProperties = new KubernetesDeployerProperties();
deployProperties.setCreateLoadBalancer(true);
deployProperties.setMinutesToWaitForLoadBalancer(1);
- ContainerFactory containerFactory = new DefaultContainerFactory(deployProperties);
- KubernetesAppDeployer lbAppDeployer = new KubernetesAppDeployer(deployProperties, kubernetesClient,
- containerFactory);
+ KubernetesAppDeployer lbAppDeployer = kubernetesAppDeployer(deployProperties);
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -327,9 +315,7 @@ public void testDeploymentWithLoadBalancerHasUrlAndAnnotation() {
KubernetesDeployerProperties deployProperties = new KubernetesDeployerProperties();
deployProperties.setCreateLoadBalancer(true);
deployProperties.setMinutesToWaitForLoadBalancer(1);
- ContainerFactory containerFactory = new DefaultContainerFactory(deployProperties);
- KubernetesAppDeployer lbAppDeployer = new KubernetesAppDeployer(deployProperties, kubernetesClient,
- containerFactory);
+ KubernetesAppDeployer lbAppDeployer = kubernetesAppDeployer(deployProperties);
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -379,10 +365,7 @@ public void testDeploymentWithLoadBalancerHasUrlAndAnnotation() {
@Test
public void testDeploymentWithPodAnnotation() {
log.info("Testing {}...", "DeploymentWithPodAnnotation");
- KubernetesDeployerProperties deployProperties = new KubernetesDeployerProperties();
- ContainerFactory containerFactory = new DefaultContainerFactory(deployProperties);
- KubernetesAppDeployer appDeployer = new KubernetesAppDeployer(deployProperties, kubernetesClient,
- containerFactory);
+ KubernetesAppDeployer appDeployer = kubernetesAppDeployer();
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -442,9 +425,7 @@ public void testDeploymentWithMountedHostPathVolume() throws IOException {
.build()));
deployProperties.setVolumeMounts(Collections.singletonList(new VolumeMount(hostPathVolumeSource.getPath(), null,
mountName, false, null, null)));
- ContainerFactory containerFactory = new DefaultContainerFactory(deployProperties);
- KubernetesAppDeployer lbAppDeployer = new KubernetesAppDeployer(deployProperties, kubernetesClient,
- containerFactory);
+ KubernetesAppDeployer lbAppDeployer = kubernetesAppDeployer(deployProperties);
AppDefinition definition = new AppDefinition(randomName(),
Collections.singletonMap("logging.file", containerPath + subPath));
@@ -583,9 +564,7 @@ public void testDeploymentWithGroupAndIndex() throws IOException {
KubernetesDeployerProperties deployProperties = new KubernetesDeployerProperties();
deployProperties.setCreateLoadBalancer(true);
deployProperties.setMinutesToWaitForLoadBalancer(1);
- ContainerFactory containerFactory = new DefaultContainerFactory(deployProperties);
- KubernetesAppDeployer testAppDeployer = new KubernetesAppDeployer(deployProperties, kubernetesClient,
- containerFactory);
+ KubernetesAppDeployer testAppDeployer = kubernetesAppDeployer(deployProperties);
Map appProperties = new HashMap<>();
appProperties.put("security.basic.enabled", "false");
@@ -642,8 +621,7 @@ public void testDeploymentServiceAccountName() {
deployProperties.setDeploymentServiceAccountName(serviceAccountName);
ContainerFactory containerFactory = new DefaultContainerFactory(deployProperties);
- KubernetesAppDeployer appDeployer = new KubernetesAppDeployer(deployProperties, kubernetesClient,
- containerFactory);
+ KubernetesAppDeployer appDeployer = kubernetesAppDeployer(deployProperties);
AppDefinition definition = new AppDefinition(randomName(), null);
AppDeploymentRequest request = new AppDeploymentRequest(definition, testApplication());
@@ -678,8 +656,7 @@ public void testCreateStatefulSet() throws Exception {
AppDefinition definition = new AppDefinition(randomName(), null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, testApplication(), props);
- KubernetesAppDeployer deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer deployer = kubernetesAppDeployer();
log.info("Deploying {}...", appDeploymentRequest.getDefinition().getName());
String deploymentId = deployer.deploy(appDeploymentRequest);
@@ -764,8 +741,7 @@ public void testCreateStatefulSetInitContainerImageNamePropOverride() throws Exc
AppDefinition definition = new AppDefinition(randomName(), null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, testApplication(), props);
- KubernetesAppDeployer deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer deployer = kubernetesAppDeployer();
log.info("Deploying {}...", appDeploymentRequest.getDefinition().getName());
String deploymentId = deployer.deploy(appDeploymentRequest);
@@ -816,7 +792,7 @@ public void createStatefulSetInitContainerImageNameGlobalOverride() throws Excep
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setStatefulSetInitContainerImageName(imageName);
- KubernetesAppDeployer deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, kubernetesClient);
+ KubernetesAppDeployer deployer = kubernetesAppDeployer(kubernetesDeployerProperties);
log.info("Deploying {}...", appDeploymentRequest.getDefinition().getName());
String deploymentId = deployer.deploy(appDeploymentRequest);
@@ -864,8 +840,7 @@ public void createStatefulSetWithOverridingRequest() throws Exception {
AppDefinition definition = new AppDefinition(randomName(), null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, testApplication(), props);
- KubernetesAppDeployer deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer deployer = kubernetesAppDeployer();
log.info("Deploying {}...", appDeploymentRequest.getDefinition().getName());
String deploymentId = deployer.deploy(appDeploymentRequest);
@@ -933,8 +908,7 @@ public void createStatefulSetWithPVCDefaultName() throws Exception {
AppDefinition definition = new AppDefinition(randomName(), null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, testApplication(), props);
- KubernetesAppDeployer deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer deployer = kubernetesAppDeployer();
log.info("Deploying {}...", appDeploymentRequest.getDefinition().getName());
String deploymentId = deployer.deploy(appDeploymentRequest);
@@ -969,11 +943,8 @@ public void createStatefulSetWithPVCDefaultName() throws Exception {
@Test
public void testStatefulSetPodAnnotations() {
log.info("Testing {}...", "StatefulSetPodAnnotations");
- KubernetesDeployerProperties deployProperties = new KubernetesDeployerProperties();
- ContainerFactory containerFactory = new DefaultContainerFactory(deployProperties);
- KubernetesAppDeployer appDeployer = new KubernetesAppDeployer(deployProperties, kubernetesClient,
- containerFactory);
+ KubernetesAppDeployer appDeployer = kubernetesAppDeployer();
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -1022,8 +993,7 @@ public void testDeploymentLabels() {
AppDefinition definition = new AppDefinition(randomName(), null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, testApplication(), props);
- KubernetesAppDeployer deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer deployer = kubernetesAppDeployer();
log.info("Deploying {}...", appDeploymentRequest.getDefinition().getName());
@@ -1068,8 +1038,7 @@ public void testDeploymentLabelsStatefulSet() {
AppDefinition definition = new AppDefinition(randomName(), null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, testApplication(), props);
- KubernetesAppDeployer deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer deployer = kubernetesAppDeployer();
log.info("Deploying {}...", appDeploymentRequest.getDefinition().getName());
@@ -1126,8 +1095,7 @@ public void testCleanupOnDeployFailure() throws InterruptedException {
kubernetesDeployerProperties.setLimits(resources);
- KubernetesAppDeployer deployer = new KubernetesAppDeployer(kubernetesDeployerProperties,
- kubernetesClient);
+ KubernetesAppDeployer deployer = kubernetesAppDeployer(kubernetesDeployerProperties);
log.info("Deploying {}...", appDeploymentRequest.getDefinition().getName());
@@ -1150,7 +1118,7 @@ public void testCleanupOnDeployFailure() throws InterruptedException {
log.info("Got expected not not deployed exception on undeployment: " + e.getMessage());
}
- deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), kubernetesClient);
+ deployer = kubernetesAppDeployer();
log.info("Deploying {}... again", deploymentId);
@@ -1176,10 +1144,7 @@ public void testCleanupOnDeployFailure() throws InterruptedException {
public void testMultipleContainersInPod() {
log.info("Testing {}...", "MultipleContainersInPod");
- KubernetesDeployerProperties deployProperties = new KubernetesDeployerProperties();
-
- KubernetesAppDeployer kubernetesAppDeployer = Mockito.spy(new KubernetesAppDeployer(deployProperties,
- kubernetesClient, new DefaultContainerFactory(deployProperties)));
+ KubernetesAppDeployer kubernetesAppDeployer = Mockito.spy(kubernetesAppDeployer());
AppDefinition definition = new AppDefinition(randomName(), Collections.singletonMap("server.port", "9090"));
Resource resource = testApplication();
@@ -1220,7 +1185,7 @@ public void testMultipleContainersInPod() {
@Test
public void testDefaultServicePort() {
log.info("Testing {}...", "DefaultServicePort");
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer();
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -1255,7 +1220,7 @@ public void testDefaultServicePort() {
@Test
public void testDefaultServicePortOverride() {
log.info("Testing {}...", "DefaultServicePortOverride");
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer();
AppDefinition definition = new AppDefinition(randomName(), Collections.singletonMap("server.port", "9090"));
Resource resource = testApplication();
@@ -1290,7 +1255,7 @@ public void testDefaultServicePortOverride() {
@Test
public void testServiceWithMultiplePorts() {
log.info("Testing {}...", "ServiceWithMultiplePorts");
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer();
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -1328,8 +1293,7 @@ public void testServiceWithMultiplePorts() {
@Test
public void testCreateInitContainer() {
log.info("Testing {}...", "CreateInitContainer");
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer();
Map props = Collections.singletonMap("spring.cloud.deployer.kubernetes.initContainer",
"{containerName: 'test', imageName: 'busybox:latest', commands: ['sh', '-c', 'echo hello']}");
@@ -1374,8 +1338,7 @@ public void testCreateInitContainer() {
@Test
public void testCreateInitContainerWithEnvVariables() {
log.info("Testing {}...", "CreateInitContainer");
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer();
Map props = Collections.singletonMap("spring.cloud.deployer.kubernetes.initContainer",
"{containerName: 'test', imageName: 'busybox:latest', commands: ['sh', '-c', 'echo hello'], environmentVariables: ['KEY1=VAL1', 'KEY2=VAL2']}");
@@ -1419,8 +1382,7 @@ public void testCreateInitContainerWithEnvVariables() {
@Test
public void testCreateInitContainerWithVolumeMounts() {
log.info("Testing {}...", "CreateInitContainerWithVolumeMounts");
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer =kubernetesAppDeployer();
Map props = Stream.of(new String[][]{
{
@@ -1489,8 +1451,7 @@ public void testCreateInitContainerWithVolumeMounts() {
@Test
public void testCreateAdditionalContainers() {
log.info("Testing {}...", "CreateAdditionalContainers");
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer();
Map props = Stream.of(new String[][]{
{
@@ -1578,8 +1539,8 @@ public void testCreateAdditionalContainersOverride() {
container2.setCommand(Arrays.asList("sh", "-c", "echo hello-from-original-properties"));
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setAdditionalContainers(Arrays.asList(container1, container2));
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(kubernetesDeployerProperties,
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer(kubernetesDeployerProperties);
+
Map props = Stream.of(new String[][]{
{
@@ -1671,8 +1632,7 @@ public void testCreateAdditionalContainersOverride() {
@Test
public void testUnknownStatusOnPendingResources() throws InterruptedException {
log.info("Testing {}...", "UnknownStatusOnPendingResources");
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer();
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -1733,7 +1693,7 @@ public void testSecretRef() throws InterruptedException {
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setSecretRefs(Collections.singletonList(secret.getMetadata().getName()));
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(kubernetesDeployerProperties, kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer(kubernetesDeployerProperties);
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -1785,8 +1745,7 @@ public void testSecretRefFromDeployerProperty() throws InterruptedException {
Secret secret = randomSecret();
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer();
Map props = new HashMap<>();
props.put("spring.cloud.deployer.kubernetes.secretRefs", secret.getMetadata().getName());
@@ -1845,8 +1804,7 @@ public void testSecretRefFromDeployerPropertyOverride() throws IOException, Inte
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setSecretRefs(Collections.singletonList(propertySecret.getMetadata().getName()));
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(kubernetesDeployerProperties,
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer =kubernetesAppDeployer(kubernetesDeployerProperties);
Map props = new HashMap<>();
props.put("spring.cloud.deployer.kubernetes.secretRefs", deployerPropertySecret.getMetadata().getName());
@@ -1913,8 +1871,7 @@ public void testSecretRefFromPropertyMultiple() throws InterruptedException {
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setSecretRefs(secrets);
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(kubernetesDeployerProperties,
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer(kubernetesDeployerProperties);
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -1979,8 +1936,7 @@ public void testSecretRefFromDeploymentPropertyMultiple() throws InterruptedExce
props.put("spring.cloud.deployer.kubernetes.secretRefs", "[" + secret1.getMetadata().getName() + "," +
secret2.getMetadata().getName() + "]");
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer();
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -2043,7 +1999,7 @@ public void testConfigMapRef() throws InterruptedException {
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setConfigMapRefs(Collections.singletonList(configMap.getMetadata().getName()));
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(kubernetesDeployerProperties, kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer(kubernetesDeployerProperties);
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -2094,8 +2050,7 @@ public void testConfigMapRefFromDeployerProperty() throws InterruptedException {
ConfigMap configMap = randomConfigMap();
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer();
Map props = new HashMap<>();
props.put("spring.cloud.deployer.kubernetes.config-map-refs", configMap.getMetadata().getName());
@@ -2153,8 +2108,7 @@ public void testConfigMapRefFromDeployerPropertyOverride() throws IOException, I
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setConfigMapRefs(Collections.singletonList(propertyConfigMap.getMetadata().getName()));
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(kubernetesDeployerProperties,
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer(kubernetesDeployerProperties);
Map props = new HashMap<>();
props.put("spring.cloud.deployer.kubernetes.configMapRefs", deployerPropertyConfigMap.getMetadata().getName());
@@ -2220,8 +2174,7 @@ public void testConfigMapRefFromPropertyMultiple() throws InterruptedException {
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setConfigMapRefs(configMaps);
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(kubernetesDeployerProperties,
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer(kubernetesDeployerProperties);
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -2285,8 +2238,7 @@ public void testConfigMapRefFromDeploymentPropertyMultiple() throws InterruptedE
props.put("spring.cloud.deployer.kubernetes.configMapRefs", "[" + configMap1.getMetadata().getName() + "," +
configMap2.getMetadata().getName() + "]");
- KubernetesAppDeployer kubernetesAppDeployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(),
- kubernetesClient);
+ KubernetesAppDeployer kubernetesAppDeployer = kubernetesAppDeployer();
AppDefinition definition = new AppDefinition(randomName(), null);
Resource resource = testApplication();
@@ -2433,4 +2385,12 @@ private ConfigMap randomConfigMap() {
return kubernetesClient.configMaps().create(configMap);
}
+
+ private KubernetesAppDeployer kubernetesAppDeployer() {
+ return kubernetesAppDeployer(new KubernetesDeployerProperties());
+ }
+ private KubernetesAppDeployer kubernetesAppDeployer(KubernetesDeployerProperties kubernetesDeployerProperties) {
+ return new KubernetesAppDeployer(kubernetesDeployerProperties, this.kubernetesClient,
+ new DefaultContainerFactory(kubernetesDeployerProperties));
+ }
}
diff --git a/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerTests.java b/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerTests.java
index 233132ae..ceb4f59b 100644
--- a/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerTests.java
+++ b/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerTests.java
@@ -91,7 +91,7 @@ public void deployWithVolumesOnly() throws Exception {
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(),
new HashMap<>());
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer =k8sAppDeployer(bindDeployerProperties());
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getVolumes()).isEmpty();
@@ -105,7 +105,7 @@ public void deployWithVolumesAndVolumeMounts() throws Exception {
+ "{name: 'testnfs', mountPath: '/test/nfs', readOnly: 'true'}" + "]");
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer = k8sAppDeployer();
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getVolumes()).containsOnly(
@@ -124,7 +124,7 @@ public void deployWithVolumesAndVolumeMounts() throws Exception {
+ "{name: 'testnfs', mountPath: '/test/nfs', readOnly: 'true'}" + "]");
appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer = k8sAppDeployer();
podSpec = deployer.createPodSpec(appDeploymentRequest);
HostPathVolumeSource hostPathVolumeSource = new HostPathVolumeSourceBuilder()
@@ -144,7 +144,7 @@ public void deployWithNodeSelectorGlobalProperty() throws Exception {
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setNodeSelector("disktype:ssd, os:qnx");
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getNodeSelector()).containsOnly(entry("disktype", "ssd"), entry("os", "qnx"));
@@ -157,7 +157,7 @@ public void deployWithNodeSelectorDeploymentProperty() throws Exception {
props.put(KubernetesDeployerProperties.KUBERNETES_DEPLOYMENT_NODE_SELECTOR, "disktype:ssd, os: linux");
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer = k8sAppDeployer();
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getNodeSelector()).containsOnly(entry("disktype", "ssd"), entry("os", "linux"));
@@ -173,7 +173,7 @@ public void deployWithNodeSelectorDeploymentPropertyGlobalOverride() throws Exce
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setNodeSelector("disktype:ssd, os:qnx");
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getNodeSelector()).containsOnly(entry("disktype", "ssd"), entry("os", "openbsd"));
@@ -188,7 +188,7 @@ public void deployWithEnvironmentWithCommaDelimitedValue() throws Exception {
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer = k8sAppDeployer();
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getContainers().get(0).getEnv())
@@ -210,7 +210,7 @@ public void deployWithEnvironmentWithSingleCommaDelimitedValue() throws Exceptio
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer = k8sAppDeployer();
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getContainers().get(0).getEnv())
@@ -226,7 +226,7 @@ public void deployWithEnvironmentWithMultipleCommaDelimitedValue() throws Except
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer = k8sAppDeployer();
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getContainers().get(0).getEnv())
@@ -244,7 +244,7 @@ public void deployWithImagePullSecretDeploymentProperty() {
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), null);
+ deployer = k8sAppDeployer(new KubernetesDeployerProperties());
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getImagePullSecrets().size()).isEqualTo(1);
@@ -260,7 +260,7 @@ public void deployWithImagePullSecretDeployerProperty() {
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setImagePullSecret("regcred");
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getImagePullSecrets().size()).isEqualTo(1);
@@ -276,7 +276,7 @@ public void deployWithImagePullSecretsDeploymentProperty() {
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), null);
+ deployer = k8sAppDeployer(new KubernetesDeployerProperties());
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getImagePullSecrets().size()).isEqualTo(2);
@@ -293,7 +293,7 @@ public void deployWithImagePullSecretsDeployerProperty() {
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setImagePullSecrets(Arrays.asList("regcredone","regcredtwo"));
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getImagePullSecrets().size()).isEqualTo(2);
@@ -310,7 +310,7 @@ public void deployWithDeploymentServiceAccountNameDeploymentProperties() {
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), null);
+ deployer = k8sAppDeployer(new KubernetesDeployerProperties());
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getServiceAccountName()).isNotNull();
@@ -326,7 +326,7 @@ public void deployWithDeploymentServiceAccountNameDeployerProperty() {
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setDeploymentServiceAccountName("myserviceaccount");
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getServiceAccountName()).isNotNull();
@@ -345,7 +345,7 @@ public void deployWithDeploymentServiceAccountNameDeploymentPropertyOverride() {
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.setDeploymentServiceAccountName("defaultsan");
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getServiceAccountName()).isNotNull();
@@ -358,7 +358,7 @@ public void deployWithTolerations() throws Exception {
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(),
new HashMap<>());
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer = k8sAppDeployer();
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getTolerations()).isNotEmpty();
@@ -375,7 +375,7 @@ public void deployWithGlobalTolerations() {
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), null);
+ deployer = k8sAppDeployer(new KubernetesDeployerProperties());
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getTolerations()).isNotNull();
@@ -405,7 +405,7 @@ public void deployWithTolerationPropertyOverride() {
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.getTolerations().add(toleration);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getTolerations()).isNotNull();
@@ -434,7 +434,7 @@ public void deployWithDuplicateTolerationKeyPropertyOverride() {
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
kubernetesDeployerProperties.getTolerations().add(toleration);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getTolerations()).isNotNull();
@@ -468,7 +468,7 @@ public void deployWithDuplicateGlobalToleration() {
kubernetesDeployerProperties.getTolerations().add(toleration2);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getTolerations()).isNotNull();
@@ -529,7 +529,7 @@ public void testSecretKeyRef() {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), null);
+ deployer =k8sAppDeployer(new KubernetesDeployerProperties());
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
List envVars = podSpec.getContainers().get(0).getEnv();
@@ -553,7 +553,7 @@ public void testSecretKeyRefMultiple() {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), null);
+ deployer = k8sAppDeployer(new KubernetesDeployerProperties());
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
List envVars = podSpec.getContainers().get(0).getEnv();
@@ -585,7 +585,7 @@ public void testSecretKeyRefGlobal() {
secretKeyRef.setDataKey("passwordGlobal");
kubernetesDeployerProperties.setSecretKeyRefs(Collections.singletonList(secretKeyRef));
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
List envVars = podSpec.getContainers().get(0).getEnv();
@@ -627,7 +627,7 @@ public void testSecretKeyRefPropertyOverride() {
kubernetesDeployerProperties.setSecretKeyRefs(globalSecretKeyRefs);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
List envVars = podSpec.getContainers().get(0).getEnv();
@@ -661,7 +661,7 @@ public void testSecretKeyRefGlobalFromYaml() throws Exception {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), null);
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer = k8sAppDeployer();
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
List envVars = podSpec.getContainers().get(0).getEnv();
@@ -684,7 +684,7 @@ public void testConfigMapKeyRef() {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), null);
+ deployer = k8sAppDeployer(new KubernetesDeployerProperties());
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
List envVars = podSpec.getContainers().get(0).getEnv();
@@ -708,7 +708,7 @@ public void testConfigMapKeyRefMultiple() {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), null);
+ deployer = k8sAppDeployer(new KubernetesDeployerProperties());
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
List envVars = podSpec.getContainers().get(0).getEnv();
@@ -740,7 +740,7 @@ public void testConfigMapKeyRefGlobal() {
configMapKeyRef.setDataKey("envGlobal");
kubernetesDeployerProperties.setConfigMapKeyRefs(Collections.singletonList(configMapKeyRef));
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
List envVars = podSpec.getContainers().get(0).getEnv();
@@ -782,7 +782,7 @@ public void testConfigMapKeyRefPropertyOverride() {
kubernetesDeployerProperties.setConfigMapKeyRefs(globalConfigMapKeyRefs);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
List envVars = podSpec.getContainers().get(0).getEnv();
@@ -816,7 +816,7 @@ public void testConfigMapKeyRefGlobalFromYaml() throws Exception {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), null);
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer = k8sAppDeployer();
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
List envVars = podSpec.getContainers().get(0).getEnv();
@@ -853,7 +853,7 @@ public void testNodeAffinityProperty() {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), null);
+ deployer = k8sAppDeployer(new KubernetesDeployerProperties());
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
NodeAffinity nodeAffinity = podSpec.getAffinity().getNodeAffinity();
@@ -888,7 +888,7 @@ public void testPodAffinityProperty() {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), null);
+ deployer = k8sAppDeployer(new KubernetesDeployerProperties());
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
PodAffinity podAffinity = podSpec.getAffinity().getPodAffinity();
@@ -923,7 +923,7 @@ public void testPodAntiAffinityProperty() {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
- deployer = new KubernetesAppDeployer(new KubernetesDeployerProperties(), null);
+ deployer = k8sAppDeployer(new KubernetesDeployerProperties());
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
PodAntiAffinity podAntiAffinity = podSpec.getAffinity().getPodAntiAffinity();
@@ -963,7 +963,7 @@ public void testNodeAffinityGlobalProperty() {
kubernetesDeployerProperties.setNodeAffinity(nodeAffinity);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
NodeAffinity nodeAffinityTest = podSpec.getAffinity().getNodeAffinity();
@@ -1003,7 +1003,7 @@ public void testPodAffinityGlobalProperty() {
kubernetesDeployerProperties.setPodAffinity(podAffinity);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
PodAffinity podAffinityTest = podSpec.getAffinity().getPodAffinity();
@@ -1043,7 +1043,7 @@ public void testPodAntiAffinityGlobalProperty() {
kubernetesDeployerProperties.setPodAntiAffinity(podAntiAffinity);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
PodAntiAffinity podAntiAffinityTest = podSpec.getAffinity().getPodAntiAffinity();
@@ -1057,7 +1057,7 @@ public void testNodeAffinityFromYaml() throws Exception {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), null);
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer = k8sAppDeployer();
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
NodeAffinity nodeAffinity = podSpec.getAffinity().getNodeAffinity();
@@ -1071,7 +1071,7 @@ public void testPodAffinityFromYaml() throws Exception {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), null);
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer = k8sAppDeployer();
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
PodAffinity podAffinity = podSpec.getAffinity().getPodAffinity();
@@ -1085,7 +1085,7 @@ public void testPodAntiAffinityFromYaml() throws Exception {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), null);
- deployer = new KubernetesAppDeployer(bindDeployerProperties(), null);
+ deployer = k8sAppDeployer();
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
PodAntiAffinity podAntiAffinity = podSpec.getAffinity().getPodAntiAffinity();
@@ -1135,7 +1135,7 @@ public void testNodeAffinityPropertyOverrideGlobal() {
kubernetesDeployerProperties.setNodeAffinity(nodeAffinity);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
NodeAffinity nodeAffinityTest = podSpec.getAffinity().getNodeAffinity();
@@ -1187,7 +1187,7 @@ public void testPodAffinityPropertyOverrideGlobal() {
kubernetesDeployerProperties.setPodAffinity(podAffinity);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
PodAffinity podAffinityTest = podSpec.getAffinity().getPodAffinity();
@@ -1239,7 +1239,7 @@ public void testPodAntiAffinityPropertyOverrideGlobal() {
kubernetesDeployerProperties.setPodAntiAffinity(podAntiAffinity);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
PodAntiAffinity podAntiAffinityTest = podSpec.getAffinity().getPodAntiAffinity();
@@ -1487,7 +1487,7 @@ private void assertThatDeployerCreatesPodSpecWithContainerSecurityContext(
private PodSpec deployerCreatesPodSpec(KubernetesDeployerProperties globalDeployerProperties, Map deploymentProperties) {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), deploymentProperties);
- KubernetesAppDeployer deployer = new KubernetesAppDeployer(globalDeployerProperties, null);
+ KubernetesAppDeployer deployer = k8sAppDeployer(globalDeployerProperties);
return deployer.createPodSpec(appDeploymentRequest);
}
@@ -1499,7 +1499,7 @@ public void testWithLifecyclePostStart() {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getContainers().get(0).getLifecycle().getPostStart().getExec().getCommand())
.containsExactlyInAnyOrder("/bin/sh","-c","echo Hello from the postStart handler > /usr/share/message");
@@ -1513,7 +1513,7 @@ public void testWithLifecyclePreStop() {
AppDefinition definition = new AppDefinition("app-test", null);
AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props);
KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties();
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getContainers().get(0).getLifecycle().getPreStop().getExec().getCommand())
.containsExactlyInAnyOrder(
@@ -1552,7 +1552,7 @@ List getCommand() {
}
});
kubernetesDeployerProperties.setLifecycle(lifecycle);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getContainers().get(0).getLifecycle().getPostStart().getExec().getCommand())
.containsExactlyInAnyOrder(
@@ -1593,7 +1593,7 @@ List getCommand() {
}
});
kubernetesDeployerProperties.setLifecycle(lifecycle);
- deployer = new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ deployer = k8sAppDeployer(kubernetesDeployerProperties);
PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest);
assertThat(podSpec.getContainers().get(0).getLifecycle().getPreStop().getExec().getCommand())
.containsExactlyInAnyOrder(
@@ -1621,4 +1621,13 @@ private KubernetesDeployerProperties bindDeployerProperties() throws Exception {
MapConfigurationPropertySource source = new MapConfigurationPropertySource(yaml);
return new Binder(source).bind("", Bindable.of(KubernetesDeployerProperties.class)).get();
}
+
+ protected KubernetesAppDeployer k8sAppDeployer() throws Exception {
+ return k8sAppDeployer(bindDeployerProperties());
+ }
+
+ protected KubernetesAppDeployer k8sAppDeployer(KubernetesDeployerProperties kubernetesDeployerProperties) {
+ return new KubernetesAppDeployer(kubernetesDeployerProperties, null);
+ }
+
}
diff --git a/src/test/resources/actuator-binding-input.json b/src/test/resources/actuator-binding-input.json
new file mode 100644
index 00000000..895f71eb
--- /dev/null
+++ b/src/test/resources/actuator-binding-input.json
@@ -0,0 +1,97 @@
+{
+ "bindingName": "input",
+ "name": "tiktok.time",
+ "group": "tiktok",
+ "pausable": false,
+ "state": "running",
+ "paused": false,
+ "input": true,
+ "extendedInfo": {
+ "bindingDestination": "RabbitConsumerDestination{queue=tiktok.time.tiktok, binding=Binding [destination=tiktok.time.tiktok, exchange=tiktok.time, routingKey=#, arguments={}]}",
+ "ExtendedConsumerProperties": {
+ "autoStartup": true,
+ "concurrency": 1,
+ "instanceCount": 2,
+ "maxAttempts": 3,
+ "backOffInitialInterval": 1000,
+ "backOffMaxInterval": 10000,
+ "backOffMultiplier": 2,
+ "defaultRetryable": true,
+ "extension": {
+ "exchangeType": "topic",
+ "declareExchange": true,
+ "exchangeDurable": true,
+ "exchangeAutoDelete": false,
+ "delayedExchange": false,
+ "queueNameGroupOnly": false,
+ "bindQueue": true,
+ "bindingRoutingKey": null,
+ "bindingRoutingKeyDelimiter": null,
+ "ttl": null,
+ "expires": null,
+ "maxLength": null,
+ "maxLengthBytes": null,
+ "maxPriority": null,
+ "deadLetterQueueName": null,
+ "deadLetterExchange": null,
+ "deadLetterExchangeType": "direct",
+ "declareDlx": true,
+ "deadLetterRoutingKey": null,
+ "dlqTtl": null,
+ "dlqExpires": null,
+ "dlqMaxLength": null,
+ "dlqMaxLengthBytes": null,
+ "dlqMaxPriority": null,
+ "dlqDeadLetterExchange": null,
+ "dlqDeadLetterRoutingKey": null,
+ "autoBindDlq": false,
+ "prefix": "",
+ "lazy": false,
+ "dlqLazy": false,
+ "overflowBehavior": null,
+ "dlqOverflowBehavior": null,
+ "queueBindingArguments": {},
+ "dlqBindingArguments": {},
+ "quorum": {
+ "enabled": false,
+ "initialGroupSize": null,
+ "deliveryLimit": null
+ },
+ "dlqQuorum": {
+ "enabled": false,
+ "initialGroupSize": null,
+ "deliveryLimit": null
+ },
+ "singleActiveConsumer": false,
+ "dlqSingleActiveConsumer": false,
+ "transacted": false,
+ "acknowledgeMode": "AUTO",
+ "maxConcurrency": 1,
+ "prefetch": 1,
+ "batchSize": 1,
+ "durableSubscription": true,
+ "republishToDlq": true,
+ "republishDeliveyMode": "PERSISTENT",
+ "requeueRejected": false,
+ "headerPatterns": [
+ "*"
+ ],
+ "recoveryInterval": 5000,
+ "exclusive": false,
+ "missingQueuesFatal": false,
+ "queueDeclarationRetries": null,
+ "failedDeclarationRetryInterval": null,
+ "consumerTagPrefix": null,
+ "frameMaxHeadroom": 20000,
+ "containerType": "SIMPLE",
+ "anonymousGroupPrefix": "anonymous.",
+ "enableBatching": false,
+ "receiveTimeout": null,
+ "requestHeaderPatterns": [
+ "*"
+ ],
+ "txSize": 1
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/actuator-bindings.json b/src/test/resources/actuator-bindings.json
new file mode 100644
index 00000000..f225ef65
--- /dev/null
+++ b/src/test/resources/actuator-bindings.json
@@ -0,0 +1,100 @@
+[
+ {
+ "bindingName": "input",
+ "name": "tiktok.time",
+ "group": "tiktok",
+ "pausable": false,
+ "state": "running",
+ "paused": false,
+ "extendedInfo": {
+ "bindingDestination": "RabbitConsumerDestination{queue=tiktok.time.tiktok, binding=Binding [destination=tiktok.time.tiktok, exchange=tiktok.time, routingKey=#, arguments={}]}",
+ "ExtendedConsumerProperties": {
+ "autoStartup": true,
+ "concurrency": 1,
+ "instanceCount": 2,
+ "instanceIndex": 1,
+ "maxAttempts": 3,
+ "backOffInitialInterval": 1000,
+ "backOffMaxInterval": 10000,
+ "backOffMultiplier": 2,
+ "defaultRetryable": true,
+ "extension": {
+ "exchangeType": "topic",
+ "declareExchange": true,
+ "exchangeDurable": true,
+ "exchangeAutoDelete": false,
+ "delayedExchange": false,
+ "queueNameGroupOnly": false,
+ "bindQueue": true,
+ "bindingRoutingKey": null,
+ "bindingRoutingKeyDelimiter": null,
+ "ttl": null,
+ "expires": null,
+ "maxLength": null,
+ "maxLengthBytes": null,
+ "maxPriority": null,
+ "deadLetterQueueName": null,
+ "deadLetterExchange": null,
+ "deadLetterExchangeType": "direct",
+ "declareDlx": true,
+ "deadLetterRoutingKey": null,
+ "dlqTtl": null,
+ "dlqExpires": null,
+ "dlqMaxLength": null,
+ "dlqMaxLengthBytes": null,
+ "dlqMaxPriority": null,
+ "dlqDeadLetterExchange": null,
+ "dlqDeadLetterRoutingKey": null,
+ "autoBindDlq": false,
+ "prefix": "",
+ "lazy": false,
+ "dlqLazy": false,
+ "overflowBehavior": null,
+ "dlqOverflowBehavior": null,
+ "queueBindingArguments": {},
+ "dlqBindingArguments": {},
+ "quorum": {
+ "enabled": false,
+ "initialGroupSize": null,
+ "deliveryLimit": null
+ },
+ "dlqQuorum": {
+ "enabled": false,
+ "initialGroupSize": null,
+ "deliveryLimit": null
+ },
+ "singleActiveConsumer": false,
+ "dlqSingleActiveConsumer": false,
+ "transacted": false,
+ "acknowledgeMode": "AUTO",
+ "maxConcurrency": 1,
+ "prefetch": 1,
+ "batchSize": 1,
+ "durableSubscription": true,
+ "republishToDlq": true,
+ "republishDeliveyMode": "PERSISTENT",
+ "requeueRejected": false,
+ "headerPatterns": [
+ "*"
+ ],
+ "recoveryInterval": 5000,
+ "exclusive": false,
+ "missingQueuesFatal": false,
+ "queueDeclarationRetries": null,
+ "failedDeclarationRetryInterval": null,
+ "consumerTagPrefix": null,
+ "frameMaxHeadroom": 20000,
+ "containerType": "SIMPLE",
+ "anonymousGroupPrefix": "anonymous.",
+ "enableBatching": false,
+ "receiveTimeout": null,
+ "requestHeaderPatterns": [
+ "*"
+ ],
+ "txSize": 1
+ }
+ }
+ },
+ "input": true
+ }
+]
\ No newline at end of file
diff --git a/src/test/resources/actuator-info.json b/src/test/resources/actuator-info.json
new file mode 100644
index 00000000..e8e2cf61
--- /dev/null
+++ b/src/test/resources/actuator-info.json
@@ -0,0 +1,7 @@
+{
+ "app": {
+ "description": "Spring Cloud Stream Log Sink Rabbit Binder Application",
+ "version": "3.1.1",
+ "name": "log-sink-rabbit"
+ }
+}
\ No newline at end of file