diff --git a/tomcat/k8s/crd.yaml b/tomcat/k8s/crd.yaml
index 44533a3..0ad6272 100644
--- a/tomcat/k8s/crd.yaml
+++ b/tomcat/k8s/crd.yaml
@@ -80,6 +80,14 @@ spec:
properties:
deployedArtifact:
type: string
+ contextPath:
+ type: string
+ ready:
+ type: string
+ message:
+ type: string
+ updateTimestamp:
+ type: string
required: [spec]
# either Namespaced or Cluster
scope: Namespaced
diff --git a/tomcat/pom.xml b/tomcat/pom.xml
index 5f3069d..f6227b0 100644
--- a/tomcat/pom.xml
+++ b/tomcat/pom.xml
@@ -19,14 +19,14 @@
11
11
- 2.7.1
+ 3.
io.javaoperatorsdk
operator-framework
- 1.8.4
+ 1.9.2
org.apache.logging.log4j
diff --git a/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEvent.java b/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEvent.java
index a213cac..d8e9190 100644
--- a/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEvent.java
+++ b/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEvent.java
@@ -2,9 +2,9 @@
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.client.Watcher;
-import io.javaoperatorsdk.operator.processing.event.AbstractEvent;
+import io.javaoperatorsdk.operator.processing.event.DefaultEvent;
-public class DeploymentEvent extends AbstractEvent {
+public class DeploymentEvent extends DefaultEvent {
private final Watcher.Action action;
private final Deployment deployment;
diff --git a/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEventSource.java b/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEventSource.java
index 30d97e5..e25f2a8 100644
--- a/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEventSource.java
+++ b/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEventSource.java
@@ -3,6 +3,7 @@
import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getUID;
import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getVersion;
+import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.Watcher;
diff --git a/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java b/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java
index 6652d8e..b0916bb 100644
--- a/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java
+++ b/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java
@@ -1,7 +1,6 @@
package io.javaoperatorsdk.operator.sample;
-import io.fabric8.kubernetes.api.model.OwnerReference;
-import io.fabric8.kubernetes.api.model.Service;
+import io.fabric8.kubernetes.api.model.*;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.api.model.apps.DeploymentStatus;
import io.fabric8.kubernetes.client.KubernetesClient;
@@ -9,6 +8,7 @@
import io.fabric8.kubernetes.client.dsl.ServiceResource;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.javaoperatorsdk.operator.api.*;
+import io.javaoperatorsdk.operator.api.Context;
import io.javaoperatorsdk.operator.processing.event.EventSourceManager;
import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEvent;
import org.slf4j.Logger;
@@ -16,6 +16,7 @@
import java.io.IOException;
import java.io.InputStream;
+import java.util.ListIterator;
import java.util.Objects;
import java.util.Optional;
@@ -73,7 +74,7 @@ public DeleteControl deleteResource(Tomcat tomcat, Context context) {
private Tomcat updateTomcatStatus(Tomcat tomcat, Deployment deployment) {
DeploymentStatus deploymentStatus =
Objects.requireNonNullElse(deployment.getStatus(), new DeploymentStatus());
- int readyReplicas = Objects.requireNonNullElse(deploymentStatus.getReadyReplicas(), 0);
+ int readyReplicas = Objects.requireNonNullElse(deploymentStatus.getUpdatedReplicas(), 0);
TomcatStatus status = new TomcatStatus();
status.setReadyReplicas(readyReplicas);
tomcat.setStatus(status);
@@ -82,6 +83,27 @@ private Tomcat updateTomcatStatus(Tomcat tomcat, Deployment deployment) {
private void createOrUpdateDeployment(Tomcat tomcat) {
String ns = tomcat.getMetadata().getNamespace();
+
+ ConfigMap configMap = kubernetesClient
+ .configMaps().inNamespace(ns).withName(tomcat.getMetadata().getName()).get();
+
+ if(configMap == null){
+ // create it
+ configMap = loadYaml(ConfigMap.class, "configmap.yaml");
+ configMap.getMetadata().setName(tomcat.getMetadata().getName());
+ configMap.getMetadata().setNamespace(ns);
+ configMap.getMetadata().getLabels().put("app.kubernetes.io/part-of", tomcat.getMetadata().getName());
+ configMap.getMetadata().getLabels().put("app.kubernetes.io/managed-by", "tomcat-operator");
+ //
+ // I wonder if that's ok that this is resource is created by TomcatController and updated by webapps
+ OwnerReference ownerReference = configMap.getMetadata().getOwnerReferences().get(0);
+ ownerReference.setName(tomcat.getMetadata().getName());
+ ownerReference.setUid(tomcat.getMetadata().getUid());
+
+ log.info("Creating Init configmap {} in {}", configMap.getMetadata().getName(), ns);
+ kubernetesClient.configMaps().inNamespace(ns).create(configMap);
+ }
+
Deployment existingDeployment =
kubernetesClient
.apps()
@@ -96,14 +118,6 @@ private void createOrUpdateDeployment(Tomcat tomcat) {
deployment.getMetadata().getLabels().put("app.kubernetes.io/part-of", tomcat.getMetadata().getName());
deployment.getMetadata().getLabels().put("app.kubernetes.io/managed-by", "tomcat-operator");
// set tomcat version
- deployment
- .getSpec()
- .getTemplate()
- .getSpec()
- .getContainers()
- .get(0)
- .setImage("tomcat:" + tomcat.getSpec().getVersion());
- deployment.getSpec().setReplicas(tomcat.getSpec().getReplicas());
// make sure label selector matches label (which has to be matched by service selector too)
deployment
@@ -121,22 +135,38 @@ private void createOrUpdateDeployment(Tomcat tomcat) {
OwnerReference ownerReference = deployment.getMetadata().getOwnerReferences().get(0);
ownerReference.setName(tomcat.getMetadata().getName());
ownerReference.setUid(tomcat.getMetadata().getUid());
-
+ setTomcatDeploymentReplicats(tomcat, ns, deployment, configMap);
log.info("Creating or updating Deployment {} in {}", deployment.getMetadata().getName(), ns);
kubernetesClient.apps().deployments().inNamespace(ns).create(deployment);
} else {
- existingDeployment
- .getSpec()
- .getTemplate()
- .getSpec()
- .getContainers()
- .get(0)
- .setImage("tomcat:" + tomcat.getSpec().getVersion());
- existingDeployment.getSpec().setReplicas(tomcat.getSpec().getReplicas());
- kubernetesClient.apps().deployments().inNamespace(ns).createOrReplace(existingDeployment);
+ setTomcatDeploymentReplicats(tomcat, ns, existingDeployment, configMap);
}
}
+ private void setTomcatDeploymentReplicats(Tomcat tomcat, String ns, Deployment existingDeployment, ConfigMap conf) {
+ ListIterator volumeListIterator = existingDeployment
+ .getSpec()
+ .getTemplate()
+ .getSpec().getVolumes().listIterator();
+
+ while (volumeListIterator.hasNext()){
+ Volume volume = volumeListIterator.next();
+ if (volume.getName().equals("webapps-war-list")) {
+ volume.getConfigMap().setName(conf.getMetadata().getName());
+ }
+ }
+
+ existingDeployment
+ .getSpec()
+ .getTemplate()
+ .getSpec()
+ .getContainers()
+ .get(0)
+ .setImage("tomcat:" + tomcat.getSpec().getVersion());
+ existingDeployment.getSpec().setReplicas(tomcat.getSpec().getReplicas());
+ kubernetesClient.apps().deployments().inNamespace(ns).createOrReplace(existingDeployment);
+ }
+
private void deleteDeployment(Tomcat tomcat) {
log.info("Deleting Deployment {}", tomcat.getMetadata().getName());
RollableScalableResource deployment =
diff --git a/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WebappController.java b/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WebappController.java
index c94dbb8..c21fbf0 100644
--- a/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WebappController.java
+++ b/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WebappController.java
@@ -1,15 +1,18 @@
package io.javaoperatorsdk.operator.sample;
+import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.javaoperatorsdk.operator.api.*;
+import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
-import java.util.List;
-import java.util.Objects;
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
@Controller
public class WebappController implements ResourceController {
@@ -24,15 +27,86 @@ public WebappController(KubernetesClient kubernetesClient) {
@Override
public UpdateControl createOrUpdateResource(Webapp webapp, Context context) {
+ log.info("UpdateControl");
if (webapp.getStatus() != null && Objects.equals(webapp.getSpec().getUrl(), webapp.getStatus().getDeployedArtifact())) {
return UpdateControl.noUpdate();
}
+ if (webapp.getStatus() == null) {
+ webapp.setStatus(new WebappStatus());
+ }
+ log.info(MessageFormat.format("looking for configMap {0}", webapp.getSpec().getTomcat()));
+ ConfigMap configMap = kubernetesClient
+ .configMaps()
+ .inNamespace(webapp.getMetadata().getNamespace())
+ .withName(webapp.getSpec().getTomcat()).get();
- String[] command = new String[] {"wget", "-O", "/data/" + webapp.getSpec().getContextPath() + ".war", webapp.getSpec().getUrl()};
+ if (configMap ==null){
+ webapp.getStatus().setReady("False");
+ webapp.getStatus().setMessage(MessageFormat.format("configMap {0} does not exist", webapp.getSpec().getTomcat()));
+ webapp.getStatus().setUpdateTimestamp(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(new Date()));
- executeCommandInAllPods(kubernetesClient, webapp, command);
+ log.info(MessageFormat.format("configMap {0} is not ready yet", webapp.getSpec().getTomcat()));
+ return UpdateControl.noUpdate();//.updateStatusSubResource(webapp);
+ }
+
+ String warList = configMap.getData().get("war-list.txt");
+ String newWebapp = MessageFormat.format("{0}={1}", webapp.getSpec().getContextPath(), webapp.getSpec().getUrl());
+ String newWarList = "";
+
+ if(StringUtils.isNotBlank(webapp.getStatus().getDeployedArtifact()) &&
+ StringUtils.isNotBlank(webapp.getStatus().getDeployedContextPath()) ) {
+
+ String previousWebapp = MessageFormat.format("{0}={1}", webapp.getStatus().getDeployedContextPath(), webapp.getStatus().getDeployedArtifact());
+
+ log.info(MessageFormat.format("replace {0} with {1}", previousWebapp, newWebapp));
+ newWarList = warList.replace(previousWebapp, newWebapp);
+ }else{
+ StringBuilder sb = new StringBuilder();
+ newWarList = sb.append(newWebapp).append("\n").append(warList).toString();
+ }
+ configMap.getData().put("war-list.txt", newWarList);
+ kubernetesClient.configMaps()
+ .inNamespace(webapp.getMetadata().getNamespace())
+ .createOrReplace(configMap);
+
+ Deployment existingDeployment =
+ kubernetesClient
+ .apps()
+ .deployments()
+ .inNamespace(webapp.getMetadata().getNamespace())
+ .withName(webapp.getSpec().getTomcat())
+ .get();
+ if (existingDeployment == null) {
+ webapp.getStatus().setReady("False");
+ webapp.getStatus().setMessage(MessageFormat.format("Deployment {0} does not exist", webapp.getSpec().getTomcat()));
+ webapp.getStatus().setUpdateTimestamp(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(new Date()));
+ log.info(MessageFormat.format("Deployment {0} Deployment", webapp.getSpec().getTomcat()));
+ return UpdateControl.updateStatusSubResource(webapp);
+ }
+ if (existingDeployment.getSpec()
+ .getTemplate()
+ .getMetadata()
+ .getAnnotations() !=null) {
+ existingDeployment.getSpec()
+ .getTemplate()
+ .getMetadata()
+ .getAnnotations()
+ .put("tomcat-operator-updated", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(new Date()));
+ }else{
+ Map annotations = new HashMap<>();
+ annotations.put("tomcat-operator-updated", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(new Date()));
+ existingDeployment.getSpec()
+ .getTemplate()
+ .getMetadata()
+ .setAnnotations(annotations);
+ }
- //webapp.getStatus().setDeployedArtifact(webapp.getSpec().getUrl());
+ webapp.getStatus().setDeployedArtifact(webapp.getSpec().getUrl());
+ webapp.getStatus().setDeployedContextPath(webapp.getSpec().getContextPath());
+ webapp.getStatus().setReady("True");
+ webapp.getStatus().setMessage(MessageFormat.format("Deployment {0} Updated", webapp.getSpec().getTomcat()));
+ webapp.getStatus().setUpdateTimestamp(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(new Date()));
+ kubernetesClient.apps().deployments().inNamespace(webapp.getMetadata().getNamespace()).createOrReplace(existingDeployment);
return UpdateControl.updateStatusSubResource(webapp);
}
diff --git a/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WebappStatus.java b/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WebappStatus.java
index 53e71fe..10079bf 100644
--- a/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WebappStatus.java
+++ b/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WebappStatus.java
@@ -11,4 +11,28 @@ public String getDeployedArtifact() {
public void setDeployedArtifact(String deployedArtifact) {
this.deployedArtifact = deployedArtifact;
}
+
+ private String ready;
+
+ public String getReady() { return ready; }
+
+ public void setReady(String ready) { this.ready = ready; }
+
+ private String message;
+
+ public String getMessage() { return message; }
+
+ public void setMessage(String message) { this.message = message; }
+
+ private String updateTimestamp;
+
+ public String getUpdateTimestamp() { return updateTimestamp; }
+
+ public void setUpdateTimestamp(String updateTimestamp) { this.updateTimestamp = updateTimestamp; }
+
+ private String contextPath;
+
+ public void setDeployedContextPath(String contextPath) { this.contextPath = contextPath; }
+
+ public String getDeployedContextPath(){ return contextPath; }
}
diff --git a/tomcat/src/main/resources/io/javaoperatorsdk/operator/sample/configmap.yaml b/tomcat/src/main/resources/io/javaoperatorsdk/operator/sample/configmap.yaml
new file mode 100644
index 0000000..215b8fb
--- /dev/null
+++ b/tomcat/src/main/resources/io/javaoperatorsdk/operator/sample/configmap.yaml
@@ -0,0 +1,37 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: ""
+ labels:
+ app.kubernetes.io/part-of: ""
+ app.kubernetes.io/managed-by: "" # used for filtering of Deployments created by the controller
+ ownerReferences: # used for finding which Tomcat does this Deployment belong to
+ - apiVersion: apps/v1
+ kind: Tomcat
+ name: ""
+ uid: ""
+data:
+ CHECKSHA256: "false"
+ wgetscript.sh: |
+ #!/bin/sh
+ #
+ #
+ #
+ if [[ ! -f /etc/war-list/war-list.txt ]]; then
+ echo "war-list.txt is empty";
+ exit;
+ fi
+
+ for WAR in $(cat /etc/war-list/war-list.txt); do
+ CONTEXT=$(echo $WAR | cut -d '=' -f 1)
+ URL=$(echo ${WAR#"$CONTEXT="})
+ wget -O /data/$CONTEXT.war $URL
+ # todo add a sha256 validation
+ # if [[ CHECKSHA256 -eq "true" ]]
+ # wget -O /data/$CONTEXT.war.sha256 $URL.sha256
+ #
+ done
+
+ # the format is contextPath=url
+ war-list.txt: ""
+
diff --git a/tomcat/src/main/resources/io/javaoperatorsdk/operator/sample/deployment.yaml b/tomcat/src/main/resources/io/javaoperatorsdk/operator/sample/deployment.yaml
index 2f6f373..a205954 100644
--- a/tomcat/src/main/resources/io/javaoperatorsdk/operator/sample/deployment.yaml
+++ b/tomcat/src/main/resources/io/javaoperatorsdk/operator/sample/deployment.yaml
@@ -20,6 +20,15 @@ spec:
labels:
app: ""
spec:
+ initContainers:
+ - name: war-downloader
+ image: busybox:1.28
+ command: ['/bin/sh', '/etc/war-list/wgetscript.sh']
+ volumeMounts:
+ - name: webapps-volume
+ mountPath: /data
+ - name: webapps-war-list
+ mountPath: /etc/war-list
containers:
- name: tomcat
image: tomcat:8.0
@@ -28,12 +37,9 @@ spec:
volumeMounts:
- mountPath: /usr/local/tomcat/webapps
name: webapps-volume
- - name: war-downloader
- image: busybox:1.28
- command: ['tail', '-f', '/dev/null']
- volumeMounts:
- - name: webapps-volume
- mountPath: /data
volumes:
- name: webapps-volume
emptydir: {}
+ - name: webapps-war-list
+ configMap:
+ name: "blank"
diff --git a/tomcat/src/test/java/sample/IntegrationTest.java b/tomcat/src/test/java/sample/IntegrationTest.java
index 3af8cd0..28de84d 100644
--- a/tomcat/src/test/java/sample/IntegrationTest.java
+++ b/tomcat/src/test/java/sample/IntegrationTest.java
@@ -1,71 +1,126 @@
-package sample;
+package io.javaoperatorsdk.operator.sample;
-import io.fabric8.kubernetes.api.model.KubernetesResourceList;
-import io.fabric8.kubernetes.api.model.Namespace;
-import io.fabric8.kubernetes.api.model.NamespaceBuilder;
-import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
+import io.fabric8.kubernetes.api.model.*;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
-import io.fabric8.kubernetes.client.DefaultKubernetesClient;
-import io.fabric8.kubernetes.client.KubernetesClient;
-import io.fabric8.kubernetes.client.dsl.MixedOperation;
-import io.fabric8.kubernetes.client.dsl.Resource;
-import io.fabric8.kubernetes.client.utils.Serialization;
+import io.fabric8.kubernetes.client.*;
+import io.fabric8.kubernetes.client.extended.run.RunConfigBuilder;
import io.javaoperatorsdk.operator.Operator;
import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService;
-import io.javaoperatorsdk.operator.sample.Tomcat;
-import io.javaoperatorsdk.operator.sample.TomcatController;
-import io.javaoperatorsdk.operator.sample.WebappController;
+import org.junit.AfterClass;
import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
+import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.awaitility.Awaitility.await;
-import static org.junit.Assert.*;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
public class IntegrationTest {
+
+ final static String TEST_NS = "tomcat-test";
+
+ final static Logger log = LoggerFactory.getLogger(IntegrationTest.class);
+
@Test
- public void test() throws InterruptedException {
+ public void test() {
+ int replicas = 3; //3
Config config = new ConfigBuilder().withNamespace(null).build();
KubernetesClient client = new DefaultKubernetesClient(config);
- Operator operator = new Operator(client, DefaultConfigurationService.instance());
-
- TomcatController tomcatController = new TomcatController(client);
- operator.register(tomcatController);
+ Operator operator = new Operator(client, DefaultConfigurationService.instance());
+ operator.register(new TomcatController(client));
operator.register(new WebappController(client));
- Tomcat tomcat = loadYaml(Tomcat.class, "tomcat-sample1.yaml");
-
- tomcat.getSpec().setReplicas(3);
- tomcat.getMetadata().setNamespace("tomcat-test");
-
- MixedOperation, Resource> tomcatClient = client.customResources(Tomcat.class);
-
- Namespace tt_ns = new NamespaceBuilder().withMetadata(new ObjectMetaBuilder().withName("tomcat-test").build()).build();
+ Tomcat tomcat = new Tomcat();
+ tomcat.setMetadata(new ObjectMetaBuilder()
+ .withName("test-tomcat1")
+ .withNamespace(TEST_NS)
+ .build());
+ tomcat.setSpec(new TomcatSpec());
+ tomcat.getSpec().setReplicas(replicas);
+ tomcat.getSpec().setVersion(9);
+
+ Webapp webapp1 = new Webapp();
+ webapp1.setMetadata(new ObjectMetaBuilder()
+ .withName("test-webapp1")
+ .withNamespace(TEST_NS)
+ .build());
+ webapp1.setSpec(new WebappSpec());
+ webapp1.getSpec().setContextPath("webapp1");
+ webapp1.getSpec().setTomcat(tomcat.getMetadata().getName());
+ webapp1.getSpec().setUrl("http://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/sample.war");
+
+ var tomcatClient = client.customResources(Tomcat.class);
+ var webappClient = client.customResources(Webapp.class);
+
+ Namespace testNs = new NamespaceBuilder().withMetadata(
+ new ObjectMetaBuilder().withName(TEST_NS).build()).build();
+
+ if (testNs != null && client.namespaces().withName(TEST_NS).isReady() == true ) {
+ // We perform a pre-run cleanup instead of a post-run cleanup. This is to help with debugging test results
+ // when running against a persistent cluster. The test namespace would stay after the test run so we can
+ // check what's there, but it would be cleaned up during the next test run.
+ log.info("Cleanup: deleting test namespace {}", TEST_NS);
+ client.namespaces().delete(testNs);
+ await().atMost(5, MINUTES).until(() -> client.namespaces().withName("tomcat-test").get() == null);
+ }
- client.namespaces().delete(tt_ns);
+ log.info("Creating test namespace {}", TEST_NS);
+ client.namespaces().create(testNs);
- await().atMost(300, SECONDS).until(() -> client.namespaces().withName("tomcat-test").get() == null);
+ log.info("Creating test resources");
+ tomcatClient.inNamespace(TEST_NS).create(tomcat);
- client.namespaces().createOrReplace(tt_ns);
+ log.info("Waiting 2 minutes for Tomcat CR statuses to be updated");
+ await().atMost(2, MINUTES).untilAsserted(() -> {
+ Tomcat updatedTomcat = tomcatClient.inNamespace(TEST_NS).withName(tomcat.getMetadata().getName()).get();
+ assertThat(updatedTomcat.getStatus(), is(notNullValue()));
+ //assertThat(updatedTomcat.getStatus().getReadyReplicas(), equalTo(3));
+ });
- tomcatClient.inNamespace("tomcat-test").create(tomcat);
+ webappClient.inNamespace(TEST_NS).create(webapp1);
+ log.info("Waiting 2 minutes for Webapp CR statuses to be updated");
+ await().atMost(2, MINUTES).untilAsserted(() -> {
+ Webapp updatedWebapp = webappClient.inNamespace(TEST_NS).withName(webapp1.getMetadata().getName()).get();
+ assertThat(updatedWebapp.getStatus(), is(notNullValue()));
+ assertThat(updatedWebapp.getStatus().getDeployedArtifact(), is(notNullValue()));
+ Tomcat updatedTomcat = tomcatClient.inNamespace(TEST_NS).withName(tomcat.getMetadata().getName()).get();
+ assertThat(updatedTomcat.getStatus(), is(notNullValue()));
+ assertThat(updatedTomcat.getStatus().getReadyReplicas(), equalTo(replicas));
+ });
+ log.info("Waiting 60 seconds for Tomcat to unpack the downloaded war");
+ // this delays is du to allows the tomcat to unpack
+ // kubectl -n tomcat-test -c war-downloader logs -l app=test-tomcat1
+ // Deployment of web application archive [/usr/local/tomcat/webapps/webapp1.war] has finished in [xxx] ms
+ try {
+ Thread.sleep(60*1000);
+ } catch (InterruptedException e) {
+ log.warn(e.getMessage(),e);
+ }
- await().atMost(60, SECONDS).until(() -> {
- Tomcat updatedTomcat = tomcatClient.inNamespace("tomcat-test").withName("test-tomcat1").get();
- return updatedTomcat.getStatus() != null && (int) updatedTomcat.getStatus().getReadyReplicas() == 3;
+ String url = "http://" + tomcat.getMetadata().getName() + "/" + webapp1.getSpec().getContextPath() + "/";
+ log.info("Starting curl Pod and waiting 2 minutes for GET of {} to return 200", url);
+ Pod curlPod = client.run().inNamespace(TEST_NS)
+ .withRunConfig(new RunConfigBuilder()
+ .withArgs("-s", "-o", "/dev/null", "-w", "%{http_code}", url)
+ .withName("curl")
+ .withImage("curlimages/curl:7.78.0")
+ .withRestartPolicy("Never")
+ .build()).done();
+ await().atMost(2, MINUTES).untilAsserted(() -> {
+ try {
+ //let's do som tries
+ String curlOutput = client.pods().inNamespace(TEST_NS).withName(curlPod.getMetadata().getName()).getLog();
+ assertThat(curlOutput, equalTo("200"));
+ } catch (KubernetesClientException ex) {
+ throw new AssertionError(ex);
+ }
});
}
- private T loadYaml(Class clazz, String yaml) {
- try (InputStream is = new FileInputStream("k8s/" + yaml)) {
- return Serialization.unmarshal(is, clazz);
- } catch (IOException ex) {
- throw new IllegalStateException("Cannot find yaml on classpath: " + yaml);
- }
- }
-}
+}
\ No newline at end of file