From 121edf600f7907048accbf355463ad9d0645f4c3 Mon Sep 17 00:00:00 2001 From: alexsilaghi Date: Wed, 11 Dec 2024 14:38:47 +0200 Subject: [PATCH] Set entity from api adding transactionality (#52) add commit/rollback mechanism. Add ChangeRequestId to Revision Events for rollback there as well. --- pom.xml | 2 +- .../GetEntityCustomScaleValueResponse.java | 3 + .../GetEntityPostCoordinationResponse.java | 6 ++ .../events/EntityUpdateFailedEvent.java | 36 +++++++++ .../EntityUpdatedSuccessfullyEvent.java | 36 +++++++++ ...ityCustomScalesRevisionCommandHandler.java | 2 +- .../AddEntityCustomScalesRevisionRequest.java | 10 ++- ...tySpecificationRevisionCommandHandler.java | 2 +- ...AddEntitySpecificationRevisionRequest.java | 6 +- .../EntityUpdatedSuccessfullyHandler.java | 41 ++++++++++ .../handlers/EventUpdateFailedHandler.java | 40 ++++++++++ ...EntityCustomScaleValuesCommandHandler.java | 4 +- ...tEntityPostCoordinationCommandHandler.java | 4 +- .../model/CommitStatus.java | 6 ++ .../EntityCustomScalesValuesHistory.java | 8 +- .../model/EntityPostCoordinationHistory.java | 8 +- .../PostCoordinationCustomScalesRevision.java | 16 +++- ...PostCoordinationSpecificationRevision.java | 15 +++- .../PostCoordinationRepository.java | 73 +++++++++++++++++ ...PostCoordinationTableConfigRepository.java | 1 + .../NewRevisionsEventEmitterService.java | 9 ++- .../NewRevisionsEventEmitterServiceImpl.java | 16 ++-- .../PostCoordinationEventProcessor.java | 6 +- .../services/PostCoordinationService.java | 78 +++++++++++++------ .../services/RevisionCommitService.java | 38 +++++++++ .../changes/NewRevisionsEvent.java | 8 +- src/main/resources/application.yml | 2 + ...ostCoordinationServiceApplicationTest.java | 18 ----- .../PostCoordinationEventProcessorTest.java | 8 +- 29 files changed, 423 insertions(+), 79 deletions(-) create mode 100644 src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/events/EntityUpdateFailedEvent.java create mode 100644 src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/events/EntityUpdatedSuccessfullyEvent.java create mode 100644 src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/EntityUpdatedSuccessfullyHandler.java create mode 100644 src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/EventUpdateFailedHandler.java create mode 100644 src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/CommitStatus.java create mode 100644 src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/RevisionCommitService.java diff --git a/pom.xml b/pom.xml index 52e4c40..b655c82 100644 --- a/pom.xml +++ b/pom.xml @@ -40,7 +40,7 @@ edu.stanford.protege webprotege-ipc - 1.0.5 + 1.0.9 diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/dto/GetEntityCustomScaleValueResponse.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/dto/GetEntityCustomScaleValueResponse.java index e343ed9..679a578 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/dto/GetEntityCustomScaleValueResponse.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/dto/GetEntityCustomScaleValueResponse.java @@ -4,11 +4,14 @@ import edu.stanford.protege.webprotege.common.Response; import edu.stanford.protege.webprotege.postcoordinationservice.model.WhoficCustomScalesValues; +import java.util.Date; + import static edu.stanford.protege.webprotege.postcoordinationservice.dto.GetEntityCustomScaleValuesRequest.CHANNEL; @JsonTypeName(CHANNEL) public record GetEntityCustomScaleValueResponse( + @JsonProperty("lastRevisionDate") Date lastRevisionDate, @JsonProperty("whoficCustomScaleValues") WhoficCustomScalesValues whoficCustomScalesValues ) implements Response { } diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/dto/GetEntityPostCoordinationResponse.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/dto/GetEntityPostCoordinationResponse.java index 0146c61..dfddec1 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/dto/GetEntityPostCoordinationResponse.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/dto/GetEntityPostCoordinationResponse.java @@ -5,11 +5,17 @@ import edu.stanford.protege.webprotege.common.Response; import edu.stanford.protege.webprotege.postcoordinationservice.model.WhoficEntityPostCoordinationSpecification; +import java.util.Date; + import static edu.stanford.protege.webprotege.postcoordinationservice.dto.GetEntityPostCoordinationRequest.CHANNEL; @JsonTypeName(CHANNEL) public record GetEntityPostCoordinationResponse(@JsonProperty("entityIri") String entityIri, + + @JsonProperty("lastRevisionDate") + Date lastRevisionDate, + @JsonProperty("postCoordinationSpecification") WhoficEntityPostCoordinationSpecification postCoordinationSpecification) implements Response { } diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/events/EntityUpdateFailedEvent.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/events/EntityUpdateFailedEvent.java new file mode 100644 index 0000000..0c03acb --- /dev/null +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/events/EntityUpdateFailedEvent.java @@ -0,0 +1,36 @@ +package edu.stanford.protege.webprotege.postcoordinationservice.events; + +import com.fasterxml.jackson.annotation.JsonProperty; +import edu.stanford.protege.webprotege.common.ChangeRequestId; +import edu.stanford.protege.webprotege.common.EventId; +import edu.stanford.protege.webprotege.common.ProjectEvent; +import edu.stanford.protege.webprotege.common.ProjectId; + +import javax.annotation.Nonnull; + +public record EntityUpdateFailedEvent(@JsonProperty("projectId") ProjectId projectId, + @JsonProperty("eventId") EventId eventId, + + @JsonProperty("entityIri") String entityIri, + @JsonProperty("changeRequestId")ChangeRequestId changeRequestId) implements ProjectEvent { + + public static String CHANNEL = "webprotege.api.EntityUpdateFailed"; + + + @Nonnull + @Override + public ProjectId projectId() { + return projectId; + } + + @Nonnull + @Override + public EventId eventId() { + return eventId; + } + + @Override + public String getChannel() { + return CHANNEL; + } +} diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/events/EntityUpdatedSuccessfullyEvent.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/events/EntityUpdatedSuccessfullyEvent.java new file mode 100644 index 0000000..a181b7a --- /dev/null +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/events/EntityUpdatedSuccessfullyEvent.java @@ -0,0 +1,36 @@ +package edu.stanford.protege.webprotege.postcoordinationservice.events; + +import com.fasterxml.jackson.annotation.JsonProperty; +import edu.stanford.protege.webprotege.common.ChangeRequestId; +import edu.stanford.protege.webprotege.common.EventId; +import edu.stanford.protege.webprotege.common.ProjectEvent; +import edu.stanford.protege.webprotege.common.ProjectId; + +import javax.annotation.Nonnull; + +public record EntityUpdatedSuccessfullyEvent(@JsonProperty("projectId") ProjectId projectId, + @JsonProperty("eventId") EventId eventId, + + @JsonProperty("entityIri") String entityIri, + @JsonProperty("changeRequestId") ChangeRequestId changeRequestId) implements ProjectEvent { + + public static String CHANNEL = "webprotege.api.EntityUpdatedSuccessfully"; + + + @Nonnull + @Override + public ProjectId projectId() { + return projectId; + } + + @Nonnull + @Override + public EventId eventId() { + return eventId; + } + + @Override + public String getChannel() { + return CHANNEL; + } +} diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntityCustomScalesRevisionCommandHandler.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntityCustomScalesRevisionCommandHandler.java index d3dc3de..9f5db65 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntityCustomScalesRevisionCommandHandler.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntityCustomScalesRevisionCommandHandler.java @@ -29,7 +29,7 @@ public Class getRequestClass() { @Override public Mono handleRequest(AddEntityCustomScalesRevisionRequest request, ExecutionContext executionContext) { - postCoordService.addCustomScaleRevision(request.entityCustomScaleValues(), request.projectId(), executionContext.userId()); + postCoordService.addCustomScaleRevision(request.entityCustomScaleValues(), request.projectId(), executionContext.userId(), request.changeRequestId()); return Mono.just(new AddEntityCustomScalesRevisionResponse()); } diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntityCustomScalesRevisionRequest.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntityCustomScalesRevisionRequest.java index 67f486e..b545b81 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntityCustomScalesRevisionRequest.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntityCustomScalesRevisionRequest.java @@ -5,13 +5,16 @@ import edu.stanford.protege.webprotege.common.*; import edu.stanford.protege.webprotege.postcoordinationservice.model.WhoficCustomScalesValues; +import javax.annotation.Nullable; + import static edu.stanford.protege.webprotege.postcoordinationservice.handlers.AddEntityCustomScalesRevisionRequest.CHANNEL; @JsonTypeName(CHANNEL) public record AddEntityCustomScalesRevisionRequest(@JsonProperty("projectId") ProjectId projectId, @JsonProperty("entityCustomScaleValues") - WhoficCustomScalesValues entityCustomScaleValues) implements Request { + WhoficCustomScalesValues entityCustomScaleValues, + @JsonProperty("changeRequestId") @Nullable ChangeRequestId changeRequestId) implements Request { public final static String CHANNEL = "webprotege.postcoordination.AddEntityCustomScalesRevision"; @@ -19,8 +22,9 @@ public record AddEntityCustomScalesRevisionRequest(@JsonProperty("projectId") public static AddEntityCustomScalesRevisionRequest create(@JsonProperty("projectId") ProjectId projectId, @JsonProperty("entityCustomScaleValues") - WhoficCustomScalesValues entityCustomScaleValues) { - return new AddEntityCustomScalesRevisionRequest(projectId, entityCustomScaleValues); + WhoficCustomScalesValues entityCustomScaleValues, + @JsonProperty("changeRequestId") @Nullable ChangeRequestId changeRequestId) { + return new AddEntityCustomScalesRevisionRequest(projectId, entityCustomScaleValues, changeRequestId); } @Override diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntitySpecificationRevisionCommandHandler.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntitySpecificationRevisionCommandHandler.java index 3676b45..e82db6a 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntitySpecificationRevisionCommandHandler.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntitySpecificationRevisionCommandHandler.java @@ -28,7 +28,7 @@ public Class getRequestClass() { @Override public Mono handleRequest(AddEntitySpecificationRevisionRequest request, ExecutionContext executionContext) { - postCoordService.addSpecificationRevision(request.entitySpecification(), executionContext.userId(), request.projectId()); + postCoordService.addSpecificationRevision(request.entitySpecification(), executionContext.userId(), request.projectId(), request.changeRequestId()); return Mono.just(new AddEntitySpecificationRevisionResponse()); } } diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntitySpecificationRevisionRequest.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntitySpecificationRevisionRequest.java index 8639459..1c48f05 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntitySpecificationRevisionRequest.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/AddEntitySpecificationRevisionRequest.java @@ -2,17 +2,21 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeName; +import edu.stanford.protege.webprotege.common.ChangeRequestId; import edu.stanford.protege.webprotege.common.ProjectId; import edu.stanford.protege.webprotege.common.Request; import edu.stanford.protege.webprotege.postcoordinationservice.model.WhoficEntityPostCoordinationSpecification; +import javax.annotation.Nullable; + import static edu.stanford.protege.webprotege.postcoordinationservice.handlers.AddEntitySpecificationRevisionRequest.CHANNEL; @JsonTypeName(CHANNEL) public record AddEntitySpecificationRevisionRequest(@JsonProperty("projectId") ProjectId projectId, @JsonProperty("entitySpecification") - WhoficEntityPostCoordinationSpecification entitySpecification) implements Request { + WhoficEntityPostCoordinationSpecification entitySpecification, + @JsonProperty("changeRequestId") @Nullable ChangeRequestId changeRequestId) implements Request { public final static String CHANNEL = "webprotege.postcoordination.AddEntitySpecificationRevision"; diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/EntityUpdatedSuccessfullyHandler.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/EntityUpdatedSuccessfullyHandler.java new file mode 100644 index 0000000..756a51e --- /dev/null +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/EntityUpdatedSuccessfullyHandler.java @@ -0,0 +1,41 @@ +package edu.stanford.protege.webprotege.postcoordinationservice.handlers; + + +import edu.stanford.protege.webprotege.ipc.EventHandler; +import edu.stanford.protege.webprotege.postcoordinationservice.events.EntityUpdatedSuccessfullyEvent; +import edu.stanford.protege.webprotege.postcoordinationservice.services.RevisionCommitService; +import org.jetbrains.annotations.NotNull; +import org.springframework.stereotype.Component; + +@Component +public class EntityUpdatedSuccessfullyHandler implements EventHandler { + + + private final RevisionCommitService revisionCommitService; + + public EntityUpdatedSuccessfullyHandler(RevisionCommitService revisionCommitService) { + this.revisionCommitService = revisionCommitService; + } + + @NotNull + @Override + public String getChannelName() { + return EntityUpdatedSuccessfullyEvent.CHANNEL; + } + + @NotNull + @Override + public String getHandlerName() { + return this.getClass().getName(); + } + + @Override + public Class getEventClass() { + return EntityUpdatedSuccessfullyEvent.class; + } + + @Override + public void handleEvent(EntityUpdatedSuccessfullyEvent event) { + revisionCommitService.commitRevision(event.changeRequestId(), event.projectId(), event.entityIri()); + } +} diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/EventUpdateFailedHandler.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/EventUpdateFailedHandler.java new file mode 100644 index 0000000..a8f4d2b --- /dev/null +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/EventUpdateFailedHandler.java @@ -0,0 +1,40 @@ +package edu.stanford.protege.webprotege.postcoordinationservice.handlers; + + +import edu.stanford.protege.webprotege.ipc.EventHandler; +import edu.stanford.protege.webprotege.postcoordinationservice.events.EntityUpdateFailedEvent; +import edu.stanford.protege.webprotege.postcoordinationservice.services.RevisionCommitService; +import org.jetbrains.annotations.NotNull; +import org.springframework.stereotype.Component; + +@Component +public class EventUpdateFailedHandler implements EventHandler { + + private final RevisionCommitService revisionCommitService; + + public EventUpdateFailedHandler(RevisionCommitService revisionCommitService) { + this.revisionCommitService = revisionCommitService; + } + + @NotNull + @Override + public String getChannelName() { + return EntityUpdateFailedEvent.CHANNEL; + } + + @NotNull + @Override + public String getHandlerName() { + return EventUpdateFailedHandler.class.getName(); + } + + @Override + public Class getEventClass() { + return EntityUpdateFailedEvent.class; + } + + @Override + public void handleEvent(EntityUpdateFailedEvent event) { + revisionCommitService.rollbackRevision(event.changeRequestId(), event.projectId(), event.entityIri()); + } +} diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/GetEntityCustomScaleValuesCommandHandler.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/GetEntityCustomScaleValuesCommandHandler.java index 55af154..d259dbd 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/GetEntityCustomScaleValuesCommandHandler.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/GetEntityCustomScaleValuesCommandHandler.java @@ -32,8 +32,8 @@ public Class getRequestClass() { @Override public Mono handleRequest(GetEntityCustomScaleValuesRequest request, ExecutionContext executionContext) { - WhoficCustomScalesValues processedScales = postCoordService.fetchCustomScalesHistory(request.entityIRI(), request.projectId()); + GetEntityCustomScaleValueResponse response = postCoordService.fetchCustomScalesHistory(request.entityIRI(), request.projectId()); - return Mono.just(new GetEntityCustomScaleValueResponse(processedScales)); + return Mono.just(response); } } diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/GetEntityPostCoordinationCommandHandler.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/GetEntityPostCoordinationCommandHandler.java index 613081e..3afa0da 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/GetEntityPostCoordinationCommandHandler.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/handlers/GetEntityPostCoordinationCommandHandler.java @@ -35,8 +35,8 @@ public Class getRequestClass() { @Override public Mono handleRequest(GetEntityPostCoordinationRequest request, ExecutionContext executionContext) { - WhoficEntityPostCoordinationSpecification processedSpec = postCoordService.fetchHistory(request.entityIRI(), request.projectId()); + GetEntityPostCoordinationResponse processedSpec = postCoordService.fetchHistory(request.entityIRI(), request.projectId()); - return Mono.just(new GetEntityPostCoordinationResponse(request.entityIRI(), processedSpec)); + return Mono.just(processedSpec); } } diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/CommitStatus.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/CommitStatus.java new file mode 100644 index 0000000..113bd22 --- /dev/null +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/CommitStatus.java @@ -0,0 +1,6 @@ +package edu.stanford.protege.webprotege.postcoordinationservice.model; + +public enum CommitStatus { + COMMITTED, + UNCOMMITTED; +} diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/EntityCustomScalesValuesHistory.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/EntityCustomScalesValuesHistory.java index 56915a8..b0cb7f0 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/EntityCustomScalesValuesHistory.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/EntityCustomScalesValuesHistory.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.*; +import org.springframework.data.mongodb.core.index.CompoundIndex; +import org.springframework.data.mongodb.core.index.CompoundIndexes; import org.springframework.data.mongodb.core.index.Indexed; import org.springframework.data.mongodb.core.mapping.*; @@ -11,6 +13,9 @@ @JsonIgnoreProperties(ignoreUnknown = true) @Document(collection = POSTCOORDINATION_CUSTOM_SCALES_COLLECTION) +@CompoundIndexes({ + @CompoundIndex(name = "entity_iri_project_idx", def = "{'" + EntityCustomScalesValuesHistory.WHOFIC_ENTITY_IRI + "': 1, '" + EntityCustomScalesValuesHistory.PROJECT_ID + "': 1}") +}) public class EntityCustomScalesValuesHistory { public static final String POSTCOORDINATION_CUSTOM_SCALES_COLLECTION = "EntityPostCoordinationCustomScales"; @@ -19,10 +24,11 @@ public class EntityCustomScalesValuesHistory { public static final String PROJECT_ID = "projectId"; public static final String CUSTOM_SCALE_REVISIONS = "postCoordinationCustomScalesRevisions"; @Field(WHOFIC_ENTITY_IRI) - @Indexed(name = "entityIriScales") + @Indexed(name = "entityIriScales_idx") private final String whoficEntityIri; @Field(PROJECT_ID) + @Indexed(name = "entityProjectId_idx") private final String projectId; @Field(CUSTOM_SCALE_REVISIONS) diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/EntityPostCoordinationHistory.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/EntityPostCoordinationHistory.java index 50d9db0..74687a5 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/EntityPostCoordinationHistory.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/EntityPostCoordinationHistory.java @@ -1,6 +1,8 @@ package edu.stanford.protege.webprotege.postcoordinationservice.model; import com.fasterxml.jackson.annotation.*; +import org.springframework.data.mongodb.core.index.CompoundIndex; +import org.springframework.data.mongodb.core.index.CompoundIndexes; import org.springframework.data.mongodb.core.index.Indexed; import org.springframework.data.mongodb.core.mapping.*; @@ -8,6 +10,9 @@ @JsonIgnoreProperties(ignoreUnknown = true) @Document(collection = EntityPostCoordinationHistory.POSTCOORDINATION_HISTORY_COLLECTION) +@CompoundIndexes({ + @CompoundIndex(name = "entity_iri_project_idx", def = "{'" + EntityPostCoordinationHistory.WHOFIC_ENTITY_IRI + "': 1, '" + EntityPostCoordinationHistory.PROJECT_ID + "': 1}") +}) public class EntityPostCoordinationHistory { @@ -18,10 +23,11 @@ public class EntityPostCoordinationHistory { public static final String SPEC_REVISIONS = "postCoordinationRevisions"; @Field(WHOFIC_ENTITY_IRI) - @Indexed(name = "entityIriSpec") + @Indexed(name = "entityIriSpec_idx") private final String whoficEntityIri; @Field(PROJECT_ID) + @Indexed(name = "entityIriProjectId_idx") private final String projectId; @Field(SPEC_REVISIONS) diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/PostCoordinationCustomScalesRevision.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/PostCoordinationCustomScalesRevision.java index 2ee8372..95ede83 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/PostCoordinationCustomScalesRevision.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/PostCoordinationCustomScalesRevision.java @@ -1,6 +1,7 @@ package edu.stanford.protege.webprotege.postcoordinationservice.model; import com.google.common.base.Objects; +import edu.stanford.protege.webprotege.common.ChangeRequestId; import edu.stanford.protege.webprotege.common.UserId; import edu.stanford.protege.webprotege.postcoordinationservice.events.PostCoordinationCustomScalesValueEvent; import org.jetbrains.annotations.NotNull; @@ -11,11 +12,22 @@ public record PostCoordinationCustomScalesRevision(UserId userId, @Indexed(name = "rev_timestamp", direction = IndexDirection.DESCENDING) Long timestamp, - Set postCoordinationEvents) implements Comparable { + Set postCoordinationEvents, + CommitStatus commitStatus, + String changeRequestId) implements Comparable { public static PostCoordinationCustomScalesRevision create(UserId userId, Set postCoordinationEventList) { - return new PostCoordinationCustomScalesRevision(userId, Instant.now().toEpochMilli(), postCoordinationEventList); + return create(userId, postCoordinationEventList, null); + } + + public static PostCoordinationCustomScalesRevision create(UserId userId, Set postCoordinationEventList, ChangeRequestId changeRequestId) { + CommitStatus status = changeRequestId != null && changeRequestId.id() != null ? CommitStatus.UNCOMMITTED : CommitStatus.COMMITTED; + return new PostCoordinationCustomScalesRevision(userId, Instant.now().toEpochMilli(), postCoordinationEventList, status, changeRequestId != null ? changeRequestId.id() : null); + } + + public static PostCoordinationCustomScalesRevision createCommittedClone(PostCoordinationCustomScalesRevision revision) { + return new PostCoordinationCustomScalesRevision(revision.userId(), revision.timestamp(), revision.postCoordinationEvents(), CommitStatus.COMMITTED, revision.changeRequestId()); } @Override diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/PostCoordinationSpecificationRevision.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/PostCoordinationSpecificationRevision.java index 453cac3..0752593 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/PostCoordinationSpecificationRevision.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/model/PostCoordinationSpecificationRevision.java @@ -2,6 +2,7 @@ import com.google.common.base.Objects; +import edu.stanford.protege.webprotege.common.ChangeRequestId; import edu.stanford.protege.webprotege.common.UserId; import org.jetbrains.annotations.NotNull; import org.springframework.data.mongodb.core.index.*; @@ -11,11 +12,21 @@ public record PostCoordinationSpecificationRevision(UserId userId, @Indexed(name = "spec_timestamp", direction = IndexDirection.DESCENDING) Long timestamp, - Set postCoordinationEvents) implements Comparable{ + Set postCoordinationEvents, + CommitStatus commitStatus, + String changeRequestId) implements Comparable{ public static PostCoordinationSpecificationRevision create(UserId userId, Set postCoordinationEventList) { - return new PostCoordinationSpecificationRevision(userId, Instant.now().toEpochMilli(), postCoordinationEventList); + return create(userId, postCoordinationEventList, null); + } + public static PostCoordinationSpecificationRevision create(UserId userId, Set postCoordinationEventList, ChangeRequestId changeRequestId) { + CommitStatus status = changeRequestId != null && changeRequestId.id() != null ? CommitStatus.UNCOMMITTED : CommitStatus.COMMITTED; + return new PostCoordinationSpecificationRevision(userId, Instant.now().toEpochMilli(), postCoordinationEventList, status, changeRequestId != null ? changeRequestId.id() : null); + } + + public static PostCoordinationSpecificationRevision createCommittedClone(PostCoordinationSpecificationRevision revision) { + return new PostCoordinationSpecificationRevision(revision.userId, revision.timestamp, revision.postCoordinationEvents, CommitStatus.COMMITTED, revision.changeRequestId); } @Override diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/repositories/PostCoordinationRepository.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/repositories/PostCoordinationRepository.java index 583a59f..187757b 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/repositories/PostCoordinationRepository.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/repositories/PostCoordinationRepository.java @@ -3,10 +3,13 @@ import com.mongodb.client.model.InsertOneModel; import com.mongodb.client.result.UpdateResult; +import edu.stanford.protege.webprotege.common.ChangeRequestId; import edu.stanford.protege.webprotege.common.ProjectId; import edu.stanford.protege.webprotege.postcoordinationservice.model.*; import edu.stanford.protege.webprotege.postcoordinationservice.services.ReadWriteLockService; import org.bson.Document; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.*; import org.springframework.stereotype.Repository; @@ -22,6 +25,7 @@ @Repository public class PostCoordinationRepository { + private final static Logger LOGGER = LoggerFactory.getLogger(PostCoordinationRepository.class); private final MongoTemplate mongoTemplate; private final ReadWriteLockService readWriteLock; @@ -132,4 +136,73 @@ public Optional getExistingCustomScaleHistoryOr ); } + + public void deletePostCoordinationCustomScalesRevision(ChangeRequestId changeRequestId, ProjectId projectId, String entityIri) { + + Query query = new Query(); + query.addCriteria( + Criteria.where(WHOFIC_ENTITY_IRI).is(entityIri) + .and(PROJECT_ID).is(projectId.value()) + ); + Update update = new Update().pull("postCoordinationCustomScalesRevisions", + new Document("changeRequestId", changeRequestId.id())); + + readWriteLock.executeWriteLock(() -> { + UpdateResult updateResult = mongoTemplate.updateFirst(query, update, EntityCustomScalesValuesHistory.class, CUSTOM_SCALE_REVISIONS); + LOGGER.info("Removed custom scales revision for " + entityIri + " with result : " + updateResult); + } + ); + } + + public void deletePostCoordinationSpecificationRevision(ChangeRequestId changeRequestId, ProjectId projectId, String entityIri) { + + Query query = new Query(); + query.addCriteria( + Criteria.where(WHOFIC_ENTITY_IRI).is(entityIri) + .and(PROJECT_ID).is(projectId.value()) + ); + Update update = new Update().pull("postCoordinationRevisions", + new Document("changeRequestId", changeRequestId.id())); + + readWriteLock.executeWriteLock(() -> { + UpdateResult updateResult = mongoTemplate.updateFirst(query, update, EntityPostCoordinationHistory.class, POSTCOORDINATION_HISTORY_COLLECTION); + LOGGER.info("Removed custom scales revision for " + entityIri + " with result : " + updateResult); + } + ); + } + + public void commitPostCoordinationSpecificationRevision(ChangeRequestId changeRequestId, ProjectId projectId, String entityIri) { + Query query = new Query(Criteria.where(WHOFIC_ENTITY_IRI) + .is(entityIri) + .and(PROJECT_ID).is(projectId.id()) + .and("postCoordinationRevisions") + .elemMatch( + Criteria.where("changeRequestId").is(changeRequestId.id()) + .and("commitStatus").is(CommitStatus.UNCOMMITTED.name()) + ) + ); + Update update = new Update().set("postCoordinationRevisions.$.commitStatus", CommitStatus.COMMITTED.name()); + + readWriteLock.executeReadLock(() -> + Optional.of(mongoTemplate.updateFirst(query, update, EntityPostCoordinationHistory.class, POSTCOORDINATION_HISTORY_COLLECTION)) + ); + } + + public void commitPostCoordinationCustomScalesRevision(ChangeRequestId changeRequestId, ProjectId projectId, String entityIri) { + Query query = new Query(Criteria.where(WHOFIC_ENTITY_IRI) + .is(entityIri) + .and(PROJECT_ID).is(projectId.id()) + .and("postCoordinationCustomScalesRevisions") + .elemMatch( + Criteria.where("changeRequestId").is(changeRequestId.id()) + .and("commitStatus").is(CommitStatus.UNCOMMITTED.name()) + ) + ); + + Update update = new Update().set("postCoordinationCustomScalesRevisions.$.commitStatus", CommitStatus.COMMITTED.name()); + + readWriteLock.executeReadLock(() -> + Optional.of(mongoTemplate.updateFirst(query, update, EntityCustomScalesValuesHistory.class, CUSTOM_SCALE_REVISIONS)) + ); + } } diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/repositories/PostCoordinationTableConfigRepository.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/repositories/PostCoordinationTableConfigRepository.java index 100c7c6..0f88648 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/repositories/PostCoordinationTableConfigRepository.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/repositories/PostCoordinationTableConfigRepository.java @@ -33,6 +33,7 @@ public List getALlTableConfiguration(){ } + @Cacheable("postCoordConfigByEntity") public TableConfiguration getTableConfigurationByEntityType(String entityType) { Query query = Query.query(Criteria.where(ENTITY_TYPE_KEY).is(entityType)); diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/NewRevisionsEventEmitterService.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/NewRevisionsEventEmitterService.java index ab2363f..48fa1b4 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/NewRevisionsEventEmitterService.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/NewRevisionsEventEmitterService.java @@ -1,16 +1,17 @@ package edu.stanford.protege.webprotege.postcoordinationservice.services; +import edu.stanford.protege.webprotege.common.ChangeRequestId; import edu.stanford.protege.webprotege.common.ProjectId; import edu.stanford.protege.webprotege.postcoordinationservice.model.*; import java.util.List; public interface NewRevisionsEventEmitterService { - void emitNewRevisionsEventForScaleHistory(ProjectId projectId, List entityCustomScaleHistories); + void emitNewRevisionsEventForScaleHistory(ProjectId projectId, List entityCustomScaleHistories, ChangeRequestId changeRequestId); - void emitNewRevisionsEventForSpecHistory(ProjectId projectId, List entitySpecHistories); + void emitNewRevisionsEventForSpecHistory(ProjectId projectId, List entitySpecHistories, ChangeRequestId changeRequestId); - void emitNewRevisionsEvent(ProjectId projectId, String whoficEntityIri, PostCoordinationCustomScalesRevision entityCustomScaleRevision); + void emitNewRevisionsEvent(ProjectId projectId, String whoficEntityIri, PostCoordinationCustomScalesRevision entityCustomScaleRevision, ChangeRequestId changeRequestId); - void emitNewRevisionsEvent(ProjectId projectId, String whoficEntityIri, PostCoordinationSpecificationRevision entitySpecRevision); + void emitNewRevisionsEvent(ProjectId projectId, String whoficEntityIri, PostCoordinationSpecificationRevision entitySpecRevision, ChangeRequestId changeRequestId); } diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/NewRevisionsEventEmitterServiceImpl.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/NewRevisionsEventEmitterServiceImpl.java index 13a61ac..c848412 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/NewRevisionsEventEmitterServiceImpl.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/NewRevisionsEventEmitterServiceImpl.java @@ -21,30 +21,30 @@ public NewRevisionsEventEmitterServiceImpl(EventDispatcher eventDispatcher, } @Override - public void emitNewRevisionsEventForScaleHistory(ProjectId projectId, List entityCustomScaleHistories) { + public void emitNewRevisionsEventForScaleHistory(ProjectId projectId, List entityCustomScaleHistories, ChangeRequestId changeRequestId) { Set changeList = projectChangesManager.getProjectChangesForCustomScaleHistories(projectId, entityCustomScaleHistories); - NewRevisionsEvent revisionsEvent = NewRevisionsEvent.create(EventId.generate(), projectId, changeList); + NewRevisionsEvent revisionsEvent = NewRevisionsEvent.create(EventId.generate(), projectId, changeList, changeRequestId); eventDispatcher.dispatchEvent(revisionsEvent); } @Override - public void emitNewRevisionsEventForSpecHistory(ProjectId projectId, List entitySpecHistories) { + public void emitNewRevisionsEventForSpecHistory(ProjectId projectId, List entitySpecHistories, ChangeRequestId changeRequestId) { Set changeList = projectChangesManager.getProjectChangesForSpecHistories(projectId, entitySpecHistories); - NewRevisionsEvent revisionsEvent = NewRevisionsEvent.create(EventId.generate(), projectId, changeList); + NewRevisionsEvent revisionsEvent = NewRevisionsEvent.create(EventId.generate(), projectId, changeList, changeRequestId); eventDispatcher.dispatchEvent(revisionsEvent); } @Override - public void emitNewRevisionsEvent(ProjectId projectId, String whoficEntityIri, PostCoordinationCustomScalesRevision entityCustomScaleRevision) { + public void emitNewRevisionsEvent(ProjectId projectId, String whoficEntityIri, PostCoordinationCustomScalesRevision entityCustomScaleRevision, ChangeRequestId changeRequestId) { ProjectChangeForEntity projectChange = projectChangesManager.getProjectChangesForCustomScaleRevision(projectId, whoficEntityIri, entityCustomScaleRevision); - NewRevisionsEvent revisionsEvent = NewRevisionsEvent.create(EventId.generate(), projectId, Set.of(projectChange)); + NewRevisionsEvent revisionsEvent = NewRevisionsEvent.create(EventId.generate(), projectId, Set.of(projectChange), changeRequestId); eventDispatcher.dispatchEvent(revisionsEvent); } @Override - public void emitNewRevisionsEvent(ProjectId projectId, String whoficEntityIri, PostCoordinationSpecificationRevision entitySpecRevision) { + public void emitNewRevisionsEvent(ProjectId projectId, String whoficEntityIri, PostCoordinationSpecificationRevision entitySpecRevision, ChangeRequestId changeRequestId) { ProjectChangeForEntity projectChange = projectChangesManager.getProjectChangesForSpecRevision(projectId, whoficEntityIri, entitySpecRevision); - NewRevisionsEvent revisionsEvent = NewRevisionsEvent.create(EventId.generate(), projectId, Set.of(projectChange)); + NewRevisionsEvent revisionsEvent = NewRevisionsEvent.create(EventId.generate(), projectId, Set.of(projectChange), changeRequestId); eventDispatcher.dispatchEvent(revisionsEvent); } } diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/PostCoordinationEventProcessor.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/PostCoordinationEventProcessor.java index bb8e65b..72e436b 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/PostCoordinationEventProcessor.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/PostCoordinationEventProcessor.java @@ -22,8 +22,10 @@ private PostCoordinationSpecification findSpecificationWithLinearizationView(Str public WhoficCustomScalesValues processCustomScaleHistory(EntityCustomScalesValuesHistory entityCustomScalesValuesHistory) { WhoficCustomScalesValues response = new WhoficCustomScalesValues(entityCustomScalesValuesHistory.getWhoficEntityIri(), new ArrayList<>()); for (PostCoordinationCustomScalesRevision revision : entityCustomScalesValuesHistory.getPostCoordinationCustomScalesRevisions()) { - for (PostCoordinationCustomScalesValueEvent event : revision.postCoordinationEvents()) { - event.applyEvent(response); + if(revision.postCoordinationEvents() != null) { + for (PostCoordinationCustomScalesValueEvent event : revision.postCoordinationEvents()) { + event.applyEvent(response); + } } } List nonEmptyCustomizations = response.scaleCustomizations().stream() diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/PostCoordinationService.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/PostCoordinationService.java index bd7bf00..9ae75b4 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/PostCoordinationService.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/PostCoordinationService.java @@ -12,6 +12,7 @@ import org.bson.Document; import org.springframework.stereotype.Service; +import java.time.Instant; import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -77,7 +78,7 @@ private Consumer> createBatchProcessorForSavingPa Set histories = new HashSet<>(); for (WhoficCustomScalesValues specification : page) { Set events = SpecificationToEventsMapper.convertToFirstImportEvents(specification); - PostCoordinationCustomScalesRevision revision = new PostCoordinationCustomScalesRevision(userId, new Date().getTime(), events); + PostCoordinationCustomScalesRevision revision = PostCoordinationCustomScalesRevision.create(userId, events); EntityCustomScalesValuesHistory history = new EntityCustomScalesValuesHistory(specification.whoficEntityIri(), projectId.id(), List.of(revision)); histories.add(history); } @@ -87,7 +88,7 @@ private Consumer> createBatchProcessorForSavingPa repository.bulkWriteDocuments(documents, POSTCOORDINATION_CUSTOM_SCALES_COLLECTION); - newRevisionsEventEmitter.emitNewRevisionsEventForScaleHistory(projectId, new ArrayList<>(histories)); + newRevisionsEventEmitter.emitNewRevisionsEventForScaleHistory(projectId, new ArrayList<>(histories), null); } }; } @@ -118,14 +119,14 @@ private Consumer> createBatchPro new PostCoordinationViewEvent(spec.getLinearizationView(), SpecificationToEventsMapper.convertFromSpecification(spec)) ) .collect(Collectors.toSet()); - PostCoordinationSpecificationRevision revision = new PostCoordinationSpecificationRevision(userId, new Date().getTime(), events); + PostCoordinationSpecificationRevision revision = PostCoordinationSpecificationRevision.create(userId, events); EntityPostCoordinationHistory history = new EntityPostCoordinationHistory(specification.whoficEntityIri(), projectId.id(), List.of(revision)); histories.add(history); } saveMultipleEntityPostCoordinationHistories(histories); - newRevisionsEventEmitter.emitNewRevisionsEventForSpecHistory(projectId, histories.stream().toList()); + newRevisionsEventEmitter.emitNewRevisionsEventForSpecHistory(projectId, histories.stream().toList(), null); } }; } @@ -167,6 +168,10 @@ PostCoordinationSpecification enrichWithMissingAxis(String entityType, PostCoord } public void addSpecificationRevision(WhoficEntityPostCoordinationSpecification newSpecification, UserId userId, ProjectId projectId) { + addSpecificationRevision(newSpecification, userId, projectId, null); + } + + public void addSpecificationRevision(WhoficEntityPostCoordinationSpecification newSpecification, UserId userId, ProjectId projectId, ChangeRequestId changeRequestId) { readWriteLock.executeWriteLock(() -> { var existingHistoryOptional = this.repository.getExistingHistoryOrderedByRevision(newSpecification.whoficEntityIri(), projectId); @@ -178,17 +183,17 @@ public void addSpecificationRevision(WhoficEntityPostCoordinationSpecification n if (!specEvents.isEmpty()) { - var newRevision = new PostCoordinationSpecificationRevision(userId, new Date().getTime(), specEvents); + var newRevision = PostCoordinationSpecificationRevision.create(userId, specEvents, changeRequestId); repository.addSpecificationRevision(newSpecification.whoficEntityIri(), projectId, newRevision); - newRevisionsEventEmitter.emitNewRevisionsEvent(projectId, newSpecification.whoficEntityIri(), newRevision); + newRevisionsEventEmitter.emitNewRevisionsEvent(projectId, newSpecification.whoficEntityIri(), newRevision, changeRequestId); } }, () -> { - EntityPostCoordinationHistory history = createNewSpecificationHistory(newSpecification, projectId, userId); + EntityPostCoordinationHistory history = createNewSpecificationHistory(newSpecification, projectId, userId, changeRequestId); var savedHistory = repository.saveNewSpecificationHistory(history); savedHistory.getPostCoordinationRevisions() .stream() .findFirst() - .ifPresent(revision -> newRevisionsEventEmitter.emitNewRevisionsEvent(projectId, savedHistory.getWhoficEntityIri(), revision)); + .ifPresent(revision -> newRevisionsEventEmitter.emitNewRevisionsEvent(projectId, savedHistory.getWhoficEntityIri(), revision, changeRequestId)); } ); } @@ -196,7 +201,14 @@ public void addSpecificationRevision(WhoficEntityPostCoordinationSpecification n } public void addCustomScaleRevision(WhoficCustomScalesValues newScales, - ProjectId projectId, UserId userId) { + ProjectId projectId, + UserId userId) { + addCustomScaleRevision(newScales, projectId, userId, null); + } + public void addCustomScaleRevision(WhoficCustomScalesValues newScales, + ProjectId projectId, + UserId userId, + ChangeRequestId changeRequestId) { readWriteLock.executeWriteLock(() -> { var existingScaleHistoryOptional = this.repository.getExistingCustomScaleHistoryOrderedByRevision(newScales.whoficEntityIri(), projectId); existingScaleHistoryOptional.ifPresentOrElse(history -> { @@ -207,17 +219,17 @@ public void addCustomScaleRevision(WhoficCustomScalesValues newScales, if (!events.isEmpty()) { - var newRevision = new PostCoordinationCustomScalesRevision(userId, new Date().getTime(), events); + var newRevision = PostCoordinationCustomScalesRevision.create(userId, events, changeRequestId); repository.addCustomScalesRevision(newScales.whoficEntityIri(), projectId, newRevision); - newRevisionsEventEmitter.emitNewRevisionsEvent(projectId, newScales.whoficEntityIri(), newRevision); + newRevisionsEventEmitter.emitNewRevisionsEvent(projectId, newScales.whoficEntityIri(), newRevision, changeRequestId); } }, () -> { - var newHistory = createNewEntityCustomScalesHistory(newScales, projectId, userId); + var newHistory = createNewEntityCustomScalesHistory(newScales, projectId, userId, changeRequestId); var savedHistory = repository.saveNewCustomScalesHistory(newHistory); savedHistory.getPostCoordinationCustomScalesRevisions() .stream() .findFirst() - .ifPresent(revision -> newRevisionsEventEmitter.emitNewRevisionsEvent(projectId, newScales.whoficEntityIri(), revision)); + .ifPresent(revision -> newRevisionsEventEmitter.emitNewRevisionsEvent(projectId, newScales.whoficEntityIri(), revision, changeRequestId)); } ); } @@ -226,34 +238,54 @@ public void addCustomScaleRevision(WhoficCustomScalesValues newScales, private EntityCustomScalesValuesHistory createNewEntityCustomScalesHistory(WhoficCustomScalesValues newScales, ProjectId projectId, - UserId userId) { + UserId userId, + ChangeRequestId changeRequestId) { WhoficCustomScalesValues oldSpec = WhoficCustomScalesValues.create(newScales.whoficEntityIri(), Collections.emptyList()); Set events = SpecificationToEventsMapper.createScaleEventsFromDiff(oldSpec, newScales); - var revision = PostCoordinationCustomScalesRevision.create(userId, events); + var revision = PostCoordinationCustomScalesRevision.create(userId, events, changeRequestId); return EntityCustomScalesValuesHistory.create(newScales.whoficEntityIri(), projectId.value(), List.of(revision)); } private EntityPostCoordinationHistory createNewSpecificationHistory(WhoficEntityPostCoordinationSpecification newSpec, ProjectId projectId, - UserId userId) { + UserId userId, + ChangeRequestId changeRequestId) { WhoficEntityPostCoordinationSpecification oldSpec = WhoficEntityPostCoordinationSpecification.create(newSpec.whoficEntityIri(), newSpec.entityType(), Collections.emptyList()); Set specEvents = SpecificationToEventsMapper.createEventsFromDiff(oldSpec, newSpec); - var newRevision = new PostCoordinationSpecificationRevision(userId, new Date().getTime(), specEvents); + var newRevision = PostCoordinationSpecificationRevision.create(userId, specEvents, changeRequestId); return EntityPostCoordinationHistory.create(newSpec.whoficEntityIri(), projectId.id(), List.of(newRevision)); } - public WhoficCustomScalesValues fetchCustomScalesHistory(String entityIri, ProjectId projectId) { + public GetEntityCustomScaleValueResponse fetchCustomScalesHistory(String entityIri, ProjectId projectId) { return this.repository.getExistingCustomScaleHistoryOrderedByRevision(entityIri, projectId) - .map(eventProcessor::processCustomScaleHistory) - .orElseGet(() -> new WhoficCustomScalesValues(entityIri, Collections.emptyList())); + .map(history -> { + Date lastRevisionDate = null; + if (!history.getPostCoordinationCustomScalesRevisions().isEmpty()) { + long lastRevisionTimestamp = history.getPostCoordinationCustomScalesRevisions().get(history.getPostCoordinationCustomScalesRevisions().size() - 1).timestamp(); + lastRevisionDate = Date.from(Instant.ofEpochMilli(lastRevisionTimestamp)); + } + WhoficCustomScalesValues scales = eventProcessor.processCustomScaleHistory(history); + return new GetEntityCustomScaleValueResponse(lastRevisionDate, scales); + }) + .orElseGet(() -> new GetEntityCustomScaleValueResponse(null, new WhoficCustomScalesValues(entityIri, Collections.emptyList()))); } - public WhoficEntityPostCoordinationSpecification fetchHistory(String entityIri, ProjectId projectId) { + public GetEntityPostCoordinationResponse fetchHistory(String entityIri, ProjectId projectId) { return this.repository.getExistingHistoryOrderedByRevision(entityIri, projectId) - .map(eventProcessor::processHistory) - .orElseGet(() -> new WhoficEntityPostCoordinationSpecification(entityIri, null, Collections.emptyList())); + .map(history -> { + Date lastChangeDate = null; + if (!history.getPostCoordinationRevisions().isEmpty()) { + long lastTimestamp = history.getPostCoordinationRevisions().get(history.getPostCoordinationRevisions().size() - 1).timestamp(); + lastChangeDate = Date.from(Instant.ofEpochMilli(lastTimestamp)); + } + + return new GetEntityPostCoordinationResponse(entityIri, lastChangeDate, eventProcessor.processHistory(history)); + }) + .orElseGet(() -> new GetEntityPostCoordinationResponse(entityIri, + null, + new WhoficEntityPostCoordinationSpecification(entityIri, null, Collections.emptyList()))); } } diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/RevisionCommitService.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/RevisionCommitService.java new file mode 100644 index 0000000..f30f689 --- /dev/null +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/services/RevisionCommitService.java @@ -0,0 +1,38 @@ +package edu.stanford.protege.webprotege.postcoordinationservice.services; + +import edu.stanford.protege.webprotege.common.ChangeRequestId; +import edu.stanford.protege.webprotege.common.ProjectId; +import edu.stanford.protege.webprotege.postcoordinationservice.model.*; +import edu.stanford.protege.webprotege.postcoordinationservice.repositories.PostCoordinationRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + + +@Service +public class RevisionCommitService { + + private final static Logger LOGGER = LoggerFactory.getLogger(RevisionCommitService.class); + private final PostCoordinationRepository postCoordinationRepository; + + public RevisionCommitService(PostCoordinationRepository postCoordinationRepository) { + this.postCoordinationRepository = postCoordinationRepository; + } + + @Transactional + public void rollbackRevision(ChangeRequestId changeRequestId, ProjectId projectId, String entityIri) { + postCoordinationRepository.deletePostCoordinationCustomScalesRevision(changeRequestId, projectId, entityIri); + postCoordinationRepository.deletePostCoordinationSpecificationRevision(changeRequestId, projectId, entityIri); + } + + + public void commitRevision(ChangeRequestId changeRequestId, ProjectId projectId, String entityIri) { + postCoordinationRepository.commitPostCoordinationSpecificationRevision(changeRequestId, projectId, entityIri); + postCoordinationRepository.commitPostCoordinationCustomScalesRevision(changeRequestId, projectId, entityIri); + } +} diff --git a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/uiHistoryConcern/changes/NewRevisionsEvent.java b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/uiHistoryConcern/changes/NewRevisionsEvent.java index 4f43768..d0305d6 100644 --- a/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/uiHistoryConcern/changes/NewRevisionsEvent.java +++ b/src/main/java/edu/stanford/protege/webprotege/postcoordinationservice/uiHistoryConcern/changes/NewRevisionsEvent.java @@ -11,14 +11,16 @@ public record NewRevisionsEvent( EventId eventId, ProjectId projectId, - Set changes + Set changes, + ChangeRequestId changeRequestId ) implements ProjectEvent { public final static String CHANNEL = "webprotege.events.projects.uiHistory.NewRevisionsEvent"; public static NewRevisionsEvent create(EventId eventId, ProjectId projectId, - Set changes) { - return new NewRevisionsEvent(eventId, projectId, changes); + Set changes, + ChangeRequestId changeRequestId) { + return new NewRevisionsEvent(eventId, projectId, changes,changeRequestId); } @NotNull diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 73b6a8b..8e359a5 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -25,6 +25,8 @@ webprotege: requestqueue: webprotege-postcoordination-service-queue responsequeue: webprotege-postcoordination-service-response-queue timeout: 60000 + eventsqueue: webprotege-postcoordination-events-queue + event-subscribe: true readWriteLock: timeoutInMillies: 1000 maxRetries: 5 diff --git a/src/test/java/edu/stanford/protege/webprotege/postcoordinationservice/WebprotegePostCoordinationServiceApplicationTest.java b/src/test/java/edu/stanford/protege/webprotege/postcoordinationservice/WebprotegePostCoordinationServiceApplicationTest.java index 24ac9f0..e69de29 100644 --- a/src/test/java/edu/stanford/protege/webprotege/postcoordinationservice/WebprotegePostCoordinationServiceApplicationTest.java +++ b/src/test/java/edu/stanford/protege/webprotege/postcoordinationservice/WebprotegePostCoordinationServiceApplicationTest.java @@ -1,18 +0,0 @@ -package edu.stanford.protege.webprotege.postcoordinationservice; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@SpringBootTest -@ExtendWith({SpringExtension.class, IntegrationTest.class}) -@ActiveProfiles("test") -public class WebprotegePostCoordinationServiceApplicationTest { - - @Test - public void contextLoads() { - } - -} diff --git a/src/test/java/edu/stanford/protege/webprotege/postcoordinationservice/services/PostCoordinationEventProcessorTest.java b/src/test/java/edu/stanford/protege/webprotege/postcoordinationservice/services/PostCoordinationEventProcessorTest.java index 26d8d88..8907a50 100644 --- a/src/test/java/edu/stanford/protege/webprotege/postcoordinationservice/services/PostCoordinationEventProcessorTest.java +++ b/src/test/java/edu/stanford/protege/webprotege/postcoordinationservice/services/PostCoordinationEventProcessorTest.java @@ -37,8 +37,8 @@ void GIVEN_customScalesHistoryWithEvents_WHEN_processCustomScaleHistory_THEN_cor "entity1", ProjectId.generate().toString(), List.of( - new PostCoordinationCustomScalesRevision(UserId.getGuest(), 1L, new HashSet<>(events1)), - new PostCoordinationCustomScalesRevision(UserId.getGuest(), 2L, new HashSet<>(events2)) + new PostCoordinationCustomScalesRevision(UserId.getGuest(), 1L, new HashSet<>(events1), CommitStatus.COMMITTED, null), + new PostCoordinationCustomScalesRevision(UserId.getGuest(), 2L, new HashSet<>(events2), CommitStatus.COMMITTED, null) ) ); @@ -71,8 +71,8 @@ void GIVEN_specificationHistoryWithEvents_WHEN_processHistory_THEN_correctSpecif "entity1", "project1", List.of( - new PostCoordinationSpecificationRevision(UserId.getGuest(), 1L, Set.of(new PostCoordinationViewEvent("view1", events1))), - new PostCoordinationSpecificationRevision(UserId.getGuest(), 2L, Set.of(new PostCoordinationViewEvent("view1", events2))) + new PostCoordinationSpecificationRevision(UserId.getGuest(), 1L, Set.of(new PostCoordinationViewEvent("view1", events1)), CommitStatus.COMMITTED, null), + new PostCoordinationSpecificationRevision(UserId.getGuest(), 2L, Set.of(new PostCoordinationViewEvent("view1", events2)), CommitStatus.COMMITTED, null) ) );