Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: rely on rabbitmq dlq for computation errors handling #119

Merged
merged 3 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@
<dependencyManagement>
<dependencies>
<!-- overrides of imports -->

<dependency><!-- To remove when integrate in next release of gridsuite-dependencies or powsybl-ws-dependencies -->
<groupId>com.powsybl</groupId>
<artifactId>powsybl-ws-commons</artifactId>
<version>1.19.0</version>
</dependency>
<!-- imports -->
<dependency>
<groupId>org.gridsuite</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,4 @@ public interface NotificationService {
void emitResultDynamicSimulationMessage(Message<String> message);

void emitCancelDynamicSimulationMessage(Message<String> message);

void emitFailDynamicSimulationMessage(Message<String> message);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,4 @@ public void emitResultDynamicSimulationMessage(Message<String> message) {
public void emitCancelDynamicSimulationMessage(Message<String> message) {
sendMessage(message, "publishCancel-out-0");
}

@Override
public void emitFailDynamicSimulationMessage(Message<String> message) {
sendMessage(message, "publishFailed-out-0");
}
}
16 changes: 13 additions & 3 deletions src/main/resources/config/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ spring:
group: dsGroup
consumer:
concurrency: 2
max-attempts: 1
publishRun-out-0:
destination: ${powsybl-ws.rabbitmq.destination.prefix:}ds.run
publishResult-out-0:
Expand All @@ -22,11 +23,20 @@ spring:
destination: ${powsybl-ws.rabbitmq.destination.prefix:}ds.cancel
publishStopped-out-0:
destination: ${powsybl-ws.rabbitmq.destination.prefix:}ds.stopped
publishFailed-out-0:
destination: ${powsybl-ws.rabbitmq.destination.prefix:}ds.failed
publishCancelFailed-out-0:
destination: ${powsybl-ws.rabbitmq.destination.prefix:}ds.cancelfailed
output-bindings: publishRun-out-0;publishResult-out-0;publishCancel-out-0;publishStopped-out-0;publishFailed-out-0;publishCancelFailed-out-0
output-bindings: publishRun-out-0;publishResult-out-0;publishCancel-out-0;publishStopped-out-0;publishCancelFailed-out-0
rabbit:
bindings:
consumeRun-in-0:
consumer:
auto-bind-dlq: true
dead-letter-exchange: ${powsybl-ws.rabbitmq.destination.prefix:}ds.run.dlx
dead-letter-queue-name: ${powsybl-ws.rabbitmq.destination.prefix:}ds.run.dlx.dlq
dead-letter-exchange-type: topic
quorum:
enabled: true
delivery-limit: 2

powsybl:
services:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ public abstract class AbstractDynamicSimulationControllerTest extends AbstractDy
protected final Logger logger = LoggerFactory.getLogger(this.getClass());

protected final String dsResultDestination = "ds.result.destination";
protected final String dsFailedDestination = "ds.failed.destination";
protected final String dsStoppedDestination = "ds.stopped.destination";
protected final String dsCancelFailedDestination = "ds.cancelfailed.destination";

Expand Down Expand Up @@ -85,7 +84,7 @@ public void tearDown() throws Exception {
super.tearDown();

OutputDestination output = getOutputDestination();
List<String> destinations = List.of(dsFailedDestination, dsResultDestination, dsStoppedDestination, dsCancelFailedDestination);
List<String> destinations = List.of(dsResultDestination, dsStoppedDestination, dsCancelFailedDestination);

try {
TestUtils.assertQueuesEmptyThenClear(destinations, output);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
package org.gridsuite.ds.server.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.datasource.ReadOnlyDataSource;
import com.powsybl.commons.datasource.ResourceDataSource;
import com.powsybl.commons.datasource.ResourceSet;
Expand All @@ -33,7 +32,6 @@
import org.junit.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.cloud.stream.binder.test.InputDestination;
Expand Down Expand Up @@ -152,32 +150,6 @@ public void tearDown() throws Exception {
.andExpect(status().isOk());
}

@Test
TheMaskedTurtle marked this conversation as resolved.
Show resolved Hide resolved
public void testGivenNotExistingNetworkUuid() throws Exception {

// mock NetworkStoreService throws exception for a none-existing network uuid
given(networkStoreClient.getNetwork(UUID.fromString(NETWORK_UUID_NOT_FOUND_STRING), PreloadingStrategy.COLLECTION)).willThrow(new PowsyblException());

// prepare parameters
DynamicSimulationParametersInfos parameters = ParameterUtils.getDefaultDynamicSimulationParameters();

// network not found
MvcResult result = mockMvc.perform(
post("/v1/networks/{networkUuid}/run?" + "&mappingName=" + MAPPING_NAME, NETWORK_UUID_NOT_FOUND_STRING)
.contentType(APPLICATION_JSON)
.header(HEADER_USER_ID, "testUserId")
.content(objectMapper.writeValueAsString(parameters)))
.andExpect(status().isOk())
.andReturn();

UUID runUuid = objectMapper.readValue(result.getResponse().getContentAsString(), UUID.class);

Message<byte[]> messageSwitch = output.receive(1000 * 5, dsFailedDestination);
assertThat(messageSwitch.getHeaders()).containsEntry(HEADER_RESULT_UUID, runUuid.toString());
assertThat(Objects.requireNonNull(messageSwitch.getHeaders().get(HEADER_MESSAGE)).toString())
.contains(getFailedMessage(COMPUTATION_TYPE));
}

@Test
public void testGivenTimeSeriesAndTimeLine() throws Exception {

Expand Down Expand Up @@ -376,37 +348,6 @@ public void testGivenEmptyTimeSeriesAndTimeLine() throws Exception {

}

@Test
public void testGivenRunWithException() throws Exception {
// setup spy bean
doAnswer((InvocationOnMock invocation) -> CompletableFuture.supplyAsync(() -> {
throw new RuntimeException(TEST_EXCEPTION_MESSAGE);
}))
.when(dynamicSimulationWorkerService).getCompletableFuture(any(), any(), any());

// prepare parameters
DynamicSimulationParametersInfos parameters = ParameterUtils.getDefaultDynamicSimulationParameters();

//run the dynamic simulation
MvcResult result = mockMvc.perform(
post("/v1/networks/{networkUuid}/run?" + "&mappingName=" + MAPPING_NAME, NETWORK_UUID_STRING)
.contentType(APPLICATION_JSON)
.header(HEADER_USER_ID, "testUserId")
.content(objectMapper.writeValueAsString(parameters)))
.andExpect(status().isOk())
.andReturn();

UUID runUuid = objectMapper.readValue(result.getResponse().getContentAsString(), UUID.class);

// Message failed must be sent
Message<byte[]> messageSwitch = output.receive(1000, dsFailedDestination);

// check uuid and failed message
assertThat(messageSwitch.getHeaders()).containsEntry(HEADER_RESULT_UUID, runUuid.toString());
assertThat(Objects.requireNonNull(messageSwitch.getHeaders().get(HEADER_MESSAGE)).toString())
.contains(TEST_EXCEPTION_MESSAGE);
}

// --- BEGIN Test cancelling a running computation ---//
private void mockSendRunMessage(Supplier<CompletableFuture<?>> runAsyncMock) {
// In test environment, the test binder calls consumers directly in the caller thread, i.e. the controller thread.
Expand Down
Loading