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 f4db398c1a3ff5fd4006c0697c77b9f4c709d788 Author: Marat Gubaidullin <marat.gubaidul...@gmail.com> AuthorDate: Thu Jul 13 11:43:11 2023 -0400 Hot reload In docker #817 --- .../apache/camel/karavan/api/DevModeResource.java | 11 +++----- .../camel/karavan/handler/PodEventHandler.java | 2 +- .../karavan/listener/DevModeCommandListener.java | 2 +- .../karavan/listener/DevModeStatusListener.java | 29 ++++++++++++++++++++++ .../{CamelStatusService.java => CamelService.java} | 11 ++++---- .../camel/karavan/bashi/ConductorService.java | 14 +++++------ .../karavan/bashi/docker/DockerEventListener.java | 11 +++++++- .../camel/karavan/bashi/docker/DockerService.java | 7 ++++-- .../camel/karavan/datagrid/DatagridService.java | 20 +++++++++------ ...erListener.java => DevModeCommandListener.java} | 4 +-- ...nerListener.java => DevModeStatusListener.java} | 8 +++--- 11 files changed, 80 insertions(+), 39 deletions(-) diff --git a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/api/DevModeResource.java b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/api/DevModeResource.java index 3cdef756..f56ad4d3 100644 --- a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/api/DevModeResource.java +++ b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/api/DevModeResource.java @@ -18,7 +18,7 @@ package org.apache.camel.karavan.api; import org.apache.camel.karavan.datagrid.DatagridService; import org.apache.camel.karavan.datagrid.model.*; -import org.apache.camel.karavan.service.CamelStatusService; +import org.apache.camel.karavan.service.CamelService; import org.eclipse.microprofile.config.inject.ConfigProperty; import javax.inject.Inject; @@ -34,7 +34,7 @@ import javax.ws.rs.core.Response; import java.time.Instant; import java.util.Optional; -import static org.apache.camel.karavan.service.CamelStatusService.DEVMODE_SUFFIX; +import static org.apache.camel.karavan.service.CamelService.DEVMODE_SUFFIX; @Path("/api/devmode") public class DevModeResource { @@ -43,7 +43,7 @@ public class DevModeResource { String environment; @Inject - CamelStatusService camelStatusService; + CamelService camelService; @Inject DatagridService datagridService; @@ -74,10 +74,7 @@ public class DevModeResource { @Produces(MediaType.APPLICATION_JSON) @Path("/reload/{projectId}") public Response reload(@PathParam("projectId") String projectId) { - camelStatusService.reloadProjectCode(projectId); - DevModeStatus dms = datagridService.getDevModeStatus(projectId); - dms.setCodeLoaded(true); - datagridService.saveDevModeStatus(dms); + camelService.reloadProjectCode(projectId); return Response.ok().build(); } diff --git a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/handler/PodEventHandler.java b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/handler/PodEventHandler.java index a834829b..2a79bd7b 100644 --- a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/handler/PodEventHandler.java +++ b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/handler/PodEventHandler.java @@ -11,7 +11,7 @@ import org.apache.camel.karavan.service.KubernetesService; import org.jboss.logging.Logger; import static org.apache.camel.karavan.service.CodeService.DEFAULT_CONTAINER_RESOURCES; -import static org.apache.camel.karavan.service.CamelStatusService.DEVMODE_SUFFIX; +import static org.apache.camel.karavan.service.CamelService.DEVMODE_SUFFIX; public class PodEventHandler implements ResourceEventHandler<Pod> { diff --git a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/listener/DevModeCommandListener.java b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/listener/DevModeCommandListener.java index 32d83ce8..26fea711 100644 --- a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/listener/DevModeCommandListener.java +++ b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/listener/DevModeCommandListener.java @@ -14,7 +14,7 @@ import javax.inject.Inject; import java.util.Objects; -import static org.apache.camel.karavan.service.CamelStatusService.DEVMODE_SUFFIX; +import static org.apache.camel.karavan.service.CamelService.DEVMODE_SUFFIX; @ApplicationScoped public class DevModeCommandListener { diff --git a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/listener/DevModeStatusListener.java b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/listener/DevModeStatusListener.java new file mode 100644 index 00000000..15d63519 --- /dev/null +++ b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/listener/DevModeStatusListener.java @@ -0,0 +1,29 @@ +package org.apache.camel.karavan.listener; + +import io.quarkus.vertx.ConsumeEvent; +import io.vertx.core.json.JsonObject; +import org.apache.camel.karavan.datagrid.DatagridService; +import org.apache.camel.karavan.datagrid.model.DevModeStatus; +import org.apache.camel.karavan.service.CamelService; +import org.jboss.logging.Logger; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +@ApplicationScoped +public class DevModeStatusListener { + + private static final Logger LOGGER = Logger.getLogger(DevModeStatusListener.class.getName()); + + @Inject + CamelService camelService; + + @ConsumeEvent(value = DatagridService.ADDRESS_DEVMODE_STATUS, blocking = true, ordered = true) + void receiveCommand(JsonObject message) { + LOGGER.info("received Status " + message); + DevModeStatus status = message.mapTo(DevModeStatus.class); + if (!status.isCodeLoaded() && status.getContainerId() != null) { + camelService.reloadProjectCode(status.getProjectId()); + } + } +} \ No newline at end of file diff --git a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/CamelStatusService.java b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/CamelService.java similarity index 96% rename from karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/CamelStatusService.java rename to karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/CamelService.java index a3ef1288..3f3ee96d 100644 --- a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/CamelStatusService.java +++ b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/CamelService.java @@ -37,9 +37,9 @@ import java.util.Objects; import java.util.concurrent.ExecutionException; @ApplicationScoped -public class CamelStatusService { +public class CamelService { - private static final Logger LOGGER = Logger.getLogger(CamelStatusService.class.getName()); + private static final Logger LOGGER = Logger.getLogger(CamelService.class.getName()); public static final String CMD_COLLECT_CAMEL_STATUS = "collect-camel-status"; public static final String CMD_DELETE_CAMEL_STATUS = "delete-camel-status"; public static final String DEVMODE_SUFFIX = "devmode"; @@ -74,10 +74,12 @@ public class CamelStatusService { try { datagridService.getProjectFiles(projectId).forEach(projectFile -> putRequest(containerName, projectFile.getName(), projectFile.getCode(), 1000)); reloadRequest(containerName); + DevModeStatus dms = datagridService.getDevModeStatus(projectId); + dms.setCodeLoaded(true); + datagridService.saveDevModeStatus(dms); } catch (Exception ex) { LOGGER.error(ex.getMessage()); } - datagridService.deleteDevModeStatus(projectId); } @CircuitBreaker(requestVolumeThreshold = 10, failureRatio = 0.5, delay = 1000) @@ -113,7 +115,6 @@ public class CamelStatusService { @Scheduled(every = "{karavan.devmode-status-interval}", concurrentExecution = Scheduled.ConcurrentExecution.SKIP) void collectDevModeStatuses() { - System.out.println("Collect DevMode Statuses"); if (datagridService.isReady()) { datagridService.getDevModeStatuses().forEach(dms -> { CamelStatusRequest csr = new CamelStatusRequest(dms.getProjectId(), dms.getContainerName()); @@ -124,7 +125,6 @@ public class CamelStatusService { @Scheduled(every = "{karavan.camel-status-interval}", concurrentExecution = Scheduled.ConcurrentExecution.SKIP) void collectNonDevModeStatuses() { - System.out.println("Collect NonDevMode Statuses"); if (datagridService.isReady()) { datagridService.getPodStatuses(environment).forEach(pod -> { CamelStatusRequest csr = new CamelStatusRequest(pod.getProjectId(), pod.getName()); @@ -148,7 +148,6 @@ public class CamelStatusService { @Scheduled(every = "{karavan.devmode-status-interval}", concurrentExecution = Scheduled.ConcurrentExecution.SKIP) void cleanupDevModeStatuses() { - System.out.println("Clean DevMode Statuses"); if (datagridService.isReady()) { datagridService.getDevModeStatuses().forEach(dms -> { PodStatus pod = datagridService.getDevModePodStatuses(dms.getProjectId(), environment); diff --git a/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/ConductorService.java b/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/ConductorService.java index 7f4f0147..09548632 100644 --- a/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/ConductorService.java +++ b/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/ConductorService.java @@ -110,17 +110,17 @@ public class ConductorService { Project p = datagridService.getProject(command.getProjectId()); if (Objects.equals(command.getCommandName(), CommandName.RUN)) { LOGGER.infof("DevMode starting for %s", p.getProjectId()); - Container container = dockerService.createContainer(containerName, runnerImage, - List.of(), "", false, new HealthCheck(), Map.of("type", "runner") + + HealthCheck healthCheck = new HealthCheck().withTest(List.of("CMD", "curl", "-f", "http://localhost:8080/q/dev/health")) + .withInterval(10000000000L).withTimeout(10000000000L).withStartPeriod(10000000000L).withRetries(30); + + dockerService.createContainer(containerName, runnerImage, + List.of(), "", false, healthCheck, + Map.of("type", "devmode", "projectId", p.getProjectId()) ); dockerService.startContainer(containerName); LOGGER.infof("DevMode started for %s", p.getProjectId()); - // update DevModeStatus - DevModeStatus dms = datagridService.getDevModeStatus(p.getProjectId()); - dms.setContainerName(containerName); - dms.setContainerId(container.getId()); - datagridService.saveDevModeStatus(dms); } else if (Objects.equals(command.getCommandName(), CommandName.DELETE)){ dockerService.stopContainer(containerName); dockerService.deleteContainer(containerName); diff --git a/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerEventListener.java b/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerEventListener.java index db7b8358..4910e603 100644 --- a/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerEventListener.java +++ b/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerEventListener.java @@ -8,6 +8,7 @@ import io.vertx.core.eventbus.EventBus; import org.apache.camel.karavan.bashi.ConductorService; import org.apache.camel.karavan.bashi.Constants; import org.apache.camel.karavan.datagrid.DatagridService; +import org.apache.camel.karavan.datagrid.model.DevModeStatus; import org.apache.camel.karavan.datagrid.model.PodStatus; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.jboss.logging.Logger; @@ -44,7 +45,6 @@ public class DockerEventListener implements ResultCallback<Event> { @Override public void onNext(Event event) { -// LOGGER.info(event.getType() + " : " + event.getStatus()); try { if (Objects.equals(event.getType(), EventType.CONTAINER)) { Container container = dockerService.getContainer(event.getId()); @@ -53,6 +53,15 @@ public class DockerEventListener implements ResultCallback<Event> { String health = status.replace("health_status: ", ""); LOGGER.infof("Container %s health status: %s", container.getNames()[0], health); eventBus.publish(ConductorService.ADDRESS_INFINISPAN_HEALTH, health); + } else if (Objects.equals(container.getLabels().get("type"), "devmode") && status.startsWith("health_status:")) { + String health = status.replace("health_status: ", ""); + LOGGER.infof("Container %s health status: %s", container.getNames()[0], health); +// update DevModeStatus + String containerName = container.getNames()[0].replace("/", ""); + DevModeStatus dms = datagridService.getDevModeStatus(container.getLabels().get("projectId")); + dms.setContainerName(containerName); + dms.setContainerId(container.getId()); + datagridService.saveDevModeStatus(dms); } else if (container.getNames()[0].endsWith(Constants.DEVMODE_SUFFIX)) { if (Arrays.asList("stop", "die", "kill", "pause", "destroy").contains(event.getStatus())) { String name = container.getNames()[0].replace("/", ""); diff --git a/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerService.java b/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerService.java index 80558b5f..eb4c8ef3 100644 --- a/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerService.java +++ b/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/docker/DockerService.java @@ -49,7 +49,6 @@ public class DockerService { @Scheduled(every = "{karavan.container-stats-interval}", concurrentExecution = Scheduled.ConcurrentExecution.SKIP) void collectContainersStats() { - System.out.println("collectContainersStats "); getDockerClient().listContainersCmd().exec().forEach(container -> { Statistics stats = getContainerStats(container.getId()); @@ -106,7 +105,11 @@ public class DockerService { if (!getDockerClient().listNetworksCmd().exec().stream() .filter(n -> n.getName().equals(NETWORK_NAME)) .findFirst().isPresent()) { - CreateNetworkResponse res = getDockerClient().createNetworkCmd().withName(NETWORK_NAME).withAttachable(true).exec(); + CreateNetworkResponse res = getDockerClient().createNetworkCmd() + .withName(NETWORK_NAME) + .withDriver("bridge") + .withInternal(false) + .withAttachable(true).exec(); LOGGER.info("Network created: {}" + res); } else { LOGGER.info("Network already exists with name: " + NETWORK_NAME); diff --git a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/DatagridService.java b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/DatagridService.java index 5535211c..38f40026 100644 --- a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/DatagridService.java +++ b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/DatagridService.java @@ -28,11 +28,9 @@ import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.client.hotrod.Search; import org.infinispan.client.hotrod.configuration.ClientIntelligence; import org.infinispan.client.hotrod.configuration.ConfigurationBuilder; -import org.infinispan.client.hotrod.impl.query.RemoteQuery; import org.infinispan.commons.configuration.StringConfiguration; import org.infinispan.commons.marshall.ProtoStreamMarshaller; import org.infinispan.query.dsl.QueryFactory; -import org.infinispan.query.remote.client.ProtobufMetadataManagerConstants; import org.jboss.logging.Logger; import javax.enterprise.context.ApplicationScoped; @@ -41,10 +39,6 @@ import javax.inject.Inject; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.time.Instant; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -58,7 +52,9 @@ import static org.infinispan.query.remote.client.ProtobufMetadataManagerConstant public class DatagridService { public static final String ADDRESS_DEVMODE_COMMAND = "ADDRESS_DEVMODE_COMMAND"; + public static final String ADDRESS_DEVMODE_STATUS = "ADDRESS_DEVMODE_STATUS"; protected static final String ADDRESS_DEVMODE_COMMAND_INTERNAL = "ADDRESS_DEVMODE_COMMAND_INTERNAL"; + protected static final String ADDRESS_DEVMODE_STATUS_INTERNAL = "ADDRESS_DEVMODE_STATUS_INTERNAL"; @ConfigProperty(name ="quarkus.infinispan-client.hosts") String infinispanHosts; @@ -126,7 +122,8 @@ public class DatagridService { devmodeStatuses = getOrCreateCache(DevModeStatus.CACHE, false); devmodeCommands = getOrCreateCache(DevModeCommand.CACHE, true); - cacheManager.getCache(DevModeCommand.CACHE).addClientListener(new ClientRunnerListener(eventBus)); + cacheManager.getCache(DevModeCommand.CACHE).addClientListener(new DevModeCommandListener(eventBus)); + cacheManager.getCache(DevModeStatus.CACHE).addClientListener(new DevModeStatusListener(eventBus)); // Grab the generated protobuf schema and registers in the server. cacheManager.getCache(PROTOBUF_METADATA_CACHE_NAME).put("karavan.proto", getResourceFile("/proto/karavan.proto")); @@ -153,12 +150,19 @@ public class DatagridService { } @ConsumeEvent(value = ADDRESS_DEVMODE_COMMAND_INTERNAL, blocking = true, ordered = true, local = false) - void replyAsync(JsonObject message) { + void sendCommand(JsonObject message) { GroupedKey key = message.mapTo(GroupedKey.class); DevModeCommand command = getDevModeCommand(key); eventBus.publish(DatagridService.ADDRESS_DEVMODE_COMMAND, JsonObject.mapFrom(command)); } + @ConsumeEvent(value = ADDRESS_DEVMODE_STATUS_INTERNAL, blocking = true, ordered = true, local = false) + void sendStatus(JsonObject message) { + GroupedKey key = message.mapTo(GroupedKey.class); + DevModeStatus status = devmodeStatuses.get(key); + eventBus.publish(DatagridService.ADDRESS_DEVMODE_STATUS, JsonObject.mapFrom(status)); + } + public List<Project> getProjects() { return projects.values().stream().collect(Collectors.toList()); } diff --git a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/ClientRunnerListener.java b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/DevModeCommandListener.java similarity index 92% copy from karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/ClientRunnerListener.java copy to karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/DevModeCommandListener.java index 8c33ac90..09f07eaa 100644 --- a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/ClientRunnerListener.java +++ b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/DevModeCommandListener.java @@ -10,11 +10,11 @@ import org.infinispan.client.hotrod.event.ClientCacheEntryCreatedEvent; import org.infinispan.client.hotrod.event.ClientCacheEntryModifiedEvent; @ClientListener -public class ClientRunnerListener { +public class DevModeCommandListener { private final EventBus eventBus; - public ClientRunnerListener(EventBus eventBus) { + public DevModeCommandListener(EventBus eventBus) { this.eventBus = eventBus; } diff --git a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/ClientRunnerListener.java b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/DevModeStatusListener.java similarity index 73% rename from karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/ClientRunnerListener.java rename to karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/DevModeStatusListener.java index 8c33ac90..7d9a88b4 100644 --- a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/ClientRunnerListener.java +++ b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/DevModeStatusListener.java @@ -10,22 +10,22 @@ import org.infinispan.client.hotrod.event.ClientCacheEntryCreatedEvent; import org.infinispan.client.hotrod.event.ClientCacheEntryModifiedEvent; @ClientListener -public class ClientRunnerListener { +public class DevModeStatusListener { private final EventBus eventBus; - public ClientRunnerListener(EventBus eventBus) { + public DevModeStatusListener(EventBus eventBus) { this.eventBus = eventBus; } @ClientCacheEntryCreated public void entryCreated(ClientCacheEntryCreatedEvent<GroupedKey> event) { - eventBus.publish(DatagridService.ADDRESS_DEVMODE_COMMAND_INTERNAL, JsonObject.mapFrom(event.getKey())); + eventBus.publish(DatagridService.ADDRESS_DEVMODE_STATUS_INTERNAL, JsonObject.mapFrom(event.getKey())); } @ClientCacheEntryModified public void entryModified(ClientCacheEntryModifiedEvent<GroupedKey> event) { - eventBus.publish(DatagridService.ADDRESS_DEVMODE_COMMAND_INTERNAL, JsonObject.mapFrom(event.getKey())); + eventBus.publish(DatagridService.ADDRESS_DEVMODE_STATUS_INTERNAL, JsonObject.mapFrom(event.getKey())); } } \ No newline at end of file