You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ma...@apache.org on 2023/07/13 16:10:04 UTC

[camel-karavan] branch main updated (1989b7b1 -> d57e1eb2)

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

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


    from 1989b7b1 DatagridService in karaan-bashi #817
     new 396de51a UI redesign #817
     new ba44e025 UI redesign #817
     new c51b8206 DataGrid query works #817
     new 7f195bd8 DataGrid in bashi works #817
     new 2c8849bc Run/Stop In docker #817
     new f4db398c Hot reload In docker #817
     new d57e1eb2 Trace In docker #817

The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../apache/camel/karavan/api/DevModeResource.java  |  16 +--
 .../apache/camel/karavan/api/StatusResource.java   |   2 +-
 .../camel/karavan/handler/PodEventHandler.java     |  10 +-
 .../karavan/listener/DevModeCommandListener.java   |   2 +-
 .../karavan/listener/DevModeStatusListener.java    |  29 +++++
 .../{DevModeService.java => CamelService.java}     |  15 ++-
 .../camel/karavan/service/KaravanService.java      |   2 +-
 .../src/main/resources/application.properties      |   2 +-
 .../karavan-app/src/main/webui/src/Main.tsx        |   6 +-
 .../src/main/webui/src/api/KaravanApi.tsx          |   8 +-
 .../src/main/webui/src/api/ProjectModels.ts        |  25 ++--
 .../src/main/webui/src/api/ProjectService.ts       |  26 ++---
 .../src/main/webui/src/api/ProjectStore.ts         |   6 +-
 .../src/main/webui/src/dashboard/DashboardPage.tsx |  16 +--
 .../{RunnerToolbar.tsx => DevModeToolbar.tsx}      |  34 +++---
 .../src/main/webui/src/project/ProjectPage.tsx     |   3 +-
 .../src/main/webui/src/project/ProjectToolbar.tsx  | 117 +------------------
 .../webui/src/project/dashboard/DashboardTab.tsx   |  36 +++---
 .../{RunnerInfoContext.tsx => InfoContext.tsx}     |   2 +-
 .../{RunnerInfoMemory.tsx => InfoMemory.tsx}       |   2 +-
 .../main/webui/src/project/dashboard/InfoPod.tsx   |  79 +++++++++++++
 .../webui/src/project/dashboard/RunnerInfoPod.tsx  | 129 ---------------------
 .../main/webui/src/project/files/FilesToolbar.tsx  | 101 +++++++++++++++-
 .../webui/src/project/pipeline/ProjectStatus.tsx   |  30 ++---
 .../src/main/webui/src/project/trace/TraceTab.tsx  |   4 +-
 karavan-cloud/karavan-bashi/.java-version          |   1 +
 .../camel/karavan/bashi/ConductorService.java      |  60 +++++++---
 .../apache/camel/karavan/bashi/KaravanBashi.java   |   4 +-
 .../karavan/bashi/docker/DockerEventListener.java  |  49 +++++---
 .../camel/karavan/bashi/docker/DockerService.java  |  97 +++++++++++++---
 .../src/main/resources/application.properties      |   2 +-
 karavan-cloud/karavan-datagrid/.java-version       |   1 +
 karavan-cloud/karavan-datagrid/pom.xml             |  20 ++--
 .../camel/karavan/datagrid/DatagridService.java    |  39 +++++--
 ...erListener.java => DevModeCommandListener.java} |   4 +-
 ...nerListener.java => DevModeStatusListener.java} |   8 +-
 .../camel/karavan/datagrid/model/KaravanGroup.java |  35 ------
 .../karavan/datagrid/model/KaravanSchema.java      |   2 +
 .../camel/karavan/datagrid/model/KaravanUser.java  |  67 -----------
 .../camel/karavan/datagrid/model/PodStatus.java    |  16 ++-
 .../camel/karavan/datagrid/model/ProjectFile.java  |   1 +
 .../{DevCommandTest.java => DataGridTest.java}     |  21 +++-
 karavan-cloud/pom.xml                              |   3 +-
 43 files changed, 573 insertions(+), 559 deletions(-)
 create mode 100644 karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/listener/DevModeStatusListener.java
 rename karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/{DevModeService.java => CamelService.java} (94%)
 rename karavan-cloud/karavan-app/src/main/webui/src/project/{RunnerToolbar.tsx => DevModeToolbar.tsx} (68%)
 rename karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/{RunnerInfoContext.tsx => InfoContext.tsx} (99%)
 rename karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/{RunnerInfoMemory.tsx => InfoMemory.tsx} (98%)
 create mode 100644 karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoPod.tsx
 delete mode 100644 karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoPod.tsx
 create mode 100644 karavan-cloud/karavan-bashi/.java-version
 create mode 100644 karavan-cloud/karavan-datagrid/.java-version
 copy karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/{ClientRunnerListener.java => DevModeCommandListener.java} (92%)
 rename karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/{ClientRunnerListener.java => DevModeStatusListener.java} (73%)
 delete mode 100644 karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/KaravanGroup.java
 delete mode 100644 karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/KaravanUser.java
 rename karavan-cloud/karavan-datagrid/src/test/java/org/apache/camel/karavan/datagrid/{DevCommandTest.java => DataGridTest.java} (75%)


[camel-karavan] 05/07: Run/Stop In docker #817

Posted by ma...@apache.org.
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 2c8849bcbc10372a8c60b25d8d82000f51161d9c
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Wed Jul 12 20:07:40 2023 -0400

    Run/Stop In docker #817
---
 .../apache/camel/karavan/api/DevModeResource.java  | 13 ++++++------
 .../apache/camel/karavan/api/StatusResource.java   |  2 +-
 .../camel/karavan/handler/PodEventHandler.java     | 10 ++++++---
 .../karavan/listener/DevModeCommandListener.java   |  2 +-
 .../camel/karavan/service/CamelStatusService.java  |  8 ++++----
 .../camel/karavan/service/KaravanService.java      |  2 +-
 .../src/main/resources/application.properties      |  2 +-
 .../src/main/webui/src/api/KaravanApi.tsx          |  4 +---
 .../src/main/webui/src/api/ProjectModels.ts        |  8 +++-----
 .../src/main/webui/src/api/ProjectService.ts       | 20 +++++++++---------
 .../src/main/webui/src/api/ProjectStore.ts         |  6 +++---
 .../src/main/webui/src/dashboard/DashboardPage.tsx | 16 +++++++--------
 .../src/main/webui/src/project/DevModeToolbar.tsx  |  4 ++--
 .../src/main/webui/src/project/ProjectPage.tsx     |  3 +--
 .../webui/src/project/dashboard/DashboardTab.tsx   |  9 ++++----
 .../webui/src/project/pipeline/ProjectStatus.tsx   | 24 +++++++++++-----------
 .../apache/camel/karavan/bashi/KaravanBashi.java   |  2 +-
 .../karavan/bashi/docker/DockerEventListener.java  |  3 +--
 .../camel/karavan/datagrid/DatagridService.java    |  8 ++++----
 .../camel/karavan/datagrid/DataGridTest.java       | 15 ++++++++++----
 karavan-cloud/pom.xml                              |  3 +--
 21 files changed, 83 insertions(+), 81 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 0984076e..3cdef756 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.DevModeService;
+import org.apache.camel.karavan.service.CamelStatusService;
 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.DevModeService.DEVMODE_SUFFIX;
+import static org.apache.camel.karavan.service.CamelStatusService.DEVMODE_SUFFIX;
 
 @Path("/api/devmode")
 public class DevModeResource {
@@ -43,7 +43,7 @@ public class DevModeResource {
     String environment;
 
     @Inject
-    DevModeService devModeService;
+    CamelStatusService camelStatusService;
 
     @Inject
     DatagridService datagridService;
@@ -74,7 +74,7 @@ public class DevModeResource {
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/reload/{projectId}")
     public Response reload(@PathParam("projectId") String projectId) {
-        devModeService.reloadProjectCode(projectId);
+        camelStatusService.reloadProjectCode(projectId);
         DevModeStatus dms = datagridService.getDevModeStatus(projectId);
         dms.setCodeLoaded(true);
         datagridService.saveDevModeStatus(dms);
@@ -108,10 +108,9 @@ public class DevModeResource {
 
     @GET
     @Produces(MediaType.APPLICATION_JSON)
-    @Path("/console/{projectId}/{statusName}")
+    @Path("/status/{projectId}/{statusName}")
     public Response getCamelStatusByProjectAndEnv(@PathParam("projectId") String projectId, @PathParam("statusName") String statusName) {
-        String name = projectId + "-" + DEVMODE_SUFFIX;
-        CamelStatus status = datagridService.getCamelStatus(name, statusName, environment);
+        CamelStatus status = datagridService.getCamelStatus(projectId, environment, statusName);
         if (status != null) {
             return Response.ok(status).build();
         } else {
diff --git a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java
index 2df5a937..29304c19 100644
--- a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java
+++ b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java
@@ -84,6 +84,6 @@ public class StatusResource {
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/camel/{env}")
     public List<CamelStatus> getCamelStatusByEnv(@PathParam("env") String env) {
-        return datagridService.getCamelStatusesByEnv(env, CamelStatusName.context.name());
+        return datagridService.getCamelStatusesByEnv(env, CamelStatusName.context);
     }
 }
\ No newline at end of file
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 3ae8a199..a834829b 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.DevModeService.DEVMODE_SUFFIX;
+import static org.apache.camel.karavan.service.CamelStatusService.DEVMODE_SUFFIX;
 
 public class PodEventHandler implements ResourceEventHandler<Pod> {
 
@@ -64,6 +64,7 @@ public class PodEventHandler implements ResourceEventHandler<Pod> {
         String project = deployment != null ? deployment : pod.getMetadata().getLabels().get("karavan/projectId");
         try {
             boolean ready = pod.getStatus().getConditions().stream().anyMatch(c -> c.getType().equals("Ready"));
+            String creationTimestamp = pod.getMetadata().getCreationTimestamp();
 
             ResourceRequirements defaultRR = kubernetesService.getResourceRequirements(DEFAULT_CONTAINER_RESOURCES);
             ResourceRequirements resourceRequirements = pod.getSpec().getContainers().stream().findFirst()
@@ -81,7 +82,9 @@ public class PodEventHandler implements ResourceEventHandler<Pod> {
                     kubernetesService.environment,
                     deployment == null || pod.getMetadata().getName().endsWith(DEVMODE_SUFFIX),
                     requestMemory + " : " + limitMemory,
-                    requestCpu + " : " + limitCpu
+                    requestCpu + " : " + limitCpu,
+                    creationTimestamp
+
             );
         } catch (Exception ex) {
             LOGGER.error(ex.getMessage(), ex.getCause());
@@ -91,7 +94,8 @@ public class PodEventHandler implements ResourceEventHandler<Pod> {
                     null,
                     project,
                     kubernetesService.environment,
-                    false);
+                    false,
+                    "");
         }
     }
 }
\ No newline at end of file
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 9a66fb71..32d83ce8 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.DevModeService.DEVMODE_SUFFIX;
+import static org.apache.camel.karavan.service.CamelStatusService.DEVMODE_SUFFIX;
 
 @ApplicationScoped
 public class DevModeCommandListener {
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/CamelStatusService.java
index da50f844..a3ef1288 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/CamelStatusService.java
@@ -37,9 +37,9 @@ import java.util.Objects;
 import java.util.concurrent.ExecutionException;
 
 @ApplicationScoped
-public class DevModeService {
+public class CamelStatusService {
 
-    private static final Logger LOGGER = Logger.getLogger(DevModeService.class.getName());
+    private static final Logger LOGGER = Logger.getLogger(CamelStatusService.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";
@@ -115,7 +115,7 @@ public class DevModeService {
     void collectDevModeStatuses() {
         System.out.println("Collect DevMode Statuses");
         if (datagridService.isReady()) {
-            datagridService.getLoadedDevModeStatuses().forEach(dms -> {
+            datagridService.getDevModeStatuses().forEach(dms -> {
                 CamelStatusRequest csr = new CamelStatusRequest(dms.getProjectId(), dms.getContainerName());
                 eventBus.publish(CMD_COLLECT_CAMEL_STATUS, JsonObject.mapFrom(csr));
             });
@@ -150,7 +150,7 @@ public class DevModeService {
     void cleanupDevModeStatuses() {
         System.out.println("Clean DevMode Statuses");
         if (datagridService.isReady()) {
-            datagridService.getLoadedDevModeStatuses().forEach(dms -> {
+            datagridService.getDevModeStatuses().forEach(dms -> {
                 PodStatus pod = datagridService.getDevModePodStatuses(dms.getProjectId(), environment);
                 if (pod == null) {
                     eventBus.publish(CMD_DELETE_CAMEL_STATUS, JsonObject.mapFrom(dms));
diff --git a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java
index b0b1f359..177401a6 100644
--- a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java
+++ b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java
@@ -48,7 +48,7 @@ public class KaravanService {
     void onStart(@Observes StartupEvent ev) {
         LOGGER.info("Start Karavan");
         datagridService.start();
-        datagridService.clearAllStatuses();
+//        datagridService.clearAllStatuses();
         setEnvironment();
         initialImport();
         startInformers();
diff --git a/karavan-cloud/karavan-app/src/main/resources/application.properties b/karavan-cloud/karavan-app/src/main/resources/application.properties
index c7a39319..4c7a49e6 100644
--- a/karavan-cloud/karavan-app/src/main/resources/application.properties
+++ b/karavan-cloud/karavan-app/src/main/resources/application.properties
@@ -2,7 +2,7 @@ karavan.version=3.21.1-SNAPSHOT
 karavan.environment=dev
 karavan.default-runtime=quarkus
 karavan.runtimes=quarkus,spring-boot
-karavan.camel-status-interval=2s
+karavan.camel-status-interval=10s
 karavan.devmode-status-interval=2s
 quarkus.scheduler.enabled=true
 
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/api/KaravanApi.tsx b/karavan-cloud/karavan-app/src/main/webui/src/api/KaravanApi.tsx
index efb86595..f1549a3a 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/api/KaravanApi.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/api/KaravanApi.tsx
@@ -306,7 +306,6 @@ export class KaravanApi {
     static async getDevModePodStatus(projectId: string, after: (res: AxiosResponse<PodStatus>) => void) {
         instance.get('/api/devmode/pod/' + projectId)
             .then(res => {
-                console.log(res);
                 after(res);
             }).catch(err => {
             after(err);
@@ -322,10 +321,9 @@ export class KaravanApi {
         });
     }
 
-    static async getDevModeStatus(projectId: string, statusName: string, after: (res: AxiosResponse<string>) => void) {
+    static async getDevModeStatus(projectId: string, statusName: string, after: (res: AxiosResponse<CamelStatus>) => void) {
         instance.get('/api/devmode/status/' + projectId + "/" + statusName)
             .then(res => {
-                console.log(res);
                 after(res);
             }).catch(err => {
             after(err);
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectModels.ts b/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectModels.ts
index d743bef0..66ebe79b 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectModels.ts
+++ b/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectModels.ts
@@ -75,11 +75,9 @@ export class PodStatus {
 
 export class CamelStatus {
     projectId: string = '';
-    registryStatus: string = '';
-    routesStatus: string = '';
-    consumerStatus: string = '';
-    contextStatus: string = '';
-    contextVersion: string = '';
+    containerName: string = '';
+    name: string = '';
+    status: string = '';
     env: string = '';
 }
 
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectService.ts b/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectService.ts
index c358ca52..d3a60eb2 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectService.ts
+++ b/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectService.ts
@@ -9,14 +9,14 @@ import {
     useFilesStore,
     useFileStore, useLogStore,
     useProjectsStore,
-    useProjectStore, useRunnerStore
+    useProjectStore, useDevModeStore
 } from "./ProjectStore";
 import {ProjectEventBus} from "./ProjectEventBus";
 
 export class ProjectService {
 
     public static startRunner(project: Project, verbose: boolean) {
-        useRunnerStore.setState({status: "starting"})
+        useDevModeStore.setState({status: "starting"})
         KaravanApi.runProject(project, verbose, res => {
             if (res.status === 200 || res.status === 201) {
                 ProjectEventBus.sendLog("set", '');
@@ -28,7 +28,7 @@ export class ProjectService {
     }
 
     public static reloadRunner(project: Project) {
-        useRunnerStore.setState({status: "reloading"})
+        useDevModeStore.setState({status: "reloading"})
         KaravanApi.reloadDevMode(project.projectId, res => {
             if (res.status === 200 || res.status === 201) {
                 // setIsReloadingPod(false);
@@ -40,7 +40,7 @@ export class ProjectService {
     }
 
     public static deleteRunner(project: Project) {
-        useRunnerStore.setState({status: "deleting"})
+        useDevModeStore.setState({status: "deleting"})
         ProjectEventBus.sendLog("set", '');
         KaravanApi.deleteRunner(project.projectId, false, res => {
             if (res.status === 202) {
@@ -57,19 +57,19 @@ export class ProjectService {
             if (res.status === 200) {
                 unstable_batchedUpdates(() => {
                     const podStatus = res.data;
-                    if (useRunnerStore.getState().podName !== podStatus.name){
-                        useRunnerStore.setState({podName: podStatus.name})
+                    if (useDevModeStore.getState().podName !== podStatus.name){
+                        useDevModeStore.setState({podName: podStatus.name})
                     }
-                    if (useRunnerStore.getState().status !== "running"){
-                        useRunnerStore.setState({status: "running"})
+                    if (useDevModeStore.getState().status !== "running"){
+                        useDevModeStore.setState({status: "running"})
                         useLogStore.setState({isRunning: true})
                     }
                     useProjectStore.setState({podStatus: res.data});
                 })
             } else {
                 unstable_batchedUpdates(() => {
-                    if (useRunnerStore.getState().status !== 'none') {
-                        useRunnerStore.setState({status: "none", podName: undefined})
+                    if (useDevModeStore.getState().status !== 'none') {
+                        useDevModeStore.setState({status: "none", podName: undefined})
                         useProjectStore.setState({podStatus: new PodStatus()});
                     }
                 })
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectStore.ts b/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectStore.ts
index 9298e283..d04fa3c2 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectStore.ts
+++ b/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectStore.ts
@@ -151,17 +151,17 @@ export const useDeploymentStatusesStore = create<DeploymentStatusesState>((set)
 }))
 
 
-interface RunnerState {
+interface DevModeState {
     podName?: string,
     status: "none" | "starting" | "deleting"| "reloading" | "running",
     setStatus: (status: "none" | "starting" | "deleting"| "reloading" | "running") => void,
 }
 
-export const useRunnerStore = create<RunnerState>((set) => ({
+export const useDevModeStore = create<DevModeState>((set) => ({
     podName: undefined,
     status: "none",
     setStatus: (status: "none" | "starting" | "deleting"| "reloading" | "running") =>  {
-        set((state: RunnerState) => ({
+        set((state: DevModeState) => ({
             status: status,
         }));
     },
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/dashboard/DashboardPage.tsx b/karavan-cloud/karavan-app/src/main/webui/src/dashboard/DashboardPage.tsx
index 8bc9be07..448c865e 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/dashboard/DashboardPage.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/dashboard/DashboardPage.tsx
@@ -323,15 +323,15 @@ export class DashboardPage extends React.Component<Props, State> {
                                     <Td modifier={"fitContent"}>
                                         <Flex direction={{default: "column"}}>
                                             {this.getCamelStatusByEnvironments(deployment).map(value => {
-                                                const color = value[1] ? (value[1].consumerStatus === "UP" ? "green" : "red") : "grey";
-                                                let icon = undefined;
-                                                if (value[1]?.consumerStatus === "UP") icon = <UpIcon/>
-                                                if (value[1]?.consumerStatus === "DOWN") icon = <DownIcon/>
-                                                const text = value[1] && value[1]?.contextVersion ? value[1]?.contextVersion : "???";
+                                                // const color = value[1] ? (value[1].consumerStatus === "UP" ? "green" : "red") : "grey";
+                                                // let icon = undefined;
+                                                // if (value[1]?.consumerStatus === "UP") icon = <UpIcon/>
+                                                // if (value[1]?.consumerStatus === "DOWN") icon = <DownIcon/>
+                                                // const text = value[1] && value[1]?.contextVersion ? value[1]?.contextVersion : "???";
                                                 return <FlexItem key={value[0]}>
-                                                    <LabelGroup numLabels={4} className="camel-label-group">
-                                                        <Label color={color} className="table-label" icon={icon}>{text}</Label>
-                                                    </LabelGroup>
+                                                    {/*<LabelGroup numLabels={4} className="camel-label-group">*/}
+                                                    {/*    <Label color={color} className="table-label" icon={icon}>{text}</Label>*/}
+                                                    {/*</LabelGroup>*/}
                                                 </FlexItem>
                                             })}
                                         </Flex>
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
index fc099b50..ee9e2c8b 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
@@ -8,7 +8,7 @@ import '../designer/karavan.css';
 import RocketIcon from "@patternfly/react-icons/dist/esm/icons/rocket-icon";
 import ReloadIcon from "@patternfly/react-icons/dist/esm/icons/bolt-icon";
 import DeleteIcon from "@patternfly/react-icons/dist/esm/icons/times-circle-icon";
-import {useProjectStore, useRunnerStore} from "../api/ProjectStore";
+import {useProjectStore, useDevModeStore} from "../api/ProjectStore";
 import {ProjectService} from "../api/ProjectService";
 import {shallow} from "zustand/shallow";
 
@@ -19,7 +19,7 @@ interface Props {
 
 export const DevModeToolbar = (props: Props) => {
 
-    const [status] = useRunnerStore((state) => [state.status], shallow)
+    const [status] = useDevModeStore((state) => [state.status], shallow)
     const [project] = useProjectStore((state) => [state.project], shallow)
     const [verbose, setVerbose] = useState(false);
 
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectPage.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectPage.tsx
index 6ad2bdd9..53febea5 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectPage.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectPage.tsx
@@ -18,7 +18,6 @@ import {shallow} from "zustand/shallow";
 
 export const ProjectPage = () => {
 
-    const [isUploadModalOpen, setIsUploadModalOpen] = useState<boolean>(false);
     const {file, operation} = useFileStore();
     const [mode, setMode] = useState<"design" | "code">("design");
     const [key, setKey] = useState<string>('');
@@ -28,7 +27,7 @@ export const ProjectPage = () => {
         // TODO: make status request only when started or just opened
         const interval = setInterval(() => {
             ProjectService.getDevModePodStatus(project);
-        }, 2000);
+        }, 1000);
         return () => {
             clearInterval(interval)
         };
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
index a2b90e28..0c065908 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
@@ -40,28 +40,27 @@ export const DashboardTab = () => {
         return () => {
             clearInterval(interval)
         };
-
-    }, [podStatus]);
+    }, []);
 
     function onRefreshStatus() {
         const projectId = project.projectId;
         KaravanApi.getDevModeStatus(projectId, "memory", res => {
             if (res.status === 200) {
-                setMemory(res.data);
+                setMemory(JSON.parse(res.data.status));
             } else {
                 setMemory({});
             }
         })
         KaravanApi.getDevModeStatus(projectId, "jvm", res => {
             if (res.status === 200) {
-                setJvm(res.data);
+                setJvm(JSON.parse(res.data.status));
             } else {
                 setJvm({});
             }
         })
         KaravanApi.getDevModeStatus(projectId, "context", res => {
             if (res.status === 200) {
-                setContext(res.data);
+                setContext(JSON.parse(res.data.status));
             } else {
                 setContext({});
             }
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx
index 25ac03f9..29e2b8a4 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx
@@ -248,20 +248,20 @@ export class ProjectStatus extends React.Component<Props, State> {
 
     getHealthPanel(env: string) {
         const status = this.state.camelStatus;
-        const routesStatus = status?.routesStatus;
-        const consumersStatus = status?.consumerStatus;
-        const contextStatus = status?.contextStatus;
-        const contextVersion = status?.contextVersion;
+        // const routesStatus = status?.routesStatus;
+        // const consumersStatus = status?.consumerStatus;
+        // const contextStatus = status?.contextStatus;
+        // const contextVersion = status?.contextVersion;
         return (
             <LabelGroup numLabels={4}>
-                {contextVersion &&
-                    <Label icon={this.getStatusIcon(contextStatus)}
-                           color={this.getStatusColor(contextStatus)}>{contextVersion}</Label>}
-                <Label icon={this.getStatusIcon(contextStatus)}
-                       color={this.getStatusColor(contextStatus)}>Context</Label>
-                <Label icon={this.getStatusIcon(consumersStatus)}
-                       color={this.getStatusColor(consumersStatus)}>Consumers</Label>
-                <Label icon={this.getStatusIcon(routesStatus)} color={this.getStatusColor(routesStatus)}>Routes</Label>
+                {/*{contextVersion &&*/}
+                {/*    <Label icon={this.getStatusIcon(contextStatus)}*/}
+                {/*           color={this.getStatusColor(contextStatus)}>{contextVersion}</Label>}*/}
+                {/*<Label icon={this.getStatusIcon(contextStatus)}*/}
+                {/*       color={this.getStatusColor(contextStatus)}>Context</Label>*/}
+                {/*<Label icon={this.getStatusIcon(consumersStatus)}*/}
+                {/*       color={this.getStatusColor(consumersStatus)}>Consumers</Label>*/}
+                {/*<Label icon={this.getStatusIcon(routesStatus)} color={this.getStatusColor(routesStatus)}>Routes</Label>*/}
             </LabelGroup>
         )
     }
diff --git a/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanBashi.java b/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanBashi.java
index f0a8a630..98c3f40d 100644
--- a/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanBashi.java
+++ b/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanBashi.java
@@ -21,7 +21,7 @@ public class KaravanBashi {
 
     private static final Logger LOGGER = Logger.getLogger(KaravanBashi.class.getName());
 
-    void onStart(@Observes StartupEvent ev) throws InterruptedException {
+    void onStart(@Observes StartupEvent ev) {
         LOGGER.info("Karavan Bashi is starting...");
         dockerService.createNetwork();
         dockerService.checkDataGridHealth();
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 be068895..db7b8358 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
@@ -57,13 +57,12 @@ public class DockerEventListener implements ResultCallback<Event> {
                     if (Arrays.asList("stop", "die", "kill", "pause", "destroy").contains(event.getStatus())) {
                         String name = container.getNames()[0].replace("/", "");
                         String projectId = name.replace("-" + Constants.DEVMODE_SUFFIX, "");
-                        LOGGER.info("Deleted PodStatus for " + projectId);
                         datagridService.deletePodStatus(projectId, environment, name);
+                        datagridService.deleteCamelStatuses(projectId, environment);
                     } else if (Arrays.asList("start", "unpause").contains(event.getStatus())) {
                         String name = container.getNames()[0].replace("/", "");
                         String projectId = name.replace("-" + Constants.DEVMODE_SUFFIX, "");
                         PodStatus ps = new PodStatus(name, true, null, projectId, environment, true, Instant.ofEpochSecond(container.getCreated()).toString());
-                        LOGGER.info("Saved PodStatus for " + projectId);
                         datagridService.savePodStatus(ps);
                     }
                 }
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 6141addd..5535211c 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
@@ -309,7 +309,7 @@ public class DatagridService  {
         return camelStatuses.get(key);
     }
 
-    public List<CamelStatus> getCamelStatusesByEnv(String env, String name) {
+    public List<CamelStatus> getCamelStatusesByEnv(String env, CamelStatusName name) {
         QueryFactory queryFactory = Search.getQueryFactory(camelStatuses);
         return queryFactory.<CamelStatus>create("FROM karavan.CamelStatus WHERE env = :env AND name = :name")
                 .setParameter("env", env)
@@ -317,11 +317,11 @@ public class DatagridService  {
                 .execute().list();
     }
 
-    public List<CamelStatus> getCamelStatusesByProjectIdEnv(String projectId, String name) {
+    public List<CamelStatus> getCamelStatusesByProjectIdEnv(String projectId, String env) {
         QueryFactory queryFactory = Search.getQueryFactory(camelStatuses);
-        return queryFactory.<CamelStatus>create("FROM karavan.CamelStatus WHERE projectId = :projectId AND name = :name")
+        return queryFactory.<CamelStatus>create("FROM karavan.CamelStatus WHERE projectId = :projectId AND name = :env")
                 .setParameter("projectId", projectId)
-                .setParameter("name", name)
+                .setParameter("env", env)
                 .execute().list();
     }
 
diff --git a/karavan-cloud/karavan-datagrid/src/test/java/org/apache/camel/karavan/datagrid/DataGridTest.java b/karavan-cloud/karavan-datagrid/src/test/java/org/apache/camel/karavan/datagrid/DataGridTest.java
index 37c272e4..5e4fb8c0 100644
--- a/karavan-cloud/karavan-datagrid/src/test/java/org/apache/camel/karavan/datagrid/DataGridTest.java
+++ b/karavan-cloud/karavan-datagrid/src/test/java/org/apache/camel/karavan/datagrid/DataGridTest.java
@@ -4,9 +4,7 @@ package org.apache.camel.karavan.datagrid;
 import io.quarkus.test.junit.QuarkusTest;
 import io.quarkus.vertx.ConsumeEvent;
 import io.vertx.core.json.JsonObject;
-import org.apache.camel.karavan.datagrid.model.CommandName;
-import org.apache.camel.karavan.datagrid.model.DevModeCommand;
-import org.apache.camel.karavan.datagrid.model.ProjectFile;
+import org.apache.camel.karavan.datagrid.model.*;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInstance;
@@ -59,8 +57,17 @@ public class DataGridTest {
     }
 
     @Test
-    public void getProjectFiles() throws InterruptedException {
+    public void testProjectFiles() throws InterruptedException {
         List<ProjectFile> files = datagridService.getProjectFiles("xxx");
         assertEquals(0, files.size());
     }
+
+    @Test
+    public void testCamelStatuses() throws InterruptedException {
+        CamelStatus cs = new CamelStatus("test1", "container1", CamelStatusName.context, "", "dev");
+        datagridService.saveCamelStatus(cs);
+        List<CamelStatus> list = datagridService.getCamelStatusesByEnv("dev", CamelStatusName.context);
+        System.out.println(list);
+        assertEquals(1, list.size());
+    }
 }
diff --git a/karavan-cloud/pom.xml b/karavan-cloud/pom.xml
index 1862fa72..c54f9c61 100644
--- a/karavan-cloud/pom.xml
+++ b/karavan-cloud/pom.xml
@@ -19,12 +19,11 @@
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
         <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
-        <quarkus.platform.version>2.16.7.Final</quarkus.platform.version>
+        <quarkus.platform.version>2.16.8.Final</quarkus.platform.version>
         <camel-quarkus.version>2.16.0</camel-quarkus.version>
         <camel.version>3.21.0</camel.version>
         <camel-kamelet.version>3.21.0</camel-kamelet.version>
         <surefire-plugin.version>3.1.0</surefire-plugin.version>
-        <infinispan.version>14.0.9.Final</infinispan.version>
         <tekton.version>6.3.1</tekton.version>
         <jgit.version>2.3.2</jgit.version>
         <quinoa.version>1.2.4</quinoa.version>


[camel-karavan] 02/07: UI redesign #817

Posted by ma...@apache.org.
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 ba44e025496c1576fc77e9b57da0e5724aef494a
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Wed Jul 12 14:02:37 2023 -0400

    UI redesign #817
---
 .../karavan-app/src/main/webui/src/api/ProjectModels.ts | 17 ++++++-----------
 .../src/main/webui/src/api/ProjectService.ts            |  6 +++---
 2 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectModels.ts b/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectModels.ts
index 07bbee92..d743bef0 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectModels.ts
+++ b/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectModels.ts
@@ -59,19 +59,14 @@ export class ServiceStatus {
 
 export class PodStatus {
     name: string = '';
-    phase: string = '';
-    started: boolean = false;
     ready: boolean = false;
-    terminating: boolean = false;
-    reason: string = '';
-    project: string = '';
     deployment: string = '';
-    runner: boolean = false;
-    requestMemory: string = '';
-    requestCpu: string = '';
-    limitMemory: string = '';
-    limitCpu: string = '';
-    creationTimestamp: string = '';
+    projectId: string = '';
+    env: string = '';
+    inDevMode: boolean = false;
+    memoryInfo: string = '';
+    cpuInfo: string = '';
+    created: string = '';
 
     public constructor(init?: Partial<PodStatus>) {
         Object.assign(this, init);
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectService.ts b/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectService.ts
index 1f8f7193..c358ca52 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectService.ts
+++ b/karavan-cloud/karavan-app/src/main/webui/src/api/ProjectService.ts
@@ -29,7 +29,7 @@ export class ProjectService {
 
     public static reloadRunner(project: Project) {
         useRunnerStore.setState({status: "reloading"})
-        KaravanApi.getRunnerReload(project.projectId, res => {
+        KaravanApi.reloadDevMode(project.projectId, res => {
             if (res.status === 200 || res.status === 201) {
                 // setIsReloadingPod(false);
             } else {
@@ -51,9 +51,9 @@ export class ProjectService {
         });
     }
 
-    public static getRunnerPodStatus(project: Project) {
+    public static getDevModePodStatus(project: Project) {
         const projectId = project.projectId;
-        KaravanApi.getRunnerPodStatus(projectId, res => {
+        KaravanApi.getDevModePodStatus(projectId, res => {
             if (res.status === 200) {
                 unstable_batchedUpdates(() => {
                     const podStatus = res.data;


[camel-karavan] 06/07: Hot reload In docker #817

Posted by ma...@apache.org.
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 <ma...@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


[camel-karavan] 03/07: DataGrid query works #817

Posted by ma...@apache.org.
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 c51b8206412a51675c7aaa39843fd9aeaad51514
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Wed Jul 12 14:56:59 2023 -0400

    DataGrid query works #817
---
 karavan-cloud/karavan-datagrid/.java-version       |  1 +
 karavan-cloud/karavan-datagrid/pom.xml             | 20 +++----
 .../camel/karavan/datagrid/DatagridService.java    | 23 +++++++-
 .../camel/karavan/datagrid/model/KaravanGroup.java | 35 -----------
 .../karavan/datagrid/model/KaravanSchema.java      |  2 +
 .../camel/karavan/datagrid/model/KaravanUser.java  | 67 ----------------------
 .../camel/karavan/datagrid/model/PodStatus.java    | 16 +++++-
 .../camel/karavan/datagrid/model/ProjectFile.java  |  1 +
 .../{DevCommandTest.java => DataGridTest.java}     | 10 +++-
 9 files changed, 54 insertions(+), 121 deletions(-)

diff --git a/karavan-cloud/karavan-datagrid/.java-version b/karavan-cloud/karavan-datagrid/.java-version
new file mode 100644
index 00000000..b4de3947
--- /dev/null
+++ b/karavan-cloud/karavan-datagrid/.java-version
@@ -0,0 +1 @@
+11
diff --git a/karavan-cloud/karavan-datagrid/pom.xml b/karavan-cloud/karavan-datagrid/pom.xml
index b66104f2..4487130b 100644
--- a/karavan-cloud/karavan-datagrid/pom.xml
+++ b/karavan-cloud/karavan-datagrid/pom.xml
@@ -63,6 +63,13 @@
                     <include>**/**.xml</include>
                 </includes>
             </resource>
+            <resource>
+                <directory>target/classes/proto</directory>
+                <filtering>true</filtering>
+                <includes>
+                    <include>karavan.proto</include>
+                </includes>
+            </resource>
         </resources>
         <plugins>
             <plugin>
@@ -113,19 +120,6 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-resources-plugin</artifactId>
-                <configuration>
-                    <nonFilteredFileExtensions>
-                        <nonFilteredFileExtension>ico</nonFilteredFileExtension>
-                        <nonFilteredFileExtension>eot</nonFilteredFileExtension>
-                        <nonFilteredFileExtension>ttf</nonFilteredFileExtension>
-                        <nonFilteredFileExtension>woff</nonFilteredFileExtension>
-                        <nonFilteredFileExtension>woff2</nonFilteredFileExtension>
-                        <nonFilteredFileExtension>js</nonFilteredFileExtension>
-                        <nonFilteredFileExtension>html</nonFilteredFileExtension>
-                        <nonFilteredFileExtension>css</nonFilteredFileExtension>
-                        <nonFilteredFileExtension>svg</nonFilteredFileExtension>
-                    </nonFilteredFileExtensions>
-                </configuration>
             </plugin>
         </plugins>
     </build>
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 4968ab83..6141addd 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,9 +28,11 @@ 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;
@@ -39,12 +41,18 @@ 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;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 
+import static org.infinispan.query.remote.client.ProtobufMetadataManagerConstants.PROTOBUF_METADATA_CACHE_NAME;
+
 @Default
 @ApplicationScoped
 public class DatagridService  {
@@ -119,6 +127,9 @@ public class DatagridService  {
         devmodeCommands = getOrCreateCache(DevModeCommand.CACHE, true);
 
         cacheManager.getCache(DevModeCommand.CACHE).addClientListener(new ClientRunnerListener(eventBus));
+        // Grab the generated protobuf schema and registers in the server.
+        cacheManager.getCache(PROTOBUF_METADATA_CACHE_NAME).put("karavan.proto", getResourceFile("/proto/karavan.proto"));
+
         ready.set(true);
         LOGGER.info("DatagridService is started in remote mode");
     }
@@ -130,7 +141,6 @@ public class DatagridService  {
     private <K, V> RemoteCache<K, V>  getOrCreateCache(String name, boolean command) {
         String config = getResourceFile(command ? "/command-cache-config.xml" : "/data-cache-config.xml");
         return cacheManager.administration().getOrCreateCache(name, new StringConfiguration(String.format(config, name)));
-
     }
 
     private void cleanData() {
@@ -139,6 +149,7 @@ public class DatagridService  {
         podStatuses.clear();
         pipelineStatuses.clear();
         camelStatuses.clear();
+        devmodeCommands.clear();
     }
 
     @ConsumeEvent(value = ADDRESS_DEVMODE_COMMAND_INTERNAL, blocking = true, ordered = true, local = false)
@@ -231,7 +242,7 @@ public class DatagridService  {
     }
 
     public List<DeploymentStatus> getDeploymentStatuses() {
-        return deploymentStatuses.values().stream().collect(Collectors.toList());
+        return new ArrayList<>(deploymentStatuses.values());
     }
 
     public List<DeploymentStatus> getDeploymentStatuses(String env) {
@@ -277,6 +288,10 @@ public class DatagridService  {
                 .execute().list();
     }
 
+    public List<PodStatus> getAllPodStatuses() {
+        return new ArrayList<>(podStatuses.values());
+    }
+
     public void savePodStatus(PodStatus status) {
         podStatuses.put(GroupedKey.create(status.getProjectId(), status.getEnv(), status.getName()), status);
     }
@@ -371,6 +386,10 @@ public class DatagridService  {
                 .execute().list();
     }
 
+    public List<DevModeStatus> getDevModeStatuses() {
+       return new ArrayList<>(devmodeStatuses.values());
+    }
+
     public void sendDevModeCommand(String projectId, DevModeCommand command) {
         if (command.getProjectId() == null) {
             command.setProjectId(projectId);
diff --git a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/KaravanGroup.java b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/KaravanGroup.java
deleted file mode 100644
index 6a194442..00000000
--- a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/KaravanGroup.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.apache.camel.karavan.datagrid.model;
-
-import org.infinispan.protostream.annotations.ProtoFactory;
-import org.infinispan.protostream.annotations.ProtoField;
-
-import java.util.List;
-
-public class KaravanGroup {
-    @ProtoField(number = 1)
-    String name;
-    @ProtoField(number = 2)
-    List<String> users;
-
-    @ProtoFactory
-    public KaravanGroup(String name, List<String> users) {
-        this.name = name;
-        this.users = users;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public List<String> getUsers() {
-        return users;
-    }
-
-    public void setUsers(List<String> users) {
-        this.users = users;
-    }
-}
diff --git a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/KaravanSchema.java b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/KaravanSchema.java
index f4152c53..be78b42a 100644
--- a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/KaravanSchema.java
+++ b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/KaravanSchema.java
@@ -19,6 +19,8 @@ import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
                 DevModeCommand.class,
                 DevModeStatus.class
         },
+        schemaFileName = "karavan.proto",
+        schemaFilePath = "proto/",
         schemaPackageName = "karavan")
 public interface KaravanSchema extends GeneratedSchema {
 }
diff --git a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/KaravanUser.java b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/KaravanUser.java
deleted file mode 100644
index 6cfc3728..00000000
--- a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/KaravanUser.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.apache.camel.karavan.datagrid.model;
-
-import org.infinispan.protostream.annotations.ProtoFactory;
-import org.infinispan.protostream.annotations.ProtoField;
-
-public class KaravanUser {
-    @ProtoField(number = 1)
-    String username;
-    @ProtoField(number = 2)
-    String password;
-    @ProtoField(number = 3)
-    String firstName;
-    @ProtoField(number = 4)
-    String lastName;
-    @ProtoField(number = 5)
-    boolean showTour;
-
-
-    @ProtoFactory
-    public KaravanUser(String username, String password, String firstName, String lastName, boolean showTour) {
-        this.username = username;
-        this.password = password;
-        this.firstName = firstName;
-        this.lastName = lastName;
-        this.showTour = showTour;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
-    public String getFirstName() {
-        return firstName;
-    }
-
-    public void setFirstName(String firstName) {
-        this.firstName = firstName;
-    }
-
-    public String getLastName() {
-        return lastName;
-    }
-
-    public void setLastName(String lastName) {
-        this.lastName = lastName;
-    }
-
-    public boolean isShowTour() {
-        return showTour;
-    }
-
-    public void setShowTour(boolean showTour) {
-        this.showTour = showTour;
-    }
-}
diff --git a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/PodStatus.java b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/PodStatus.java
index ffb7b9f5..c1ee17e8 100644
--- a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/PodStatus.java
+++ b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/PodStatus.java
@@ -21,9 +21,11 @@ public class PodStatus {
     String memoryInfo;
     @ProtoField(number = 8)
     String cpuInfo;
+    @ProtoField(number = 9)
+    String created;
 
     @ProtoFactory
-    public PodStatus(String name, Boolean ready, String deployment, String projectId, String env, Boolean inDevMode, String memoryInfo, String cpuInfo) {
+    public PodStatus(String name, Boolean ready, String deployment, String projectId, String env, Boolean inDevMode, String memoryInfo, String cpuInfo, String created) {
         this.name = name;
         this.ready = ready;
         this.deployment = deployment;
@@ -32,15 +34,17 @@ public class PodStatus {
         this.inDevMode = inDevMode;
         this.memoryInfo = memoryInfo;
         this.cpuInfo = cpuInfo;
+        this.created = created;
     }
 
-    public PodStatus(String name, Boolean ready, String deployment, String projectId, String env, Boolean inDevMode) {
+    public PodStatus(String name, Boolean ready, String deployment, String projectId, String env, Boolean inDevMode, String created) {
         this.name = name;
         this.ready = ready;
         this.deployment = deployment;
         this.projectId = projectId;
         this.env = env;
         this.inDevMode = inDevMode;
+        this.created = created;
     }
 
     public String getName() {
@@ -106,4 +110,12 @@ public class PodStatus {
     public void setCpuInfo(String cpuInfo) {
         this.cpuInfo = cpuInfo;
     }
+
+    public String getCreated() {
+        return created;
+    }
+
+    public void setCreated(String created) {
+        this.created = created;
+    }
 }
diff --git a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/ProjectFile.java b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/ProjectFile.java
index bab93c65..ff1e1311 100644
--- a/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/ProjectFile.java
+++ b/karavan-cloud/karavan-datagrid/src/main/java/org/apache/camel/karavan/datagrid/model/ProjectFile.java
@@ -1,5 +1,6 @@
 package org.apache.camel.karavan.datagrid.model;
 
+import org.infinispan.api.annotations.indexing.Indexed;
 import org.infinispan.protostream.annotations.ProtoDoc;
 import org.infinispan.protostream.annotations.ProtoFactory;
 import org.infinispan.protostream.annotations.ProtoField;
diff --git a/karavan-cloud/karavan-datagrid/src/test/java/org/apache/camel/karavan/datagrid/DevCommandTest.java b/karavan-cloud/karavan-datagrid/src/test/java/org/apache/camel/karavan/datagrid/DataGridTest.java
similarity index 88%
rename from karavan-cloud/karavan-datagrid/src/test/java/org/apache/camel/karavan/datagrid/DevCommandTest.java
rename to karavan-cloud/karavan-datagrid/src/test/java/org/apache/camel/karavan/datagrid/DataGridTest.java
index 8602f589..37c272e4 100644
--- a/karavan-cloud/karavan-datagrid/src/test/java/org/apache/camel/karavan/datagrid/DevCommandTest.java
+++ b/karavan-cloud/karavan-datagrid/src/test/java/org/apache/camel/karavan/datagrid/DataGridTest.java
@@ -6,6 +6,7 @@ import io.quarkus.vertx.ConsumeEvent;
 import io.vertx.core.json.JsonObject;
 import org.apache.camel.karavan.datagrid.model.CommandName;
 import org.apache.camel.karavan.datagrid.model.DevModeCommand;
+import org.apache.camel.karavan.datagrid.model.ProjectFile;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInstance;
@@ -20,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 
 @QuarkusTest
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
-public class DevCommandTest {
+public class DataGridTest {
 
     @Inject
     DatagridService datagridService;
@@ -39,7 +40,7 @@ public class DevCommandTest {
         commandsReceived.add(message.mapTo(DevModeCommand.class));
     }
 
-    @Test
+//    @Test
     public void sendCommand() throws InterruptedException {
         List<DevModeCommand> commandsSent = List.of(
                 new DevModeCommand(CommandName.RUN, Instant.now().toEpochMilli()),
@@ -57,4 +58,9 @@ public class DevCommandTest {
         assertEquals(commandsSent.get(2).getCommandName().name(),  commandsReceived.get(2).getCommandName().name());
     }
 
+    @Test
+    public void getProjectFiles() throws InterruptedException {
+        List<ProjectFile> files = datagridService.getProjectFiles("xxx");
+        assertEquals(0, files.size());
+    }
 }


[camel-karavan] 01/07: UI redesign #817

Posted by ma...@apache.org.
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 396de51a5f17df294d2bb6e87b023885b7cac2c6
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Wed Jul 12 13:59:23 2023 -0400

    UI redesign #817
---
 ...DevModeService.java => CamelStatusService.java} |   0
 .../src/main/webui/src/api/KaravanApi.tsx          |  10 +-
 .../{RunnerToolbar.tsx => DevModeToolbar.tsx}      |   6 +-
 .../src/main/webui/src/project/ProjectPage.tsx     |   4 +-
 .../src/main/webui/src/project/ProjectToolbar.tsx  | 107 +--------------------
 .../webui/src/project/dashboard/DashboardTab.tsx   |  29 +++---
 .../{RunnerInfoContext.tsx => InfoContext.tsx}     |   2 +-
 .../{RunnerInfoMemory.tsx => InfoMemory.tsx}       |   2 +-
 .../dashboard/{RunnerInfoPod.tsx => InfoPod.tsx}   |  59 +++---------
 .../main/webui/src/project/files/FilesToolbar.tsx  | 101 ++++++++++++++++++-
 .../webui/src/project/pipeline/ProjectStatus.tsx   |   6 +-
 .../src/main/webui/src/project/trace/TraceTab.tsx  |   2 +-
 12 files changed, 144 insertions(+), 184 deletions(-)

diff --git a/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/DevModeService.java b/karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/CamelStatusService.java
similarity index 100%
rename from karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/DevModeService.java
rename to karavan-cloud/karavan-app/src/main/java/org/apache/camel/karavan/service/CamelStatusService.java
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/api/KaravanApi.tsx b/karavan-cloud/karavan-app/src/main/webui/src/api/KaravanApi.tsx
index c2b53c14..efb86595 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/api/KaravanApi.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/api/KaravanApi.tsx
@@ -303,16 +303,17 @@ export class KaravanApi {
         });
     }
 
-    static async getRunnerPodStatus(projectId: string, after: (res: AxiosResponse<PodStatus>) => void) {
+    static async getDevModePodStatus(projectId: string, after: (res: AxiosResponse<PodStatus>) => void) {
         instance.get('/api/devmode/pod/' + projectId)
             .then(res => {
+                console.log(res);
                 after(res);
             }).catch(err => {
             after(err);
         });
     }
 
-    static async getRunnerReload(projectId: string, after: (res: AxiosResponse<any>) => void) {
+    static async reloadDevMode(projectId: string, after: (res: AxiosResponse<any>) => void) {
         instance.get('/api/devmode/reload/' + projectId)
             .then(res => {
                 after(res);
@@ -321,9 +322,10 @@ export class KaravanApi {
         });
     }
 
-    static async getRunnerConsoleStatus(projectId: string, statusName: string, after: (res: AxiosResponse<string>) => void) {
-        instance.get('/api/devmode/console/' + projectId + "/" + statusName)
+    static async getDevModeStatus(projectId: string, statusName: string, after: (res: AxiosResponse<string>) => void) {
+        instance.get('/api/devmode/status/' + projectId + "/" + statusName)
             .then(res => {
+                console.log(res);
                 after(res);
             }).catch(err => {
             after(err);
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/RunnerToolbar.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
similarity index 93%
rename from karavan-cloud/karavan-app/src/main/webui/src/project/RunnerToolbar.tsx
rename to karavan-cloud/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
index a065773c..fc099b50 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/RunnerToolbar.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
@@ -17,7 +17,7 @@ interface Props {
     reloadOnly?: boolean
 }
 
-export const RunnerToolbar = (props: Props) => {
+export const DevModeToolbar = (props: Props) => {
 
     const [status] = useRunnerStore((state) => [state.status], shallow)
     const [project] = useProjectStore((state) => [state.project], shallow)
@@ -29,7 +29,7 @@ export const RunnerToolbar = (props: Props) => {
     const isDeletingPod = status === "deleting";
     return (<>
         {(isRunning || isDeletingPod) && !isReloadingPod && props.reloadOnly !== true && <FlexItem>
-            <Tooltip content="Stop runner" position={TooltipPosition.bottom}>
+            <Tooltip content="Stop devmode" position={TooltipPosition.bottom}>
                 <Button isLoading={isDeletingPod ? true : undefined}
                         isSmall
                         variant={"secondary"}
@@ -50,7 +50,7 @@ export const RunnerToolbar = (props: Props) => {
             </Tooltip>
         </FlexItem>}
         {!isRunning && !isReloadingPod && props.reloadOnly !== true && <FlexItem>
-            <Tooltip content="Run in development mode" position={TooltipPosition.bottom}>
+            <Tooltip content="Run in developer mode" position={TooltipPosition.bottom}>
                 <Button isLoading={isStartingPod ? true : undefined}
                         isSmall
                         variant={"primary"}
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectPage.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectPage.tsx
index 1221e0cb..6ad2bdd9 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectPage.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectPage.tsx
@@ -27,8 +27,8 @@ export const ProjectPage = () => {
     useEffect(() => {
         // TODO: make status request only when started or just opened
         const interval = setInterval(() => {
-            ProjectService.getRunnerPodStatus(project);
-        }, 1000);
+            ProjectService.getDevModePodStatus(project);
+        }, 2000);
         return () => {
             clearInterval(interval)
         };
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx
index 95d177ae..c65d5ced 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx
@@ -22,9 +22,8 @@ import '../designer/karavan.css';
 import DownloadImageIcon from "@patternfly/react-icons/dist/esm/icons/image-icon";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
 import {CamelDefinitionYaml} from "karavan-core/lib/api/CamelDefinitionYaml";
-import PushIcon from "@patternfly/react-icons/dist/esm/icons/code-branch-icon";
-import {RunnerToolbar} from "./RunnerToolbar";
-import {useFilesStore, useFileStore, useProjectStore} from "../api/ProjectStore";
+import {DevModeToolbar} from "./DevModeToolbar";
+import {useFileStore, useProjectStore} from "../api/ProjectStore";
 import {EventBus} from "../designer/utils/EventBus";
 import {ProjectService} from "../api/ProjectService";
 import {shallow} from "zustand/shallow";
@@ -38,10 +37,7 @@ interface Props {
 
 export const ProjectToolbar = (props: Props) => {
 
-    const [commitMessageIsOpen, setCommitMessageIsOpen] = useState(false);
-    const [commitMessage, setCommitMessage] = useState('');
     const [project, isPushing] = useProjectStore((state) => [state.project, state.isPushing], shallow )
-    const {files} = useFilesStore();
     const [file, editAdvancedProperties, setEditAdvancedProperties, setAddProperty] = useFileStore((state) =>
         [state.file, state.editAdvancedProperties, state.setEditAdvancedProperties, state.setAddProperty], shallow )
 
@@ -69,10 +65,6 @@ export const ProjectToolbar = (props: Props) => {
         return file !== undefined && file.name.endsWith("java");
     }
 
-    function needCommit(): boolean {
-        return project ? files.filter(f => f.lastUpdate > project.lastCommitTimestamp).length > 0 : false;
-    }
-
     function downloadImage () {
         EventBus.sendCommand("downloadImage");
     }
@@ -88,43 +80,6 @@ export const ProjectToolbar = (props: Props) => {
         }
     }
 
-    function push () {
-        setCommitMessageIsOpen(false);
-        ProjectService.pushProject(project, commitMessage);
-    }
-
-    function getDate(lastUpdate: number): string {
-        if (lastUpdate) {
-            const date = new Date(lastUpdate);
-            return date.toISOString().slice(0, 19).replace('T',' ');
-        } else {
-            return "N/A"
-        }
-    }
-
-    function getLastUpdatePanel() {
-        const color = needCommit() ? "grey" : "green";
-        const commit = project?.lastCommit;
-        return (
-            <Flex direction={{default: "row"}} justifyContent={{default: "justifyContentFlexStart"}}>
-                {project?.lastCommitTimestamp > 0 &&
-                    <FlexItem>
-                        <Tooltip content="Last update" position={TooltipPosition.bottom}>
-                            <Label color={color}>{getDate(project?.lastCommitTimestamp)}</Label>
-                        </Tooltip>
-                    </FlexItem>}
-                {project?.lastCommitTimestamp > 0 &&
-                <FlexItem>
-                    <Tooltip content={commit} position={TooltipPosition.bottom}>
-                        <Label
-                            color={color}>{commit ? commit?.substring(0, 18) : "-"}</Label>
-                    </Tooltip>
-                </FlexItem>}
-            </Flex>
-        )
-    }
-
-
     function getFileToolbar() {
         const { mode} = props;
         return <Toolbar id="toolbar-group-types">
@@ -135,22 +90,7 @@ export const ProjectToolbar = (props: Props) => {
                             <Label>{file?.code?.length}</Label>
                         </Tooltip>
                     </FlexItem>}
-                    {isRunnable() && <RunnerToolbar reloadOnly={true}/>}
-                    {!isFile && <FlexItem>
-                        <Tooltip content="Commit and push to git" position={"bottom-end"}>
-                            <Button isLoading={isPushing ? true : undefined}
-                                    isSmall
-                                    variant={needCommit() ? "primary" : "secondary"}
-                                    className="project-button"
-                                    icon={!isPushing ? <PushIcon/> : <div></div>}
-                                    onClick={() => {
-                                        setCommitMessage(commitMessage === '' ? new Date().toLocaleString() : commitMessage);
-                                        setCommitMessageIsOpen(true);
-                                    }}>
-                                {isPushing ? "..." : "Push"}
-                            </Button>
-                        </Tooltip>
-                    </FlexItem>}
+                    {isRunnable() && <DevModeToolbar reloadOnly={true}/>}
                     {isYaml() && <FlexItem>
                         <ToggleGroup>
                             <ToggleGroupItem text="Design" buttonId="design" isSelected={mode === "design"}
@@ -186,49 +126,13 @@ export const ProjectToolbar = (props: Props) => {
         return (<Toolbar id="toolbar-group-types">
             <ToolbarContent>
                 <Flex className="toolbar" direction={{default: "row"}} alignItems={{default: "alignItemsCenter"}}>
-                    <FlexItem>{getLastUpdatePanel()}</FlexItem>
-                    {isRunnable() && <RunnerToolbar/>}
-                    <FlexItem>
-                        <Tooltip content="Commit and push to git" position={"bottom-end"}>
-                            <Button isLoading={isPushing ? true : undefined}
-                                    isSmall
-                                    variant={needCommit() ? "primary" : "secondary"}
-                                    className="project-button"
-                                    icon={!isPushing ? <PushIcon/> : <div></div>}
-                                    onClick={() => {
-                                        setCommitMessage(commitMessage === '' ? new Date().toLocaleString() : commitMessage);
-                                        setCommitMessageIsOpen(true);
-                                    }}>
-                                {isPushing ? "..." : "Push"}
-                            </Button>
-                        </Tooltip>
-                    </FlexItem>
+                    {isRunnable() && <DevModeToolbar/>}
                 </Flex>
             </ToolbarContent>
         </Toolbar>)
     }
 
-    function getCommitModal() {
-        return (
-            <Modal
-                title="Commit"
-                variant={ModalVariant.small}
-                isOpen={commitMessageIsOpen}
-                onClose={() => setCommitMessageIsOpen(false)}
-                actions={[
-                    <Button key="confirm" variant="primary" onClick={() => push()}>Save</Button>,
-                    <Button key="cancel" variant="secondary" onClick={() => setCommitMessageIsOpen(false)}>Cancel</Button>
-                ]}
-            >
-                <Form autoComplete="off" isHorizontal className="create-file-form">
-                    <FormGroup label="Message" fieldId="name" isRequired>
-                        <TextInput value={commitMessage} onChange={value => setCommitMessage(value)}/>
-                        <FormHelperText isHidden={false} component="div"/>
-                    </FormGroup>
-                </Form>
-            </Modal>
-        )
-    }
+
 
     function isKameletsProject(): boolean {
         return project.projectId === 'kamelets';
@@ -249,7 +153,6 @@ export const ProjectToolbar = (props: Props) => {
             {/*{!isTemplates && getProjectToolbar()}*/}
              {!isFile() && getProjectToolbar()}
              {isFile() && getFileToolbar()}
-             {getCommitModal()}
         </>
     )
 }
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
index ee0135bf..a2b90e28 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
@@ -14,23 +14,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import React, {useEffect, useRef, useState} from 'react';
+import React, {useEffect, useState} from 'react';
 import {
     Card,
     CardBody, Flex, FlexItem, Divider, PageSection
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
-import {RunnerInfoPod} from "./RunnerInfoPod";
-import {RunnerInfoContext} from "./RunnerInfoContext";
-import {RunnerInfoMemory} from "./RunnerInfoMemory";
+import {InfoPod} from "./InfoPod";
+import {InfoContext} from "./InfoContext";
+import {InfoMemory} from "./InfoMemory";
 import {KaravanApi} from "../../api/KaravanApi";
-import {PodStatus} from "../../api/ProjectModels";
 import {useProjectStore} from "../../api/ProjectStore";
 
-export function isRunning(status: PodStatus): boolean {
-    return status.phase === 'Running' && !status.terminating;
-}
-
 export const DashboardTab = () => {
 
     const {project, podStatus} = useProjectStore();
@@ -41,7 +36,7 @@ export const DashboardTab = () => {
     useEffect(() => {
         const interval = setInterval(() => {
             onRefreshStatus();
-        }, 1000);
+        }, 2000);
         return () => {
             clearInterval(interval)
         };
@@ -50,21 +45,21 @@ export const DashboardTab = () => {
 
     function onRefreshStatus() {
         const projectId = project.projectId;
-        KaravanApi.getRunnerConsoleStatus(projectId, "memory", res => {
+        KaravanApi.getDevModeStatus(projectId, "memory", res => {
             if (res.status === 200) {
                 setMemory(res.data);
             } else {
                 setMemory({});
             }
         })
-        KaravanApi.getRunnerConsoleStatus(projectId, "jvm", res => {
+        KaravanApi.getDevModeStatus(projectId, "jvm", res => {
             if (res.status === 200) {
                 setJvm(res.data);
             } else {
                 setJvm({});
             }
         })
-        KaravanApi.getRunnerConsoleStatus(projectId, "context", res => {
+        KaravanApi.getDevModeStatus(projectId, "context", res => {
             if (res.status === 200) {
                 setContext(res.data);
             } else {
@@ -74,7 +69,7 @@ export const DashboardTab = () => {
     }
 
     function showConsole(): boolean {
-        return podStatus.phase !== '';
+        return podStatus.ready;
     }
 
     return (
@@ -84,15 +79,15 @@ export const DashboardTab = () => {
                     <Flex direction={{default: "row"}}
                           justifyContent={{default: "justifyContentSpaceBetween"}}>
                         <FlexItem flex={{default: "flex_1"}}>
-                            <RunnerInfoPod podStatus={podStatus}/>
+                            <InfoPod podStatus={podStatus}/>
                         </FlexItem>
                         <Divider orientation={{default: "vertical"}}/>
                         <FlexItem flex={{default: "flex_1"}}>
-                            <RunnerInfoMemory jvm={jvm} memory={memory} showConsole={showConsole()}/>
+                            <InfoMemory jvm={jvm} memory={memory} showConsole={showConsole()}/>
                         </FlexItem>
                         <Divider orientation={{default: "vertical"}}/>
                         <FlexItem flex={{default: "flex_1"}}>
-                            <RunnerInfoContext context={context} showConsole={showConsole()}/>
+                            <InfoContext context={context} showConsole={showConsole()}/>
                         </FlexItem>
                     </Flex>
                 </CardBody>
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoContext.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoContext.tsx
similarity index 99%
rename from karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoContext.tsx
rename to karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoContext.tsx
index c07cf810..69134d23 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoContext.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoContext.tsx
@@ -17,7 +17,7 @@ interface Props {
     showConsole: boolean
 }
 
-export const RunnerInfoContext = (props: Props) => {
+export const InfoContext = (props: Props) => {
 
     function getContextInfo() {
         return (
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoMemory.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoMemory.tsx
similarity index 98%
rename from karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoMemory.tsx
rename to karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoMemory.tsx
index 67e576ad..28aee4ac 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoMemory.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoMemory.tsx
@@ -18,7 +18,7 @@ interface Props {
     showConsole: boolean
 }
 
-export const RunnerInfoMemory = (props: Props) => {
+export const InfoMemory = (props: Props) => {
 
     function getJvmInfo() {
         return (
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoPod.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoPod.tsx
similarity index 59%
rename from karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoPod.tsx
rename to karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoPod.tsx
index 6dbda49c..af24bde5 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoPod.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoPod.tsx
@@ -12,18 +12,14 @@ import '../../designer/karavan.css';
 import DownIcon from "@patternfly/react-icons/dist/esm/icons/error-circle-o-icon";
 import UpIcon from "@patternfly/react-icons/dist/esm/icons/check-circle-icon";
 import {PodStatus} from "../../api/ProjectModels";
-import {useLogStore, useRunnerStore} from "../../api/ProjectStore";
+import {useLogStore} from "../../api/ProjectStore";
 
 
-export function isRunning(status: PodStatus): boolean {
-    return status.phase === 'Running' && !status.terminating;
-}
-
 interface Props {
     podStatus: PodStatus,
 }
 
-export const RunnerInfoPod = (props: Props) => {
+export const InfoPod = (props: Props) => {
 
     function getPodInfo() {
         const podStatus = props.podStatus;
@@ -40,42 +36,10 @@ export const RunnerInfoPod = (props: Props) => {
         )
     }
 
-    function getPodStatus() {
-        const podStatus = props.podStatus;
-        const status = !podStatus.terminating ? podStatus.phase : "Terminating"
-        return (
-            <Label icon={getIcon()} color={getColor()}>
-                {status !== "" ? status : "N/A"}
-            </Label>
-        )
-    }
-
-    function getPodRequests() {
-        const podStatus = props.podStatus;
-        const text = podStatus.requestCpu !== '' ? podStatus.requestCpu + " : " + podStatus.requestMemory : "N/A";
-        return (
-            <Label icon={getIcon()} color={getColor()}>
-                {text}
-            </Label>
-        )
-    }
-
-    function getPodCreation() {
-        const podStatus = props.podStatus;
-        const text = podStatus.creationTimestamp !== '' ? podStatus.creationTimestamp : "N/A";
-        return (
-            <Label icon={getIcon()} color={getColor()}>
-                {text}
-            </Label>
-        )
-    }
-
-    function getPodLimits() {
-        const podStatus = props.podStatus;
-        const text = podStatus.limitCpu !== '' ? podStatus.limitCpu + " : " + podStatus.limitMemory : "N/A";
+    function getPodInfoLabel(info: string) {
         return (
             <Label icon={getIcon()} color={getColor()}>
-                {text}
+                {info}
             </Label>
         )
     }
@@ -89,9 +53,10 @@ export const RunnerInfoPod = (props: Props) => {
     }
 
     function getRunning(): boolean {
-        return isRunning(props.podStatus);
+        return props.podStatus.ready;
     }
 
+    const podStatus = props.podStatus;
     return (
         <DescriptionList isHorizontal>
             <DescriptionListGroup>
@@ -103,25 +68,25 @@ export const RunnerInfoPod = (props: Props) => {
             <DescriptionListGroup>
                 <DescriptionListTerm>Status</DescriptionListTerm>
                 <DescriptionListDescription>
-                    {getPodStatus()}
+                    {getPodInfoLabel(podStatus.ready ? "Ready" : "Not Ready")}
                 </DescriptionListDescription>
             </DescriptionListGroup>
             <DescriptionListGroup>
-                <DescriptionListTerm>Requests</DescriptionListTerm>
+                <DescriptionListTerm>CPU</DescriptionListTerm>
                 <DescriptionListDescription>
-                    {getPodRequests()}
+                    {getPodInfoLabel(podStatus.cpuInfo)}
                 </DescriptionListDescription>
             </DescriptionListGroup>
             <DescriptionListGroup>
-                <DescriptionListTerm>Limits</DescriptionListTerm>
+                <DescriptionListTerm>Memory</DescriptionListTerm>
                 <DescriptionListDescription>
-                    {getPodLimits()}
+                    {getPodInfoLabel(podStatus.memoryInfo)}
                 </DescriptionListDescription>
             </DescriptionListGroup>
             <DescriptionListGroup>
                 <DescriptionListTerm>Created</DescriptionListTerm>
                 <DescriptionListDescription>
-                    {getPodCreation()}
+                    {getPodInfoLabel(podStatus.created)}
                 </DescriptionListDescription>
             </DescriptionListGroup>
         </DescriptionList>
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/files/FilesToolbar.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/files/FilesToolbar.tsx
index 00835fe4..d35ed094 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/files/FilesToolbar.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/files/FilesToolbar.tsx
@@ -14,20 +14,114 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import React from 'react';
+import React, {useEffect, useState} from 'react';
 import {
     Button,
     Flex,
-    FlexItem,
+    FlexItem, Form, FormGroup, FormHelperText, Label, Modal, ModalVariant, TextInput, Tooltip, TooltipPosition,
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import UploadIcon from "@patternfly/react-icons/dist/esm/icons/upload-icon";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
-import {useFileStore} from "../../api/ProjectStore";
+import {useFilesStore, useFileStore, useProjectStore} from "../../api/ProjectStore";
+import {shallow} from "zustand/shallow";
+import {ProjectService} from "../../api/ProjectService";
+import PushIcon from "@patternfly/react-icons/dist/esm/icons/code-branch-icon";
 
 export const FileToolbar = () => {
 
+    const [commitMessageIsOpen, setCommitMessageIsOpen] = useState(false);
+    const [commitMessage, setCommitMessage] = useState('');
+    const [project, isPushing] = useProjectStore((state) => [state.project, state.isPushing], shallow )
+    const {files} = useFilesStore();
+    const [file, editAdvancedProperties, setEditAdvancedProperties, setAddProperty] = useFileStore((state) =>
+        [state.file, state.editAdvancedProperties, state.setEditAdvancedProperties, state.setAddProperty], shallow )
+
+
+    useEffect(() => {
+        console.log("ProjectToolbar useEffect", isPushing, project.lastCommitTimestamp);
+    }, [project, file]);
+
+    function push () {
+        setCommitMessageIsOpen(false);
+        ProjectService.pushProject(project, commitMessage);
+    }
+
+    function getCommitModal() {
+        return (
+            <Modal
+                title="Commit"
+                variant={ModalVariant.small}
+                isOpen={commitMessageIsOpen}
+                onClose={() => setCommitMessageIsOpen(false)}
+                actions={[
+                    <Button key="confirm" variant="primary" onClick={() => push()}>Save</Button>,
+                    <Button key="cancel" variant="secondary" onClick={() => setCommitMessageIsOpen(false)}>Cancel</Button>
+                ]}
+            >
+                <Form autoComplete="off" isHorizontal className="create-file-form">
+                    <FormGroup label="Message" fieldId="name" isRequired>
+                        <TextInput value={commitMessage} onChange={value => setCommitMessage(value)}/>
+                        <FormHelperText isHidden={false} component="div"/>
+                    </FormGroup>
+                </Form>
+            </Modal>
+        )
+    }
+
+    function needCommit(): boolean {
+        return project ? files.filter(f => f.lastUpdate > project.lastCommitTimestamp).length > 0 : false;
+    }
+
+
+    function getDate(lastUpdate: number): string {
+        if (lastUpdate) {
+            const date = new Date(lastUpdate);
+            return date.toISOString().slice(0, 19).replace('T',' ');
+        } else {
+            return "N/A"
+        }
+    }
+
+    function getLastUpdatePanel() {
+        const color = needCommit() ? "grey" : "green";
+        const commit = project?.lastCommit;
+        return (
+            <Flex direction={{default: "row"}} justifyContent={{default: "justifyContentFlexStart"}}>
+                {project?.lastCommitTimestamp > 0 &&
+                    <FlexItem>
+                        <Tooltip content="Last update" position={TooltipPosition.bottom}>
+                            <Label color={color}>{getDate(project?.lastCommitTimestamp)}</Label>
+                        </Tooltip>
+                    </FlexItem>}
+                {project?.lastCommitTimestamp > 0 &&
+                    <FlexItem>
+                        <Tooltip content={commit} position={TooltipPosition.bottom}>
+                            <Label
+                                color={color}>{commit ? commit?.substring(0, 18) : "-"}</Label>
+                        </Tooltip>
+                    </FlexItem>}
+            </Flex>
+        )
+    }
+
     return <Flex className="toolbar" direction={{default: "row"}} justifyContent={{default: "justifyContentFlexEnd"}}>
+        <FlexItem>{getLastUpdatePanel()}</FlexItem>
+        <FlexItem>
+            <Tooltip content="Commit and push to git" position={"bottom-end"}>
+                <Button isLoading={isPushing ? true : undefined}
+                        isSmall
+                        variant={needCommit() ? "primary" : "secondary"}
+                        className="project-button"
+                        icon={!isPushing ? <PushIcon/> : <div></div>}
+                        onClick={() => {
+                            setCommitMessage(commitMessage === '' ? new Date().toLocaleString() : commitMessage);
+                            setCommitMessageIsOpen(true);
+                        }}>
+                    {isPushing ? "..." : "Push"}
+                </Button>
+            </Tooltip>
+        </FlexItem>
         <FlexItem>
             <Button isSmall variant={"secondary"} icon={<PlusIcon/>}
                     onClick={e => useFileStore.setState({operation:"create"})}>Create</Button>
@@ -36,5 +130,6 @@ export const FileToolbar = () => {
             <Button isSmall variant="secondary" icon={<UploadIcon/>}
                     onClick={e => useFileStore.setState({operation:"upload"})}>Upload</Button>
         </FlexItem>
+        {getCommitModal()}
     </Flex>
 }
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx
index 67ec90ea..25ac03f9 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx
@@ -201,10 +201,10 @@ export class ProjectStatus extends React.Component<Props, State> {
                     {podStatuses.length === 0 && <Label icon={<DownIcon/>} color={"grey"}>No pods</Label>}
                     <LabelGroup numLabels={2} isVertical>
                         {podStatuses.map(pod => {
-                                const running = pod.phase === 'Running' && !pod.terminating
+                                const ready = pod.ready;
                                 return (
-                                    <Tooltip key={pod.name} content={running ? "Running" : pod.phase}>
-                                        <Label icon={running ? <UpIcon/> : <DownIcon/>} color={running ? "green" : "red"}>
+                                    <Tooltip key={pod.name} content={ready ? "Ready" : "Not ready"}>
+                                        <Label icon={ready ? <UpIcon/> : <DownIcon/>} color={ready ? "green" : "red"}>
                                             <Button variant="link"
                                                     onClick={e => {
                                                         useLogStore.setState({
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
index a33eb340..aa076f81 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
@@ -55,7 +55,7 @@ export const TraceTab = () => {
     function onRefreshStatus() {
         const projectId = project.projectId;
         if (refreshTrace) {
-            KaravanApi.getRunnerConsoleStatus(projectId, "trace", res => {
+            KaravanApi.getDevModeStatus(projectId, "trace", res => {
                 if (res.status === 200) {
                     setTrace(res.data);
                 } else {


[camel-karavan] 04/07: DataGrid in bashi works #817

Posted by ma...@apache.org.
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 7f195bd8875b46562b393053b5f8d591f8a60259
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Wed Jul 12 14:58:51 2023 -0400

    DataGrid in bashi works #817
---
 karavan-cloud/karavan-bashi/.java-version          |  1 +
 .../camel/karavan/bashi/ConductorService.java      | 58 ++++++++++----
 .../apache/camel/karavan/bashi/KaravanBashi.java   |  2 +-
 .../karavan/bashi/docker/DockerEventListener.java  | 39 +++++----
 .../camel/karavan/bashi/docker/DockerService.java  | 92 ++++++++++++++++++----
 .../src/main/resources/application.properties      |  2 +-
 6 files changed, 146 insertions(+), 48 deletions(-)

diff --git a/karavan-cloud/karavan-bashi/.java-version b/karavan-cloud/karavan-bashi/.java-version
new file mode 100644
index 00000000..b4de3947
--- /dev/null
+++ b/karavan-cloud/karavan-bashi/.java-version
@@ -0,0 +1 @@
+11
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 71e2872b..7f4f0147 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
@@ -1,13 +1,13 @@
 package org.apache.camel.karavan.bashi;
 
+import com.github.dockerjava.api.model.Container;
 import com.github.dockerjava.api.model.HealthCheck;
+import com.github.dockerjava.api.model.Statistics;
 import io.quarkus.vertx.ConsumeEvent;
 import io.vertx.core.json.JsonObject;
 import org.apache.camel.karavan.bashi.docker.DockerService;
 import org.apache.camel.karavan.datagrid.DatagridService;
-import org.apache.camel.karavan.datagrid.model.CommandName;
-import org.apache.camel.karavan.datagrid.model.DevModeCommand;
-import org.apache.camel.karavan.datagrid.model.Project;
+import org.apache.camel.karavan.datagrid.model.*;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
 import org.jboss.logging.Logger;
 
@@ -46,6 +46,9 @@ public class ConductorService {
     @ConfigProperty(name = "infinispan.password")
     String infinispanPassword;
 
+    @ConfigProperty(name = "karavan.environment")
+    String environment;
+
     @Inject
     DockerService dockerService;
 
@@ -56,6 +59,7 @@ public class ConductorService {
 
     public static final String ADDRESS_INFINISPAN_START = "ADDRESS_INFINISPAN_START";
     public static final String ADDRESS_INFINISPAN_HEALTH = "ADDRESS_DATAGRID_HEALTH";
+    public static final String ADDRESS_CONTAINER_STATS = "ADDRESS_CONTAINER_STATS";
 
     @ConsumeEvent(value = ADDRESS_INFINISPAN_START, blocking = true, ordered = true)
     void startInfinispan(String data) throws InterruptedException {
@@ -73,11 +77,13 @@ public class ConductorService {
     }
 
     @ConsumeEvent(value = ADDRESS_INFINISPAN_HEALTH, blocking = true, ordered = true)
-    void startDatagridService(String infinispanHealth){
-        datagridService.start();
+    void startServices(String infinispanHealth){
+        if (infinispanHealth.equals("healthy")) {
+            datagridService.start();
+        }
     }
 
-//    @ConsumeEvent(value = ADDRESS_INFINISPAN_HEALTH, blocking = true, ordered = true)
+    @ConsumeEvent(value = ADDRESS_INFINISPAN_HEALTH, blocking = true, ordered = true)
     void startKaravan(String infinispanHealth) throws InterruptedException {
         if (infinispanHealth.equals("healthy")) {
             LOGGER.info("Karavan is starting...");
@@ -98,20 +104,42 @@ public class ConductorService {
 
     @ConsumeEvent(value = DatagridService.ADDRESS_DEVMODE_COMMAND, blocking = true, ordered = true)
     void receiveCommand(JsonObject message) throws InterruptedException {
-        System.out.println("receiveCommand " + message);
+        LOGGER.info("DevMode Command: " + message);
         DevModeCommand command = message.mapTo(DevModeCommand.class);
-        String runnerName = command.getProjectId() + "-" + DEVMODE_SUFFIX;
+        String containerName = command.getProjectId() + "-" + DEVMODE_SUFFIX;
+        Project p = datagridService.getProject(command.getProjectId());
         if (Objects.equals(command.getCommandName(), CommandName.RUN)) {
-            Project p = datagridService.getProject(command.getProjectId());
-            LOGGER.infof("Runner starting for %s", p.getProjectId());
-            dockerService.createContainer(runnerName, runnerImage,
+            LOGGER.infof("DevMode starting for %s", p.getProjectId());
+            Container container = dockerService.createContainer(containerName, runnerImage,
                     List.of(), "", false, new HealthCheck(), Map.of("type", "runner")
             );
-            dockerService.startContainer(runnerName);
-            LOGGER.infof("Runner started for %s", 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(runnerName);
-            dockerService.deleteContainer(runnerName);
+            dockerService.stopContainer(containerName);
+            dockerService.deleteContainer(containerName);
+            datagridService.deleteDevModeStatus(p.getName());
+        }
+    }
+
+    @ConsumeEvent(value = ADDRESS_CONTAINER_STATS, blocking = true, ordered = true)
+    public void saveStats(JsonObject data) {
+        String projectId = data.getString("projectId");
+        String memory = data.getString("memory");
+        String cpu = data.getString("cpu");
+        if (datagridService.isReady()) {
+            PodStatus podStatus = datagridService.getDevModePodStatuses(projectId, environment);
+            if (podStatus != null) {
+                podStatus.setCpuInfo(cpu);
+                podStatus.setMemoryInfo(memory);
+                datagridService.savePodStatus(podStatus);
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanBashi.java b/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanBashi.java
index 7b3ed5d7..f0a8a630 100644
--- a/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanBashi.java
+++ b/karavan-cloud/karavan-bashi/src/main/java/org/apache/camel/karavan/bashi/KaravanBashi.java
@@ -23,8 +23,8 @@ public class KaravanBashi {
 
     void onStart(@Observes StartupEvent ev) throws InterruptedException {
         LOGGER.info("Karavan Bashi is starting...");
-        dockerService.checkContainersStatus();
         dockerService.createNetwork();
+        dockerService.checkDataGridHealth();
         dockerService.startListeners();
         eventBus.publish(ConductorService.ADDRESS_INFINISPAN_START, "");
     }
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 64acd143..be068895 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.PodStatus;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
 import org.jboss.logging.Logger;
 
@@ -15,6 +16,7 @@ import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
 import java.io.Closeable;
 import java.io.IOException;
+import java.time.Instant;
 import java.util.Arrays;
 import java.util.Objects;
 
@@ -43,22 +45,31 @@ public class DockerEventListener implements ResultCallback<Event> {
     @Override
     public void onNext(Event event) {
 //        LOGGER.info(event.getType() + " : " + event.getStatus());
-        if (Objects.equals(event.getType(), EventType.CONTAINER)) {
-            Container container = dockerService.getContainer(event.getId());
-            String status = event.getStatus();
-            if (container.getNames()[0].equals("/infinispan") && status.startsWith("health_status:")) {
-                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 (container.getNames()[0].endsWith(Constants.DEVMODE_SUFFIX)) {
-                if (Arrays.asList("stop", "die", "kill", "pause", "destroy").contains(event.getStatus())) {
-                    String name = container.getNames()[0].replace("/", "");
-                    String projectId = name.replace("-" + Constants.DEVMODE_SUFFIX, "");
-                    datagridService.deletePodStatus(projectId, environment, name);
-                } else if (Arrays.asList("start", "unpause").contains(event.getStatus())) {
-
+        try {
+            if (Objects.equals(event.getType(), EventType.CONTAINER)) {
+                Container container = dockerService.getContainer(event.getId());
+                String status = event.getStatus();
+                if (container.getNames()[0].equals("/infinispan") && status.startsWith("health_status:")) {
+                    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 (container.getNames()[0].endsWith(Constants.DEVMODE_SUFFIX)) {
+                    if (Arrays.asList("stop", "die", "kill", "pause", "destroy").contains(event.getStatus())) {
+                        String name = container.getNames()[0].replace("/", "");
+                        String projectId = name.replace("-" + Constants.DEVMODE_SUFFIX, "");
+                        LOGGER.info("Deleted PodStatus for " + projectId);
+                        datagridService.deletePodStatus(projectId, environment, name);
+                    } else if (Arrays.asList("start", "unpause").contains(event.getStatus())) {
+                        String name = container.getNames()[0].replace("/", "");
+                        String projectId = name.replace("-" + Constants.DEVMODE_SUFFIX, "");
+                        PodStatus ps = new PodStatus(name, true, null, projectId, environment, true, Instant.ofEpochSecond(container.getCreated()).toString());
+                        LOGGER.info("Saved PodStatus for " + projectId);
+                        datagridService.savePodStatus(ps);
+                    }
                 }
             }
+        } catch (Exception exception) {
+            LOGGER.error(exception.getMessage());
         }
     }
 
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 44fa6824..80558b5f 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
@@ -12,25 +12,34 @@ import com.github.dockerjava.core.DockerClientImpl;
 import com.github.dockerjava.core.InvocationBuilder;
 import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
 import com.github.dockerjava.transport.DockerHttpClient;
+import io.quarkus.scheduler.Scheduled;
+import io.smallrye.mutiny.tuples.Tuple2;
 import io.vertx.core.eventbus.EventBus;
+import io.vertx.core.json.JsonObject;
+import org.apache.camel.karavan.bashi.Constants;
 import org.jboss.logging.Logger;
 
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
 import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.text.DecimalFormat;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
+import static org.apache.camel.karavan.bashi.ConductorService.ADDRESS_CONTAINER_STATS;
 import static org.apache.camel.karavan.bashi.ConductorService.ADDRESS_INFINISPAN_HEALTH;
+import static org.apache.camel.karavan.bashi.Constants.DATAGRID_CONTAINER_NAME;
 import static org.apache.camel.karavan.bashi.Constants.NETWORK_NAME;
 
 @ApplicationScoped
 public class DockerService {
 
     private static final Logger LOGGER = Logger.getLogger(DockerService.class.getName());
+    private static final DecimalFormat formatCpu = new DecimalFormat("0.00");
+    private static final DecimalFormat formatMiB = new DecimalFormat("0.0");
+    private static final DecimalFormat formatGiB = new DecimalFormat("0.00");
+    private static final Map<String, Tuple2<Long, Long>> previousStats = new ConcurrentHashMap<>();
 
     @Inject
     DockerEventListener dockerEventListener;
@@ -38,6 +47,57 @@ public class DockerService {
     @Inject
     EventBus eventBus;
 
+    @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());
+
+            String name = container.getNames()[0].replace("/", "");
+            String projectId = name.replace("-" + Constants.DEVMODE_SUFFIX, "");
+            String memoryUsage = formatMemory(stats.getMemoryStats().getUsage());
+            String memoryLimit = formatMemory(stats.getMemoryStats().getLimit());
+            JsonObject data = JsonObject.of(
+                    "projectId", projectId,
+                    "memory", memoryUsage + " / " + memoryLimit,
+                    "cpu", formatCpu(name, stats)
+            );
+            eventBus.publish(ADDRESS_CONTAINER_STATS, data);
+        });
+    }
+
+    private String formatMemory(Long memory) {
+        if (memory < (1073741824)) {
+            return formatMiB.format(memory.doubleValue() / 1048576) + "MiB";
+        } else {
+            return formatGiB.format(memory.doubleValue() / 1073741824) + "GiB";
+        }
+    }
+
+    private String formatCpu(String containerName, Statistics stats) {
+        double cpuUsage = 0;
+        long previousCpu = previousStats.containsKey(containerName) ? previousStats.get(containerName).getItem1() : -1;
+        long previousSystem = previousStats.containsKey(containerName) ? previousStats.get(containerName).getItem2() : -1;
+
+        CpuStatsConfig cpuStats = stats.getCpuStats();
+        if (cpuStats != null) {
+            CpuUsageConfig cpuUsageConfig = cpuStats.getCpuUsage();
+            long systemUsage = cpuStats.getSystemCpuUsage();
+            long totalUsage = cpuUsageConfig.getTotalUsage();
+
+            if (previousCpu != -1 && previousSystem != -1) {
+                float cpuDelta = totalUsage - previousCpu;
+                float systemDelta = systemUsage - previousSystem;
+
+                if (cpuDelta > 0 && systemDelta > 0) {
+                    cpuUsage = cpuDelta / systemDelta * cpuStats.getOnlineCpus() * 100;
+                }
+            }
+            previousStats.put(containerName, Tuple2.of(totalUsage, systemUsage));
+        }
+        return formatCpu.format(cpuUsage) + "%";
+    }
+
     public void startListeners() {
         getDockerClient().eventsCmd().exec(dockerEventListener);
     }
@@ -53,12 +113,12 @@ public class DockerService {
         }
     }
 
-    public void checkContainersStatus() {
-        getDockerClient().listContainersCmd().withShowAll(true).exec().stream()
+    public void checkDataGridHealth() {
+        getDockerClient().listContainersCmd().exec().stream()
                 .filter(c -> c.getState().equals("running"))
                 .forEach(c -> {
                     HealthState hs = getDockerClient().inspectContainerCmd(c.getId()).exec().getState().getHealth();
-                    if (c.getNames()[0].equals("/infinispan")) {
+                    if (c.getNames()[0].equals("/" + DATAGRID_CONTAINER_NAME)) {
                         eventBus.publish(ADDRESS_INFINISPAN_HEALTH, hs.getStatus());
                     }
                 });
@@ -69,14 +129,9 @@ public class DockerService {
         return containers.get(0);
     }
 
-    public List<Container> getRunnerContainer() {
-        return getDockerClient().listContainersCmd()
-                .withShowAll(true).withLabelFilter(Map.of("type", "runner")).exec();
-    }
-
-    public Statistics getContainerStats(String id) {
+    public Statistics getContainerStats(String containerId) {
         InvocationBuilder.AsyncResultCallback<Statistics> callback = new InvocationBuilder.AsyncResultCallback<>();
-        getDockerClient().statsCmd(id).withContainerId(id).exec(callback);
+        getDockerClient().statsCmd(containerId).withContainerId(containerId).withNoStream(true).exec(callback);
         Statistics stats = null;
         try {
             stats = callback.awaitResult();
@@ -87,7 +142,7 @@ public class DockerService {
         return stats;
     }
 
-    public void createContainer(String name, String image, List<String> env, String ports,
+    public Container createContainer(String name, String image, List<String> env, String ports,
                                 boolean exposedPort, HealthCheck healthCheck, Map<String, String> labels) throws InterruptedException {
         List<Container> containers = getDockerClient().listContainersCmd().withShowAll(true).withNameFilter(List.of(name)).exec();
         if (containers.size() == 0) {
@@ -95,7 +150,7 @@ public class DockerService {
 
             List<ExposedPort> exposedPorts = getPortsFromString(ports).values().stream().map(i -> ExposedPort.tcp(i)).collect(Collectors.toList());
 
-            CreateContainerResponse container = getDockerClient().createContainerCmd(image)
+            CreateContainerResponse response = getDockerClient().createContainerCmd(image)
                     .withName(name)
                     .withLabels(labels)
                     .withEnv(env)
@@ -104,9 +159,12 @@ public class DockerService {
                     .withHostConfig(getHostConfig(ports, exposedPort))
                     .withHealthcheck(healthCheck)
                     .exec();
-            LOGGER.info("Container created: " + container.getId());
+            LOGGER.info("Container created: " + response.getId());
+            return getDockerClient().listContainersCmd().withShowAll(true)
+                    .withIdFilter(Collections.singleton(response.getId())).exec().get(0);
         } else {
             LOGGER.info("Container already exists: " + containers.get(0).getId());
+            return containers.get(0);
         }
     }
 
diff --git a/karavan-cloud/karavan-bashi/src/main/resources/application.properties b/karavan-cloud/karavan-bashi/src/main/resources/application.properties
index 1ed3add7..534ad21d 100644
--- a/karavan-cloud/karavan-bashi/src/main/resources/application.properties
+++ b/karavan-cloud/karavan-bashi/src/main/resources/application.properties
@@ -11,7 +11,7 @@ karavan.port=8080:8080
 karavan.environment=dev
 karavan.default-runtime=quarkus
 karavan.runtimes=quarkus,spring-boot
-karavan.devmode-status-interval=2s
+karavan.container-stats-interval=5s
 
 # Git repository Configuration
 karavan.git-repository=${GIT_REPOSITORY}


[camel-karavan] 07/07: Trace In docker #817

Posted by ma...@apache.org.
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 d57e1eb2a94f997853f102b50b33ae687148304e
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Thu Jul 13 12:09:52 2023 -0400

    Trace In docker #817
---
 .../karavan-app/src/main/webui/src/Main.tsx        |  6 +++--
 .../src/main/webui/src/project/DevModeToolbar.tsx  | 26 ++++++++++++++--------
 .../src/main/webui/src/project/ProjectToolbar.tsx  | 14 ++----------
 .../webui/src/project/dashboard/DashboardTab.tsx   |  2 +-
 .../main/webui/src/project/dashboard/InfoPod.tsx   | 17 +-------------
 .../src/main/webui/src/project/trace/TraceTab.tsx  |  2 +-
 6 files changed, 26 insertions(+), 41 deletions(-)

diff --git a/karavan-cloud/karavan-app/src/main/webui/src/Main.tsx b/karavan-cloud/karavan-app/src/main/webui/src/Main.tsx
index 89e1a728..cf61f783 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/Main.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/Main.tsx
@@ -28,9 +28,9 @@ import {MainLogin} from "./MainLogin";
 import {DashboardPage} from "./dashboard/DashboardPage";
 import {Subscription} from "rxjs";
 import {ProjectEventBus} from "./api/ProjectEventBus";
-import {Project, ToastMessage} from "./api/ProjectModels";
+import {PodStatus, Project, ToastMessage} from "./api/ProjectModels";
 import {ProjectPage} from "./project/ProjectPage";
-import {useAppConfigStore, useFileStore} from "./api/ProjectStore";
+import {useAppConfigStore, useDevModeStore, useFileStore, useProjectStore} from "./api/ProjectStore";
 import {Notification} from "./Notification";
 
 class MenuItem {
@@ -175,6 +175,8 @@ export class Main extends React.Component<Props, State> {
                                 className={this.state.pageId === page.pageId ? "nav-button-selected" : ""}
                                 onClick={event => {
                                     useFileStore.setState({operation:'none', file: undefined})
+                                    useDevModeStore.setState({podName: undefined, status: "none"})
+                                    useProjectStore.setState({podStatus: new PodStatus({}), })
                                     this.setState({pageId: page.pageId});
                                 }}
                         />
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
index ee9e2c8b..99bff60e 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
@@ -1,16 +1,13 @@
 import React, {useState} from 'react';
-import {
-    Button, FlexItem, Switch,
-    Tooltip,
-    TooltipPosition
-} from '@patternfly/react-core';
+import {Button, Flex, FlexItem, Label, Switch, Tooltip, TooltipPosition} from '@patternfly/react-core';
 import '../designer/karavan.css';
 import RocketIcon from "@patternfly/react-icons/dist/esm/icons/rocket-icon";
 import ReloadIcon from "@patternfly/react-icons/dist/esm/icons/bolt-icon";
 import DeleteIcon from "@patternfly/react-icons/dist/esm/icons/times-circle-icon";
-import {useProjectStore, useDevModeStore} from "../api/ProjectStore";
+import {useDevModeStore, useLogStore, useProjectStore} from "../api/ProjectStore";
 import {ProjectService} from "../api/ProjectService";
 import {shallow} from "zustand/shallow";
+import UpIcon from "@patternfly/react-icons/dist/esm/icons/check-circle-icon";
 
 
 interface Props {
@@ -20,14 +17,25 @@ interface Props {
 export const DevModeToolbar = (props: Props) => {
 
     const [status] = useDevModeStore((state) => [state.status], shallow)
-    const [project] = useProjectStore((state) => [state.project], shallow)
+    const [project,podStatus ] = useProjectStore((state) => [state.project, state.podStatus], shallow)
     const [verbose, setVerbose] = useState(false);
 
     const isRunning = status === "running";
     const isStartingPod = status === "starting";
     const isReloadingPod = status === "reloading";
     const isDeletingPod = status === "deleting";
-    return (<>
+    return (<Flex className="toolbar" direction={{default: "row"}} alignItems={{default: "alignItemsCenter"}}>
+        {isRunning && <FlexItem>
+            <Label icon={<UpIcon/>} color={"green"}>
+                <Tooltip content={"Show log"} position={TooltipPosition.bottom}>
+                    <Button variant="link"
+                            onClick={e =>
+                                useLogStore.setState({showLog: true, type: 'container', podName: podStatus.name})}>
+                        {podStatus.name}
+                    </Button>
+                </Tooltip>
+            </Label>
+        </FlexItem>}
         {(isRunning || isDeletingPod) && !isReloadingPod && props.reloadOnly !== true && <FlexItem>
             <Tooltip content="Stop devmode" position={TooltipPosition.bottom}>
                 <Button isLoading={isDeletingPod ? true : undefined}
@@ -73,5 +81,5 @@ export const DevModeToolbar = (props: Props) => {
                 </Button>
             </Tooltip>
         </FlexItem>}
-    </>);
+    </Flex>);
 }
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx
index c65d5ced..4e6c5704 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx
@@ -1,16 +1,10 @@
-import React, {useEffect, useState} from 'react';
+import React, {useEffect} from 'react';
 import {
     Button,
     Checkbox,
     Flex,
     FlexItem,
-    Form,
-    FormGroup,
-    FormHelperText,
     Label,
-    Modal,
-    ModalVariant,
-    TextInput,
     ToggleGroup,
     ToggleGroupItem,
     Toolbar,
@@ -125,15 +119,11 @@ export const ProjectToolbar = (props: Props) => {
     function getProjectToolbar() {
         return (<Toolbar id="toolbar-group-types">
             <ToolbarContent>
-                <Flex className="toolbar" direction={{default: "row"}} alignItems={{default: "alignItemsCenter"}}>
-                    {isRunnable() && <DevModeToolbar/>}
-                </Flex>
+                {isRunnable() && <DevModeToolbar/>}
             </ToolbarContent>
         </Toolbar>)
     }
 
-
-
     function isKameletsProject(): boolean {
         return project.projectId === 'kamelets';
     }
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
index 0c065908..1831dd65 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
@@ -36,7 +36,7 @@ export const DashboardTab = () => {
     useEffect(() => {
         const interval = setInterval(() => {
             onRefreshStatus();
-        }, 2000);
+        }, 1000);
         return () => {
             clearInterval(interval)
         };
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoPod.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoPod.tsx
index af24bde5..5e544ac1 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoPod.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/dashboard/InfoPod.tsx
@@ -21,21 +21,6 @@ interface Props {
 
 export const InfoPod = (props: Props) => {
 
-    function getPodInfo() {
-        const podStatus = props.podStatus;
-        return (
-            <Label icon={getIcon()} color={getColor()}>
-                <Tooltip content={"Show log"}>
-                    <Button variant="link"
-                            onClick={e =>
-                                useLogStore.setState({showLog: true, type: 'container', podName: podStatus.name})}>
-                        {podStatus.name}
-                    </Button>
-                </Tooltip>
-            </Label>
-        )
-    }
-
     function getPodInfoLabel(info: string) {
         return (
             <Label icon={getIcon()} color={getColor()}>
@@ -62,7 +47,7 @@ export const InfoPod = (props: Props) => {
             <DescriptionListGroup>
                 <DescriptionListTerm>Pod</DescriptionListTerm>
                 <DescriptionListDescription>
-                    {getPodInfo()}
+                    {getPodInfoLabel(podStatus.name)}
                 </DescriptionListDescription>
             </DescriptionListGroup>
             <DescriptionListGroup>
diff --git a/karavan-cloud/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx b/karavan-cloud/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
index aa076f81..f10bf0ab 100644
--- a/karavan-cloud/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
+++ b/karavan-cloud/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
@@ -57,7 +57,7 @@ export const TraceTab = () => {
         if (refreshTrace) {
             KaravanApi.getDevModeStatus(projectId, "trace", res => {
                 if (res.status === 200) {
-                    setTrace(res.data);
+                    setTrace(JSON.parse(res.data.status));
                 } else {
                     setTrace({});
                 }