This is an automated email from the ASF dual-hosted git repository.

marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git

commit ac306f7fb85e344078f4d4e5c448a4f044305732
Author: Marat Gubaidullin <marat.gubaidul...@gmail.com>
AuthorDate: Thu Jul 6 16:29:26 2023 -0400

    Infinispan and Karavan up and running #817
---
 karavan-bashi/pom.xml                              |  8 ++++
 .../apache/camel/karavan/bashi/HealthChecker.java  | 31 ++++++++++++++
 .../apache/camel/karavan/bashi/KaravanBashi.java   | 49 ++++++++++++++++++----
 .../camel/karavan/bashi/KaravanConstants.java      |  4 ++
 .../camel/karavan/bashi/KaravanContainers.java     | 33 +++++++++++++++
 .../karavan/bashi/docker/DockerEventListener.java  | 27 +++++++++++-
 .../camel/karavan/bashi/docker/DockerService.java  | 47 ++++++++++++++++-----
 .../src/main/resources/application.properties      |  6 +--
 8 files changed, 182 insertions(+), 23 deletions(-)

diff --git a/karavan-bashi/pom.xml b/karavan-bashi/pom.xml
index 3f4f0b6b..a5ae14d4 100644
--- a/karavan-bashi/pom.xml
+++ b/karavan-bashi/pom.xml
@@ -33,6 +33,14 @@
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-arc</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-scheduler</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-vertx</artifactId>
+        </dependency>
         <dependency>
             <groupId>com.github.docker-java</groupId>
             <artifactId>docker-java-core</artifactId>
diff --git 
a/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/HealthChecker.java 
b/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/HealthChecker.java
new file mode 100644
index 00000000..681fbf19
--- /dev/null
+++ 
b/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/HealthChecker.java
@@ -0,0 +1,31 @@
+package org.apache.camel.karavan.bashi;
+
+import com.github.dockerjava.api.model.Container;
+import io.quarkus.scheduler.Scheduled;
+import org.jboss.logging.Logger;
+
+import javax.enterprise.context.ApplicationScoped;
+import java.util.concurrent.ConcurrentHashMap;
+
+@ApplicationScoped
+public class HealthChecker {
+
+    private static final Logger LOGGER = 
Logger.getLogger(HealthChecker.class.getName());
+
+    private static final ConcurrentHashMap<String, Container> containers = new 
ConcurrentHashMap<>();
+
+//    @Scheduled(every = "{karavan.health-checker-interval}", 
concurrentExecution = Scheduled.ConcurrentExecution.SKIP)
+//    void collectHealthStatuses() {
+//        containers.forEach((s, s2) -> {
+//            LOGGER.infof("HealthCheck for %s", s);
+//        });
+//    }
+
+//    public void addContainer(Container container){
+//        containers.put(container.getId(), container);
+//    }
+//
+//    public void removeContainer(String id){
+//        containers.remove(id);
+//    }
+}
diff --git 
a/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanBashi.java 
b/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanBashi.java
index 1f21389b..3058c2a0 100644
--- 
a/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanBashi.java
+++ 
b/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanBashi.java
@@ -1,7 +1,9 @@
 package org.apache.camel.karavan.bashi;
 
+import com.github.dockerjava.api.model.HealthCheck;
 import io.quarkus.runtime.ShutdownEvent;
 import io.quarkus.runtime.StartupEvent;
+import io.quarkus.vertx.ConsumeEvent;
 import org.apache.camel.karavan.bashi.docker.DockerService;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
 import org.jboss.logging.Logger;
@@ -11,11 +13,24 @@ import javax.enterprise.event.Observes;
 import javax.inject.Inject;
 import java.util.List;
 
-import static 
org.apache.camel.karavan.bashi.KaravanConstants.INFINISPAN_CONTAINER_NAME;
+import static org.apache.camel.karavan.bashi.KaravanConstants.*;
 
 @ApplicationScoped
 public class KaravanBashi {
 
+    @ConfigProperty(name = "karavan.image")
+    String karavanImage;
+    @ConfigProperty(name = "karavan.port")
+    String karavanPort;
+    @ConfigProperty(name = "karavan.git-repository")
+    String gitRepository;
+    @ConfigProperty(name = "karavan.git-username")
+    String gitUsername;
+    @ConfigProperty(name = "karavan.git-password")
+    String gitPassword;
+    @ConfigProperty(name = "karavan.git-branch")
+    String gitBranch;
+
     @ConfigProperty(name = "infinispan.image")
     String infinispanImage;
     @ConfigProperty(name = "infinispan.port")
@@ -32,6 +47,7 @@ public class KaravanBashi {
 
     void onStart(@Observes StartupEvent ev) throws InterruptedException {
         LOGGER.info("Karavan Bashi is starting...");
+        dockerService.checkContainersStatus();
         dockerService.createNetwork();
         dockerService.startListeners();
         startInfinispan();
@@ -39,20 +55,35 @@ public class KaravanBashi {
 
     void startInfinispan() throws InterruptedException {
         LOGGER.info("Infinispan is starting...");
+
+        HealthCheck healthCheck = new HealthCheck().withTest(List.of("CMD", 
"curl", "-f", 
"http://localhost:11222/rest/v2/cache-managers/default/health/status";))
+                
.withInterval(10000000000L).withTimeout(10000000000L).withStartPeriod(10000000000L).withRetries(30);
+
         dockerService.createContainer(INFINISPAN_CONTAINER_NAME, 
infinispanImage,
-                List.of("USER=" + infinispanUsername, "PASS=" + 
infinispanPassword), infinispanPort, false
+                List.of("USER=" + infinispanUsername, "PASS=" + 
infinispanPassword),
+                infinispanPort, true, healthCheck
         );
         dockerService.startContainer(INFINISPAN_CONTAINER_NAME);
         LOGGER.info("Infinispan is started");
     }
 
-    void startKaravan() throws InterruptedException {
-        LOGGER.info("Karavan is starting...");
-        dockerService.createContainer(INFINISPAN_CONTAINER_NAME, 
infinispanImage,
-                List.of("USER=" + infinispanUsername, "PASS=" + 
infinispanPassword), infinispanPort, false
-        );
-        dockerService.startContainer(INFINISPAN_CONTAINER_NAME);
-        LOGGER.info("Karavan is started");
+    @ConsumeEvent(value = ADDRESS_INFINISPAN_HEALTH, blocking = true, ordered 
= false)
+    void startKaravan(String infinispanHealth) throws InterruptedException {
+        if (infinispanHealth.equals("healthy")) {
+            LOGGER.info("Karavan is starting...");
+            dockerService.createContainer(KARAVAN_CONTAINER_NAME, karavanImage,
+                    List.of(
+                            "QUARKUS_INFINISPAN_CLIENT_HOSTS=infinispan:11222",
+                            "KARAVAN_GIT_REPOSITORY=" + gitRepository,
+                            "KARAVAN_GIT_USERNAME=" + gitUsername,
+                            "KARAVAN_GIT_PASSWORD=" + gitPassword,
+                            "KARAVAN_GIT_BRANCH=" + gitBranch
+                    ),
+                    karavanPort, true, new HealthCheck()
+            );
+            dockerService.startContainer(KARAVAN_CONTAINER_NAME);
+            LOGGER.info("Karavan is started");
+        }
     }
 
     void onStop(@Observes ShutdownEvent ev) {
diff --git 
a/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanConstants.java
 
b/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanConstants.java
index eab76977..8e53e011 100644
--- 
a/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanConstants.java
+++ 
b/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanConstants.java
@@ -4,4 +4,8 @@ public class KaravanConstants {
 
     public static final String NETWORK_NAME = "karavan";
     public static final String INFINISPAN_CONTAINER_NAME = "infinispan";
+
+    public static final String KARAVAN_CONTAINER_NAME = "karavan";
+
+    public static final String ADDRESS_INFINISPAN_HEALTH = 
"ADDRESS_INFINISPAN_HEALTH";
 }
diff --git 
a/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanContainers.java
 
b/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanContainers.java
new file mode 100644
index 00000000..7fe14977
--- /dev/null
+++ 
b/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanContainers.java
@@ -0,0 +1,33 @@
+package org.apache.camel.karavan.bashi;
+
+import com.github.dockerjava.api.model.Container;
+import io.vertx.core.eventbus.EventBus;
+import org.jboss.logging.Logger;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static 
org.apache.camel.karavan.bashi.KaravanConstants.ADDRESS_INFINISPAN_HEALTH;
+
+@ApplicationScoped
+public class KaravanContainers {
+
+    private static final Logger LOGGER = 
Logger.getLogger(KaravanContainers.class.getName());
+
+    private static final ConcurrentHashMap<String, String> containers = new 
ConcurrentHashMap<>();
+
+    @Inject
+    EventBus eventBus;
+
+    public void addContainer(Container container, String health){
+        containers.put(container.getId(), health);
+        if (container.getNames()[0].equals("/infinispan")) {
+            eventBus.publish(ADDRESS_INFINISPAN_HEALTH, health);
+        }
+    }
+
+    public void removeContainer(String id){
+        containers.remove(id);
+    }
+}
diff --git 
a/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerEventListener.java
 
b/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerEventListener.java
index d0551ba7..9ea88796 100644
--- 
a/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerEventListener.java
+++ 
b/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerEventListener.java
@@ -1,16 +1,29 @@
 package org.apache.camel.karavan.bashi.docker;
 
 import com.github.dockerjava.api.async.ResultCallback;
+import com.github.dockerjava.api.model.Container;
 import com.github.dockerjava.api.model.Event;
+import com.github.dockerjava.api.model.EventType;
+import org.apache.camel.karavan.bashi.HealthChecker;
+import org.apache.camel.karavan.bashi.KaravanContainers;
 import org.jboss.logging.Logger;
 
 import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
 import java.io.Closeable;
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.Objects;
 
 @ApplicationScoped
 public class DockerEventListener implements ResultCallback<Event> {
 
+    @Inject
+    KaravanContainers karavanContainers;
+
+    @Inject
+    DockerService dockerService;
+
     private static final Logger LOGGER = 
Logger.getLogger(DockerEventListener.class.getName());
 
     @Override
@@ -20,7 +33,19 @@ public class DockerEventListener implements 
ResultCallback<Event> {
 
     @Override
     public void onNext(Event event) {
-        LOGGER.info(event.getType() + " : " + event.getStatus());
+//        LOGGER.info(event.getType() + " : " + event.getStatus());
+        if (Objects.equals(event.getType(), EventType.CONTAINER)){
+            Container c = dockerService.getContainer(event.getId());
+            if (Arrays.asList("stop", "die", "kill", "pause", 
"destroy").contains(event.getStatus())) {
+                karavanContainers.removeContainer(c.getId());
+            } else if (Arrays.asList("start", 
"unpause").contains(event.getStatus())) {
+                karavanContainers.addContainer(c, "unknown");
+            } else if (event.getStatus().startsWith("health_status:")) {
+                String health = event.getStatus().replace("health_status: ", 
"");
+                LOGGER.info(event.getType() + " : " + event.getId() + " : " + 
health);
+                karavanContainers.addContainer(c, health);
+            }
+        }
     }
 
     @Override
diff --git 
a/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerService.java
 
b/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerService.java
index e65af77f..89d54d74 100644
--- 
a/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerService.java
+++ 
b/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerService.java
@@ -4,12 +4,15 @@ import com.github.dockerjava.api.DockerClient;
 import com.github.dockerjava.api.async.ResultCallback;
 import com.github.dockerjava.api.command.CreateContainerResponse;
 import com.github.dockerjava.api.command.CreateNetworkResponse;
+import com.github.dockerjava.api.command.HealthState;
 import com.github.dockerjava.api.model.*;
 import com.github.dockerjava.core.DefaultDockerClientConfig;
 import com.github.dockerjava.core.DockerClientConfig;
 import com.github.dockerjava.core.DockerClientImpl;
 import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
 import com.github.dockerjava.transport.DockerHttpClient;
+import org.apache.camel.karavan.bashi.HealthChecker;
+import org.apache.camel.karavan.bashi.KaravanContainers;
 import org.jboss.logging.Logger;
 
 import javax.enterprise.context.ApplicationScoped;
@@ -18,6 +21,7 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 import static org.apache.camel.karavan.bashi.KaravanConstants.NETWORK_NAME;
 
@@ -29,6 +33,9 @@ public class DockerService {
     @Inject
     DockerEventListener dockerEventListener;
 
+    @Inject
+    KaravanContainers karavanContainers;
+
     public void startListeners() {
         getDockerClient().eventsCmd().exec(dockerEventListener);
     }
@@ -36,28 +43,45 @@ public class DockerService {
     public void createNetwork() {
         if (!getDockerClient().listNetworksCmd().exec().stream().filter(n -> 
n.getName().equals(NETWORK_NAME))
                 .findFirst().isPresent()) {
-            CreateNetworkResponse res = 
getDockerClient().createNetworkCmd().withName(NETWORK_NAME).exec();
+            CreateNetworkResponse res = 
getDockerClient().createNetworkCmd().withName(NETWORK_NAME).withAttachable(true).exec();
             LOGGER.info("Network created: {}" + res);
         } else {
             LOGGER.info("Network already exists with name: " + NETWORK_NAME);
         }
     }
 
-    public void createContainer(String name, String image, List<String> env, 
String ports, boolean hostNet) throws InterruptedException {
+    public void checkContainersStatus() {
+        getDockerClient().listContainersCmd().withShowAll(true).exec().stream()
+                .filter(c -> c.getState().equals("running"))
+                .forEach(c -> {
+                    HealthState hs = 
getDockerClient().inspectContainerCmd(c.getId()).exec().getState().getHealth();
+                    karavanContainers.addContainer(c, hs != null ? 
hs.getStatus() : "unknown");
+                });
+    }
+
+    public Container getContainer(String id) {
+        List<Container> containers = 
getDockerClient().listContainersCmd().withShowAll(true).withIdFilter(List.of(id)).exec();
+        return containers.get(0);
+    }
+
+    public void createContainer(String name, String image, List<String> env, 
String ports, boolean exposedPort, HealthCheck healthCheck) throws 
InterruptedException {
         List<Container> containers = 
getDockerClient().listContainersCmd().withShowAll(true).withNameFilter(List.of(name)).exec();
-        System.out.println(containers);
         if (containers.size() == 0) {
             pullImage(image);
 
+            List<ExposedPort> exposedPorts = 
getPortsFromString(ports).values().stream().map(i -> 
ExposedPort.tcp(i)).collect(Collectors.toList());
+
             CreateContainerResponse container = 
getDockerClient().createContainerCmd(image)
                     .withName(name)
                     .withEnv(env)
+                    .withExposedPorts(exposedPorts)
                     .withHostName(name)
-                    .withHostConfig(getHostConfig(ports, hostNet))
+                    .withHostConfig(getHostConfig(ports))
+                    .withHealthcheck(healthCheck)
                     .exec();
-            LOGGER.info("Container created: " + container.toString());
+            LOGGER.info("Container created: " + container.getId());
         } else {
-            LOGGER.info("Container already exists: " + 
containers.get(0).toString());
+            LOGGER.info("Container already exists: " + 
containers.get(0).getId());
         }
     }
 
@@ -87,17 +111,20 @@ public class DockerService {
     }
 
     public void pullImage(String image) throws InterruptedException {
-        ResultCallback.Adapter<PullResponseItem>  pull = 
getDockerClient().pullImageCmd(image).start().awaitCompletion();
+        List<Image> images = 
getDockerClient().listImagesCmd().withShowAll(true).exec();
+        if (!images.stream().filter(i -> 
Arrays.asList(i.getRepoTags()).contains(image)).findFirst().isPresent()) {
+            ResultCallback.Adapter<PullResponseItem>  pull = 
getDockerClient().pullImageCmd(image).start().awaitCompletion();
+        }
     }
 
-    private HostConfig getHostConfig(String ports, boolean hostNet) {
+    private HostConfig getHostConfig(String ports) {
         Ports portBindings = new Ports();
         getPortsFromString(ports).forEach((hostPort, containerPort) -> {
-            portBindings.bind(ExposedPort.tcp(containerPort), 
Ports.Binding.bindPort(hostPort));
+            portBindings.bind(ExposedPort.tcp(containerPort), 
Ports.Binding.bindIp("0.0.0.0").bindPort(hostPort));
         });
         return new HostConfig()
                 .withPortBindings(portBindings)
-                .withNetworkMode(hostNet ? "host" : NETWORK_NAME);
+                .withNetworkMode(NETWORK_NAME);
     }
 
     private Map<Integer,Integer> getPortsFromString(String ports){
diff --git a/karavan-bashi/src/main/resources/application.properties 
b/karavan-bashi/src/main/resources/application.properties
index d9eb55bb..8649065e 100644
--- a/karavan-bashi/src/main/resources/application.properties
+++ b/karavan-bashi/src/main/resources/application.properties
@@ -1,10 +1,10 @@
-infinispan.image=quay.io/infinispan/server:14.0
+infinispan.image=quay.io/infinispan/server:14.0.6.Final
 infinispan.port=11222:11222
 infinispan.username=admin
 infinispan.password=karavan
 
-karavan.image=ghcr.io/apache/camel-karavan
-
+karavan.image=marat/karavan:3.21.1-SNAPSHOT
+karavan.port=8080:8080
 karavan.environment=dev
 karavan.default-runtime=quarkus
 karavan.runtimes=quarkus,spring-boot

Reply via email to