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/12/04 23:09:12 UTC

(camel-karavan) 01/02: Fix #934

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 dbfcf4fcd9fcc09feae646c86bbdbd044d6b78ff
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Mon Dec 4 18:08:23 2023 -0500

    Fix #934
---
 .../camel/karavan/api/ProjectGitResource.java      | 17 +++++--
 .../org/apache/camel/karavan/git/GitService.java   |  9 +---
 .../camel/karavan/service/ProjectService.java      | 22 ++++-----
 .../src/main/webui/src/api/KaravanApi.tsx          | 10 ++--
 .../src/main/webui/src/api/ProjectService.ts       | 19 +++++++-
 .../src/main/webui/src/api/ProjectStore.ts         |  2 +
 .../main/webui/src/project/files/FilesToolbar.tsx  | 53 ++++++++++++++++++++--
 7 files changed, 100 insertions(+), 32 deletions(-)

diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectGitResource.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectGitResource.java
index 948b88a2..efcdfbff 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectGitResource.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectGitResource.java
@@ -19,14 +19,18 @@ package org.apache.camel.karavan.api;
 import jakarta.inject.Inject;
 import jakarta.ws.rs.*;
 import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
 import org.apache.camel.karavan.infinispan.model.Project;
 import org.apache.camel.karavan.service.ProjectService;
+import org.jboss.logging.Logger;
 
 import java.util.HashMap;
 
 @Path("/api/git")
 public class ProjectGitResource {
 
+    private static final Logger LOGGER = Logger.getLogger(ProjectGitResource.class.getName());
+
     @Inject
     ProjectService projectService;
 
@@ -37,11 +41,18 @@ public class ProjectGitResource {
         return projectService.commitAndPushProject(params.get("projectId"), params.get("message"));
     }
 
-    @GET
+    @PUT
     @Produces(MediaType.APPLICATION_JSON)
     @Consumes(MediaType.APPLICATION_JSON)
     @Path("/{projectId}")
-    public Project pull(@PathParam("projectId") String projectId) throws Exception {
-        return projectService.importProject(projectId);
+    public Response pull(@PathParam("projectId") String projectId) {
+        try {
+            projectService.importProject(projectId);
+            return Response.ok().build();
+        } catch (Exception e) {
+            LOGGER.error(e.getMessage());
+            return Response.serverError().entity(e.getMessage()).build();
+        }
+
     }
 }
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/git/GitService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/git/GitService.java
index 010750a2..779e0edb 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/git/GitService.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/git/GitService.java
@@ -166,13 +166,8 @@ public class GitService {
         return new ArrayList<>(0);
     }
 
-    public GitRepo readProjectFromRepository(String projectId) {
-        Git git = null;
-        try {
-            git = getGit(true, vertx.fileSystem().createTempDirectoryBlocking(UUID.randomUUID().toString()));
-        } catch (Exception e) {
-            LOGGER.error("Error", e);
-        }
+    public GitRepo readProjectFromRepository(String projectId) throws GitAPIException, IOException, URISyntaxException {
+        Git git = getGit(true, vertx.fileSystem().createTempDirectoryBlocking(UUID.randomUUID().toString()));
         return readProjectsFromRepository(git, projectId).get(0);
     }
 
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 fca9c3c1..eeeb6c08 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
@@ -288,15 +288,10 @@ public class ProjectService implements HealthCheck {
         }
     }
 
-    public Project importProject(String projectId) {
+    public Project importProject(String projectId) throws Exception {
         LOGGER.info("Import project from Git " + projectId);
-        try {
-            GitRepo repo = gitService.readProjectFromRepository(projectId);
-            return importProjectFromRepo(repo);
-        } catch (Exception e) {
-            LOGGER.error("Error during project import", e);
-            return null;
-        }
+        GitRepo repo = gitService.readProjectFromRepository(projectId);
+        return importProjectFromRepo(repo);
     }
 
     private Project importProjectFromRepo(GitRepo repo) {
@@ -318,9 +313,14 @@ public class ProjectService implements HealthCheck {
     public Project getProjectFromRepo(GitRepo repo) {
         String folderName = repo.getName();
         String propertiesFile = codeService.getPropertiesFile(repo);
-        String projectName = codeService.getProjectName(propertiesFile);
-        String projectDescription = codeService.getProjectDescription(propertiesFile);
-        return new Project(folderName, projectName, projectDescription, repo.getCommitId(), repo.getLastCommitTimestamp());
+        if (propertiesFile != null) {
+            String projectName = codeService.getProjectName(propertiesFile);
+            String projectDescription = codeService.getProjectDescription(propertiesFile);
+            return new Project(folderName, projectName, projectDescription, repo.getCommitId(), repo.getLastCommitTimestamp());
+        } else {
+            return new Project(folderName, folderName, folderName, repo.getCommitId(), repo.getLastCommitTimestamp());
+        }
+
     }
 
     public Project commitAndPushProject(String projectId, String message) throws Exception {
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 8f584d93..00b3441f 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
@@ -294,14 +294,12 @@ export class KaravanApi {
         });
     }
 
-    static async pull(projectId: string, after: (res: AxiosResponse<any>) => void) {
-        instance.get('/api/git/' + projectId)
+    static async pull(projectId: string, after: (res: AxiosResponse<any> | any) => void) {
+        instance.put('/api/git/' + projectId)
             .then(res => {
-                if (res.status === 200) {
-                    after(res.data);
-                }
+                after(res);
             }).catch(err => {
-            console.log(err);
+            after(err);
         });
     }
 
diff --git a/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts b/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts
index 3c1588bc..11f4d89b 100644
--- a/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts
+++ b/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts
@@ -127,15 +127,30 @@ export class ProjectService {
         };
         KaravanApi.push(params, res => {
             if (res.status === 200 || res.status === 201) {
-                useProjectStore.setState({isPushing: false})
                 ProjectService.refreshProject(project.projectId);
                 ProjectService.refreshProjectData(project.projectId);
             } else {
-                // Todo notification
+                EventBus.sendAlert("Error pushing", (res as any)?.response?.data, 'danger')
             }
+            useProjectStore.setState({isPushing: false})
         });
     }
 
+    public static pullProject(projectId: string) {
+            useProjectStore.setState({isPulling: true})
+            KaravanApi.pull(projectId, res => {
+                console.log(res);
+                if (res.status === 200 || res.status === 201) {
+                    useProjectStore.setState({isPulling: false})
+                    ProjectService.refreshProject(projectId);
+                    ProjectService.refreshProjectData(projectId);
+                } else {
+                    EventBus.sendAlert("Error pulling", (res as any)?.response?.data, 'danger')
+                }
+                useProjectStore.setState({isPulling: false})
+            });
+        }
+
     public static reloadKamelets() {
         KaravanApi.getKamelets(yamls => {
             const kamelets: string[] = [];
diff --git a/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts b/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts
index 23d90b90..02a65dd0 100644
--- a/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts
+++ b/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts
@@ -107,6 +107,7 @@ export const useProjectsStore = createWithEqualityFn<ProjectsState>((set) => ({
 }), shallow)
 
 interface ProjectState {
+    isPulling: boolean,
     isPushing: boolean,
     isRunning: boolean,
     images: string [],
@@ -131,6 +132,7 @@ export const useProjectStore = createWithEqualityFn<ProjectState>((set) => ({
     operation: 'none',
     tabIndex: 'files',
     isPushing: false,
+    isPulling: false,
     isRunning: false,
     setProject: (project: Project, operation:  "create" | "select" | "delete"| "none" | "copy") => {
         set((state: ProjectState) => ({
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/files/FilesToolbar.tsx b/karavan-web/karavan-app/src/main/webui/src/project/files/FilesToolbar.tsx
index 9acb08b9..2b22b917 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/files/FilesToolbar.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/files/FilesToolbar.tsx
@@ -16,6 +16,7 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
+    Alert,
     Button,
     Flex,
     FlexItem,
@@ -41,8 +42,9 @@ import RefreshIcon from "@patternfly/react-icons/dist/esm/icons/sync-alt-icon";
 export function FileToolbar () {
 
     const [commitMessageIsOpen, setCommitMessageIsOpen] = useState(false);
+    const [pullIsOpen, setPullIsOpen] = useState(false);
     const [commitMessage, setCommitMessage] = useState('');
-    const [project, isPushing] = useProjectStore((state) => [state.project, state.isPushing], shallow )
+    const [project, isPushing, isPulling] = useProjectStore((s) => [s.project, s.isPushing, s.isPulling], shallow )
     const {files} = useFilesStore();
     const [file, editAdvancedProperties, setEditAdvancedProperties, setAddProperty, setFile] = useFileStore((s) =>
         [s.file, s.editAdvancedProperties, s.setEditAdvancedProperties, s.setAddProperty, s.setFile], shallow )
@@ -56,6 +58,11 @@ export function FileToolbar () {
         ProjectService.pushProject(project, commitMessage);
     }
 
+    function pull () {
+        setPullIsOpen(false);
+        ProjectService.pullProject(project.projectId);
+    }
+
     function canAddFiles(): boolean {
         return !['templates', 'services'].includes(project.projectId);
     }
@@ -63,12 +70,12 @@ export function FileToolbar () {
     function getCommitModal() {
         return (
             <Modal
-                title="Commit"
+                title="Commit and push"
                 variant={ModalVariant.small}
                 isOpen={commitMessageIsOpen}
                 onClose={() => setCommitMessageIsOpen(false)}
                 actions={[
-                    <Button key="confirm" variant="primary" onClick={() => push()}>Save</Button>,
+                    <Button key="confirm" variant="primary" onClick={() => push()}>Commit and push</Button>,
                     <Button key="cancel" variant="secondary" onClick={() => setCommitMessageIsOpen(false)}>Cancel</Button>
                 ]}
             >
@@ -82,6 +89,30 @@ export function FileToolbar () {
         )
     }
 
+    function getPullModal() {
+        return (
+            <Modal
+                title="Pull"
+                titleIconVariant={"danger"}
+                variant={ModalVariant.small}
+                isOpen={pullIsOpen}
+                onClose={() => setPullIsOpen(false)}
+                actions={[
+                    <Button key="confirm" variant="danger" isDanger onClick={() => pull()}>Pull</Button>,
+                    <Button key="cancel" variant="primary" onClick={() => setPullIsOpen(false)}>Cancel</Button>
+                ]}
+            >
+                <div>
+                    <Alert customIcon={<PushIcon />}
+                           isInline
+                           variant="danger"
+                           title="Pulling code from git rewrites all non-commited code in the project!"
+                    />
+                </div>
+            </Modal>
+        )
+    }
+
     function needCommit(): boolean {
         return project ? files.filter(f => f.lastUpdate > project.lastCommitTimestamp).length > 0 : false;
     }
@@ -137,6 +168,21 @@ export function FileToolbar () {
             </Tooltip>
         </FlexItem>}
         <FlexItem>{getLastUpdatePanel()}</FlexItem>
+        <FlexItem>
+            <Tooltip content="Pull from git" position={"bottom-end"}>
+                <Button isLoading={isPulling ? true : undefined}
+                        size="sm"
+                        variant={"secondary"}
+                        isDanger
+                        className="project-button"
+                        icon={!isPulling ? <PushIcon/> : <div></div>}
+                        onClick={() => {
+                            setPullIsOpen(true);
+                        }}>
+                    {isPulling ? "..." : "Pull"}
+                </Button>
+            </Tooltip>
+        </FlexItem>
         <FlexItem>
             <Tooltip content="Commit and push to git" position={"bottom-end"}>
                 <Button isLoading={isPushing ? true : undefined}
@@ -161,5 +207,6 @@ export function FileToolbar () {
                     onClick={e => setFile("upload")}>Upload</Button>
         </FlexItem>}
         {getCommitModal()}
+        {getPullModal()}
     </Flex>
 }