8000 Merge pull request #13 from java-operator-sdk/finalize-tomcat-test · java-operator-sdk/samples@ad32eb0 · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Jan 4, 2022. It is now read-only.

Commit ad32eb0

Browse files
authored
Merge pull request #13 from java-operator-sdk/finalize-tomcat-test
End to end tests for Tomcat operator
2 parents 17a18d7 + 6686a6f commit ad32eb0

File tree

19 files changed

+496
-146
lines changed

19 files changed

+496
-146
lines changed
Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# End to end integration test which deploys the Tomcat operator to a Kubernetes
2+
# (Kind) cluster and creates custom resources to verify the operator's functionality
13
name: Tomcat integration test
24
on:
35
push:
@@ -6,35 +8,72 @@ on:
68
jobs:
79
tomcat_integration_test:
810
runs-on: ubuntu-latest
11+
env:
12+
KIND_CL_NAME: tomcat-integration-test
913
steps:
1014
- name: Checkout
1115
uses: actions/checkout@v2
12-
13-
- name: Set up Helm
14-
uses: azure/setup-helm@v1
15-
with:
16-
version: v3.4.0
17-
18-
- uses: actions/setup-python@v2
19-
with:
20-
python-version: 3.7
2116

22-
- name: Create kind cluster
23-
uses: helm/kind-action@v1.2.0
17+
- name: clean resident local docker
18+
if: ${{ env.ACT }}
19+
continue-on-error: true
20+
run: |
21+
for DIMG in "$KIND_CL_NAME-control-plane "; do
22+
docker stop $DIMG ; docker rm $DIMG ;
23+
done ;
24+
sleep 1
25+
26+
- name: Create Kubernetes KinD Cluster
27+
uses: container-tools/kind-action@v1.5.0
28+
with:
29+
cluster_name: tomcat-integration-test
30+
registry: false
2431

2532
- name: Apply CRDs
2633
run: kubectl apply -f tomcat/k8s/crd.yaml
2734

2835
- name: Set up Java and Maven
29-
uses: actions/setup-java@v1
36+
uses: actions/setup-java@v2
3037
with:
31-
# java-version: ${{ matrix.java }}
3238
java-version: 15
33-
- uses: actions/cache@v2
39+
distribution: adopt-hotspot
40+
41+
- name: cache
42+
uses: actions/cache@v2
43+
if: ${{ !env.ACT }}
3444
with:
3545
path: ~/.m2/repository
3646
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
3747
restore-keys: |
38-
${{ runner.os }}-maven-
48+
${{ runner.os }}-maven-m2
49+
50+
- name: Set up Maven
51+
uses: stCarolas/setup-maven@v4
52+
if: ${{ env.ACT }}
53+
with:
54+
maven-version: 3.8.1
55+
56+
- name: build jib
57+
run: |
58+
mvn --version
59+
mvn -B package jib:dockerBuild jib:buildTar -Djib-maven-image=tomcat-operator --file tomcat/pom.xml -DskipTests
60+
kind load image-archive tomcat/target/jib-image.tar --name=${{ env.KIND_CL_NAME }}
61+
62+
- name: Apply CRDs
63+
run: kubectl apply -f tomcat/k8s/crd.yaml
64+
65+
- name: install tomcat operator
66+
run: |
67+
kubectl apply -f tomcat/k8s/operator.yaml
68+
69+
- name: create ns tomcatoperator-sample
70+
run: kubectl create ns tomcatoperator-sample
71+
3972
- name: Run unit tests
40-
run: mvn -B test --file tomcat/pom.xml
73+
run: mvn -B test -q --file tomcat/pom.xml
74+
75+
- name: Dump state
76+
if: ${{ failure() }}
77+
run: |
78+
kubectl get all -n tomcat-test -o yaml
79+
kubectl logs curl -n tomcat-test

tomcat/k8s/crd.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ spec:
8080
properties:
8181
deployedArtifact:
8282
type: string
83+
deploymentStatus:
84+
type: array
85+
items:
86+
type: string
8387
required: [spec]
8488
# either Namespaced or Cluster
8589
scope: Namespaced

tomcat/k8s/operator.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,27 @@ metadata:
6565
rules:
6666
- apiGroups:
6767
- ""
68+
- "extensions"
69+
- "apps"
6870
resources:
6971
- deployments
7072
- services
73+
- pods
74+
- pods/exec
7175
verbs:
7276
- '*'
77+
- apiGroups:
78+
- "apiextensions.k8s.io"
79+
resources:
80+
- customresourcedefinitions
81+
verbs:
82+
- '*'
83+
- apiGroups:
84+
- "tomcatoperator.io"
85+
resources:
86+
- tomcats
87+
- tomcats/status
88+
- webapps
89+
- webapps/status
90+
verbs:
91+
- '*'

tomcat/k8s/webapp-sample2.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ metadata:
55
spec:
66
tomcat: test-tomcat2
77
url: charlottemach.com/assets/jax.war
8-
contextPath: mysample
8+
contextPath: othercontext

tomcat/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
<properties>
2020
<maven.compiler.source>11</maven.compiler.source>
2121
<maven.compiler.target>11</maven.compiler.target>
22-
<jib-maven-plugin.version>2.7.1</jib-maven-plugin.version>
22+
<jib-maven-plugin.version>3.1.4</jib-maven-plugin.version>
2323
</properties>
2424

2525
<dependencies>
2626
<dependency>
2727
<groupId>io.javaoperatorsdk</groupId>
2828
<artifactId>operator-framework</artifactId>
29-
<version>1.8.4</version>
29+
<version>1.9.2</version>
3030
</dependency>
3131
<dependency>
3232
<groupId>org.apache.logging.log4j</groupId>

tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEvent.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
import io.fabric8.kubernetes.api.model.apps.Deployment;
44
import io.fabric8.kubernetes.client.Watcher;
5-
import io.javaoperatorsdk.operator.processing.event.AbstractEvent;
5+
import io.javaoperatorsdk.operator.processing.event.DefaultEvent;
66

7-
public class DeploymentEvent extends AbstractEvent {
7+
public class DeploymentEvent extends DefaultEvent {
88

99
private final Watcher.Action action;
1010
private final Deployment deployment;

tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEventSource.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
import org.slf4j.Logger;
1212
import org.slf4j.LoggerFactory;
1313

14+
/**
15+
* Used by the TomcatController to watch changes on Deployment objects. As the Pods of the Deployment start up
16+
* the TomcatController updates the status.readyReplicas field.
17+
*/
1418
public class DeploymentEventSource extends AbstractEventSource implements Watcher<Deployment> {
1519
private static final Logger log = LoggerFactory.getLogger(DeploymentEventSource.class);
1620

tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
import java.util.Objects;
2020
import java.util.Optional;
2121

22+
/**
23+
* Runs a specified number of Tomcat app server Pods. It uses a Deployment to create the Pods. Also creates a
24+
* Service over which the Pods can be accessed.
25+
*/
2226
@Controller
2327
public class TomcatController implements ResourceController<Tomcat> {
2428

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package io.javaoperatorsdk.operator.sample;
2+
3+
import io.fabric8.kubernetes.client.Watcher;
4+
import io.javaoperatorsdk.operator.processing.event.DefaultEvent;
5+
6+
public class TomcatEvent extends DefaultEvent {
7+
8+
private final Watcher.Action action;
9+
private final Tomcat tomcat;
10+
11+
public TomcatEvent(
12+
Watcher.Action action, Tomcat resource, TomcatEventSource tomcatEventSource, String webappUid) {
13+
super(webappUid, tomcatEventSource);
14+
this.action = action;
15+
this.tomcat = resource;
16+
}
17+
18+
public Watcher.Action getAction() {
19+
return action;
20+
}
21+
22+
public String resourceUid() {
23+
return getTomcat().getMetadata().getUid();
24+
}
25+
26+
@Override
27+
public String toString() {
28+
return "CustomResourceEvent{"
29+
+ "action="
30+
+ action
31+
+ ", resource=[ name="
32+
+ getTomcat().getMetadata().getName()
33+
+ ", kind="
34+
+ getTomcat().getKind()
35+
+ ", apiVersion="
36+
+ getTomcat().getApiVersion()
37+
+ " ,resourceVersion="
38+
+ getTomcat().getMetadata().getResourceVersion()
39+
+ ", markedForDeletion: "
40+
+ (getTomcat().getMetadata().getDeletionTimestamp() != null
41+
&& !getTomcat().getMetadata().getDeletionTimestamp().isEmpty())
42+
+ " ]"
43+
+ '}';
44+
}
45+
46+
public Tomcat getTomcat() {
47+
return tomcat;
48+
}
49+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package io.javaoperatorsdk.operator.sample;
2+
3+
import io.fabric8.kubernetes.client.KubernetesClient;
4+
import io.fabric8.kubernetes.client.Watcher;
5+
import io.fabric8.kubernetes.client.WatcherException;
6+
import io.javaoperatorsdk.operator.processing.event.AbstractEventSource;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
10+
import java.util.Optional;
11+
12+
import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getUID;
13+
import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getVersion;
14+
15+
/**
16+
* Used by the WebappController to watch changes on Tomcat objects
17+
*/
18+
public class TomcatEventSource extends AbstractEventSource implements Watcher<Tomcat> {
19+
private static final Logger log = LoggerFactory.getLogger(TomcatEventSource.class);
20+
21+
private final KubernetesClient client;
22+
23+
public static TomcatEventSource createAndRegisterWatch(KubernetesClient client) {
24+
TomcatEventSource tomcatEventSource = new TomcatEventSource(client);
25+
tomcatEventSource.registerWatch();
26+
return tomcatEventSource;
27+
}
28+
29+
private TomcatEventSource(KubernetesClient client) {
30+
this.client = client;
31+
}
32+
33+
private void registerWatch() {
34+
var tomcatClient = client.customResources(Tomcat.class);
35+
tomcatClient.inAnyNamespace().watch(this);
36+
}
37+
38+
@Override
39+
public void eventReceived(Action action, Tomcat tomcat) {
40+
log.info("Event received for action: {}, Tomcat: {}", action.name(), tomcat.getMetadata().getName());
41+
42+
if (action == Action.ERROR) {
43+
log.warn(
44+
"Skipping {} event for custom resource uid: {}, version: {}",
45+
action,
46+
getUID(tomcat),
47+
getVersion(tomcat));
48+
return;
49+
}
50+
51+
var webappClient = client.customResources(Webapp.class);
52+
Optional<Webapp> webapp = webappClient.inNamespace(tomcat.getMetadata().getNamespace())
53+
.list().getItems().stream()
54+
.filter(wapp -> wapp.getSpec().getTomcat().equals(tomcat.getMetadata().getName()))
55+
.findFirst();
56+
57+
if (webapp.isPresent()) {
58+
eventHandler.handleEvent(new TomcatEvent(action, tomcat, this,
59+
webapp.get().getMetadata().getUid()));
60+
} else {
61+
log.debug("Webapp not found for Tomcat {}", tomcat.getMetadata().getName());
62+
}
63+
}
64+
65+
@Override
66+
public void onClose(WatcherException e) {
67+
if (e == null) {
68+
return;
69+
}
70+
if (e.isHttpGone()) {
71+
log.warn("Received error for watch, will try to reconnect.", e);
72+
registerWatch();
73+
} else {
74+
// Note that this should not happen normally, since fabric8 client handles reconnect.
75+
// In case it tries to reconnect this method is not called.
76+
log.error("Unexpected error happened with watch. Will exit.", e);
77+
System.exit(1);
78+
}
79+
}
80+
}

tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WatchedResource.java

Lines changed: 0 additions & 40 deletions
This file was deleted.

tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import io.fabric8.kubernetes.model.annotation.Group;
66
import io.fabric8.kubernetes.model.annotation.Version;
77

8+
/**
9+
* Represents a web application deployed in a Tomcat deployment
10+
*/
811
@Group("tomcatoperator.io")
912
@Version("v1")
1013
public class Webapp extends CustomResource<WebappSpec, WebappStatus> implements Namespaced {}

0 commit comments

Comments
 (0)
0