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(); }