Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[3019] Restore support for the project events subscription
Bug: #3019 Signed-off-by: Stéphane Bégaudeau <stephane.begaudeau@obeo.fr>
- Loading branch information
1 parent
5940967
commit fbe2108
Showing
14 changed files
with
451 additions
and
1 deletion.
There are no files selected for viewing
59 changes: 59 additions & 0 deletions
59
...lipse/sirius/web/application/project/controllers/SubscriptionProjectEventDataFetcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/******************************************************************************* | ||
* 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.controllers; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import java.util.Objects; | ||
import java.util.function.Supplier; | ||
|
||
import org.eclipse.sirius.components.annotations.spring.graphql.SubscriptionDataFetcher; | ||
import org.eclipse.sirius.components.core.api.IPayload; | ||
import org.eclipse.sirius.components.graphql.api.IDataFetcherWithFieldCoordinates; | ||
import org.eclipse.sirius.components.graphql.api.IExceptionWrapper; | ||
import org.eclipse.sirius.web.application.project.dto.ProjectEventInput; | ||
import org.eclipse.sirius.web.application.project.services.api.IProjectSubscriptions; | ||
import org.reactivestreams.Publisher; | ||
|
||
import graphql.schema.DataFetchingEnvironment; | ||
import reactor.core.publisher.Flux; | ||
|
||
/** | ||
* Data fetcher for the field Subscription#projectEvent. | ||
* | ||
* @author sbegaudeau | ||
*/ | ||
@SubscriptionDataFetcher(type = "Subscription", field = "projectEvent") | ||
public class SubscriptionProjectEventDataFetcher implements IDataFetcherWithFieldCoordinates<Publisher<IPayload>> { | ||
|
||
private final ObjectMapper objectMapper; | ||
|
||
private final IExceptionWrapper exceptionWrapper; | ||
|
||
private final IProjectSubscriptions projectSubscriptions; | ||
|
||
public SubscriptionProjectEventDataFetcher(ObjectMapper objectMapper, IExceptionWrapper exceptionWrapper, IProjectSubscriptions projectSubscriptions) { | ||
this.objectMapper = Objects.requireNonNull(objectMapper); | ||
this.exceptionWrapper = Objects.requireNonNull(exceptionWrapper); | ||
this.projectSubscriptions = Objects.requireNonNull(projectSubscriptions); | ||
} | ||
|
||
@Override | ||
public Publisher<IPayload> get(DataFetchingEnvironment environment) throws Exception { | ||
Object argument = environment.getArgument("input"); | ||
var input = this.objectMapper.convertValue(argument, ProjectEventInput.class); | ||
|
||
Supplier<Flux<IPayload>> supplier = () -> this.projectSubscriptions.findProjectSubscriptionById(input.projectId()).orElse(Flux.empty()); | ||
return this.exceptionWrapper.wrapFlux(supplier, input); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
...ation/src/main/java/org/eclipse/sirius/web/application/project/dto/ProjectEventInput.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023, 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.dto; | ||
|
||
import java.util.UUID; | ||
|
||
import org.eclipse.sirius.components.core.api.IInput; | ||
|
||
import jakarta.validation.constraints.NotNull; | ||
|
||
/** | ||
* The input of the project event subscription. | ||
* | ||
* @author arichard | ||
*/ | ||
public record ProjectEventInput(@NotNull UUID id, @NotNull UUID projectId) implements IInput { | ||
} |
27 changes: 27 additions & 0 deletions
27
.../main/java/org/eclipse/sirius/web/application/project/dto/ProjectRenamedEventPayload.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023, 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.dto; | ||
|
||
import java.util.UUID; | ||
|
||
import org.eclipse.sirius.components.core.api.IPayload; | ||
|
||
import jakarta.validation.constraints.NotNull; | ||
|
||
/** | ||
* Payload used to indicate that project's name has been updated. | ||
* | ||
* @author arichard | ||
*/ | ||
public record ProjectRenamedEventPayload(@NotNull UUID id, @NotNull UUID projectId, @NotNull String newName) implements IPayload { | ||
} |
49 changes: 49 additions & 0 deletions
49
...ava/org/eclipse/sirius/web/application/project/listeners/ProjectSubscriptionListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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.project.listeners; | ||
|
||
import java.util.Objects; | ||
import java.util.UUID; | ||
|
||
import org.eclipse.sirius.web.application.project.dto.ProjectRenamedEventPayload; | ||
import org.eclipse.sirius.web.application.project.services.api.IProjectSubscriptions; | ||
import org.eclipse.sirius.web.domain.boundedcontexts.project.events.ProjectDeletedEvent; | ||
import org.eclipse.sirius.web.domain.boundedcontexts.project.events.ProjectNameUpdatedEvent; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.event.TransactionalEventListener; | ||
|
||
/** | ||
* Used to listen to project events in order to provide events for the project subscriptions. | ||
* | ||
* @author sbegaudeau | ||
*/ | ||
@Service | ||
public class ProjectSubscriptionListener { | ||
|
||
private final IProjectSubscriptions projectSubscriptions; | ||
|
||
public ProjectSubscriptionListener(IProjectSubscriptions projectSubscriptions) { | ||
this.projectSubscriptions = Objects.requireNonNull(projectSubscriptions); | ||
} | ||
|
||
@TransactionalEventListener | ||
public void onProjectNameUpdatedEvent(ProjectNameUpdatedEvent event) { | ||
var payload = new ProjectRenamedEventPayload(UUID.randomUUID(), event.project().getId(), event.project().getName()); | ||
this.projectSubscriptions.emit(event.project().getId(), payload); | ||
} | ||
|
||
@TransactionalEventListener | ||
public void onProjectDeletedEvent(ProjectDeletedEvent event) { | ||
this.projectSubscriptions.dispose(event.project().getId()); | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
...c/main/java/org/eclipse/sirius/web/application/project/services/ProjectSubscriptions.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/******************************************************************************* | ||
* 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.services; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.Optional; | ||
import java.util.UUID; | ||
|
||
import org.eclipse.sirius.components.core.api.IPayload; | ||
import org.eclipse.sirius.web.application.project.services.api.IProjectSubscriptions; | ||
import org.eclipse.sirius.web.domain.boundedcontexts.project.services.api.IProjectSearchService; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import reactor.core.publisher.Flux; | ||
import reactor.core.publisher.Sinks; | ||
|
||
/** | ||
* Used to publish and subscribe to project events. | ||
* | ||
* @author sbegaudeau | ||
*/ | ||
@Service | ||
public class ProjectSubscriptions implements IProjectSubscriptions { | ||
|
||
private final IProjectSearchService projectSearchService; | ||
|
||
private final Map<UUID, Sinks.Many<IPayload>> projectIdsToSink = new HashMap<>(); | ||
|
||
public ProjectSubscriptions(IProjectSearchService projectSearchService) { | ||
this.projectSearchService = Objects.requireNonNull(projectSearchService); | ||
} | ||
|
||
@Override | ||
@Transactional(readOnly = true) | ||
public Optional<Flux<IPayload>> findProjectSubscriptionById(UUID projectId) { | ||
if (this.projectSearchService.existsById(projectId)) { | ||
var many = this.projectIdsToSink.computeIfAbsent(projectId, id -> Sinks.many().multicast().directBestEffort()); | ||
return Optional.of(many.asFlux()); | ||
} | ||
return Optional.empty(); | ||
} | ||
|
||
@Override | ||
public void emit(UUID projectId, IPayload payload) { | ||
Optional.ofNullable(this.projectIdsToSink.get(projectId)).ifPresent(many -> many.tryEmitNext(payload)); | ||
} | ||
|
||
@Override | ||
public void dispose(UUID projectId) { | ||
Optional.ofNullable(this.projectIdsToSink.get(projectId)).ifPresent(Sinks.Many::tryEmitComplete); | ||
this.projectIdsToSink.remove(projectId); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
...n/java/org/eclipse/sirius/web/application/project/services/api/IProjectSubscriptions.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024, 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.services.api; | ||
|
||
import java.util.Optional; | ||
import java.util.UUID; | ||
|
||
import org.eclipse.sirius.components.core.api.IPayload; | ||
|
||
import reactor.core.publisher.Flux; | ||
|
||
/** | ||
* Used to publish or subscribe to project events. | ||
* | ||
* @author sbegaudeau | ||
*/ | ||
public interface IProjectSubscriptions { | ||
Optional<Flux<IPayload>> findProjectSubscriptionById(UUID projectId); | ||
|
||
void emit(UUID projectId, IPayload payload); | ||
|
||
void dispose(UUID projectId); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
...end/sirius-web-starter/src/main/java/org/eclipse/sirius/web/starter/ExceptionWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2022, 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.starter; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.function.Supplier; | ||
|
||
import org.eclipse.sirius.components.core.api.IInput; | ||
import org.eclipse.sirius.components.core.api.IPayload; | ||
import org.eclipse.sirius.components.graphql.api.IExceptionWrapper; | ||
|
||
import graphql.relay.Connection; | ||
import reactor.core.publisher.Flux; | ||
import reactor.core.publisher.Mono; | ||
|
||
/** | ||
* Used to encapsulate calls to methods which can throw exceptions. | ||
* | ||
* @author sbegaudeau | ||
*/ | ||
public class ExceptionWrapper implements IExceptionWrapper { | ||
|
||
@Override | ||
public Flux<IPayload> wrapFlux(Supplier<Flux<IPayload>> supplier, IInput input) { | ||
return supplier.get(); | ||
} | ||
|
||
@Override | ||
public IPayload wrap(Supplier<IPayload> supplier, IInput input) { | ||
return supplier.get(); | ||
} | ||
|
||
@Override | ||
public <T> List<T> wrapList(Supplier<List<T>> supplier) { | ||
return supplier.get(); | ||
} | ||
|
||
@Override | ||
public <T> Optional<T> wrapOptional(Supplier<Optional<T>> supplier) { | ||
return supplier.get(); | ||
} | ||
|
||
@Override | ||
public <T> Connection<T> wrapConnection(Supplier<Connection<T>> supplier) { | ||
return supplier.get(); | ||
} | ||
|
||
@Override | ||
public Mono<IPayload> wrapMono(Supplier<Mono<IPayload>> supplier, IInput input) { | ||
return supplier.get(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.