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/11/10 16:06:41 UTC

(camel-karavan) branch main updated: #973 - Copy project (#985)

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 6d28f007 #973 - Copy project (#985)
6d28f007 is described below

commit 6d28f007c22f844532df662ed9c39145b5e2b60b
Author: Mario Volf <mv...@users.noreply.github.com>
AuthorDate: Fri Nov 10 17:06:36 2023 +0100

    #973 - Copy project (#985)
    
    * mvolf - web - Implement copy project functionality
    
    * mvolf - web - Implement copy project functionality
    
    * #973 - Copy project
    
    * #973 - Copy project
---
 .../apache/camel/karavan/api/ProjectResource.java  | 18 +------
 .../karavan/infinispan/InfinispanService.java      | 12 ++---
 .../camel/karavan/infinispan/model/GroupedKey.java |  1 -
 .../camel/karavan/service/ProjectService.java      | 58 ++++++++++++++++++++++
 .../org/apache/camel/karavan/shared/Property.java  | 18 +++++++
 .../src/main/webui/src/api/ProjectService.ts       | 11 ++++
 .../main/webui/src/projects/CreateProjectModal.tsx |  4 +-
 .../webui/src/templates/CreateProjectModal.tsx     |  4 +-
 8 files changed, 99 insertions(+), 27 deletions(-)

diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java
index af14df34..ab2042e2 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java
@@ -32,9 +32,7 @@ import org.jboss.logging.Logger;
 import java.net.URLDecoder;
 import java.nio.charset.StandardCharsets;
 import java.util.List;
-import java.util.Map;
 import java.util.Objects;
-import java.util.stream.Collectors;
 
 @Path("/api/project")
 public class ProjectResource {
@@ -154,20 +152,6 @@ public class ProjectResource {
     @Consumes(MediaType.APPLICATION_JSON)
     @Path("/copy/{sourceProject}")
     public Project copy(@PathParam("sourceProject") String sourceProject, Project project) throws Exception {
-//        Save project
-        Project s = infinispanService.getProject(sourceProject);
-        infinispanService.saveProject(project);
-//        Copy files
-        Map<GroupedKey, ProjectFile> map = infinispanService.getProjectFilesMap(sourceProject).entrySet().stream()
-                .collect(Collectors.toMap(
-                        e -> new GroupedKey(project.getProjectId(), e.getKey().getEnv(), e.getKey().getKey()),
-                        e -> {
-                            ProjectFile file = e.getValue();
-                            file.setProjectId(project.getProjectId());
-                            return file;
-                        })
-                );
-        infinispanService.saveProjectFiles(map);
-        return project;
+        return projectService.copy(sourceProject, project);
     }
 }
\ No newline at end of file
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 6b1e9d6e..27492c57 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
@@ -160,7 +160,7 @@ public class InfinispanService implements HealthCheck {
                 .setParameter("name", filename)
                 .setParameter("projectId", projectId)
                 .execute().list();
-        return list.size() > 0 ? list.get(0) : null;
+        return !list.isEmpty() ? list.get(0) : null;
     }
 
     public List<ProjectFile> getProjectFilesByName(String filename) {
@@ -174,12 +174,10 @@ public class InfinispanService implements HealthCheck {
         files.put(GroupedKey.create(file.getProjectId(), DEFAULT_ENVIRONMENT, file.getName()), file);
     }
 
-    public void saveProjectFiles(Map<GroupedKey, ProjectFile> f) {
-        Map<GroupedKey, ProjectFile> files = new HashMap<>(f.size());
-        f.forEach((groupedKey, projectFile) -> {
-            projectFile.setLastUpdate(Instant.now().toEpochMilli());
-        });
-        files.putAll(files);
+    public void saveProjectFiles(Map<GroupedKey, ProjectFile> filesToSave) {
+        long lastUpdate = Instant.now().toEpochMilli();
+        filesToSave.forEach((groupedKey, projectFile) -> projectFile.setLastUpdate(lastUpdate));
+        files.putAll(filesToSave);
     }
 
     public void deleteProject(String projectId) {
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/GroupedKey.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/GroupedKey.java
index 285a96e4..6d619d90 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/GroupedKey.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/GroupedKey.java
@@ -19,7 +19,6 @@ package org.apache.camel.karavan.infinispan.model;
 
 import org.infinispan.protostream.annotations.ProtoFactory;
 import org.infinispan.protostream.annotations.ProtoField;
-//import org.infinispan.distribution.group.Group;
 
 
 public class GroupedKey {
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 7ed2c1cc..b163dbd8 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
@@ -28,6 +28,8 @@ import org.apache.camel.karavan.infinispan.InfinispanService;
 import org.apache.camel.karavan.infinispan.model.*;
 import org.apache.camel.karavan.kubernetes.KubernetesService;
 import org.apache.camel.karavan.registry.RegistryService;
+import org.apache.camel.karavan.shared.Property;
+import org.apache.commons.lang3.StringUtils;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
 import org.eclipse.microprofile.health.HealthCheck;
@@ -184,6 +186,62 @@ public class ProjectService implements HealthCheck {
         return project;
     }
 
+    public Project copy(String sourceProjectId, Project project) throws Exception {
+        Project sourceProject = infinispanService.getProject(sourceProjectId);
+        // Save project
+        infinispanService.saveProject(project);
+
+        // Copy files from the source and make necessary modifications
+        Map<GroupedKey, ProjectFile> filesMap = infinispanService.getProjectFilesMap(sourceProjectId).entrySet().stream()
+                .filter(e -> !Objects.equals(e.getValue().getName(), PROJECT_COMPOSE_FILENAME) &&
+                        !Objects.equals(e.getValue().getName(), PROJECT_DEPLOYMENT_JKUBE_FILENAME)
+                )
+                .collect(Collectors.toMap(
+                        e -> new GroupedKey(project.getProjectId(), e.getKey().getEnv(), e.getKey().getKey()),
+                        e -> {
+                            ProjectFile file = e.getValue();
+                            file.setProjectId(project.getProjectId());
+                            if(Objects.equals(file.getName(), APPLICATION_PROPERTIES_FILENAME)) {
+                                modifyPropertyFileOnProjectCopy(file, sourceProject, project);
+                            }
+                            return file;
+                        })
+                );
+        infinispanService.saveProjectFiles(filesMap);
+
+        if (!ConfigService.inKubernetes()) {
+            ProjectFile projectCompose = codeService.createInitialProjectCompose(project);
+            infinispanService.saveProjectFile(projectCompose);
+        } else if (kubernetesService.isOpenshift()){
+            ProjectFile projectCompose = codeService.createInitialDeployment(project);
+            infinispanService.saveProjectFile(projectCompose);
+        }
+
+        return project;
+    }
+
+    private void modifyPropertyFileOnProjectCopy(ProjectFile propertyFile, Project sourceProject, Project project) {
+        String fileContent = propertyFile.getCode();
+
+        String sourceProjectIdProperty = String.format(Property.PROJECT_ID.getKeyValueFormatter(), sourceProject.getProjectId());
+        String sourceProjectNameProperty = String.format(Property.PROJECT_NAME.getKeyValueFormatter(), sourceProject.getName());
+        String sourceProjectDescriptionProperty = String.format(Property.PROJECT_DESCRIPTION.getKeyValueFormatter(), sourceProject.getDescription());
+        String sourceGavProperty = String.format(Property.GAV.getKeyValueFormatter(), sourceProject.getProjectId());
+
+        String[] searchValues = {sourceProjectIdProperty, sourceProjectNameProperty, sourceProjectDescriptionProperty, sourceGavProperty};
+
+        String updatedProjectIdProperty = String.format(Property.PROJECT_ID.getKeyValueFormatter(), project.getProjectId());
+        String updatedProjectNameProperty = String.format(Property.PROJECT_NAME.getKeyValueFormatter(), project.getName());
+        String updatedProjectDescriptionProperty = String.format(Property.PROJECT_DESCRIPTION.getKeyValueFormatter(), project.getDescription());
+        String updatedGavProperty = String.format(Property.GAV.getKeyValueFormatter(), project.getProjectId());
+
+        String[] replacementValues = {updatedProjectIdProperty, updatedProjectNameProperty, updatedProjectDescriptionProperty, updatedGavProperty};
+
+        String updatedCode = StringUtils.replaceEach(fileContent, searchValues, replacementValues);
+
+        propertyFile.setCode(updatedCode);
+    }
+
     public Integer getProjectPort(String projectId) {
         ProjectFile composeFile = infinispanService.getProjectFile(projectId, PROJECT_COMPOSE_FILENAME);
         return codeService.getProjectPort(composeFile);
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Property.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Property.java
new file mode 100644
index 00000000..5958f1e9
--- /dev/null
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Property.java
@@ -0,0 +1,18 @@
+package org.apache.camel.karavan.shared;
+
+public enum Property {
+    PROJECT_ID("camel.karavan.project-id=%s"),
+    PROJECT_NAME("camel.karavan.project-name=%s"),
+    PROJECT_DESCRIPTION("camel.karavan.project-description=%s"),
+    GAV("camel.jbang.gav=org.camel.karavan.demo:%s:1");
+
+    private final String keyValueFormatter;
+
+    Property(String keyValueFormatter) {
+        this.keyValueFormatter = keyValueFormatter;
+    }
+
+    public String getKeyValueFormatter() {
+        return keyValueFormatter;
+    }
+}
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 b7ea258c..26400e4d 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
@@ -255,6 +255,17 @@ export class ProjectService {
         });
     }
 
+    public static copyProject(sourceProject: string, project: Project) {
+        KaravanApi.copyProject(sourceProject, project, res => {
+            if (res.status === 200 || res.status === 201) {
+                EventBus.sendAlert( 'Success', 'Project copied', 'success');
+                ProjectService.refreshProjects();
+            } else {
+                EventBus.sendAlert( 'Warning', 'Error when copying project:' + res.statusText, 'warning');
+            }
+        });
+    }
+
     public static createFile(file: ProjectFile) {
         KaravanApi.postProjectFile(file, res => {
             if (res.status === 200) {
diff --git a/karavan-web/karavan-app/src/main/webui/src/projects/CreateProjectModal.tsx b/karavan-web/karavan-app/src/main/webui/src/projects/CreateProjectModal.tsx
index 87a2bf45..f4320e72 100644
--- a/karavan-web/karavan-app/src/main/webui/src/projects/CreateProjectModal.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/projects/CreateProjectModal.tsx
@@ -47,7 +47,9 @@ export function CreateProjectModal () {
     }
 
     function confirmAndCloseModal() {
-        ProjectService.createProject(new Project({name: name, description: description, projectId: projectId}));
+        operation !== 'copy' ?
+            ProjectService.createProject(new Project({name: name, description: description, projectId: projectId})) :
+            ProjectService.copyProject(project?.projectId, new Project({name: name, description: description, projectId: projectId}));
         setOperation('none');
         cleanValues();
     }
diff --git a/karavan-web/karavan-app/src/main/webui/src/templates/CreateProjectModal.tsx b/karavan-web/karavan-app/src/main/webui/src/templates/CreateProjectModal.tsx
index 7d3ae0a4..09850a90 100644
--- a/karavan-web/karavan-app/src/main/webui/src/templates/CreateProjectModal.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/templates/CreateProjectModal.tsx
@@ -47,7 +47,9 @@ export function CreateProjectModal () {
     }
 
     function confirmAndCloseModal() {
-        ProjectService.createProject(new Project({name: name, description: description, projectId: projectId}));
+        operation !== 'copy' ?
+            ProjectService.createProject(new Project({name: name, description: description, projectId: projectId})) :
+            ProjectService.copyProject(project?.projectId, new Project({name: name, description: description, projectId: projectId}));
         useProjectStore.setState({operation: "none"});
         cleanValues();
     }