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/05 16:10:43 UTC

[camel-karavan] branch main updated: Fix #809

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


The following commit(s) were added to refs/heads/main by this push:
     new 88f0157f Fix #809
88f0157f is described below

commit 88f0157f94ca5974122df3b1ecf6445e12c6481a
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Wed Jul 5 12:10:35 2023 -0400

    Fix #809
---
 .../apache/camel/karavan/api/LogWatchResource.java | 12 -------
 .../camel/karavan/service/StatusService.java       |  5 ++-
 karavan-app/src/main/webui/src/api/KaravanApi.tsx  |  2 +-
 .../src/main/webui/src/api/ProjectService.ts       |  3 +-
 karavan-app/src/main/webui/src/api/ProjectStore.ts | 11 ++++--
 .../main/webui/src/project/log/ProjectLogPanel.tsx | 24 +++++++------
 .../webui/src/project/pipeline/ProjectStatus.tsx   | 39 ++++++++++------------
 .../src/main/webui/src/project/trace/TraceTab.tsx  |  1 -
 .../main/webui/src/projects/ProjectsTableRow.tsx   | 17 +++++++---
 9 files changed, 58 insertions(+), 56 deletions(-)

diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/LogWatchResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/LogWatchResource.java
index fd1183bd..5b1ba723 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/api/LogWatchResource.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/LogWatchResource.java
@@ -30,15 +30,11 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.sse.Sse;
 import javax.ws.rs.sse.SseEventSink;
-import javax.xml.crypto.Data;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.util.Date;
 import java.util.concurrent.ConcurrentHashMap;
 
-import static org.apache.camel.karavan.service.RunnerService.RUNNER_SUFFIX;
-
 @Path("/api/logwatch")
 public class LogWatchResource {
 
@@ -62,14 +58,6 @@ public class LogWatchResource {
         managedExecutor.execute(() -> {
             LOGGER.info("LogWatch for " + name + " starting...");
             try (SseEventSink sink = eventSink) {
-//                    while (true) {
-//                        sink.send(sse.newEvent(new Date().toString()));
-//                        try {
-//                            Thread.sleep(2000);
-//                        } catch (InterruptedException e) {
-//                            throw new RuntimeException(e);
-//                        }
-//                    }
                 LogWatch logWatch = type.equals("container")
                         ? kubernetesService.getContainerLogWatch(name)
                         : kubernetesService.getPipelineRunLogWatch(name);
diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java
index a993437d..99917a5e 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java
@@ -36,7 +36,6 @@ import org.jboss.logging.Logger;
 
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
-import javax.ws.rs.core.Response;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -82,7 +81,7 @@ public class StatusService {
         return webClient;
     }
 
-//    @ConsumeEvent(value = CMD_COLLECT_PROJECT_STATUS, blocking = true, ordered = true)
+    @ConsumeEvent(value = CMD_COLLECT_PROJECT_STATUS, blocking = true, ordered = true)
     public void collectProjectStatus(JsonObject data) {
         String projectId = data.getString("projectId");
         String env = data.getString("env");
@@ -98,7 +97,7 @@ public class StatusService {
         }
     }
 
-//    @ConsumeEvent(value = CMD_COLLECT_ALL_STATUSES, blocking = true, ordered = true)
+    @ConsumeEvent(value = CMD_COLLECT_ALL_STATUSES, blocking = true, ordered = true)
     public void collectAllStatuses(String data) {
         String all = "ALL_PROJECTS";
         if ((System.currentTimeMillis() - lastCollect.getOrDefault(all, 0L)) > threshold) {
diff --git a/karavan-app/src/main/webui/src/api/KaravanApi.tsx b/karavan-app/src/main/webui/src/api/KaravanApi.tsx
index a5eb75ef..8ce5abc0 100644
--- a/karavan-app/src/main/webui/src/api/KaravanApi.tsx
+++ b/karavan-app/src/main/webui/src/api/KaravanApi.tsx
@@ -588,7 +588,7 @@ export class KaravanApi {
                     }
                 },
                 onmessage(event) {
-                    ProjectEventBus.sendLog('add', event.data)
+                    ProjectEventBus.sendLog('add', event.data);
                 },
                 onclose() {
                     console.log("Connection closed by the server");
diff --git a/karavan-app/src/main/webui/src/api/ProjectService.ts b/karavan-app/src/main/webui/src/api/ProjectService.ts
index 204a9cf2..1f8f7193 100644
--- a/karavan-app/src/main/webui/src/api/ProjectService.ts
+++ b/karavan-app/src/main/webui/src/api/ProjectService.ts
@@ -44,7 +44,7 @@ export class ProjectService {
         ProjectEventBus.sendLog("set", '');
         KaravanApi.deleteRunner(project.projectId, false, res => {
             if (res.status === 202) {
-                useLogStore.setState({showLog: false, type: 'container'})
+                useLogStore.setState({showLog: false, type: 'container', isRunning: false})
             } else {
                 ProjectEventBus.sendAlert(new ToastMessage("Error delete runner", res.statusText, 'warning'))
             }
@@ -62,6 +62,7 @@ export class ProjectService {
                     }
                     if (useRunnerStore.getState().status !== "running"){
                         useRunnerStore.setState({status: "running"})
+                        useLogStore.setState({isRunning: true})
                     }
                     useProjectStore.setState({podStatus: res.data});
                 })
diff --git a/karavan-app/src/main/webui/src/api/ProjectStore.ts b/karavan-app/src/main/webui/src/api/ProjectStore.ts
index 89c6e77e..9298e283 100644
--- a/karavan-app/src/main/webui/src/api/ProjectStore.ts
+++ b/karavan-app/src/main/webui/src/api/ProjectStore.ts
@@ -72,9 +72,10 @@ export const useProjectStore = create<ProjectState>((set) => ({
     isPushing: false,
     isRunning: false,
     podStatus: new PodStatus(),
-    setProject: (p: Project) => {
+    setProject: (project: Project, operation:  "create" | "select" | "delete"| "none" | "copy") => {
         set((state: ProjectState) => ({
-            project: p
+            project: project,
+            operation: operation
         }));
     },
     setOperation: (o: "create" | "select" | "delete"| "none" | "copy") => {
@@ -168,6 +169,7 @@ export const useRunnerStore = create<RunnerState>((set) => ({
 
 interface LogState {
     podName?: string,
+    isRunning: boolean,
     data: string;
     setData: (data: string) => void;
     addData: (data: string) => void;
@@ -178,11 +180,13 @@ interface LogState {
     setShowLog: (showLog: boolean) => void;
     type: 'container' | 'pipeline' | 'none',
     setType: (type: 'container' | 'pipeline' | 'none') => void,
+    setIsRunning: (isRunning: boolean) => void;
 }
 
 export const useLogStore = create<LogState>((set) => ({
     podName: undefined,
     data: '',
+    isRunning: false,
     setData: (data: string)  => {
         set({data: data})
     },
@@ -200,6 +204,9 @@ export const useLogStore = create<LogState>((set) => ({
     setShowLog: (showLog: boolean) => {
         set(() => ({showLog: showLog}));
     },
+    setIsRunning: (isRunning: boolean) => {
+        set(() => ({isRunning: isRunning}));
+    },
     type: "none",
     setType: (type: 'container' | 'pipeline' | 'none') =>  {
         set((state: LogState) => ({type: type}));
diff --git a/karavan-app/src/main/webui/src/project/log/ProjectLogPanel.tsx b/karavan-app/src/main/webui/src/project/log/ProjectLogPanel.tsx
index a0c51a94..619b1ff7 100644
--- a/karavan-app/src/main/webui/src/project/log/ProjectLogPanel.tsx
+++ b/karavan-app/src/main/webui/src/project/log/ProjectLogPanel.tsx
@@ -14,8 +14,8 @@ import {ProjectLog} from "./ProjectLog";
 const INITIAL_LOG_HEIGHT = "50%";
 
 export const ProjectLogPanel = () => {
-    const [showLog, type, setShowLog, podName] = useLogStore(
-        (state) => [state.showLog, state.type, state.setShowLog, state.podName], shallow)
+    const [showLog, type, setShowLog, podName, isRunning] = useLogStore(
+        (state) => [state.showLog, state.type, state.setShowLog, state.podName, state.isRunning], shallow)
 
     const [height, setHeight] = useState(INITIAL_LOG_HEIGHT);
     const [isTextWrapped, setIsTextWrapped] = useState(true);
@@ -24,9 +24,9 @@ export const ProjectLogPanel = () => {
     const [currentPodName, setCurrentPodName] = useState<string | undefined>(undefined);
 
     useEffect(() => {
-        console.log("ProjectLogPanel", showLog, type, podName);
+        console.log("ProjectLogPanel", showLog, type, podName, isRunning);
         const controller = new AbortController();
-        if (showLog && type !== 'none' && podName !== undefined) {
+        if (showLog && type !== 'none' && podName !== undefined && isRunning) {
             const f = KaravanApi.fetchData(type, podName, controller).then(value => {
                 console.log("Fetch Started for: " + podName)
             });
@@ -37,7 +37,7 @@ export const ProjectLogPanel = () => {
             console.log("end");
             controller.abort();
         };
-    }, [showLog, type, podName]);
+    }, [showLog, type, podName, isRunning]);
 
     useEffect(() => {
         if (currentPodName !== podName) {
@@ -48,18 +48,20 @@ export const ProjectLogPanel = () => {
 
     function getButtons() {
         return (<div className="buttons">
-            <Label className="log-name">{podName!== undefined ? (type + ": " + podName) : ''}</Label>
+            <Label className="log-name">{podName !== undefined ? (type + ": " + podName) : ''}</Label>
             <Tooltip content={"Clean log"} position={TooltipPosition.bottom}>
                 <Button variant="plain" onClick={() => ProjectEventBus.sendLog('set', '')} icon={<CleanIcon/>}/>
             </Tooltip>
-            <Checkbox label="Wrap text" aria-label="wrap text checkbox" isChecked={isTextWrapped} id="wrap-text-checkbox"
-                      onChange={checked => setIsTextWrapped(checked)} />
-            <Checkbox label="Autoscroll" aria-label="autoscroll checkbox" isChecked={autoScroll} id="autoscroll-checkbox"
-                      onChange={checked => setAutoScroll(checked)} />
+            <Checkbox label="Wrap text" aria-label="wrap text checkbox" isChecked={isTextWrapped}
+                      id="wrap-text-checkbox"
+                      onChange={checked => setIsTextWrapped(checked)}/>
+            <Checkbox label="Autoscroll" aria-label="autoscroll checkbox" isChecked={autoScroll}
+                      id="autoscroll-checkbox"
+                      onChange={checked => setAutoScroll(checked)}/>
             {/*<Tooltip content={"Scroll to bottom"} position={TooltipPosition.bottom}>*/}
             {/*    <Button variant="plain" onClick={() => } icon={<ScrollIcon/>}/>*/}
             {/*</Tooltip>*/}
-            <Tooltip content={height === "100%" ? "Collapse": "Expand"} position={TooltipPosition.bottom}>
+            <Tooltip content={height === "100%" ? "Collapse" : "Expand"} position={TooltipPosition.bottom}>
                 <Button variant="plain" onClick={() => {
                     const h = height === "100%" ? INITIAL_LOG_HEIGHT : "100%";
                     setHeight(h);
diff --git a/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx b/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx
index d4bb077a..67ec90ea 100644
--- a/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx
+++ b/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx
@@ -15,7 +15,7 @@ import DownIcon from "@patternfly/react-icons/dist/esm/icons/error-circle-o-icon
 import ClockIcon from "@patternfly/react-icons/dist/esm/icons/clock-icon";
 import DeleteIcon from "@patternfly/react-icons/dist/esm/icons/times-circle-icon";
 import {CamelStatus, DeploymentStatus, PipelineStatus, PodStatus, Project} from "../../api/ProjectModels";
-import {useLogStore, useRunnerStore} from "../../api/ProjectStore";
+import {useLogStore} from "../../api/ProjectStore";
 
 interface Props {
     project: Project,
@@ -62,7 +62,6 @@ export class ProjectStatus extends React.Component<Props, State> {
         if (this.props.project) {
             KaravanApi.getProjectPipelineStatus(projectId, env, (status?: PipelineStatus) => {
                 this.setState({pipelineStatus: status});
-                // console.log(status);
             });
             KaravanApi.getProjectDeploymentStatus(projectId, env, (status?: DeploymentStatus) => {
                 this.setState({deploymentStatus: status});
@@ -84,19 +83,19 @@ export class ProjectStatus extends React.Component<Props, State> {
             case "deployment":
                 KaravanApi.deleteDeployment(environment, name, (res: any) => {
                     // if (Array.isArray(res) && Array.from(res).length > 0)
-                        // this.onRefresh();
+                    // this.onRefresh();
                 });
                 break;
             case "pod":
                 KaravanApi.deletePod(environment, name, (res: any) => {
                     // if (Array.isArray(res) && Array.from(res).length > 0)
-                        // this.onRefresh();
+                    // this.onRefresh();
                 });
                 break;
             case "pipelinerun":
                 KaravanApi.stopPipelineRun(environment, name, (res: any) => {
                     // if (Array.isArray(res) && Array.from(res).length > 0)
-                        // this.onRefresh();
+                    // this.onRefresh();
                 });
                 break;
         }
@@ -107,7 +106,6 @@ export class ProjectStatus extends React.Component<Props, State> {
         KaravanApi.pipelineRun(this.props.project, this.props.env, res => {
             if (res.status === 200 || res.status === 201) {
                 this.setState({isBuilding: false});
-                useLogStore.setState({showLog: true, type: 'pipeline', podName:  res.data})
             } else {
                 // Todo notification
             }
@@ -212,7 +210,8 @@ export class ProjectStatus extends React.Component<Props, State> {
                                                         useLogStore.setState({
                                                             showLog: true,
                                                             type: 'container',
-                                                            podName: pod.name
+                                                            podName: pod.name,
+                                                            isRunning: true
                                                         });
                                                     }}>
                                                 {pod.name}
@@ -247,12 +246,6 @@ export class ProjectStatus extends React.Component<Props, State> {
         return (status === 'UP' ? <UpIcon/> : <DownIcon/>)
     }
 
-    showPipelineLog(pipeline: string, env: string) {
-        if (pipeline) {
-            useLogStore.setState({showLog: true, type: 'pipeline', podName:  pipeline})
-        }
-    }
-
     getHealthPanel(env: string) {
         const status = this.state.camelStatus;
         const routesStatus = status?.routesStatus;
@@ -296,20 +289,24 @@ export class ProjectStatus extends React.Component<Props, State> {
                         <LabelGroup numLabels={2}>
                             <Label icon={isRunning ? <Spinner isSVG diameter="16px" className="spinner"/> : icon} color={color}>
                                 {pipeline
-                                    ? <Button variant="link" onClick={e => this.showPipelineLog(pipeline, env)}>
+                                    ? <Button variant="link" onClick={e =>
+                                        useLogStore.setState({showLog: true, type: 'pipeline', podName: pipeline, isRunning: true})
+                                    }>
                                         {pipeline}
                                     </Button>
                                     : "No pipeline"}
                                 {isRunning && <Tooltip content={"Stop PipelineRun"}>
-                                    <Button icon={<DeleteIcon/>} variant="link" onClick={e => this.setState({
-                                        showDeleteConfirmation: true,
-                                        deleteEntity: "pipelinerun",
-                                        deleteEntityEnv: env,
-                                        deleteEntityName: pipeline
-                                    })}></Button>
+                                    <Button icon={<DeleteIcon/>} variant="link" onClick={e =>
+                                        this.setState({
+                                            showDeleteConfirmation: true,
+                                            deleteEntity: "pipelinerun",
+                                            deleteEntityEnv: env,
+                                            deleteEntityName: pipeline
+                                        })
+                                    }></Button>
                                 </Tooltip>}
                             </Label>
-                            {pipeline && showTime && lastPipelineRunTime !== undefined &&
+                            {pipeline !== undefined && showTime === true && lastPipelineRunTime !== undefined &&
                                 <Label icon={<ClockIcon className="not-spinner"/>} color={color}>{lastPipelineRunTime + "s"}</Label>}
                         </LabelGroup>
                     </Tooltip>
diff --git a/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx b/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
index f1c5b2cb..a33eb340 100644
--- a/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
+++ b/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
@@ -43,7 +43,6 @@ export const TraceTab = () => {
     const [refreshTrace, setRefreshTrace] = useState(false);
 
     useEffect(() => {
-        console.log("TraceTab useEffect", refreshTrace, project)
         const interval = setInterval(() => {
             onRefreshStatus();
         }, 1000);
diff --git a/karavan-app/src/main/webui/src/projects/ProjectsTableRow.tsx b/karavan-app/src/main/webui/src/projects/ProjectsTableRow.tsx
index 701d1424..a416035f 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectsTableRow.tsx
+++ b/karavan-app/src/main/webui/src/projects/ProjectsTableRow.tsx
@@ -10,8 +10,14 @@ import { Td, Tr} from "@patternfly/react-table";
 import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
 import CopyIcon from "@patternfly/react-icons/dist/esm/icons/copy-icon";
 import {DeploymentStatus, Project} from '../api/ProjectModels';
-import {useAppConfigStore, useDeploymentStatusesStore, useProjectStore} from "../api/ProjectStore";
+import {
+    useAppConfigStore,
+    useDeploymentStatusesStore,
+    useLogStore,
+    useProjectStore,
+} from "../api/ProjectStore";
 import {ProjectEventBus} from "../api/ProjectEventBus";
+import {shallow} from "zustand/shallow";
 
 interface Props {
     project: Project
@@ -21,6 +27,8 @@ export const ProjectsTableRow = (props: Props) => {
 
     const {statuses} = useDeploymentStatusesStore();
     const {config} = useAppConfigStore();
+    const [setProject] = useProjectStore((state) => [state.setProject, state.setOperation], shallow);
+    const [setShowLog] = useLogStore((state) => [state.setShowLog], shallow);
 
     function getEnvironments(): string [] {
         return config.environments && Array.isArray(config.environments) ? Array.from(config.environments) : [];
@@ -46,7 +54,8 @@ export const ProjectsTableRow = (props: Props) => {
             </Td>
             <Td>
                 <Button style={{padding: '6px'}} variant={"link"} onClick={e => {
-                    useProjectStore.setState({project: project, operation: "select"});
+                    setProject(project, "select");
+                    setShowLog(false);
                     ProjectEventBus.selectProject(project);
                 }}>
                     {project.projectId}
@@ -78,14 +87,14 @@ export const ProjectsTableRow = (props: Props) => {
                             <Tooltip content={"Copy project"} position={"bottom"}>
                                 <Button variant={"plain"} icon={<CopyIcon/>}
                                         onClick={e => {
-                                            useProjectStore.setState({project: project, operation: "copy"});
+                                            setProject(project, "copy");
                                         }}></Button>
                             </Tooltip>
                         </FlexItem>
                         <FlexItem>
                             <Tooltip content={"Delete project"} position={"bottom"}>
                                 <Button variant={"plain"} icon={<DeleteIcon/>} onClick={e => {
-                                    useProjectStore.setState({project: project, operation: "delete"});
+                                    setProject(project, "delete");
                                 }}></Button>
                             </Tooltip>
                         </FlexItem>