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]

Reply via email to