This is an automated email from the ASF dual-hosted git repository.
fanningpj pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-pekko-samples.git
The following commit(s) were added to refs/heads/main by this push:
new 6da91d3 Issue 286: migrate cluster k8s java (#38)
6da91d3 is described below
commit 6da91d358253e577946474973d14a9ed41a8e0ea
Author: Sam Byng <[email protected]>
AuthorDate: Wed Apr 26 12:33:32 2023 +0100
Issue 286: migrate cluster k8s java (#38)
* Copy akka-sample-cluster-kubernetes-java from original repo
* Change dirname to pekko and add test to CI workflow
* #286: update k8s-java samples pom.xml
* Update app config
* Update cluster name to pekko-cluster.yml
* Update pekko-cluster k8s definition file
* Update src code
* Update docs to pekko. NOTE: akka-management docs references are not
present any more
* Update app files so that CI tests can run.
NOTE: CI tests failing: issue with delay in caller responses the same as
with docker
Exception in thread main java.lang.IllegalStateException: cannot enqueue
after timer shutdown
at
org.apache.pekko.actor.LightArrayRevolverScheduler.scheduleOnce(LightArrayRevolverScheduler.scala:165)
at org.apache.pekko.actor.Scheduler9anon.<init>(Scheduler.scala:88)
at
org.apache.pekko.actor.Scheduler.scheduleWithFixedDelay(Scheduler.scala:85)
at org.apache.pekko.actor.Scheduler.scheduleWithFixedDelay
at
org.apache.pekko.actor.LightArrayRevolverScheduler.scheduleWithFixedDelay(LightArrayRevolverScheduler.scala:109)
at
org.apache.pekko.cluster.ddata.protobuf.ReplicatorMessageSerializer.<init>(ReplicatorMessageSerializer.scala:175)
at
java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method)
at
java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown
Source)
at
java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown
Source)
at java.base/java.lang.reflect.Constructor.newInstance(Unknown
Source)
at
org.apache.pekko.actor.ReflectiveDynamicAccess.(ReflectiveDynamicAccess.scala:50)
at scala.util.Try$.apply(Try.scala:210)
at
org.apache.pekko.actor.ReflectiveDynamicAccess.createInstanceFor(ReflectiveDynamicAccess.scala:45)
at
org.apache.pekko.actor.ReflectiveDynamicAccess.(ReflectiveDynamicAccess.scala:58)
at scala.util.Success.flatMap(Try.scala:258)
at
org.apache.pekko.actor.ReflectiveDynamicAccess.createInstanceFor(ReflectiveDynamicAccess.scala:57)
at
org.apache.pekko.serialization.Serialization.serializerOf(Serialization.scala:403)
at
org.apache.pekko.serialization.Serialization.(Serialization.scala:437)
at scala.collection.Iterator9anon.next(Iterator.scala:584)
at
scala.collection.immutable.HashMapBuilder.addAll(HashMap.scala:2360)
at scala.collection.immutable.HashMap$.from(HashMap.scala:2182)
at scala.collection.immutable.HashMap$.from(HashMap.scala:2158)
at scala.collection.MapOps.map(Map.scala:381)
at
org.apache.pekko.serialization.Serialization.<init>(Serialization.scala:437)
at
org.apache.pekko.serialization.SerializationExtension$.createExtension(SerializationExtension.scala:28)
at
org.apache.pekko.serialization.SerializationExtension$.createExtension(SerializationExtension.scala:24)
at
org.apache.pekko.actor.ActorSystemImpl.registerExtension(ActorSystem.scala:1177)
at org.apache.pekko.actor.ActorSystemImpl.(ActorSystem.scala:1220)
at scala.collection.immutable.Vector.foreach(Vector.scala:1895)
at
org.apache.pekko.actor.ActorSystemImpl.loadExtensions(ActorSystem.scala:1214)
at
org.apache.pekko.actor.ActorSystemImpl.loadExtensions(ActorSystem.scala:1233)
at
org.apache.pekko.actor.ActorSystemImpl.liftedTree2(ActorSystem.scala:1054)
at
org.apache.pekko.actor.ActorSystemImpl._start(ActorSystem.scala:1041)
at
org.apache.pekko.actor.ActorSystemImpl._start(ActorSystem.scala:1040)
at
org.apache.pekko.actor.ActorSystemImpl.start(ActorSystem.scala:1064)
at
org.apache.pekko.actor.typed.ActorSystem$.createInternal(ActorSystem.scala:300)
at
org.apache.pekko.actor.typed.ActorSystem$.apply(ActorSystem.scala:208)
at
org.apache.pekko.actor.typed.ActorSystem$.create(ActorSystem.scala:245)
at
org.apache.pekko.actor.typed.ActorSystem.create(ActorSystem.scala)
at
org.apache.pekko.cluster.bootstrap.demo.DemoApp.main(DemoApp.java:70)
Caused by: org.apache.pekko.actor.SchedulerException: cannot enqueue after
timer shutdown
* Set http to a version that all http libraries present are using (due to
error message)
* Set kubernetes image name to match the directory name
* Issue 286: Set wait time to 6s since it can take 45s for k8s cluster pods
to return MemberUp
* Issue 286: Fix application.conf so that it uses full, unquoted package
paths
* Update package name to have -java suffix
* Update README
* Add cleanup to both kubernetes-java test scripts + k8s-scala desktop test
script
---------
Co-authored-by: sb5 <[email protected]>
---
.github/workflows/build-test.yml | 3 +
pekko-sample-cluster-kubernetes-java/README.md | 85 +++++++++++
.../kubernetes/namespace.json | 11 ++
.../kubernetes/pekko-cluster.yml | 82 +++++++++++
pekko-sample-cluster-kubernetes-java/pom.xml | 157 +++++++++++++++++++++
.../scripts/setup-minikube-for-linux.sh | 34 +++++
.../scripts/test.sh | 19 +--
.../scripts/test_docker_desktop.sh | 10 +-
.../java/pekko/cluster/bootstrap/demo/DemoApp.java | 73 ++++++++++
.../cluster/bootstrap/demo/DemoHealthCheck.java | 22 +++
.../src/main/resources/application.conf | 36 +++++
.../src/main/resources/logback.xml | 21 +++
.../scripts/test_docker_desktop.sh | 6 +-
13 files changed, 537 insertions(+), 22 deletions(-)
diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml
index 0fd0ca0..ad33cb6 100644
--- a/.github/workflows/build-test.yml
+++ b/.github/workflows/build-test.yml
@@ -79,6 +79,9 @@ jobs:
- name: Test pekko-sample-cluster-kubernetes-scala
run: cd pekko-sample-cluster-kubernetes-scala &&
./scripts/setup-minikube-for-linux.sh && ./scripts/test.sh
+
+ - name: Test pekko-sample-cluster-kubernetes-java
+ run: cd pekko-sample-cluster-kubernetes-java &&
./scripts/setup-minikube-for-linux.sh && ./scripts/test.sh
- name: Test docs gen
run: cd docs-gen && sbt paradox
diff --git a/pekko-sample-cluster-kubernetes-java/README.md
b/pekko-sample-cluster-kubernetes-java/README.md
new file mode 100644
index 0000000..478c9d0
--- /dev/null
+++ b/pekko-sample-cluster-kubernetes-java/README.md
@@ -0,0 +1,85 @@
+# pekko-sample-cluster-kubernetes-java
+
+This is an example Maven project showing how to create an Apache Pekko Cluster
on
+Kubernetes.
+
+It is not always necessary to use Apache Pekko Cluster when deploying an
Apache Pekko
+application to Kubernetes: if your application can be designed as independent
+stateless services that do not need coordination, deploying them on Kubernetes
+as individual Apache Pekko application without Apache Pekko Cluster can be a
good fit. When
+state or coordination between nodes is necessary, this is where the
+[Apache Pekko Cluster
features](https://pekko.apache.org/docs/pekko/current/typed/cluster.html)
+become interesting and it is worth consider making the nodes form an Apache
Pekko
+Cluster.
+
+## Kubernetes Instructions
+
+### Docker Desktop for Kubernetes
+For Windows and Mac users, may be handier to use a Kubernetes cluster on
[Docker-Desktop](https://www.docker.com/products/docker-desktop).
+If you use Kubernetes on Docker Desktop, after turning it on, you should first
issue:
+
+ export KUBECONFIG=~/.kube/config
+ kubectl config set-context docker-desktop
+
+A script that comprises all steps involved is
`scripts/test_docker_desktop.sh`. To run it, do:
+
+ cd pekko-sample-cluster-kubernetes-java
+ scripts/test_docker_desktop.sh
+
+### Minikube
+If you are using minikube for Kubernetes, please run the included scripts in
the `scripts` directory.
+
+
+## Starting
+
+First, package the application and make it available locally as a docker image:
+
+ mvn clean package docker:build
+
+Then `pekko-cluster.yml` should be sufficient to deploy a 2-node Apache Pekko
Cluster, after
+creating a namespace for it:
+
+ kubectl apply -f kubernetes/namespace.json
+ kubectl config set-context --current --namespace=appka-1
+ kubectl apply -f kubernetes/pekko-cluster.yml
+
+Finally, create a service so that you can then test
[http://127.0.0.1:8080](http://127.0.0.1:8080)
+for 'hello world':
+
+ kubectl expose deployment appka --type=LoadBalancer --name=appka-service
+
+You can inspect the Apache Pekko Cluster membership status with the [Cluster
HTTP
Management](https://pekko.apache.org/docs/pekko-management/current/cluster-http-management.html).
+
+ curl http://127.0.0.1:8558/cluster/members/
+
+To check what you have done in Kubernetes so far, you can do:
+
+ kubectl get deployments
+ kubectl get pods
+ kubectl get replicasets
+ kubectl cluster-info dump
+ kubectl logs appka-79c98cf745-abcdee # pod name
+
+To wipe everything clean and start over, do:
+
+ kubectl delete namespaces appka-1
+
+## Running in a real Kubernetes cluster
+
+#### Publish to a registry the cluster can access e.g. Dockerhub with the
kubpekko user
+
+The app image must be in a registry the cluster can see. The build.sbt uses
DockerHub by default.
+Use `mvn -Ddocker.registry=$DOCKER_REPO_URL/$NAMESPACE` if your cluster can't
access DockerHub.
+
+To push an image to docker hub run:
+
+ mvn -am -pl bootstrap-demo-kubernetes-api package docker:push
+
+And remove the `imagePullPolicy: Never` from the deployments. Then you can use
the same `kubectl` commands
+as described in the [Starting](#starting) section.
+
+## How it works
+
+This example uses [Apache Pekko Cluster
Bootstrap](https://pekko.apache.org/docs/pekko-management/current/bootstrap/index.html)
+to initialize the cluster, using the [Kubernetes API discovery
mechanism](https://pekko.apache.org/docs/pekko-management/current/discovery/index.html#discovery-method-kubernetes-api)
+to find peer nodes.
diff --git a/pekko-sample-cluster-kubernetes-java/kubernetes/namespace.json
b/pekko-sample-cluster-kubernetes-java/kubernetes/namespace.json
new file mode 100644
index 0000000..466d18c
--- /dev/null
+++ b/pekko-sample-cluster-kubernetes-java/kubernetes/namespace.json
@@ -0,0 +1,11 @@
+{
+ "kind": "Namespace",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "appka-1",
+ "labels": {
+ "name": "appka-1"
+ }
+ }
+}
+
diff --git a/pekko-sample-cluster-kubernetes-java/kubernetes/pekko-cluster.yml
b/pekko-sample-cluster-kubernetes-java/kubernetes/pekko-cluster.yml
new file mode 100644
index 0000000..4e4e1e4
--- /dev/null
+++ b/pekko-sample-cluster-kubernetes-java/kubernetes/pekko-cluster.yml
@@ -0,0 +1,82 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ app: appka
+ name: appka
+ namespace: appka-1
+spec:
+ replicas: 3
+ selector:
+ matchLabels:
+ app: appka
+ template:
+ metadata:
+ labels:
+ app: appka
+ actorSystemName: appka
+ spec:
+ containers:
+ - name: appka
+ image: pekko-sample-cluster-kubernetes-java:latest
+ # remove for real clusters, useful for minikube
+ imagePullPolicy: Never
+ readinessProbe:
+ httpGet:
+ path: /ready
+ port: management
+ periodSeconds: 10
+ failureThreshold: 3
+ initialDelaySeconds: 10
+ livenessProbe:
+ httpGet:
+ path: "/alive"
+ port: management
+ periodSeconds: 10
+ failureThreshold: 5
+ initialDelaySeconds: 20
+ ports:
+ # pekko remoting
+ - name: remoting
+ containerPort: 7355
+ protocol: TCP
+ # pekko-management and bootstrap
+ - name: management
+ containerPort: 8558
+ protocol: TCP
+ - name: http
+ containerPort: 8080
+ protocol: TCP
+ env:
+ - name: NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: REQUIRED_CONTACT_POINT_NR
+ value: "2"
+
+---
+kind: Role
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: pod-reader
+ namespace: appka-1
+rules:
+ - apiGroups: [""] # "" indicates the core API group
+ resources: ["pods"]
+ verbs: ["get", "watch", "list"]
+---
+kind: RoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: read-pods
+ namespace: appka-1
+subjects:
+ # Note the `name` line below. The first default refers to the namespace. The
second refers to the service account name.
+ # For instance, `name: system:serviceaccount:myns:default` would refer to
the default service account in namespace `myns`
+ - kind: User
+ name: system:serviceaccount:appka-1:default
+roleRef:
+ kind: Role
+ name: pod-reader
+ apiGroup: rbac.authorization.k8s.io
diff --git a/pekko-sample-cluster-kubernetes-java/pom.xml
b/pekko-sample-cluster-kubernetes-java/pom.xml
new file mode 100644
index 0000000..98c87e9
--- /dev/null
+++ b/pekko-sample-cluster-kubernetes-java/pom.xml
@@ -0,0 +1,157 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.pekko</groupId>
+ <artifactId>pekko-sample-cluster-kubernetes-java</artifactId>
+ <version>${version.number}</version>
+ <name>${project.artifactId}</name>
+ <description>Apache Pekko Sample for forming a Cluster in
Kubernetes</description>
+ <inceptionYear>2023</inceptionYear>
+ <licenses>
+ <license>
+ <name>Apache2.0</name>
+ <url>https://www.apache.org/licenses/LICENSE-2.0</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <properties>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ <encoding>UTF-8</encoding>
+ <pekko.version>0.0.0+26617-325e2156-SNAPSHOT</pekko.version>
+ <pekko-http.version>0.0.0+4334-7826b8b0-SNAPSHOT</pekko-http.version>
+
<pekko-management.version>0.0.0+710-b49055bd-SNAPSHOT</pekko-management.version>
+ <scala.binary.version>2.13</scala.binary.version>
+ <version.number>${git.commit.time}-${git.commit.id.abbrev}</version.number>
+ </properties>
+
+ <repositories>
+ <repository>
+ <id>apache-pekko-snapshots</id>
+ <name>Apache Snapshots Repository</name>
+ <url>https://repository.apache.org/content/repositories/snapshots/</url>
+ <layout>default</layout>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.pekko</groupId>
+ <artifactId>pekko-http_${scala.binary.version}</artifactId>
+ <version>${pekko-http.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.pekko</groupId>
+ <artifactId>pekko-http-spray-json_${scala.binary.version}</artifactId>
+ <version>${pekko-http.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.pekko</groupId>
+ <artifactId>pekko-cluster-typed_${scala.binary.version}</artifactId>
+ <version>${pekko.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.pekko</groupId>
+
<artifactId>pekko-cluster-sharding-typed_${scala.binary.version}</artifactId>
+ <version>${pekko.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.pekko</groupId>
+ <artifactId>pekko-slf4j_${scala.binary.version}</artifactId>
+ <version>${pekko.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.pekko</groupId>
+ <artifactId>pekko-stream-typed_${scala.binary.version}</artifactId>
+ <version>${pekko.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.pekko</groupId>
+ <artifactId>pekko-discovery_${scala.binary.version}</artifactId>
+ <version>${pekko.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.2.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.pekko</groupId>
+
<artifactId>pekko-management-cluster-bootstrap_${scala.binary.version}</artifactId>
+ <version>${pekko-management.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.pekko</groupId>
+
<artifactId>pekko-discovery-kubernetes-api_${scala.binary.version}</artifactId>
+ <version>${pekko-management.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.pekko</groupId>
+
<artifactId>pekko-management-cluster-http_${scala.binary.version}</artifactId>
+ <version>${pekko-management.version}</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>io.fabric8</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ <version>0.34.1</version>
+ <configuration>
+ <images>
+ <image>
+ <name>%a</name>
+ <build>
+ <tags>
+ <tag>${version.number}</tag>
+ <tag>latest</tag>
+ </tags>
+ <from>adoptopenjdk:11-jre-hotspot</from>
+ <ports>
+ <port>8080</port>
+ <port>8558</port>
+ </ports>
+ <entryPoint>
+ java $JAVA_OPTS -cp '/maven/*'
org.apache.pekko.cluster.bootstrap.demo.DemoApp
+ </entryPoint>
+ <assembly>
+ <descriptorRef>artifact-with-dependencies</descriptorRef>
+ </assembly>
+ </build>
+ </image>
+ </images>
+ </configuration>
+ <executions>
+ <execution>
+ <id>build-docker-image</id>
+ <phase>package</phase>
+ <goals>
+ <goal>build</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>pl.project13.maven</groupId>
+ <artifactId>git-commit-id-plugin</artifactId>
+ <version>4.0.0</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>revision</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <dateFormat>yyyyMMdd-HHmmss</dateFormat>
+ <dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
+ <generateGitPropertiesFile>false</generateGitPropertiesFile>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git
a/pekko-sample-cluster-kubernetes-java/scripts/setup-minikube-for-linux.sh
b/pekko-sample-cluster-kubernetes-java/scripts/setup-minikube-for-linux.sh
new file mode 100755
index 0000000..ede7eca
--- /dev/null
+++ b/pekko-sample-cluster-kubernetes-java/scripts/setup-minikube-for-linux.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+set -exu
+
+# MINIKUBE_VERSION="latest" --
https://github.com/kubernetes/minikube/issues/2704
+MINIKUBE_VERSION="latest"
+
+# From
https://github.com/kubernetes/minikube#linux-continuous-integration-without-vm-support
+curl -Lo minikube
https://storage.googleapis.com/minikube/releases/${MINIKUBE_VERSION}/minikube-linux-amd64
&& chmod +x minikube && sudo cp minikube /usr/local/bin/ && rm minikube
+curl -Lo kubectl
https://storage.googleapis.com/kubernetes-release/release/$(curl -s
https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
&& chmod +x kubectl && sudo cp kubectl /usr/local/bin/ && rm kubectl
+
+export MINIKUBE_WANTUPDATENOTIFICATION=false
+export MINIKUBE_WANTREPORTERRORPROMPT=false
+export MINIKUBE_HOME=$HOME
+export CHANGE_MINIKUBE_NONE_USER=true
+mkdir -p $HOME/.kube
+touch $HOME/.kube/config
+
+export KUBECONFIG=$HOME/.kube/config
+minikube start --driver=docker
+minikube addons enable ingress
+#sudo -E chmod a+r ~/.minikube/client.key
+
+# this for loop waits until kubectl can access the api server that Minikube
has created
+set +e
+for i in {1..150}; do # timeout for 5 minutes
+ kubectl get po &> /dev/null
+ if [ $? -ne 1 ]; then
+ break
+ fi
+ sleep 2
+done
+
+# kubectl commands are now able to interact with Minikube cluster
diff --git
a/pekko-sample-cluster-kubernetes-scala/scripts/test_docker_desktop.sh
b/pekko-sample-cluster-kubernetes-java/scripts/test.sh
similarity index 67%
copy from pekko-sample-cluster-kubernetes-scala/scripts/test_docker_desktop.sh
copy to pekko-sample-cluster-kubernetes-java/scripts/test.sh
index e75b735..82f0726 100755
--- a/pekko-sample-cluster-kubernetes-scala/scripts/test_docker_desktop.sh
+++ b/pekko-sample-cluster-kubernetes-java/scripts/test.sh
@@ -3,17 +3,12 @@
set -exu
clean_up () {
- echo "cleaning up test kubernetes instance and minikube container"
- kubectl delete -f kubernetes/namespace.json
- docker container kill minikube
- docker container rm minikube
+ echo "Cleaning up test kubernetes instance and minikube container"
+ minikube delete
}
eval $(minikube -p minikube docker-env)
-sbt docker:publishLocal
-
-export KUBECONFIG=~/.kube/config
-kubectl config set-context docker-desktop
+mvn clean package docker:build
kubectl apply -f kubernetes/namespace.json
kubectl config set-context --current --namespace=appka-1
@@ -24,7 +19,7 @@ for i in {1..10}
do
echo "Waiting for pods to get ready..."
kubectl get pods
- [ `kubectl get pods | grep Running | wc -l` -eq 2 ] && break
+ [ `kubectl get pods | grep Running | wc -l` -eq 3 ] && break
sleep 4
done
@@ -41,7 +36,7 @@ for i in {1..10}
do
echo "Checking for MemberUp logging..."
kubectl logs $POD | grep MemberUp || true
- [ `kubectl logs $POD | grep MemberUp | wc -l` -eq 2 ] && break
+ [ `kubectl logs $POD | grep MemberUp | wc -l` -eq 3 ] && break
sleep 6
done
@@ -57,10 +52,10 @@ done
if [ $i -eq 10 ]
then
- echo "No 2 MemberUp log events found"
+ echo "No 3 MemberUp log events found"
echo "=============================="
clean_up
exit -1
fi
-clean_up
+clean_up
\ No newline at end of file
diff --git
a/pekko-sample-cluster-kubernetes-scala/scripts/test_docker_desktop.sh
b/pekko-sample-cluster-kubernetes-java/scripts/test_docker_desktop.sh
similarity index 85%
copy from pekko-sample-cluster-kubernetes-scala/scripts/test_docker_desktop.sh
copy to pekko-sample-cluster-kubernetes-java/scripts/test_docker_desktop.sh
index e75b735..8e6d9b2 100755
--- a/pekko-sample-cluster-kubernetes-scala/scripts/test_docker_desktop.sh
+++ b/pekko-sample-cluster-kubernetes-java/scripts/test_docker_desktop.sh
@@ -3,14 +3,12 @@
set -exu
clean_up () {
- echo "cleaning up test kubernetes instance and minikube container"
- kubectl delete -f kubernetes/namespace.json
- docker container kill minikube
- docker container rm minikube
+ echo "Cleaning up test kubernetes instance and minikube container"
+ minikube delete
}
eval $(minikube -p minikube docker-env)
-sbt docker:publishLocal
+mvn clean package docker:build
export KUBECONFIG=~/.kube/config
kubectl config set-context docker-desktop
@@ -63,4 +61,4 @@ then
exit -1
fi
-clean_up
+clean_up
\ No newline at end of file
diff --git
a/pekko-sample-cluster-kubernetes-java/src/main/java/pekko/cluster/bootstrap/demo/DemoApp.java
b/pekko-sample-cluster-kubernetes-java/src/main/java/pekko/cluster/bootstrap/demo/DemoApp.java
new file mode 100644
index 0000000..2a4001f
--- /dev/null
+++
b/pekko-sample-cluster-kubernetes-java/src/main/java/pekko/cluster/bootstrap/demo/DemoApp.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017 Lightbend Inc. <http://www.lightbend.com>
+ */
+package org.apache.pekko.cluster.bootstrap.demo;
+
+import org.apache.pekko.actor.typed.ActorRef;
+import org.apache.pekko.actor.typed.ActorSystem;
+import org.apache.pekko.actor.typed.Behavior;
+import org.apache.pekko.actor.typed.javadsl.Adapter;
+import org.apache.pekko.actor.typed.javadsl.Behaviors;
+import org.apache.pekko.cluster.ClusterEvent;
+import org.apache.pekko.cluster.typed.Cluster;
+import org.apache.pekko.cluster.typed.Subscribe;
+import org.apache.pekko.http.javadsl.ConnectHttp;
+import org.apache.pekko.http.javadsl.Http;
+import static org.apache.pekko.http.javadsl.server.Directives.*;
+import org.apache.pekko.management.cluster.bootstrap.ClusterBootstrap;
+import org.apache.pekko.management.scaladsl.PekkoManagement;
+import org.apache.pekko.stream.Materializer;
+
+public class DemoApp {
+
+ static class MemberEventLogger {
+ public static Behavior<ClusterEvent.MemberEvent> create() {
+ return Behaviors.setup(context -> {
+ Cluster cluster = Cluster.get(context.getSystem());
+
+ context.getLog().info("Started [{}], cluster.selfAddress = {})",
+ context.getSystem(),
+ cluster.selfMember().address());
+
+ cluster.subscriptions().tell(new Subscribe<>(context.getSelf(),
ClusterEvent.MemberEvent.class));
+
+ return Behaviors.receiveMessage(event -> {
+ context.getLog().info("MemberEvent: {}", event);
+ return Behaviors.same();
+ });
+ });
+ }
+ }
+
+ static class Guardian {
+ public static Behavior<Void> create() {
+ return Behaviors.setup(context -> {
+ final org.apache.pekko.actor.ActorSystem classicSystem =
Adapter.toClassic(context.getSystem());
+ Materializer mat = Materializer.matFromSystem(classicSystem);
+
+ Http.get(classicSystem).bindAndHandle(complete("Hello world")
+ .flow(classicSystem, mat), ConnectHttp.toHost("0.0.0.0",
8080), mat)
+ .whenComplete((binding, failure) -> {
+ if (failure == null) {
+ classicSystem.log().info("HTTP server now listening at
port 8080");
+ } else {
+ classicSystem.log().error(failure, "Failed to bind HTTP
server, terminating.");
+ classicSystem.terminate();
+ }
+ });
+
+ context.spawn(MemberEventLogger.create(), "listener");
+
+ PekkoManagement.get(classicSystem).start();
+ ClusterBootstrap.get(classicSystem).start();
+
+ return Behaviors.empty();
+ });
+ }
+ }
+
+ public static void main(String[] args) {
+ ActorSystem.create(Guardian.create(), "Appka");
+ }
+
+}
\ No newline at end of file
diff --git
a/pekko-sample-cluster-kubernetes-java/src/main/java/pekko/cluster/bootstrap/demo/DemoHealthCheck.java
b/pekko-sample-cluster-kubernetes-java/src/main/java/pekko/cluster/bootstrap/demo/DemoHealthCheck.java
new file mode 100644
index 0000000..5bf707c
--- /dev/null
+++
b/pekko-sample-cluster-kubernetes-java/src/main/java/pekko/cluster/bootstrap/demo/DemoHealthCheck.java
@@ -0,0 +1,22 @@
+package org.apache.pekko.cluster.bootstrap.demo;
+
+import org.apache.pekko.actor.ActorSystem;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.function.Supplier;
+
+public class DemoHealthCheck implements Supplier<CompletionStage<Boolean>> {
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ public DemoHealthCheck(ActorSystem system) {
+ }
+
+ @Override
+ public CompletionStage<Boolean> get() {
+ log.info("DemoHealthCheck called");
+ return CompletableFuture.completedFuture(true);
+ }
+}
diff --git
a/pekko-sample-cluster-kubernetes-java/src/main/resources/application.conf
b/pekko-sample-cluster-kubernetes-java/src/main/resources/application.conf
new file mode 100644
index 0000000..69e0f56
--- /dev/null
+++ b/pekko-sample-cluster-kubernetes-java/src/main/resources/application.conf
@@ -0,0 +1,36 @@
+pekko {
+ loglevel = "DEBUG"
+ actor.provider = "cluster"
+
+ coordinated-shutdown.exit-jvm = on
+
+ cluster {
+ shutdown-after-unsuccessful-join-seed-nodes = 60s
+ downing-provider-class =
org.apache.pekko.cluster.sbr.SplitBrainResolverProvider
+ }
+}
+
+#management-config
+pekko.management {
+ cluster.bootstrap {
+ contact-point-discovery {
+ # For the kubernetes API this value is substributed into the %s in
pod-label-selector
+ service-name = "appka"
+
+ # pick the discovery method you'd like to use:
+ discovery-method = kubernetes-api
+
+ required-contact-point-nr = 2
+ required-contact-point-nr = ${?REQUIRED_CONTACT_POINT_NR}
+ }
+ }
+}
+#management-config
+
+pekko.management {
+ health-checks {
+ readiness-checks {
+ example-ready = org.apache.pekko.cluster.bootstrap.demo.DemoHealthCheck
+ }
+ }
+}
diff --git
a/pekko-sample-cluster-kubernetes-java/src/main/resources/logback.xml
b/pekko-sample-cluster-kubernetes-java/src/main/resources/logback.xml
new file mode 100644
index 0000000..058a3ff
--- /dev/null
+++ b/pekko-sample-cluster-kubernetes-java/src/main/resources/logback.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <target>System.out</target>
+ <encoder>
+ <pattern>[%date{ISO8601}] [%level] [%logger] [%marker] [%thread] -
%msg MDC: {%mdc}%n</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>8192</queueSize>
+ <neverBlock>true</neverBlock>
+ <appender-ref ref="CONSOLE" />
+ </appender>
+
+ <root level="INFO">
+ <appender-ref ref="ASYNC"/>
+ </root>
+
+</configuration>
diff --git
a/pekko-sample-cluster-kubernetes-scala/scripts/test_docker_desktop.sh
b/pekko-sample-cluster-kubernetes-scala/scripts/test_docker_desktop.sh
index e75b735..fa133e5 100755
--- a/pekko-sample-cluster-kubernetes-scala/scripts/test_docker_desktop.sh
+++ b/pekko-sample-cluster-kubernetes-scala/scripts/test_docker_desktop.sh
@@ -3,10 +3,8 @@
set -exu
clean_up () {
- echo "cleaning up test kubernetes instance and minikube container"
- kubectl delete -f kubernetes/namespace.json
- docker container kill minikube
- docker container rm minikube
+ echo "Cleaning up test kubernetes instance and minikube container"
+ minikube delete
}
eval $(minikube -p minikube docker-env)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]