From bcfad1b1359f4c98157c7bc8c0c78de851cb5ab4 Mon Sep 17 00:00:00 2001 From: Axel RICHARD Date: Wed, 13 Nov 2024 10:12:42 +0100 Subject: [PATCH] [4193] Implement Project Data Versioning REST APIs Bug: https://github.com/eclipse-sirius/sirius-web/issues/4193 Signed-off-by: Axel RICHARD --- CHANGELOG.adoc | 26 +- .../dto/{IRestRecord.java => Identified.java} | 22 +- .../controllers/ProjectRestController.java | 16 +- .../controllers/CommitRestController.java | 106 +++++++ .../data/versioning/dto/ChangeType.java | 22 ++ .../dto/CreateCommitRestInput.java} | 16 +- .../dto/CreateCommitRestSuccessPayload.java | 30 ++ ...rence.java => GetCommitByIdRestInput.java} | 11 +- .../dto/GetCommitByIdRestSuccessPayload.java | 30 ++ .../dto/GetCommitChangeByIdRestInput.java | 26 ++ ...GetCommitChangeByIdRestSuccessPayload.java | 30 ++ .../dto/GetCommitChangeRestInput.java | 26 ++ .../GetCommitChangeRestSuccessPayload.java | 31 ++ .../versioning/dto/GetCommitsRestInput.java | 26 ++ .../dto/GetCommitsRestSuccessPayload.java | 31 ++ .../data/versioning/dto/RestBranch.java | 37 ++- .../data/versioning/dto/RestCommit.java | 54 ++++ .../data/versioning/dto/RestDataIdentity.java | 37 +++ .../data/versioning/dto/RestDataVersion.java | 48 +++ .../CreateCommitRestEventHandler.java | 84 ++++++ .../GetCommitByIdRestEventHandler.java | 85 ++++++ .../GetCommitChangeByIdRestEventHandler.java | 85 ++++++ .../GetCommitChangeRestEventHandler.java | 86 ++++++ .../handlers/GetCommitsRestEventHandler.java | 80 +++++ ...posedProjectDataVersioningRestService.java | 101 +++++++ ...DefaultProjectDataVersiongRestService.java | 129 ++++++++ .../RestDataVersionPayloadSerializer.java | 50 ++++ ...faultProjectDataVersioningRestService.java | 40 +++ .../IProjectDataVersioningRestService.java | 40 +++ ...jectDataVersioningRestServiceDelegate.java | 42 +++ ...stDataVersionPayloadSerializerService.java | 32 ++ .../application/project/dto/RestProject.java | 38 ++- .../architecture/CodingRulesTests.java | 6 + .../sirius/web/EObjectJsonSerializer.java | 95 ++++++ .../web/EObjectSerializerTestConfig.java | 77 ----- .../CommitRestControllerIntegrationTests.java | 278 ++++++++++++++++++ ...ProjectRestControllerIntegrationTests.java | 4 +- ...taVersionPayloadSerializerTestService.java | 49 +++ 38 files changed, 1893 insertions(+), 133 deletions(-) rename packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/dto/{IRestRecord.java => Identified.java} (69%) create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/controllers/CommitRestController.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/ChangeType.java rename packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/{query/dto/RestQuery.java => project/data/versioning/dto/CreateCommitRestInput.java} (62%) create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/CreateCommitRestSuccessPayload.java rename packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/{IRestCommitReference.java => GetCommitByIdRestInput.java} (71%) create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitByIdRestSuccessPayload.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeByIdRestInput.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeByIdRestSuccessPayload.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeRestInput.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeRestSuccessPayload.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitsRestInput.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitsRestSuccessPayload.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestCommit.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestDataIdentity.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestDataVersion.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/CreateCommitRestEventHandler.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitByIdRestEventHandler.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitChangeByIdRestEventHandler.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitChangeRestEventHandler.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitsRestEventHandler.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/ComposedProjectDataVersioningRestService.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/DefaultProjectDataVersiongRestService.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/RestDataVersionPayloadSerializer.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IDefaultProjectDataVersioningRestService.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IProjectDataVersioningRestService.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IProjectDataVersioningRestServiceDelegate.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IRestDataVersionPayloadSerializerService.java create mode 100644 packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/EObjectJsonSerializer.java create mode 100644 packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/projects/CommitRestControllerIntegrationTests.java create mode 100644 packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/projects/RestDataVersionPayloadSerializerTestService.java diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 5e71f8dc7b6..84e8ed9f684 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -18,6 +18,18 @@ === Breaking changes - https://github.com/eclipse-sirius/sirius-web/issues/4110[#4110] [view] CheckboxDescriptionStyle.labelPlacement is replaced by Grid layout properties +- https://github.com/eclipse-sirius/sirius-web/issues/4193[#4193] [core] Implement Project Data Versioning REST APIs. +The following classes/interfaces have been removed, they are not used anymore: +* RestQuery +* IRestRecord +* IRestCommitReference +The following records parameters have been modified: +* RestBranch: +** from RestBranch(UUID id, String resourceIdentifier, List alias, String humanIdentifier, String description, OffsetDateTime created) +** to RestBranch(UUID id, String type, OffsetDateTime created, Identified head, Identified owningProject, Identified referencedCommit) +* RestProject +** from RestProject(UUID id, String resourceIdentifier, List alias, String humanIdentifier, String description, List queries) +** to RestProject(UUID id, String type, OffsetDateTime created, Identified defaultBranch, String description, String name) === Dependency update @@ -27,16 +39,26 @@ - https://github.com/eclipse-sirius/sirius-web/issues/4195[#4195] [sirius-web] Prevent objects disappearing when dropped on themselves (or a descendant) in the _Explorer_. + === New Features - https://github.com/eclipse-sirius/sirius-web/issues/4110[#4110] [form] Add layout capabilities for form widgets +- https://github.com/eclipse-sirius/sirius-web/issues/4193[#4193] [core] Implement Project Data Versioning REST APIs. +The new endpoints are: +** getCommits (`GET /api/rest/projects/{projectId}/commits`): Get all commits in the given project. There is only one commit per project in Sirius Web for now, and its Id is the same as the project Id. It represents the current state of the project, without taking care of data created/updated/deleted since the creation of the project. +** createCommit (`POST /api/rest/projects/{projectId}/commits`): Create a commit in the given project. There is only one commit per project in Sirius Web for now, so the default implementation of this method does nothing. +** getCommitById (`GET /api/rest/projects/{projectId}/commits/{commitId}`): Get the commit represented by its Id for the given project. There is only one commit per project in Sirius Web for now, and its Id is the same as the project Id. It represents the current state of the project, without taking care of data created/updated/deleted since the creation of the project. +** getCommitChange (`GET /api/rest/projects/{projectId}/commits/{commitId}/changes`): Get all changes of the commit represented by its Id for the given project. There is only one commit per project in Sirius Web for now, and its Id is the same as the project Id. The default implementation retrieves all elements containing in the project, without taking care of data created/updated/deleted since the creation of the project. +** getCommitChangeById (`GET /api/rest/projects/{projectId}/commits/{commitId}/changes/{changeId}`): Get the changes associated to the given change Id for the commit represented by its Id for the given project. There is only one commit per project in Sirius Web for now, and its Id is the same as the project Id. The default implementation retrieves all changes containing in the project, without taking care of data created/updated/deleted since the creation of the project. The change Id parameter should be randomly generated but constant for an unlimited period. We decided to generate this Id from it's commit Id and element Id, to be able to compute it. +A new `IProjectDataVersioningRestServiceDelegate` interface is available, allowing to customize the default implementation of services related to Project Data Versioning related REST APIs. +Specifiers can implement this new interface with a spring `Service`. +A new `IRestDataVersionPayloadSerializerService` interface is available, allowing to customize the default implementation of the JSON serialization of the payload object of `RestDataVersion`. +Specifiers are also encouraged to implement their own `IRestDataVersionPayloadSerializerService` for their domains, as the default one may not return expected results. === Improvements - - == v2024.11.0 === Shapes diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/dto/IRestRecord.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/dto/Identified.java similarity index 69% rename from packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/dto/IRestRecord.java rename to packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/dto/Identified.java index 17ee2b1fc8c..4349110fd28 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/dto/IRestRecord.java +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/dto/Identified.java @@ -12,23 +12,17 @@ *******************************************************************************/ package org.eclipse.sirius.web.application.dto; -import java.util.List; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Objects; import java.util.UUID; /** - * Interface for the REST Record DTO. - * + * Simple record allowing to serialize an object with only its id. * @author arichard */ -public interface IRestRecord { - - UUID id(); - - String resourceIdentifier(); - - List alias(); - - String humanIdentifier(); - - String decription(); +public record Identified(@JsonProperty("@id") UUID id) { + public Identified { + Objects.requireNonNull(id); + } } diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/controllers/ProjectRestController.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/controllers/ProjectRestController.java index 9f5c3653506..e7b886685a2 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/controllers/ProjectRestController.java +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/controllers/ProjectRestController.java @@ -12,12 +12,16 @@ *******************************************************************************/ package org.eclipse.sirius.web.application.project.controllers; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.UUID; import org.eclipse.sirius.components.core.api.ErrorPayload; +import org.eclipse.sirius.web.application.dto.Identified; import org.eclipse.sirius.web.application.project.data.versioning.dto.RestBranch; import org.eclipse.sirius.web.application.project.dto.CreateProjectInput; import org.eclipse.sirius.web.application.project.dto.CreateProjectSuccessPayload; @@ -47,6 +51,8 @@ @RequestMapping("/api/rest/projects") public class ProjectRestController { + private static final OffsetDateTime DEFAULT_CREATED = Instant.EPOCH.atOffset(ZoneOffset.UTC); + private final IProjectApplicationService projectApplicationService; public ProjectRestController(IProjectApplicationService projectApplicationService) { @@ -56,7 +62,7 @@ public ProjectRestController(IProjectApplicationService projectApplicationServic @GetMapping public ResponseEntity> getProjects() { var restProjects = this.projectApplicationService.findAll(PageRequest.of(0, 20)) - .map(project -> new RestProject(project.id(), null, List.of(), null, null, project.name(), List.of())) + .map(project -> new RestProject(project.id(), DEFAULT_CREATED, new Identified(project.id()), null, project.name())) .toList(); return new ResponseEntity<>(restProjects, HttpStatus.OK); @@ -65,7 +71,7 @@ public ResponseEntity> getProjects() { @GetMapping(path = "/{projectId}") public ResponseEntity getProjectById(@PathVariable UUID projectId) { var restProject = this.projectApplicationService.findById(projectId) - .map(project -> new RestProject(project.id(), null, List.of(), null, null, project.name(), List.of())); + .map(project -> new RestProject(project.id(), DEFAULT_CREATED, new Identified(project.id()), null, project.name())); if (restProject.isPresent()) { return new ResponseEntity<>(restProject.get(), HttpStatus.OK); @@ -81,7 +87,7 @@ public ResponseEntity createProject(@RequestParam String name, @Req if (newProjectPayload instanceof CreateProjectSuccessPayload createProjectSuccessPayload) { var projectDTO = createProjectSuccessPayload.project(); - var restProject = new RestProject(projectDTO.id(), null, List.of(), null, null, projectDTO.name(), List.of()); + var restProject = new RestProject(projectDTO.id(), DEFAULT_CREATED, new Identified(projectDTO.id()), null, projectDTO.name()); return new ResponseEntity<>(restProject, HttpStatus.CREATED); } // The specification does not handle other HttpStatus than HttpStatus.CREATED for this endpoint @@ -94,7 +100,7 @@ public ResponseEntity updateProject(@PathVariable UUID projectId, @ var renameProjectInput = new RenameProjectInput(UUID.randomUUID(), projectId, name.get()); var renamedProjectPayload = this.projectApplicationService.renameProject(renameProjectInput); if (renamedProjectPayload instanceof RenameProjectSuccessPayload) { - var restProject = new RestProject(projectId, null, List.of(), null, null, name.get(), List.of()); + var restProject = new RestProject(projectId, DEFAULT_CREATED, new Identified(projectId), null, name.get()); return new ResponseEntity<>(restProject, HttpStatus.OK); } } @@ -105,7 +111,7 @@ public ResponseEntity updateProject(@PathVariable UUID projectId, @ @DeleteMapping(path = "/{projectId}") public ResponseEntity deleteProject(@PathVariable UUID projectId) { var restProject = this.projectApplicationService.findById(projectId) - .map(project -> new RestProject(project.id(), null, List.of(), null, null, project.name(), List.of())) + .map(project -> new RestProject(project.id(), DEFAULT_CREATED, new Identified(project.id()), null, project.name())) .orElse(null); var deleteProjectInput = new DeleteProjectInput(UUID.randomUUID(), projectId); diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/controllers/CommitRestController.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/controllers/CommitRestController.java new file mode 100644 index 00000000000..2bf9ac1176d --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/controllers/CommitRestController.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.controllers; + +import java.time.Duration; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; + +import org.eclipse.sirius.components.graphql.api.IEditingContextDispatcher; +import org.eclipse.sirius.web.application.project.data.versioning.dto.ChangeType; +import org.eclipse.sirius.web.application.project.data.versioning.dto.CreateCommitRestInput; +import org.eclipse.sirius.web.application.project.data.versioning.dto.CreateCommitRestSuccessPayload; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitByIdRestInput; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitByIdRestSuccessPayload; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitChangeByIdRestInput; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitChangeByIdRestSuccessPayload; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitChangeRestInput; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitChangeRestSuccessPayload; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitsRestInput; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitsRestSuccessPayload; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestCommit; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestDataVersion; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * REST Controller for the Project Data Versioning - Commits Endpoints. + * + * @author arichard + */ +@RestController +@RequestMapping("/api/rest/projects/{projectId}/commits") +public class CommitRestController { + + private static final int TIMEOUT = 20; + + private final IEditingContextDispatcher editingContextDispatcher; + + public CommitRestController(IEditingContextDispatcher editingContextDispatcher) { + this.editingContextDispatcher = Objects.requireNonNull(editingContextDispatcher); + } + + @GetMapping + public ResponseEntity> getCommits(@PathVariable UUID projectId) { + var payload = this.editingContextDispatcher.dispatchQuery(projectId.toString(), new GetCommitsRestInput(UUID.randomUUID())).block(Duration.ofSeconds(TIMEOUT)); + if (payload instanceof GetCommitsRestSuccessPayload successPayload) { + return new ResponseEntity<>(successPayload.commits(), HttpStatus.OK); + } + return new ResponseEntity<>(null, HttpStatus.NOT_FOUND); + } + + @PostMapping + public ResponseEntity createCommit(@PathVariable UUID projectId, @RequestParam Optional branchId) { + var payload = this.editingContextDispatcher.dispatchQuery(projectId.toString(), new CreateCommitRestInput(UUID.randomUUID(), branchId)).block(Duration.ofSeconds(TIMEOUT)); + if (payload instanceof CreateCommitRestSuccessPayload successPayload) { + return new ResponseEntity<>(successPayload.commit(), HttpStatus.OK); + } + // The specification does not handle other HttpStatus than HttpStatus.CREATED for this endpoint + return null; + } + + @GetMapping(path = "/{commitId}") + public ResponseEntity getCommitById(@PathVariable UUID projectId, @PathVariable UUID commitId) { + var payload = this.editingContextDispatcher.dispatchQuery(projectId.toString(), new GetCommitByIdRestInput(UUID.randomUUID(), commitId)).block(Duration.ofSeconds(TIMEOUT)); + if (payload instanceof GetCommitByIdRestSuccessPayload successPayload) { + return new ResponseEntity<>(successPayload.commit(), HttpStatus.OK); + } + return new ResponseEntity<>(null, HttpStatus.NOT_FOUND); + } + + @GetMapping(path = "/{commitId}/changes") + public ResponseEntity> getCommitChange(@PathVariable UUID projectId, @PathVariable UUID commitId, @RequestParam Optional> changeTypes) { + var payload = this.editingContextDispatcher.dispatchQuery(projectId.toString(), new GetCommitChangeRestInput(UUID.randomUUID(), commitId)).block(Duration.ofSeconds(TIMEOUT)); + if (payload instanceof GetCommitChangeRestSuccessPayload successPayload) { + return new ResponseEntity<>(successPayload.commitChanges(), HttpStatus.OK); + } + return new ResponseEntity<>(null, HttpStatus.NOT_FOUND); + } + + @GetMapping(path = "/{commitId}/changes/{changeId}") + public ResponseEntity getCommitChangeById(@PathVariable UUID projectId, @PathVariable UUID commitId, @PathVariable UUID changeId) { + var payload = this.editingContextDispatcher.dispatchQuery(projectId.toString(), new GetCommitChangeByIdRestInput(UUID.randomUUID(), commitId, changeId)).block(Duration.ofSeconds(TIMEOUT)); + if (payload instanceof GetCommitChangeByIdRestSuccessPayload successPayload) { + return new ResponseEntity<>(successPayload.commitChange(), HttpStatus.OK); + } + return new ResponseEntity<>(null, HttpStatus.NOT_FOUND); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/ChangeType.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/ChangeType.java new file mode 100644 index 00000000000..481a9d4733e --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/ChangeType.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.dto; + +/** + * Used to indicate the type of commit when calling "getCommitChange" or "diffCommits" REST APIs. + * + * @author arichard + */ +public enum ChangeType { + CREATED, UPDATED, DELETED +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/query/dto/RestQuery.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/CreateCommitRestInput.java similarity index 62% rename from packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/query/dto/RestQuery.java rename to packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/CreateCommitRestInput.java index 8b9279684e5..f826bfcb246 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/query/dto/RestQuery.java +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/CreateCommitRestInput.java @@ -10,22 +10,18 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.sirius.web.application.query.dto; +package org.eclipse.sirius.web.application.project.data.versioning.dto; -import java.util.List; +import java.util.Optional; import java.util.UUID; -import org.eclipse.sirius.web.application.dto.IRestRecord; +import org.eclipse.sirius.components.core.api.IInput; /** - * REST Query DTO. + * The input object of the CreateCommitRestEventHandler. * * @author arichard */ -public record RestQuery( - UUID id, - String resourceIdentifier, - List alias, - String humanIdentifier, - String decription) implements IRestRecord { +public record CreateCommitRestInput(UUID id, Optional branchId) implements IInput { + } diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/CreateCommitRestSuccessPayload.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/CreateCommitRestSuccessPayload.java new file mode 100644 index 00000000000..dc7fabf6d0e --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/CreateCommitRestSuccessPayload.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.dto; + +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IPayload; + +/** + * The payload for the "createCommit" REST API on success. + * + * @author arichard + */ +public record CreateCommitRestSuccessPayload(UUID id, RestCommit commit) implements IPayload { + public CreateCommitRestSuccessPayload { + Objects.requireNonNull(id); + Objects.requireNonNull(commit); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/IRestCommitReference.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitByIdRestInput.java similarity index 71% rename from packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/IRestCommitReference.java rename to packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitByIdRestInput.java index 11c416ab8d9..d82d54d95cc 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/IRestCommitReference.java +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitByIdRestInput.java @@ -12,18 +12,15 @@ *******************************************************************************/ package org.eclipse.sirius.web.application.project.data.versioning.dto; -import java.time.OffsetDateTime; +import java.util.UUID; -import org.eclipse.sirius.web.application.dto.IRestRecord; +import org.eclipse.sirius.components.core.api.IInput; /** - * Interface for the REST CommitReference DTO. + * The input object of the GetCommitByIdRestEventHandler. * * @author arichard */ -public interface IRestCommitReference extends IRestRecord { +public record GetCommitByIdRestInput(UUID id, UUID commitId) implements IInput { - OffsetDateTime created(); - - String name(); } diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitByIdRestSuccessPayload.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitByIdRestSuccessPayload.java new file mode 100644 index 00000000000..9335cd27a0e --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitByIdRestSuccessPayload.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.dto; + +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IPayload; + +/** + * The payload for the "getCommitById" REST API on success. + * + * @author arichard + */ +public record GetCommitByIdRestSuccessPayload(UUID id, RestCommit commit) implements IPayload { + public GetCommitByIdRestSuccessPayload { + Objects.requireNonNull(id); + Objects.requireNonNull(commit); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeByIdRestInput.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeByIdRestInput.java new file mode 100644 index 00000000000..445e6ebba4c --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeByIdRestInput.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.dto; + +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IInput; + +/** + * The input object of the GetCommitChangeByIdRestEventHandler. + * + * @author arichard + */ +public record GetCommitChangeByIdRestInput(UUID id, UUID commitId, UUID changeId) implements IInput { + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeByIdRestSuccessPayload.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeByIdRestSuccessPayload.java new file mode 100644 index 00000000000..0c76f3b1fd8 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeByIdRestSuccessPayload.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.dto; + +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IPayload; + +/** + * The payload for the "getCommitChangeById" REST API on success. + * + * @author arichard + */ +public record GetCommitChangeByIdRestSuccessPayload(UUID id, RestDataVersion commitChange) implements IPayload { + public GetCommitChangeByIdRestSuccessPayload { + Objects.requireNonNull(id); + Objects.requireNonNull(commitChange); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeRestInput.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeRestInput.java new file mode 100644 index 00000000000..528d51037c7 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeRestInput.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.dto; + +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IInput; + +/** + * The input object of the GetCommitChangeRestEventHandler. + * + * @author arichard + */ +public record GetCommitChangeRestInput(UUID id, UUID commitId) implements IInput { + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeRestSuccessPayload.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeRestSuccessPayload.java new file mode 100644 index 00000000000..8caef2d544c --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitChangeRestSuccessPayload.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.dto; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IPayload; + +/** + * The payload for the "getCommitChange" REST API on success. + * + * @author arichard + */ +public record GetCommitChangeRestSuccessPayload(UUID id, List commitChanges) implements IPayload { + public GetCommitChangeRestSuccessPayload { + Objects.requireNonNull(id); + Objects.requireNonNull(commitChanges); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitsRestInput.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitsRestInput.java new file mode 100644 index 00000000000..5d0acec569a --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitsRestInput.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.dto; + +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IInput; + +/** + * The input object of the GetCommitsRestEventHandler. + * + * @author arichard + */ +public record GetCommitsRestInput(UUID id) implements IInput { + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitsRestSuccessPayload.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitsRestSuccessPayload.java new file mode 100644 index 00000000000..0eb3fedc333 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/GetCommitsRestSuccessPayload.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.dto; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IPayload; + +/** + * The payload for the "getCommits" REST API on success. + * + * @author arichard + */ +public record GetCommitsRestSuccessPayload(UUID id, List commits) implements IPayload { + public GetCommitsRestSuccessPayload { + Objects.requireNonNull(id); + Objects.requireNonNull(commits); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestBranch.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestBranch.java index db71a1584ca..75c73ee1ccd 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestBranch.java +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestBranch.java @@ -12,22 +12,45 @@ *******************************************************************************/ package org.eclipse.sirius.web.application.project.data.versioning.dto; +import com.fasterxml.jackson.annotation.JsonProperty; + import java.time.OffsetDateTime; -import java.util.List; +import java.util.Objects; import java.util.UUID; +import org.eclipse.sirius.web.application.dto.Identified; + /** * REST Branch DTO. * * @author arichard */ public record RestBranch( - UUID id, - String resourceIdentifier, - List alias, - String humanIdentifier, - String decription, + @JsonProperty("@id") UUID id, + @JsonProperty("@type") String type, + OffsetDateTime created, + Identified head, String name, - OffsetDateTime created) implements IRestCommitReference { + Identified owningProject, + Identified referencedCommit) { + + public RestBranch { + Objects.requireNonNull(id); + Objects.requireNonNull(type); + Objects.requireNonNull(created); + // head can be null + Objects.requireNonNull(name); + Objects.requireNonNull(owningProject); + Objects.requireNonNull(referencedCommit); + } + public RestBranch( + UUID id, + OffsetDateTime created, + Identified head, + String name, + Identified owningProject, + Identified referencedCommit) { + this(id, "Branch", created, head, name, owningProject, referencedCommit); + } } diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestCommit.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestCommit.java new file mode 100644 index 00000000000..93238e47029 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestCommit.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.OffsetDateTime; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.web.application.dto.Identified; + +/** + * REST Commit DTO. + * + * @author arichard + */ +public record RestCommit( + @JsonProperty("@id") UUID id, + @JsonProperty("@type") String type, + OffsetDateTime created, + String description, + Identified owningProject, + List previousCommits) { + + public RestCommit { + Objects.requireNonNull(id); + Objects.requireNonNull(type); + Objects.requireNonNull(created); + // description can be null + Objects.requireNonNull(owningProject); + Objects.requireNonNull(previousCommits); + } + + public RestCommit( + UUID id, + OffsetDateTime created, + String description, + Identified owningProject, + List previousCommits) { + this(id, "Commit", created, description, owningProject, previousCommits); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestDataIdentity.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestDataIdentity.java new file mode 100644 index 00000000000..78b946f1f1c --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestDataIdentity.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Objects; +import java.util.UUID; + +/** + * REST DataIdentity DTO. + * + * @author arichard + */ +public record RestDataIdentity( + @JsonProperty("@id") UUID id, + @JsonProperty("@type") String type) { + + public RestDataIdentity { + Objects.requireNonNull(id); + Objects.requireNonNull(type); + } + + public RestDataIdentity(UUID id) { + this(id, "DataIdentity"); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestDataVersion.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestDataVersion.java new file mode 100644 index 00000000000..d101d3c9419 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/dto/RestDataVersion.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.web.application.project.data.versioning.services.RestDataVersionPayloadSerializer; + +/** + * REST DataVersion DTO. + * + * @author arichard + */ +public record RestDataVersion( + @JsonProperty("@id") UUID id, + @JsonProperty("@type") String type, + RestDataIdentity identity, + @JsonSerialize(using = RestDataVersionPayloadSerializer.class) + Object payload) { + + public RestDataVersion { + Objects.requireNonNull(id); + Objects.requireNonNull(type); + Objects.requireNonNull(identity); + // payload can be null + } + + public RestDataVersion( + UUID id, + RestDataIdentity identity, + Object payload) { + this(id, "DataVersion", identity, payload); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/CreateCommitRestEventHandler.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/CreateCommitRestEventHandler.java new file mode 100644 index 00000000000..f539f202d41 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/CreateCommitRestEventHandler.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.handlers; + +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.api.ChangeDescription; +import org.eclipse.sirius.components.collaborative.api.ChangeKind; +import org.eclipse.sirius.components.collaborative.api.IEditingContextEventHandler; +import org.eclipse.sirius.components.collaborative.api.Monitoring; +import org.eclipse.sirius.components.core.api.ErrorPayload; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IInput; +import org.eclipse.sirius.components.core.api.IPayload; +import org.eclipse.sirius.web.application.project.data.versioning.dto.CreateCommitRestInput; +import org.eclipse.sirius.web.application.project.data.versioning.dto.CreateCommitRestSuccessPayload; +import org.eclipse.sirius.web.application.project.data.versioning.services.api.IProjectDataVersioningRestService; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.MeterRegistry; +import reactor.core.publisher.Sinks.Many; +import reactor.core.publisher.Sinks.One; + +/** + * Handler used to execute the "createCommit" REST API. + * + * @author arichard + */ +@Service +public class CreateCommitRestEventHandler implements IEditingContextEventHandler { + + private final IProjectDataVersioningRestService projectDataVersioningRestService; + + private final IMessageService messageService; + + private final Counter counter; + + public CreateCommitRestEventHandler(IProjectDataVersioningRestService projectDataVersioningRestService, IMessageService messageService, MeterRegistry meterRegistry) { + this.projectDataVersioningRestService = Objects.requireNonNull(projectDataVersioningRestService); + this.messageService = Objects.requireNonNull(messageService); + + this.counter = Counter.builder(Monitoring.EVENT_HANDLER) + .tag(Monitoring.NAME, this.getClass().getSimpleName()) + .register(meterRegistry); + } + + @Override + public boolean canHandle(IEditingContext editingContext, IInput input) { + return input instanceof CreateCommitRestInput; + } + + @Override + public void handle(One payloadSink, Many changeDescriptionSink, IEditingContext editingContext, IInput input) { + this.counter.increment(); + + String message = this.messageService.invalidInput(input.getClass().getSimpleName(), CreateCommitRestInput.class.getSimpleName()); + IPayload payload = new ErrorPayload(input.id(), message); + if (input instanceof CreateCommitRestInput restInput) { + var commit = this.projectDataVersioningRestService.createCommit(editingContext, restInput.branchId()); + if (commit != null) { + payload = new CreateCommitRestSuccessPayload(UUID.randomUUID(), commit); + } else { + payload = new ErrorPayload(input.id(), "Unable to create a new commit."); + } + } + payloadSink.tryEmitValue(payload); + + ChangeDescription changeDescription = new ChangeDescription(ChangeKind.NOTHING, editingContext.getId(), input); + changeDescriptionSink.tryEmitNext(changeDescription); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitByIdRestEventHandler.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitByIdRestEventHandler.java new file mode 100644 index 00000000000..e81ee160c11 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitByIdRestEventHandler.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.handlers; + +import java.text.MessageFormat; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.api.ChangeDescription; +import org.eclipse.sirius.components.collaborative.api.ChangeKind; +import org.eclipse.sirius.components.collaborative.api.IEditingContextEventHandler; +import org.eclipse.sirius.components.collaborative.api.Monitoring; +import org.eclipse.sirius.components.core.api.ErrorPayload; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IInput; +import org.eclipse.sirius.components.core.api.IPayload; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitByIdRestInput; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitByIdRestSuccessPayload; +import org.eclipse.sirius.web.application.project.data.versioning.services.api.IProjectDataVersioningRestService; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.MeterRegistry; +import reactor.core.publisher.Sinks.Many; +import reactor.core.publisher.Sinks.One; + +/** + * Handler used to execute the "getCommitById" REST API. + * + * @author arichard + */ +@Service +public class GetCommitByIdRestEventHandler implements IEditingContextEventHandler { + + private final IProjectDataVersioningRestService projectDataVersioningRestService; + + private final IMessageService messageService; + + private final Counter counter; + + public GetCommitByIdRestEventHandler(IProjectDataVersioningRestService projectDataVersioningRestService, IMessageService messageService, MeterRegistry meterRegistry) { + this.projectDataVersioningRestService = Objects.requireNonNull(projectDataVersioningRestService); + this.messageService = Objects.requireNonNull(messageService); + + this.counter = Counter.builder(Monitoring.EVENT_HANDLER) + .tag(Monitoring.NAME, this.getClass().getSimpleName()) + .register(meterRegistry); + } + + @Override + public boolean canHandle(IEditingContext editingContext, IInput input) { + return input instanceof GetCommitByIdRestInput; + } + + @Override + public void handle(One payloadSink, Many changeDescriptionSink, IEditingContext editingContext, IInput input) { + this.counter.increment(); + + String message = this.messageService.invalidInput(input.getClass().getSimpleName(), GetCommitByIdRestInput.class.getSimpleName()); + IPayload payload = new ErrorPayload(input.id(), message); + if (input instanceof GetCommitByIdRestInput restInput) { + var commit = this.projectDataVersioningRestService.getCommitById(editingContext, restInput.commitId()); + if (commit != null) { + payload = new GetCommitByIdRestSuccessPayload(UUID.randomUUID(), commit); + } else { + payload = new ErrorPayload(input.id(), MessageFormat.format("The commit {0} does not exist for the current project.", restInput.commitId())); + } + } + payloadSink.tryEmitValue(payload); + + ChangeDescription changeDescription = new ChangeDescription(ChangeKind.NOTHING, editingContext.getId(), input); + changeDescriptionSink.tryEmitNext(changeDescription); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitChangeByIdRestEventHandler.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitChangeByIdRestEventHandler.java new file mode 100644 index 00000000000..cb74011ce0e --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitChangeByIdRestEventHandler.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.handlers; + +import java.text.MessageFormat; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.api.ChangeDescription; +import org.eclipse.sirius.components.collaborative.api.ChangeKind; +import org.eclipse.sirius.components.collaborative.api.IEditingContextEventHandler; +import org.eclipse.sirius.components.collaborative.api.Monitoring; +import org.eclipse.sirius.components.core.api.ErrorPayload; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IInput; +import org.eclipse.sirius.components.core.api.IPayload; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitChangeByIdRestInput; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitChangeByIdRestSuccessPayload; +import org.eclipse.sirius.web.application.project.data.versioning.services.api.IProjectDataVersioningRestService; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.MeterRegistry; +import reactor.core.publisher.Sinks.Many; +import reactor.core.publisher.Sinks.One; + +/** + * Handler used to execute the "getCommitChangeById" REST API. + * + * @author arichard + */ +@Service +public class GetCommitChangeByIdRestEventHandler implements IEditingContextEventHandler { + + private final IProjectDataVersioningRestService projectDataVersioningRestService; + + private final IMessageService messageService; + + private final Counter counter; + + public GetCommitChangeByIdRestEventHandler(IProjectDataVersioningRestService projectDataVersioningRestService, IMessageService messageService, MeterRegistry meterRegistry) { + this.projectDataVersioningRestService = Objects.requireNonNull(projectDataVersioningRestService); + this.messageService = Objects.requireNonNull(messageService); + + this.counter = Counter.builder(Monitoring.EVENT_HANDLER) + .tag(Monitoring.NAME, this.getClass().getSimpleName()) + .register(meterRegistry); + } + + @Override + public boolean canHandle(IEditingContext editingContext, IInput input) { + return input instanceof GetCommitChangeByIdRestInput; + } + + @Override + public void handle(One payloadSink, Many changeDescriptionSink, IEditingContext editingContext, IInput input) { + this.counter.increment(); + + String message = this.messageService.invalidInput(input.getClass().getSimpleName(), GetCommitChangeByIdRestInput.class.getSimpleName()); + IPayload payload = new ErrorPayload(input.id(), message); + if (input instanceof GetCommitChangeByIdRestInput restInput) { + var commitChange = this.projectDataVersioningRestService.getCommitChangeById(editingContext, restInput.commitId(), restInput.changeId()); + if (commitChange != null) { + payload = new GetCommitChangeByIdRestSuccessPayload(UUID.randomUUID(), commitChange); + } else { + payload = new ErrorPayload(input.id(), MessageFormat.format("The change {0} of the commit {0} for the current project does not exist.", restInput.changeId(), restInput.commitId())); + } + } + payloadSink.tryEmitValue(payload); + + ChangeDescription changeDescription = new ChangeDescription(ChangeKind.NOTHING, editingContext.getId(), input); + changeDescriptionSink.tryEmitNext(changeDescription); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitChangeRestEventHandler.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitChangeRestEventHandler.java new file mode 100644 index 00000000000..138d2cb0462 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitChangeRestEventHandler.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.handlers; + +import java.text.MessageFormat; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.api.ChangeDescription; +import org.eclipse.sirius.components.collaborative.api.ChangeKind; +import org.eclipse.sirius.components.collaborative.api.IEditingContextEventHandler; +import org.eclipse.sirius.components.collaborative.api.Monitoring; +import org.eclipse.sirius.components.core.api.ErrorPayload; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IInput; +import org.eclipse.sirius.components.core.api.IPayload; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitChangeRestInput; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitChangeRestSuccessPayload; +import org.eclipse.sirius.web.application.project.data.versioning.services.api.IProjectDataVersioningRestService; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.MeterRegistry; +import reactor.core.publisher.Sinks.Many; +import reactor.core.publisher.Sinks.One; + +/** + * Handler used to execute the "getCommitChange" REST API. + * + * @author arichard + */ +@Service +public class GetCommitChangeRestEventHandler implements IEditingContextEventHandler { + + private final IProjectDataVersioningRestService projectDataVersioningRestService; + + private final IMessageService messageService; + + private final Counter counter; + + public GetCommitChangeRestEventHandler(IProjectDataVersioningRestService projectDataVersioningRestService, IMessageService messageService, MeterRegistry meterRegistry) { + this.projectDataVersioningRestService = Objects.requireNonNull(projectDataVersioningRestService); + this.messageService = Objects.requireNonNull(messageService); + + this.counter = Counter.builder(Monitoring.EVENT_HANDLER) + .tag(Monitoring.NAME, this.getClass().getSimpleName()) + .register(meterRegistry); + } + + @Override + public boolean canHandle(IEditingContext editingContext, IInput input) { + return input instanceof GetCommitChangeRestInput; + } + + @Override + public void handle(One payloadSink, Many changeDescriptionSink, IEditingContext editingContext, IInput input) { + this.counter.increment(); + + String message = this.messageService.invalidInput(input.getClass().getSimpleName(), GetCommitChangeRestInput.class.getSimpleName()); + IPayload payload = new ErrorPayload(input.id(), message); + if (input instanceof GetCommitChangeRestInput restInput) { + var commitChange = this.projectDataVersioningRestService.getCommitChange(editingContext, restInput.commitId(), List.of()); + if (commitChange != null && !commitChange.isEmpty()) { + payload = new GetCommitChangeRestSuccessPayload(UUID.randomUUID(), commitChange); + } else { + payload = new ErrorPayload(input.id(), MessageFormat.format("The commit {0} for the current project does not have DataVersion.", restInput.commitId())); + } + } + payloadSink.tryEmitValue(payload); + + ChangeDescription changeDescription = new ChangeDescription(ChangeKind.NOTHING, editingContext.getId(), input); + changeDescriptionSink.tryEmitNext(changeDescription); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitsRestEventHandler.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitsRestEventHandler.java new file mode 100644 index 00000000000..b73b89f397a --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/handlers/GetCommitsRestEventHandler.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.handlers; + +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.api.ChangeDescription; +import org.eclipse.sirius.components.collaborative.api.ChangeKind; +import org.eclipse.sirius.components.collaborative.api.IEditingContextEventHandler; +import org.eclipse.sirius.components.collaborative.api.Monitoring; +import org.eclipse.sirius.components.core.api.ErrorPayload; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IInput; +import org.eclipse.sirius.components.core.api.IPayload; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitsRestInput; +import org.eclipse.sirius.web.application.project.data.versioning.dto.GetCommitsRestSuccessPayload; +import org.eclipse.sirius.web.application.project.data.versioning.services.api.IProjectDataVersioningRestService; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.MeterRegistry; +import reactor.core.publisher.Sinks.Many; +import reactor.core.publisher.Sinks.One; + +/** + * Handler used to execute the "getCommits" REST API. + * + * @author arichard + */ +@Service +public class GetCommitsRestEventHandler implements IEditingContextEventHandler { + + private final IProjectDataVersioningRestService projectDataVersioningRestService; + + private final IMessageService messageService; + + private final Counter counter; + + public GetCommitsRestEventHandler(IProjectDataVersioningRestService projectDataVersioningRestService, IMessageService messageService, MeterRegistry meterRegistry) { + this.projectDataVersioningRestService = Objects.requireNonNull(projectDataVersioningRestService); + this.messageService = Objects.requireNonNull(messageService); + + this.counter = Counter.builder(Monitoring.EVENT_HANDLER) + .tag(Monitoring.NAME, this.getClass().getSimpleName()) + .register(meterRegistry); + } + + @Override + public boolean canHandle(IEditingContext editingContext, IInput input) { + return input instanceof GetCommitsRestInput; + } + + @Override + public void handle(One payloadSink, Many changeDescriptionSink, IEditingContext editingContext, IInput input) { + this.counter.increment(); + + String message = this.messageService.invalidInput(input.getClass().getSimpleName(), GetCommitsRestInput.class.getSimpleName()); + IPayload payload = new ErrorPayload(input.id(), message); + if (input instanceof GetCommitsRestInput) { + var commits = this.projectDataVersioningRestService.getCommits(editingContext); + payload = new GetCommitsRestSuccessPayload(UUID.randomUUID(), commits); + } + payloadSink.tryEmitValue(payload); + + ChangeDescription changeDescription = new ChangeDescription(ChangeKind.NOTHING, editingContext.getId(), input); + changeDescriptionSink.tryEmitNext(changeDescription); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/ComposedProjectDataVersioningRestService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/ComposedProjectDataVersioningRestService.java new file mode 100644 index 00000000000..341b100a921 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/ComposedProjectDataVersioningRestService.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.services; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.web.application.project.data.versioning.dto.ChangeType; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestCommit; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestDataVersion; +import org.eclipse.sirius.web.application.project.data.versioning.services.api.IDefaultProjectDataVersioningRestService; +import org.eclipse.sirius.web.application.project.data.versioning.services.api.IProjectDataVersioningRestService; +import org.eclipse.sirius.web.application.project.data.versioning.services.api.IProjectDataVersioningRestServiceDelegate; +import org.springframework.stereotype.Service; + +/** + * Implementation of {@link IProjectDataVersioningRestService}. + * + * @author arichard + */ +@Service +public class ComposedProjectDataVersioningRestService implements IProjectDataVersioningRestService { + + private final List projectDataVersioningRestServiceDelegate; + + private IDefaultProjectDataVersioningRestService defaultProjectDataVersioningRestService; + + public ComposedProjectDataVersioningRestService(List projectDataVersioningRestServiceDelegate, IDefaultProjectDataVersioningRestService defaultProjectDataVersioningRestService) { + this.projectDataVersioningRestServiceDelegate = Objects.requireNonNull(projectDataVersioningRestServiceDelegate); + this.defaultProjectDataVersioningRestService = Objects.requireNonNull(defaultProjectDataVersioningRestService); + } + + @Override + public List getCommits(IEditingContext editingContext) { + var optionalDelegate = this.projectDataVersioningRestServiceDelegate.stream() + .filter(delegate -> delegate.canHandle(editingContext)) + .findFirst(); + if (optionalDelegate.isPresent()) { + return optionalDelegate.get().getCommits(editingContext); + } + return this.defaultProjectDataVersioningRestService.getCommits(editingContext); + } + + @Override + public RestCommit createCommit(IEditingContext editingContext, Optional branchId) { + var optionalDelegate = this.projectDataVersioningRestServiceDelegate.stream() + .filter(delegate -> delegate.canHandle(editingContext)) + .findFirst(); + if (optionalDelegate.isPresent()) { + return optionalDelegate.get().createCommit(editingContext, branchId); + } + return this.defaultProjectDataVersioningRestService.createCommit(editingContext, branchId); + } + + @Override + public RestCommit getCommitById(IEditingContext editingContext, UUID commitId) { + var optionalDelegate = this.projectDataVersioningRestServiceDelegate.stream() + .filter(delegate -> delegate.canHandle(editingContext)) + .findFirst(); + if (optionalDelegate.isPresent()) { + return optionalDelegate.get().getCommitById(editingContext, commitId); + } + return this.defaultProjectDataVersioningRestService.getCommitById(editingContext, commitId); + } + + @Override + public List getCommitChange(IEditingContext editingContext, UUID commitId, List changeTypes) { + var optionalDelegate = this.projectDataVersioningRestServiceDelegate.stream() + .filter(delegate -> delegate.canHandle(editingContext)) + .findFirst(); + if (optionalDelegate.isPresent()) { + return optionalDelegate.get().getCommitChange(editingContext, commitId, changeTypes); + } + return this.defaultProjectDataVersioningRestService.getCommitChange(editingContext, commitId, changeTypes); + } + + @Override + public RestDataVersion getCommitChangeById(IEditingContext editingContext, UUID commitId, UUID changeId) { + var optionalDelegate = this.projectDataVersioningRestServiceDelegate.stream() + .filter(delegate -> delegate.canHandle(editingContext)) + .findFirst(); + if (optionalDelegate.isPresent()) { + return optionalDelegate.get().getCommitChangeById(editingContext, commitId, changeId); + } + return this.defaultProjectDataVersioningRestService.getCommitChangeById(editingContext, commitId, changeId); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/DefaultProjectDataVersiongRestService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/DefaultProjectDataVersiongRestService.java new file mode 100644 index 00000000000..7f402c9ff4d --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/DefaultProjectDataVersiongRestService.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.services; + +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.web.application.dto.Identified; +import org.eclipse.sirius.web.application.object.services.api.IDefaultObjectRestService; +import org.eclipse.sirius.web.application.project.data.versioning.dto.ChangeType; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestCommit; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestDataIdentity; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestDataVersion; +import org.eclipse.sirius.web.application.project.data.versioning.services.api.IDefaultProjectDataVersioningRestService; +import org.springframework.stereotype.Service; + +/** + * Implementation of {@link IDefaultProjectDataVersioningRestService}. + * + * @author arichard + */ +@Service +public class DefaultProjectDataVersiongRestService implements IDefaultProjectDataVersioningRestService { + + private static final OffsetDateTime DEFAULT_CREATED = Instant.EPOCH.atOffset(ZoneOffset.UTC); + + private static final String DEFAULT_DESCRIPTION = "The one and only commit for this project"; + + private final IDefaultObjectRestService defaultObjectRestService; + + private final IObjectService objectService; + + public DefaultProjectDataVersiongRestService(IDefaultObjectRestService defaultObjectRestService, IObjectService objectService) { + this.defaultObjectRestService = Objects.requireNonNull(defaultObjectRestService); + this.objectService = Objects.requireNonNull(objectService); + } + + /** + * There is only one commit per project in the default implementation. + * It represents the current state of the project, without taking care of data created/updated/deleted since the creation of the project. + * It's creation date/time is the Epoch date/time. + * It's a tradeoff as it does not strictly follow the SystemModelingAPI specification. + */ + @Override + public List getCommits(IEditingContext editingContext) { + var projectId = UUID.fromString(editingContext.getId()); + var commit = new RestCommit(projectId, DEFAULT_CREATED, DEFAULT_DESCRIPTION, new Identified(projectId), List.of()); + return List.of(commit); + } + + /** + * The default implementation does not allow several commits per project. + */ + @Override + public RestCommit createCommit(IEditingContext editingContext, Optional branchId) { + return null; + } + + @Override + public RestCommit getCommitById(IEditingContext editingContext, UUID commitId) { + RestCommit commit = null; + if (commitId != null && commitId.toString().equals(editingContext.getId())) { + var projectId = UUID.fromString(editingContext.getId()); + commit = new RestCommit(commitId, DEFAULT_CREATED, DEFAULT_DESCRIPTION, new Identified(projectId), List.of()); + } + return commit; + } + + /** + * The default implementation retrieves all elements containing in the project, without taking care of data created/updated/deleted since the creation of the project. + * It is not able to distinguish CREATED, UPDATED or DELETED elements. + * Furthermore, the DataVersion.id attribute should be randomly generated but constant for an unlimited period. + * We decided to generate this Id from it's commit Id and element Id, to be able to compute it for tests purpose. + * These are tradeoffs as it does not strictly follow the SystemModelingAPI specification. + */ + @Override + public List getCommitChange(IEditingContext editingContext, UUID commitId, List changeTypes) { + List dataVersions = new ArrayList<>(); + var changeTypesAllowed = changeTypes == null || changeTypes.isEmpty(); + if (commitId != null && commitId.toString().equals(editingContext.getId()) && changeTypesAllowed) { + var elements = this.defaultObjectRestService.getElements(editingContext); + for (var element : elements) { + var elementId = this.objectService.getId(element); + var changeId = UUID.nameUUIDFromBytes((commitId.toString() + elementId).getBytes()); + var dataVersion = new RestDataVersion(changeId, new RestDataIdentity(UUID.fromString(elementId)), element); + dataVersions.add(dataVersion); + } + } + return dataVersions; + } + + @Override + public RestDataVersion getCommitChangeById(IEditingContext editingContext, UUID commitId, UUID changeId) { + RestDataVersion dataVersion = null; + if (changeId != null && commitId != null && commitId.toString().equals(editingContext.getId())) { + var elements = this.defaultObjectRestService.getElements(editingContext); + for (var element : elements) { + var elementId = this.objectService.getId(element); + if (elementId != null) { + var computedChangeId = UUID.nameUUIDFromBytes((commitId.toString() + elementId).getBytes()); + if (changeId.toString().equals(computedChangeId.toString())) { + dataVersion = new RestDataVersion(changeId, new RestDataIdentity(UUID.fromString(elementId)), element); + break; + } + } + } + } + return dataVersion; + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/RestDataVersionPayloadSerializer.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/RestDataVersionPayloadSerializer.java new file mode 100644 index 00000000000..93d044da628 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/RestDataVersionPayloadSerializer.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.services; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.util.List; +import java.util.Objects; + +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestDataVersion; +import org.eclipse.sirius.web.application.project.data.versioning.services.api.IRestDataVersionPayloadSerializerService; +import org.springframework.stereotype.Service; + +/** + * Specific JSON serializer for the payload attribute of {@link RestDataVersion}. + * + * @author arichard + */ +@Service +public class RestDataVersionPayloadSerializer extends JsonSerializer { + + private final List restDataVersionPayloadSerializerServices; + + public RestDataVersionPayloadSerializer(List restDataVersionPayloadSerializerServices) { + this.restDataVersionPayloadSerializerServices = Objects.requireNonNull(restDataVersionPayloadSerializerServices); + } + + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + var optionalDelegate = this.restDataVersionPayloadSerializerServices.stream() + .filter(delegate -> delegate.canHandle(value)) + .findFirst(); + if (optionalDelegate.isPresent()) { + optionalDelegate.get().serialize(value, gen, serializers); + } + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IDefaultProjectDataVersioningRestService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IDefaultProjectDataVersioningRestService.java new file mode 100644 index 00000000000..5c0dc99f32a --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IDefaultProjectDataVersioningRestService.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.services.api; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.web.application.project.data.versioning.dto.ChangeType; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestCommit; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestDataVersion; + +/** + * Interface of the default service used by project-data-versioning-related REST APIs. + * + * @author arichard + */ +public interface IDefaultProjectDataVersioningRestService { + + List getCommits(IEditingContext editingContext); + + RestCommit createCommit(IEditingContext editingContext, Optional branchId); + + RestCommit getCommitById(IEditingContext editingContext, UUID commitId); + + List getCommitChange(IEditingContext editingContext, UUID commitId, List changeTypes); + + RestDataVersion getCommitChangeById(IEditingContext editingContext, UUID commitId, UUID changeId); +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IProjectDataVersioningRestService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IProjectDataVersioningRestService.java new file mode 100644 index 00000000000..77feb49de0e --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IProjectDataVersioningRestService.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.services.api; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.web.application.project.data.versioning.dto.ChangeType; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestCommit; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestDataVersion; + +/** + * Interface of the service used by project-data-versioning-related REST APIs. + * + * @author arichard + */ +public interface IProjectDataVersioningRestService { + + List getCommits(IEditingContext editingContext); + + RestCommit createCommit(IEditingContext editingContext, Optional branchId); + + RestCommit getCommitById(IEditingContext editingContext, UUID commitId); + + List getCommitChange(IEditingContext editingContext, UUID commitId, List changeTypes); + + RestDataVersion getCommitChangeById(IEditingContext editingContext, UUID commitId, UUID changeId); +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IProjectDataVersioningRestServiceDelegate.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IProjectDataVersioningRestServiceDelegate.java new file mode 100644 index 00000000000..46180522f2e --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IProjectDataVersioningRestServiceDelegate.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.services.api; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.web.application.project.data.versioning.dto.ChangeType; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestCommit; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestDataVersion; + +/** + * Interface of the delegate service used by project-data-versioning-related REST APIs. + * + * @author arichard + */ +public interface IProjectDataVersioningRestServiceDelegate { + + boolean canHandle(IEditingContext editingContext); + + List getCommits(IEditingContext editingContext); + + RestCommit createCommit(IEditingContext editingContext, Optional branchId); + + RestCommit getCommitById(IEditingContext editingContext, UUID commitId); + + List getCommitChange(IEditingContext editingContext, UUID commitId, List changeTypes); + + RestDataVersion getCommitChangeById(IEditingContext editingContext, UUID commitId, UUID changeId); +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IRestDataVersionPayloadSerializerService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IRestDataVersionPayloadSerializerService.java new file mode 100644 index 00000000000..a30a9db548b --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/data/versioning/services/api/IRestDataVersionPayloadSerializerService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.project.data.versioning.services.api; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +import org.eclipse.sirius.web.application.project.data.versioning.services.RestDataVersionPayloadSerializer; + +/** + * Interface of the delegate service used by {@link RestDataVersionPayloadSerializer}. + * + * @author arichard + */ +public interface IRestDataVersionPayloadSerializerService { + + boolean canHandle(Object object); + + void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException; +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/dto/RestProject.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/dto/RestProject.java index fd18719ccfd..b2938cc70bb 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/dto/RestProject.java +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/project/dto/RestProject.java @@ -12,11 +12,13 @@ *******************************************************************************/ package org.eclipse.sirius.web.application.project.dto; -import java.util.List; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.OffsetDateTime; +import java.util.Objects; import java.util.UUID; -import org.eclipse.sirius.web.application.dto.IRestRecord; -import org.eclipse.sirius.web.application.query.dto.RestQuery; +import org.eclipse.sirius.web.application.dto.Identified; /** * REST Project DTO. @@ -24,12 +26,28 @@ * @author arichard */ public record RestProject( - UUID id, - String resourceIdentifier, - List alias, - String humanIdentifier, - String decription, - String name, - List queries) implements IRestRecord { + @JsonProperty("@id") UUID id, + @JsonProperty("@type") String type, + OffsetDateTime created, + Identified defaultBranch, + String description, + String name) { + + public RestProject { + Objects.requireNonNull(id); + Objects.requireNonNull(created); + Objects.requireNonNull(defaultBranch); + // description can be null + Objects.requireNonNull(name); + + } + public RestProject( + UUID id, + OffsetDateTime created, + Identified defaultBranch, + String description, + String name) { + this(id, "Project", created, defaultBranch, description, name); + } } diff --git a/packages/sirius-web/backend/sirius-web-application/src/test/java/org/eclipse/sirius/web/application/architecture/CodingRulesTests.java b/packages/sirius-web/backend/sirius-web-application/src/test/java/org/eclipse/sirius/web/application/architecture/CodingRulesTests.java index a03a57533ac..7028a3a1319 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/test/java/org/eclipse/sirius/web/application/architecture/CodingRulesTests.java +++ b/packages/sirius-web/backend/sirius-web-application/src/test/java/org/eclipse/sirius/web/application/architecture/CodingRulesTests.java @@ -39,4 +39,10 @@ protected JavaClasses getClasses() { public void noClassesShouldUseApacheCommons() { super.noClassesShouldUseApacheCommons(); } + + @Test + @Override + public void noClassesShouldUseJacksonAnnotations() { + // Jackson annotations are used by REST APIs + } } diff --git a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/EObjectJsonSerializer.java b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/EObjectJsonSerializer.java new file mode 100644 index 00000000000..678d4c130a5 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/EObjectJsonSerializer.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.util.List; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.sirius.components.emf.services.EObjectIDManager; + +/** + * Custom JSON Serializer for EObjects, only for tests purpose. + * + * @author arichard + */ +public class EObjectJsonSerializer extends JsonSerializer { + + private static final String ID = "@id"; + + private static final String TYPE = "@type"; + + private EObjectIDManager eObjectIDManager = new EObjectIDManager(); + + @Override + public void serialize(EObject value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + var id = this.eObjectIDManager.findId(value); + if (id.isPresent()) { + gen.writeStringField(ID, id.get()); + } + gen.writeStringField(TYPE, value.eClass().getName()); + EList eAllAttributes = value.eClass().getEAllAttributes(); + for (EAttribute eAttribute : eAllAttributes) { + Object objectValue = value.eGet(eAttribute); + if (objectValue != null) { + gen.writeStringField(eAttribute.getName(), objectValue.toString()); + } else { + gen.writeStringField(eAttribute.getName(), null); + } + } + EList eAllReferences = value.eClass().getEAllReferences(); + for (EReference eReference : eAllReferences) { + Object objectValue = value.eGet(eReference); + if (objectValue != null) { + if (eReference.isMany()) { + this.writeArray(gen, eReference.getName(), objectValue); + } else if (objectValue instanceof EObject eObject) { + var refElementId = this.eObjectIDManager.findId(eObject); + if (refElementId.isPresent()) { + gen.writeObjectFieldStart(eReference.getName()); + gen.writeStringField(ID, refElementId.get()); + gen.writeEndObject(); + } + } + } else { + gen.writeStringField(eReference.getName(), null); + } + } + gen.writeEndObject(); + } + + private void writeArray(JsonGenerator gen, String arrayName, Object objectValue) throws IOException { + gen.writeArrayFieldStart(arrayName); + if (objectValue instanceof List listValue && !listValue.isEmpty()) { + for (Object listElementValue : listValue) { + if (listElementValue instanceof EObject eObject) { + var listElementId = this.eObjectIDManager.findId(eObject); + if (listElementId.isPresent()) { + gen.writeStartObject(); + gen.writeStringField(ID, listElementId.get()); + gen.writeEndObject(); + } + } + } + } + gen.writeEndArray(); + } +} \ No newline at end of file diff --git a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/EObjectSerializerTestConfig.java b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/EObjectSerializerTestConfig.java index 196a9c6ce4d..bae261b4942 100644 --- a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/EObjectSerializerTestConfig.java +++ b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/EObjectSerializerTestConfig.java @@ -12,20 +12,10 @@ *******************************************************************************/ package org.eclipse.sirius.web; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.module.SimpleModule; -import java.io.IOException; -import java.util.List; - -import org.eclipse.emf.common.util.EList; -import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.sirius.components.emf.services.EObjectIDManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; @@ -67,71 +57,4 @@ public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType this.converter.setObjectMapper(this.customObjectMapper); return body; } - - /** - * Custom JSON Serializer for EObjects, only for tests purpose. - * - * @author arichard - */ - private final class EObjectJsonSerializer extends JsonSerializer { - - private static final String ID = "@id"; - - private EObjectIDManager eObjectIDManager = new EObjectIDManager(); - - @Override - public void serialize(EObject value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeStartObject(); - var id = this.eObjectIDManager.findId(value); - if (id.isPresent()) { - gen.writeStringField(ID, id.get()); - } - gen.writeStringField("@type", value.eClass().getName()); - EList eAllAttributes = value.eClass().getEAllAttributes(); - for (EAttribute eAttribute : eAllAttributes) { - Object objectValue = value.eGet(eAttribute); - if (objectValue != null) { - gen.writeStringField(eAttribute.getName(), objectValue.toString()); - } else { - gen.writeStringField(eAttribute.getName(), null); - } - } - EList eAllReferences = value.eClass().getEAllReferences(); - for (EReference eReference : eAllReferences) { - Object objectValue = value.eGet(eReference); - if (objectValue != null) { - if (eReference.isMany()) { - this.writeArray(gen, eReference.getName(), objectValue); - } else if (objectValue instanceof EObject eObject) { - var refElementId = this.eObjectIDManager.findId(eObject); - if (refElementId.isPresent()) { - gen.writeObjectFieldStart(eReference.getName()); - gen.writeStringField(ID, refElementId.get()); - gen.writeEndObject(); - } - } - } else { - gen.writeStringField(eReference.getName(), null); - } - } - gen.writeEndObject(); - } - - private void writeArray(JsonGenerator gen, String arrayName, Object objectValue) throws IOException { - gen.writeArrayFieldStart(arrayName); - if (objectValue instanceof List listValue && !listValue.isEmpty()) { - for (Object listElementValue : listValue) { - if (listElementValue instanceof EObject eObject) { - var listElementId = this.eObjectIDManager.findId(eObject); - if (listElementId.isPresent()) { - gen.writeStartObject(); - gen.writeStringField(ID, listElementId.get()); - gen.writeEndObject(); - } - } - } - } - gen.writeEndArray(); - } - } } diff --git a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/projects/CommitRestControllerIntegrationTests.java b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/projects/CommitRestControllerIntegrationTests.java new file mode 100644 index 00000000000..35e61134644 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/projects/CommitRestControllerIntegrationTests.java @@ -0,0 +1,278 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.controllers.projects; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.UUID; + +import org.eclipse.sirius.web.AbstractIntegrationTests; +import org.eclipse.sirius.web.application.project.data.versioning.dto.RestCommit; +import org.eclipse.sirius.web.data.TestIdentifiers; +import org.eclipse.sirius.web.tests.services.api.IGivenInitialServerState; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.jdbc.SqlConfig; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.transaction.annotation.Transactional; + +/** + * Integration tests of the project-data-versioning commits REST controller. + * + * @author arichard + */ +@Transactional +@SuppressWarnings("checkstyle:MultipleStringLiterals") +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class CommitRestControllerIntegrationTests extends AbstractIntegrationTests { + + @Autowired + private IGivenInitialServerState givenInitialServerState; + + @LocalServerPort + private String port; + + private String getHTTPBaseUrl() { + return "http://localhost:" + this.port; + } + + @BeforeEach + public void beforeEach() { + this.givenInitialServerState.initialize(); + } + + @Test + @DisplayName("Given the Sirius Web REST API, when we ask for all commits of a project, then it should return all commits of a project") + @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenSiriusWebRestAPIWhenWeAskForAllCommitsOfAProjectThenItShouldReturnAllCommitsOfAProject() { + var webTestClient = WebTestClient.bindToServer() + .baseUrl(this.getHTTPBaseUrl()) + .build(); + + var uri = String.format("/api/rest/projects/%s/commits", TestIdentifiers.UML_SAMPLE_PROJECT); + webTestClient + .get() + .uri(uri) + .exchange() + .expectStatus() + .isOk() + .expectBodyList(RestCommit.class) + .hasSize(1) + .consumeWith(result -> { + var restCommits = result.getResponseBody(); + assertEquals(TestIdentifiers.UML_SAMPLE_PROJECT, restCommits.get(0).id()); + assertEquals("Commit", restCommits.get(0).type()); + assertEquals(TestIdentifiers.UML_SAMPLE_PROJECT, restCommits.get(0).owningProject().id()); + }); + } + + @Test + @DisplayName("Given the Sirius Web REST API, when we ask for all commits of an unknown project, then it should return an error") + @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenSiriusWebRestAPIWhenWeAskForAllCommitsOfAnUnknownProjectThenItShouldReturnAnError() { + var webTestClient = WebTestClient.bindToServer() + .baseUrl(this.getHTTPBaseUrl()) + .build(); + + var uri = String.format("/api/rest/projects/%s/commits", TestIdentifiers.INVALID_PROJECT); + webTestClient + .get() + .uri(uri) + .exchange() + .expectStatus() + .isNotFound(); + } + + @Test + @DisplayName("Given the Sirius Web REST API, when we ask for the creation of a commit, then it should return an empty response") + @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenSiriusWebRestAPIWhenWeAskForTheCreationOfACommitThenItShouldReturnAnEmptyResponse() { + var webTestClient = WebTestClient.bindToServer() + .baseUrl(this.getHTTPBaseUrl()) + .build(); + + var uri = String.format("/api/rest/projects/%s/commits", TestIdentifiers.UML_SAMPLE_PROJECT); + webTestClient + .post() + .uri(uri) + .exchange() + .expectStatus() + .isOk() + .expectBody() + .isEmpty(); + } + + @Test + @DisplayName("Given the Sirius Web REST API, when we ask for the creation of a commit on an ivalid project, then it should return an empty response") + @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenSiriusWebRestAPIWhenWeAskForTheCreationOfACommitOnAnInvalidProjectThenItShouldReturnAnEmptyResponse() { + var webTestClient = WebTestClient.bindToServer() + .baseUrl(this.getHTTPBaseUrl()) + .build(); + + var uri = String.format("/api/rest/projects/%s/commits", TestIdentifiers.INVALID_PROJECT); + webTestClient + .post() + .uri(uri) + .exchange() + .expectStatus() + .isOk() + .expectBody() + .isEmpty(); + } + + @Test + @DisplayName("Given the Sirius Web REST API, when we ask for a specific commit of a project, then it should return this commit") + @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenSiriusWebRestAPIWhenWeAskForASpecificCommitOfAProjectThenItShouldReturnThisCommit() { + var webTestClient = WebTestClient.bindToServer() + .baseUrl(this.getHTTPBaseUrl()) + .build(); + + var uri = String.format("/api/rest/projects/%s/commits/%s", TestIdentifiers.UML_SAMPLE_PROJECT, TestIdentifiers.UML_SAMPLE_PROJECT); + webTestClient + .get() + .uri(uri) + .exchange() + .expectStatus() + .isOk() + .expectBody(RestCommit.class) + .consumeWith(result -> { + var restCommit = result.getResponseBody(); + assertEquals(TestIdentifiers.UML_SAMPLE_PROJECT, restCommit.id()); + assertEquals("Commit", restCommit.type()); + assertEquals(TestIdentifiers.UML_SAMPLE_PROJECT, restCommit.owningProject().id()); + }); + } + + @Test + @DisplayName("Given the Sirius Web REST API, when we ask for an unknown commit of a project, then it should return an error") + @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenSiriusWebRestAPIWhenWeAskForAnUnknownCommitOfAProjectThenItShouldReturnAnError() { + var webTestClient = WebTestClient.bindToServer() + .baseUrl(this.getHTTPBaseUrl()) + .build(); + + var uri = String.format("/api/rest/projects/%s/commits/%s", TestIdentifiers.UML_SAMPLE_PROJECT, TestIdentifiers.INVALID_PROJECT); + webTestClient + .get() + .uri(uri) + .exchange() + .expectStatus() + .isNotFound(); + } + + @Test + @DisplayName("Given the Sirius Web REST API, when we ask for commit changes of a project, then it should return these commit changes") + @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenSiriusWebRestAPIWhenWeAskForCommitChangesOfAProjectThenItShouldReturnTheseCommitChanges() { + var webTestClient = WebTestClient.bindToServer() + .baseUrl(this.getHTTPBaseUrl()) + .build(); + + var uri = String.format("/api/rest/projects/%s/commits/%s/changes", TestIdentifiers.ECORE_SAMPLE_PROJECT, TestIdentifiers.ECORE_SAMPLE_PROJECT); + webTestClient + .get() + .uri(uri) + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("$[0].@type").isEqualTo("DataVersion") + .jsonPath("$[0].identity.@id").isEqualTo(TestIdentifiers.EPACKAGE_OBJECT.toString()) + .jsonPath("$[0].identity.@type").isEqualTo("DataIdentity") + .jsonPath("$[0].payload.@id").isEqualTo(TestIdentifiers.EPACKAGE_OBJECT.toString()) + .jsonPath("$[0].payload.@type").isEqualTo("EPackage") + .jsonPath("$[0].payload.name").isEqualTo("Sample") + .jsonPath("$[1].@type").isEqualTo("DataVersion") + .jsonPath("$[1].identity.@id").isEqualTo(TestIdentifiers.ECLASS_OBJECT.toString()) + .jsonPath("$[0].identity.@type").isEqualTo("DataIdentity") + .jsonPath("$[1].payload.@id").isEqualTo(TestIdentifiers.ECLASS_OBJECT.toString()) + .jsonPath("$[1].payload.@type").isEqualTo("EClass") + .jsonPath("$[1].payload.name").isEqualTo("SampleEClass"); + } + + @Test + @DisplayName("Given the Sirius Web REST API, when we ask for commit changes of a project with no data, then it should return an error") + @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenSiriusWebRestAPIWhenWeAskForCommitChangesOfAProjectWithNoDataThenItShouldReturnAnError() { + var webTestClient = WebTestClient.bindToServer() + .baseUrl(this.getHTTPBaseUrl()) + .build(); + + var uri = String.format("/api/rest/projects/%s/commits/%s/changes", TestIdentifiers.UML_SAMPLE_PROJECT, TestIdentifiers.UML_SAMPLE_PROJECT); + webTestClient + .get() + .uri(uri) + .exchange() + .expectStatus() + .isNotFound(); // no data in this project, so RestDataVersion + } + + @Test + @DisplayName("Given the Sirius Web REST API, when we ask for a specific commit change, then it should return this commit change") + @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenSiriusWebRestAPIWhenWeAskForASpecificCommitChangeThenItShouldReturnThisCommitChange() { + var webTestClient = WebTestClient.bindToServer() + .baseUrl(this.getHTTPBaseUrl()) + .build(); + + var changeId = UUID.nameUUIDFromBytes((TestIdentifiers.ECORE_SAMPLE_PROJECT.toString() + TestIdentifiers.EPACKAGE_OBJECT.toString()).getBytes()); + var uri = String.format("/api/rest/projects/%s/commits/%s/changes/%s", TestIdentifiers.ECORE_SAMPLE_PROJECT, TestIdentifiers.ECORE_SAMPLE_PROJECT, changeId); + webTestClient + .get() + .uri(uri) + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("$.@type").isEqualTo("DataVersion") + .jsonPath("$.identity.@id").isEqualTo(TestIdentifiers.EPACKAGE_OBJECT.toString()) + .jsonPath("$.identity.@type").isEqualTo("DataIdentity") + .jsonPath("$.payload.@id").isEqualTo(TestIdentifiers.EPACKAGE_OBJECT.toString()) + .jsonPath("$.payload.@type").isEqualTo("EPackage") + .jsonPath("$.payload.name").isEqualTo("Sample"); + } + + @Test + @DisplayName("Given the Sirius Web REST API, when we ask for an invalid commit change, then it should return an error") + @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenSiriusWebRestAPIWhenWeAskForAnInvalidCommitChangeThenItShouldReturnAnError() { + var webTestClient = WebTestClient.bindToServer() + .baseUrl(this.getHTTPBaseUrl()) + .build(); + + var uri = String.format("/api/rest/projects/%s/commits/%s/changes/%s", TestIdentifiers.UML_SAMPLE_PROJECT, TestIdentifiers.UML_SAMPLE_PROJECT, TestIdentifiers.INVALID_PROJECT); + webTestClient + .get() + .uri(uri) + .exchange() + .expectStatus() + .isNotFound(); + } +} diff --git a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/projects/ProjectRestControllerIntegrationTests.java b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/projects/ProjectRestControllerIntegrationTests.java index 94d9594bdd6..9e2c7ce9f58 100644 --- a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/projects/ProjectRestControllerIntegrationTests.java +++ b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/projects/ProjectRestControllerIntegrationTests.java @@ -83,7 +83,7 @@ public void givenSiriusWebRestAPIWhenWeAskForProjectThenItShouldReturnTheProject .build(); var uri = String.format("/api/rest/projects/%s", TestIdentifiers.UML_SAMPLE_PROJECT); - var response = webTestClient + webTestClient .get() .uri(uri) .exchange() @@ -93,6 +93,7 @@ public void givenSiriusWebRestAPIWhenWeAskForProjectThenItShouldReturnTheProject .consumeWith(result -> { var restProject = result.getResponseBody(); assertEquals(TestIdentifiers.UML_SAMPLE_PROJECT, restProject.id()); + assertEquals("Project", restProject.type()); assertEquals("UML Sample", restProject.name()); }); } @@ -210,6 +211,7 @@ public void givenSiriusWebRestAPIWhenWeDeleteProjectThenItShouldBeDeleted() { .consumeWith(result -> { var restProject = result.getResponseBody(); assertEquals(TestIdentifiers.UML_SAMPLE_PROJECT, restProject.id()); + assertEquals("Project", restProject.type()); assertEquals("UML Sample", restProject.name()); }); } diff --git a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/projects/RestDataVersionPayloadSerializerTestService.java b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/projects/RestDataVersionPayloadSerializerTestService.java new file mode 100644 index 00000000000..c140f66746a --- /dev/null +++ b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/projects/RestDataVersionPayloadSerializerTestService.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.web.application.controllers.projects; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.sirius.web.EObjectJsonSerializer; +import org.eclipse.sirius.web.application.project.data.versioning.services.api.IRestDataVersionPayloadSerializerService; +import org.springframework.stereotype.Service; + +/** + * Test implementation of {@link IRestDataVersionPayloadSerializerService}. Used indirectly by + * {@link CommitRestControllerIntegrationTests}. + * + * @author arichard + */ +@Service +public class RestDataVersionPayloadSerializerTestService implements IRestDataVersionPayloadSerializerService { + + private EObjectJsonSerializer eObjectJsonSerializer; + + public RestDataVersionPayloadSerializerTestService() { + this.eObjectJsonSerializer = new EObjectJsonSerializer(); + } + + @Override + public boolean canHandle(Object object) { + return object instanceof EObject; + } + + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + this.eObjectJsonSerializer.serialize((EObject) value, gen, serializers); + } +}