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 87a0b0fa Installation UI for #817
87a0b0fa is described below

commit 87a0b0faf50f7a8a455dc378e1ffb621c6306cdf
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Wed Sep 6 18:42:22 2023 -0400

    Installation UI for #817
---
 .../org/apache/camel/karavan/api/AuthResource.java | 33 +++++++++++
 .../camel/karavan/api/ConfigurationResource.java   |  3 +-
 .../karavan/infinispan/InfinispanService.java      |  4 +-
 .../karavan/kubernetes/KubernetesService.java      |  6 +-
 .../camel/karavan/service/KaravanService.java      | 13 ++++-
 .../camel/karavan/service/ProjectService.java      |  4 +-
 .../apache/camel/karavan/shared/Configuration.java |  9 +++
 .../snippets/quarkus-builder-script-docker.sh      | 32 +++++++++++
 .../snippets/spring-boot-builder-script-docker.sh  | 32 +++++++++++
 .../src/main/webui/src/api/KaravanApi.tsx          |  2 +-
 .../src/main/webui/src/api/ProjectModels.ts        |  1 +
 .../karavan-app/src/main/webui/src/main/Main.tsx   | 64 +++++++++++++++++++---
 .../src/main/webui/src/main/MainDataPoller.tsx     | 42 +++++++-------
 13 files changed, 203 insertions(+), 42 deletions(-)

diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/AuthResource.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/AuthResource.java
index ad4b6416..ed067a60 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/AuthResource.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/AuthResource.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.karavan.api;
 
+import org.apache.camel.karavan.infinispan.InfinispanService;
+import org.apache.camel.karavan.kubernetes.KubernetesService;
 import org.apache.camel.karavan.service.AuthService;
 
 import jakarta.inject.Inject;
@@ -24,6 +26,13 @@ import jakarta.ws.rs.Path;
 import jakarta.ws.rs.Produces;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
+import org.apache.camel.karavan.service.ProjectService;
+import org.apache.camel.karavan.shared.Configuration;
+import org.eclipse.microprofile.health.HealthCheckResponse;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 
 @Path("/public")
 public class AuthResource {
@@ -31,6 +40,15 @@ public class AuthResource {
     @Inject
     AuthService authService;
 
+    @Inject
+    ProjectService projectService;
+
+    @Inject
+    KubernetesService kubernetesService;
+
+    @Inject
+    InfinispanService infinispanService;
+
     @GET
     @Path("/auth")
     @Produces(MediaType.TEXT_PLAIN)
@@ -44,4 +62,19 @@ public class AuthResource {
     public Response ssoConfig() throws Exception {
         return Response.ok(authService.getSsoConfig()).build();
     }
+
+    @GET
+    @Path("/readiness")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getConfiguration() throws Exception {
+        List<HealthCheckResponse> list = List.of(
+                infinispanService.call(),
+                kubernetesService.call(),
+                projectService.call()
+        );
+        return Response.ok(Map.of(
+                "status", list.stream().allMatch(h -> 
Objects.equals(h.getStatus(), HealthCheckResponse.Status.UP)),
+                "checks", list
+        )).build();
+    }
 }
\ No newline at end of file
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java
index a2c8dbcc..4b43f169 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java
@@ -16,14 +16,13 @@
  */
 package org.apache.camel.karavan.api;
 
-import org.apache.camel.karavan.shared.ConfigService;
-
 import jakarta.inject.Inject;
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.Path;
 import jakarta.ws.rs.Produces;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
+import org.apache.camel.karavan.shared.ConfigService;
 
 @Path("/api/configuration")
 public class ConfigurationResource {
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java
index cda9603d..1734d8a4 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java
@@ -385,9 +385,9 @@ public class InfinispanService implements HealthCheck {
     @Override
     public HealthCheckResponse call() {
         if (isReady()) {
-            return HealthCheckResponse.named("infinispan").up().build();
+            return HealthCheckResponse.named("Infinispan").up().build();
         } else {
-            return HealthCheckResponse.named("infinispan").down().build();
+            return HealthCheckResponse.named("Infinispan").down().build();
         }
     }
 }
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/KubernetesService.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/KubernetesService.java
index 90423baf..abdf4f48 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/KubernetesService.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/KubernetesService.java
@@ -128,12 +128,12 @@ public class KubernetesService implements HealthCheck {
     public HealthCheckResponse call() {
         if (ConfigService.inKubernetes()) {
             if (informers.size() == INFORMERS) {
-                return 
HealthCheckResponse.named("kubernetes").withData("mode", 
"kubernetes").up().build();
+                return HealthCheckResponse.named("Kubernetes").up().build();
             } else {
-                return HealthCheckResponse.named("kubernetes").down().build();
+                return HealthCheckResponse.named("Kubernetes").down().build();
             }
         } else {
-            return HealthCheckResponse.named("kubernetes").withData("mode", 
"kubernetesless").up().build();
+            return HealthCheckResponse.named("Kubernetesless").up().build();
         }
     }
 
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java
index 744ed95d..1d2270d4 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java
@@ -18,6 +18,7 @@ package org.apache.camel.karavan.service;
 
 import io.quarkus.runtime.Quarkus;
 import io.quarkus.runtime.ShutdownEvent;
+import io.quarkus.runtime.Startup;
 import io.quarkus.runtime.StartupEvent;
 import io.quarkus.vertx.ConsumeEvent;
 import io.vertx.core.eventbus.EventBus;
@@ -30,14 +31,19 @@ import 
org.apache.camel.karavan.infinispan.InfinispanService;
 import org.apache.camel.karavan.kubernetes.KubernetesService;
 import org.apache.camel.karavan.shared.ConfigService;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.eclipse.microprofile.health.HealthCheck;
+import org.eclipse.microprofile.health.HealthCheckResponse;
+import org.eclipse.microprofile.health.Liveness;
 import org.jboss.logging.Logger;
 
 import jakarta.enterprise.event.Observes;
 import jakarta.inject.Inject;
 import java.io.IOException;
 
+@Startup
+@Liveness
 @Singleton
-public class KaravanService {
+public class KaravanService implements HealthCheck {
 
     private static final Logger LOGGER = 
Logger.getLogger(KaravanService.class.getName());
 
@@ -78,6 +84,11 @@ public class KaravanService {
     private static final String START_INTERNAL_DOCKER_SERVICES = 
"START_INTERNAL_DOCKER_SERVICES";
     private static final String START_SERVICES = "START_SERVICES";
 
+    @Override
+    public HealthCheckResponse call() {
+        return HealthCheckResponse.up("Karavan");
+    }
+
     void onStart(@Observes StartupEvent ev) throws Exception {
         if (!ConfigService.inKubernetes()) {
             eventBus.publish(START_INTERNAL_DOCKER_SERVICES, null);
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
index 00123f52..8755ca93 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
@@ -93,9 +93,9 @@ public class ProjectService implements HealthCheck {
     @Override
     public HealthCheckResponse call() {
         if (ready.get()) {
-            return HealthCheckResponse.named("project").up().build();
+            return HealthCheckResponse.named("Projects").up().build();
         } else {
-            return HealthCheckResponse.named("project").down().build();
+            return HealthCheckResponse.named("Projects").down().build();
         }
     }
 
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Configuration.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Configuration.java
index 6ccabdf9..cec29fda 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Configuration.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Configuration.java
@@ -25,6 +25,7 @@ public class Configuration {
     private List<String> environments;
     private String runtime;
     private List<String> runtimes;
+    private List<Object> status;
 
     public Configuration() {
     }
@@ -85,4 +86,12 @@ public class Configuration {
     public void setRuntimes(List<String> runtimes) {
         this.runtimes = runtimes;
     }
+
+    public List<Object> getStatus() {
+        return status;
+    }
+
+    public void setStatus(List<Object> status) {
+        this.status = status;
+    }
 }
diff --git 
a/karavan-web/karavan-app/src/main/resources/snippets/quarkus-builder-script-docker.sh
 
b/karavan-web/karavan-app/src/main/resources/snippets/quarkus-builder-script-docker.sh
new file mode 100644
index 00000000..037632f8
--- /dev/null
+++ 
b/karavan-web/karavan-app/src/main/resources/snippets/quarkus-builder-script-docker.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+CHECKOUT_DIR="/scripts"
+KAMELETS_DIR="/scripts/kamelets"
+
+if  [[ ${GIT_REPOSITORY} == https* ]] ;
+then
+    replacer=https://${GIT_USERNAME}:${GIT_PASSWORD}@
+    prefix=https://
+    url="${GIT_REPOSITORY/$prefix/$replacer}"
+    git clone --depth 1 --branch ${GIT_BRANCH} $url ${CHECKOUT_DIR}
+elif [[ ${GIT_REPOSITORY} == http* ]] ;
+then
+  replacer=http://${GIT_USERNAME}:${GIT_PASSWORD}@
+      prefix=http://
+      url="${GIT_REPOSITORY/$prefix/$replacer}"
+      git clone --depth 1 --branch ${GIT_BRANCH} $url ${CHECKOUT_DIR}
+else
+    git clone --depth 1 --branch ${GIT_BRANCH} ${GIT_REPOSITORY} 
${CHECKOUT_DIR}
+fi
+
+cd ${CHECKOUT_DIR}/${PROJECT_ID}
+
+jbang -Dcamel.jbang.version=${CAMEL_VERSION} camel@apache/camel export 
--local-kamelet-dir=${KAMELETS_DIR}
+
+export LAST_COMMIT=$(git rev-parse --short HEAD)
+export DATE=${TAG}
+
+mvn package jib:build \
+  -Djib.allowInsecureRegistries=true \
+  -Djib.to.image=${IMAGE_REGISTRY}/${IMAGE_GROUP}/${PROJECT_ID}:${DATE} \
+  -Djib.to.auth.username=${IMAGE_REGISTRY_USERNAME} \
+  -Djib.to.auth.password=${IMAGE_REGISTRY_PASSWORD}
\ No newline at end of file
diff --git 
a/karavan-web/karavan-app/src/main/resources/snippets/spring-boot-builder-script-docker.sh
 
b/karavan-web/karavan-app/src/main/resources/snippets/spring-boot-builder-script-docker.sh
new file mode 100644
index 00000000..037632f8
--- /dev/null
+++ 
b/karavan-web/karavan-app/src/main/resources/snippets/spring-boot-builder-script-docker.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+CHECKOUT_DIR="/scripts"
+KAMELETS_DIR="/scripts/kamelets"
+
+if  [[ ${GIT_REPOSITORY} == https* ]] ;
+then
+    replacer=https://${GIT_USERNAME}:${GIT_PASSWORD}@
+    prefix=https://
+    url="${GIT_REPOSITORY/$prefix/$replacer}"
+    git clone --depth 1 --branch ${GIT_BRANCH} $url ${CHECKOUT_DIR}
+elif [[ ${GIT_REPOSITORY} == http* ]] ;
+then
+  replacer=http://${GIT_USERNAME}:${GIT_PASSWORD}@
+      prefix=http://
+      url="${GIT_REPOSITORY/$prefix/$replacer}"
+      git clone --depth 1 --branch ${GIT_BRANCH} $url ${CHECKOUT_DIR}
+else
+    git clone --depth 1 --branch ${GIT_BRANCH} ${GIT_REPOSITORY} 
${CHECKOUT_DIR}
+fi
+
+cd ${CHECKOUT_DIR}/${PROJECT_ID}
+
+jbang -Dcamel.jbang.version=${CAMEL_VERSION} camel@apache/camel export 
--local-kamelet-dir=${KAMELETS_DIR}
+
+export LAST_COMMIT=$(git rev-parse --short HEAD)
+export DATE=${TAG}
+
+mvn package jib:build \
+  -Djib.allowInsecureRegistries=true \
+  -Djib.to.image=${IMAGE_REGISTRY}/${IMAGE_GROUP}/${PROJECT_ID}:${DATE} \
+  -Djib.to.auth.username=${IMAGE_REGISTRY_USERNAME} \
+  -Djib.to.auth.password=${IMAGE_REGISTRY_PASSWORD}
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx 
b/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx
index 259f5420..e9704a20 100644
--- a/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx
@@ -85,7 +85,7 @@ export class KaravanApi {
     }
 
     static async getReadiness(after: (readiness: any) => void) {
-        axios.get('/q/health/ready', {headers: {'Accept': 'application/json'}})
+        axios.get('/public/readiness', {headers: {'Accept': 
'application/json'}})
             .then(res => {
                 if (res.status === 200) {
                     after(res.data);
diff --git a/karavan-web/karavan-app/src/main/webui/src/api/ProjectModels.ts 
b/karavan-web/karavan-app/src/main/webui/src/api/ProjectModels.ts
index 6888c0b0..29f62995 100644
--- a/karavan-web/karavan-app/src/main/webui/src/api/ProjectModels.ts
+++ b/karavan-web/karavan-app/src/main/webui/src/api/ProjectModels.ts
@@ -7,6 +7,7 @@ export class AppConfig {
     environments: string[] = [];
     runtime: string = '';
     runtimes: string[] = [];
+    status: any[] = [];
 }
 
 export enum ProjectType {
diff --git a/karavan-web/karavan-app/src/main/webui/src/main/Main.tsx 
b/karavan-web/karavan-app/src/main/webui/src/main/Main.tsx
index 75ec85ec..6e4d70d6 100644
--- a/karavan-web/karavan-app/src/main/webui/src/main/Main.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/main/Main.tsx
@@ -1,7 +1,17 @@
-import {Routes, Route, Navigate} from 'react-router-dom';
+import {Navigate, Route, Routes} from 'react-router-dom';
 import React, {useEffect, useRef} from "react";
 import {KaravanApi} from "../api/KaravanApi";
-import {Bullseye, Flex, FlexItem, Page, Spinner} from "@patternfly/react-core";
+import {
+    Bullseye, capitalize,
+    Flex,
+    FlexItem,
+    Page,
+    ProgressStep,
+    ProgressStepper,
+    Spinner,
+    Tooltip,
+    TooltipPosition
+} from "@patternfly/react-core";
 import Icon from "../Logo";
 import {MainLogin} from "./MainLogin";
 import {DashboardPage} from "../dashboard/DashboardPage";
@@ -20,10 +30,10 @@ import {TemplatesPage} from "../templates/TemplatesPage";
 import {EventBus} from "../designer/utils/EventBus";
 import {Notification} from "../designer/utils/Notification";
 
-export function Main () {
+export function Main() {
 
-    const [config] = useAppConfigStore((state) => [state.config], shallow)
-    const { getData, getStatuses } = useMainHook();
+    const [config, readiness] = useAppConfigStore((s) => [s.config, 
s.readiness], shallow)
+    const {getData, getStatuses} = useMainHook();
 
     const initialized = useRef(false)
 
@@ -57,14 +67,50 @@ export function Main () {
         EventBus.sendAlert(title, text, variant)
     }
 
+    function showSpinner() {
+        return KaravanApi.authType === undefined || readiness === undefined;
+    }
+
+    function showStepper() {
+        return readiness !== undefined && readiness.status !== true;
+    }
+
+    function getStepper() {
+        const steps: any[] = Array.isArray(readiness.checks) ? 
readiness.checks : [];
+        return (
+            <Bullseye className="">
+                <ProgressStepper aria-label="Readiness progress" 
isCenterAligned isVertical >
+                    {steps.map(step => (
+                        <ProgressStep
+                            variant={step.status === 'UP' ? "success" : "info"}
+                            id={step.name}
+                            titleId={step.name}
+                            aria-label={step.name}
+                        >
+                            {step.name}
+                        </ProgressStep>
+                    ))}
+                </ProgressStepper>
+            </Bullseye>
+        )
+    }
+
+    function showMain() {
+        return !showStepper() && !showSpinner() && (KaravanApi.isAuthorized || 
KaravanApi.authType === 'public');
+    }
+
     return (
         <Page className="karavan">
-            {KaravanApi.authType === undefined &&
+            {showSpinner() &&
                 <Bullseye className="loading-page">
                     <Spinner className="spinner" diameter="140px" 
aria-label="Loading..."/>
-                    <div className="logo-placeholder">{Icon()}</div>
-                </Bullseye>}
-            {(KaravanApi.isAuthorized || KaravanApi.authType === 'public') &&
+                    <Tooltip content="Connecting to server..." 
position={TooltipPosition.bottom}>
+                        <div className="logo-placeholder">{Icon()}</div>
+                    </Tooltip>
+                </Bullseye>
+            }
+            {showStepper() && getStepper()}
+            {showMain() &&
                 <Flex direction={{default: "row"}} style={{width: "100%", 
height: "100%"}}
                       alignItems={{default: "alignItemsStretch"}} 
spaceItems={{default: 'spaceItemsNone'}}>
                     <FlexItem>
diff --git a/karavan-web/karavan-app/src/main/webui/src/main/MainDataPoller.tsx 
b/karavan-web/karavan-app/src/main/webui/src/main/MainDataPoller.tsx
index 8d7de7ab..31885ad0 100644
--- a/karavan-web/karavan-app/src/main/webui/src/main/MainDataPoller.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/main/MainDataPoller.tsx
@@ -30,7 +30,7 @@ export function MainDataPoller () {
         return () => {
             clearInterval(interval);
         };
-    }, [project, readiness]);
+    }, [project]);
 
     function getData() {
         KaravanApi.getReadiness((r: any) => {
@@ -38,29 +38,27 @@ export function MainDataPoller () {
         })
         if (readiness) {
             setLoading(true);
-            KaravanApi.getConfiguration((config: AppConfig) => {
-                if (project.projectId === undefined) {
-                    KaravanApi.getProjects((projects: Project[]) => {
-                        setProjects(projects);
-                    });
-                }
-                KaravanApi.getAllDeploymentStatuses((statuses: 
DeploymentStatus[]) => {
-                    setDeployments(statuses);
+            if (project.projectId === undefined) {
+                KaravanApi.getProjects((projects: Project[]) => {
+                    setProjects(projects);
                 });
-                KaravanApi.getAllServiceStatuses((statuses: ServiceStatus[]) 
=> {
-                    setServices(statuses);
-                });
-                KaravanApi.getAllContainerStatuses((statuses: 
ContainerStatus[]) => {
-                    setContainers(statuses);
-                });
-                KaravanApi.getAllCamelStatuses(config.environment, (statuses: 
CamelStatus[]) => {
-                    setCamels(statuses);
-                });
-                KaravanApi.getPipelineStatuses(config.environment, (status: 
PipelineStatus[]) => {
-                    setPipelineStatuses(status);
-                });
-                setLoading(false);
+            }
+            KaravanApi.getAllDeploymentStatuses((statuses: DeploymentStatus[]) 
=> {
+                setDeployments(statuses);
+            });
+            KaravanApi.getAllServiceStatuses((statuses: ServiceStatus[]) => {
+                setServices(statuses);
+            });
+            KaravanApi.getAllContainerStatuses((statuses: ContainerStatus[]) 
=> {
+                setContainers(statuses);
+            });
+            KaravanApi.getAllCamelStatuses(config.environment, (statuses: 
CamelStatus[]) => {
+                setCamels(statuses);
+            });
+            KaravanApi.getPipelineStatuses(config.environment, (status: 
PipelineStatus[]) => {
+                setPipelineStatuses(status);
             });
+            setLoading(false);
         }
     }
 

Reply via email to