8000 merge · java-operator-sdk/samples@6f2e0fa · GitHub
[go: up one dir, main page]

Skip to content
< 10000 script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_remote-form_dist_index_js-node_modules_delegated-events_dist_inde-94fd67-b0625c39513c.js" defer="defer">
This repository was archived by the owner on Jan 4, 2022. It is now read-only.

Commit 6f2e0fa

Browse files
merge
2 parents 6315926 + a860b2c commit 6f2e0fa

File tree

14 files changed

+301
-135
lines changed

14 files changed

+301
-135
lines changed

.github/workflows/TomcatIntegrationTest.yml

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,6 @@ jobs:
99
steps:
1010
- name: Checkout
1111
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
2112

2213
- name: Create kind cluster
2314
uses: helm/kind-action@v1.2.0
@@ -30,7 +21,6 @@ jobs:
3021
- name: Set up Java and Maven
3122
uses: actions/setup-java@v2
3223
with:
33-
# java-version: ${{ matrix.java }}
3424
java-version: 15
3525
distribution: adopt-hotspot
3626

@@ -41,7 +31,7 @@ jobs:
4131
path: ~/.m2/repository
4232
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
4333
restore-keys: |
44-
${{ runner.os }}-maven-
34+
${{ runner.os }}-maven-m2
4535
4636
- name: Set up Maven
4737
uses: stCarolas/setup-maven@v4
@@ -66,10 +56,6 @@ jobs:
6656
uses: azure/setup-helm@v1
6757
with:
6858
version: v3.4.0
69-
70-
- uses: actions/setup-python@v2
71-
with:
72-
python-version: 3.7
7359

7460
- name: test
7561
if: ${{ env.ACT }}
@@ -128,7 +114,10 @@ jobs:
128114
fi
129115
130116
- name: build jib
131-
run: mvn -B install jib:dockerBuild jib:build -Djib.allowInsecureRegistries=true -Djib.to.image=$KIND_REGISTRY/io.javaoperatorsdk/sample:1.7.1-SNAPSHOT --file tomcat/pom.xml -DskipTests
117+< 10000 /span>
run: |
118+
mvn -B install jib:dockerBuild jib:build -Djib.allowInsecureRegistries=true \
119+
-Djib.to.image=$KIND_REGISTRY/io.javaoperatorsdk/sample:1.7.1-SNAPSHOT \
120+
--file tomcat/pom.xml -DskipTests
132121
133122
- name: Apply CRDs
134123
run: kubectl apply -f tomcat/k8s/crd.yaml

tomcat/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
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 {}

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

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import io.fabric8.kubernetes.api.model.apps.Deployment;
55
import io.fabric8.kubernetes.client.KubernetesClient;
66
import io.javaoperatorsdk.operator.api.*;
7+
import io.javaoperatorsdk.operator.processing.event.EventSourceManager;
78
import org.slf4j.Logger;
89
import org.slf4j.LoggerFactory;
910

@@ -22,25 +23,53 @@ public WebappController(KubernetesClient kubernetesClient) {
2223
this.kubernetesClient = kubernetesClient;
2324
}
2425

26+
@Override
27+
public void init(EventSourceManager eventSourceManager) {
28+
TomcatEventSource tomcatEventSource = TomcatEventSource.createAndRegisterWatch(kubernetesClient);
29+
eventSourceManager.registerEventSource("tomcat-event-source", tomcatEventSource);
30+
}
31+
32+
/**
33+
* This method will be called not only on changes to Webapp objects but also when Tomcat objects change.
34+
*/
2535
@Override
2636
public UpdateControl<Webapp> createOrUpdateResource(Webapp webapp, Context<Webapp> context) {
2737
if (webapp.getStatus() != null && Objects.equals(webapp.getSpec().getUrl(), webapp.getStatus().getDeployedArtifact())) {
2838
return UpdateControl.noUpdate();
2939
}
3040

31-
String[] command = new String[] {"wget", "-O", "/data/" + webapp.getSpec().getContextPath() + ".war", webapp.getSpec().getUrl()};
41+
var tomcatClient = kubernetesClient.customResources(Tomcat.class);
42+
Tomcat tomcat = tomcatClient.inNamespace(webapp.getMetadata().getNamespace()).withName(webapp.getSpec().getTomcat()).get();
43+
if (tomcat == null) {
44+
throw new IllegalStateException("Cannot find Tomcat " + webapp.getSpec().getTomcat() + " for Webapp " + webapp.getMetadata().getName() + " in namespace " + webapp.getMetadata().getNamespace());
45+
}
3246

33-
executeCommandInAllPods(kubernetesClient, webapp, command);
47+
if (tomcat.getStatus() != null && Objects.equals(tomcat.getSpec().getReplicas(), tomcat.getStatus().getReadyReplicas())) {
48+
log.info("Tomcat is ready and webapps not yet deployed. Commencing deployment of {} in Tomcat {}", webapp.getMetadata().getName(), tomcat.getMetadata().getName());
49+
String[] command = new String[]{"wget", "-O", "/data/" + webapp.getSpec().getContextPath() + ".war", webapp.getSpec().getUrl()};
3450

35-
//webapp.getStatus().setDeployedArtifact(webapp.getSpec().getUrl());
36-
return UpdateControl.updateStatusSubResource(webapp);
51+
executeCommandInAllPods(kubernetesClient, webapp, command);
52+
53+
if (webapp.getStatus() == null) {
54+
webapp.setStatus(new WebappStatus());
55+
}
56+
webapp.getStatus().setDeployedArtifact(webapp.getSpec().getUrl());
57+
return UpdateControl.updateStatusSubResource(webapp);
58+
} else {
59+
log.info("WebappController invoked but Tomcat not ready yet ({}/{})", tomcat.getSpec().getReplicas(),
60+
tomcat.getStatus() != null ? tomcat.getStatus().getReadyReplicas() : 0);
61+
return UpdateControl.noUpdate();
62+
}
3763
}
3864

3965
@Override
4066
public DeleteControl deleteResource(Webapp webapp, Context<Webapp> context) {
4167

4268
String[] command = new String[] {"rm", "/data/" + webapp.getSpec().getContextPath() + ".war"};
4369
executeCommandInAllPods(kubernetesClient, webapp, command);
70+
if (webapp.getStatus() != null) {
71+
webapp.getStatus().setDeployedArtifact(null);
72+
}
4473
return DeleteControl.DEFAULT_DELETE;
4574
}
4675

0 commit comments

Comments
 (0)
0