Skip to content

Commit d874882

Browse files
authored
Bug fix running status remain when error occur (#11)
Signed-off-by: Slimane AMAR <[email protected]>
1 parent 9f66f6a commit d874882

File tree

4 files changed

+84
-13
lines changed

4 files changed

+84
-13
lines changed

src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisStoppedPublisherService.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
@Service
2424
public class SecurityAnalysisStoppedPublisherService {
2525

26+
public static final String CANCEL_MESSAGE = "Security analysis has canceled";
27+
public static final String FAIL_MESSAGE = "Security analysis has failed";
28+
2629
private static final String CATEGORY_BROKER_OUTPUT = SecurityAnalysisStoppedPublisherService.class.getName()
2730
+ ".output-broker-messages";
2831

@@ -33,11 +36,20 @@ public Supplier<Flux<Message<String>>> publishStopped() {
3336
return () -> stoppedMessagePublisher.log(CATEGORY_BROKER_OUTPUT, Level.FINE);
3437
}
3538

36-
public void publish(UUID resultUuid, String receiver) {
39+
public void publishCancel(UUID resultUuid, String receiver) {
40+
publish(resultUuid, receiver, CANCEL_MESSAGE);
41+
}
42+
43+
public void publishFail(UUID resultUuid, String receiver, String causeMessage) {
44+
publish(resultUuid, receiver, FAIL_MESSAGE + " : " + causeMessage);
45+
}
46+
47+
public void publish(UUID resultUuid, String receiver, String stopMessage) {
3748
stoppedMessagePublisher.onNext(MessageBuilder
3849
.withPayload("")
3950
.setHeader("resultUuid", resultUuid.toString())
4051
.setHeader("receiver", receiver)
52+
.setHeader("message", stopMessage)
4153
.build());
4254
}
4355
}

src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
import java.util.function.Consumer;
3939
import java.util.stream.Collectors;
4040

41+
import static org.gridsuite.securityanalysis.server.service.SecurityAnalysisStoppedPublisherService.CANCEL_MESSAGE;
42+
import static org.gridsuite.securityanalysis.server.service.SecurityAnalysisStoppedPublisherService.FAIL_MESSAGE;
43+
4144
/**
4245
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
4346
* @author Franck Lecuyer <franck.lecuyer at rte-france.com>
@@ -168,14 +171,17 @@ public Consumer<Message<String>> consumeRun() {
168171
LOGGER.info("Security analysis complete (resultUuid='{}')", resultContext.getResultUuid());
169172
} else { // result not available : stop computation request
170173
if (cancelComputationRequests.get(resultContext.getResultUuid()) != null) {
171-
stoppedPublisherService.publish(resultContext.getResultUuid(), cancelComputationRequests.get(resultContext.getResultUuid()).getReceiver());
174+
stoppedPublisherService.publishCancel(resultContext.getResultUuid(), cancelComputationRequests.get(resultContext.getResultUuid()).getReceiver());
172175
}
173176
}
174177
})
175-
.doOnError(throwable -> {
178+
.onErrorResume(throwable -> {
176179
if (!(throwable instanceof CancellationException)) {
177-
LOGGER.error(throwable.toString(), throwable);
180+
LOGGER.error(FAIL_MESSAGE, throwable);
181+
stoppedPublisherService.publishFail(resultContext.getResultUuid(), resultContext.getRunContext().getReceiver(), throwable.getMessage());
182+
return resultRepository.delete(resultContext.getResultUuid()).then(Mono.empty());
178183
}
184+
return Mono.empty();
179185
})
180186
.doFinally(s -> {
181187
futures.remove(resultContext.getResultUuid());
@@ -202,8 +208,8 @@ public Consumer<Message<String>> consumeCancel() {
202208

203209
resultRepository.delete(cancelContext.getResultUuid())
204210
.doOnSuccess(unused -> {
205-
stoppedPublisherService.publish(cancelContext.getResultUuid(), cancelContext.getReceiver());
206-
LOGGER.info("Security analysis stopped (resultUuid='{}')", cancelContext.getResultUuid());
211+
stoppedPublisherService.publishCancel(cancelContext.getResultUuid(), cancelContext.getReceiver());
212+
LOGGER.info(CANCEL_MESSAGE + " (resultUuid='{}')", cancelContext.getResultUuid());
207213
})
208214
.doOnError(throwable -> LOGGER.error(throwable.toString(), throwable))
209215
.subscribe();

src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import com.powsybl.network.store.client.PreloadingStrategy;
1313
import org.gridsuite.securityanalysis.server.service.ActionsService;
1414
import org.gridsuite.securityanalysis.server.service.SecurityAnalysisConfigService;
15-
import org.gridsuite.securityanalysis.server.service.SecurityAnalysisService;
1615
import org.gridsuite.securityanalysis.server.service.UuidGeneratorService;
1716
import org.junit.Before;
1817
import org.junit.Test;
@@ -37,7 +36,10 @@
3736

3837
import static com.powsybl.network.store.model.NetworkStoreApi.VERSION;
3938
import static org.gridsuite.securityanalysis.server.SecurityAnalysisFactoryMock.*;
39+
import static org.gridsuite.securityanalysis.server.service.SecurityAnalysisStoppedPublisherService.CANCEL_MESSAGE;
40+
import static org.gridsuite.securityanalysis.server.service.SecurityAnalysisStoppedPublisherService.FAIL_MESSAGE;
4041
import static org.junit.Assert.assertEquals;
42+
import static org.junit.Assert.assertNull;
4143
import static org.mockito.BDDMockito.given;
4244

4345
/**
@@ -59,6 +61,8 @@ public class SecurityAnalysisControllerTest extends AbstractEmbeddedCassandraSet
5961

6062
private static final String EXPECTED_FILTERED_JSON = "{\"version\":\"1.0\",\"preContingencyResult\":{\"computationOk\":true,\"limitViolations\":[{\"subjectId\":\"l3\",\"limitType\":\"CURRENT\",\"acceptableDuration\":1200,\"limit\":10.0,\"limitReduction\":1.0,\"value\":11.0,\"side\":\"ONE\"}],\"actionsTaken\":[]},\"postContingencyResults\":[{\"contingency\":{\"id\":\"l1\",\"elements\":[{\"id\":\"l1\",\"type\":\"BRANCH\"}]},\"limitViolationsResult\":{\"computationOk\":true,\"limitViolations\":[],\"actionsTaken\":[]}},{\"contingency\":{\"id\":\"l2\",\"elements\":[{\"id\":\"l2\",\"type\":\"BRANCH\"}]},\"limitViolationsResult\":{\"computationOk\":true,\"limitViolations\":[],\"actionsTaken\":[]}}]}";
6163

64+
private static final String ERROR_MESSAGE = "Error message test";
65+
6266
@Autowired
6367
private OutputDestination output;
6468

@@ -74,9 +78,6 @@ public class SecurityAnalysisControllerTest extends AbstractEmbeddedCassandraSet
7478
@MockBean
7579
private UuidGeneratorService uuidGeneratorService;
7680

77-
@Autowired
78-
private SecurityAnalysisService securityAnalysisService;
79-
8081
@Autowired
8182
private SecurityAnalysisConfigService configService;
8283

@@ -96,12 +97,18 @@ public void setUp() {
9697
.willReturn(Flux.fromIterable(SecurityAnalysisFactoryMock.CONTINGENCIES));
9798
given(actionsService.getContingencyList(CONTINGENCY_LIST2_NAME, NETWORK_UUID))
9899
.willReturn(Flux.fromIterable(SecurityAnalysisFactoryMock.CONTINGENCIES));
100+
given(actionsService.getContingencyList(CONTINGENCY_LIST_ERROR_NAME, NETWORK_UUID))
101+
.willReturn(Flux.fromIterable(SecurityAnalysisFactoryMock.CONTINGENCIES).thenMany(Flux.error(new RuntimeException(ERROR_MESSAGE))));
99102

100103
// UUID service mocking to always generate the same result UUID
101104
given(uuidGeneratorService.generate()).willReturn(RESULT_UUID);
102105

103106
// mock the powsybl security analysis service
104107
configService.setSecurityAnalysisFactoryClass(SecurityAnalysisFactoryMock.class.getName());
108+
109+
// purge messages
110+
while (output.receive(1000) != null) {
111+
}
105112
}
106113

107114
@Test
@@ -244,14 +251,59 @@ public void stopTest() {
244251
.expectBody(UUID.class)
245252
.isEqualTo(RESULT_UUID);
246253

254+
Message<byte[]> message = output.receive(1000, "sa.run.destination");
255+
assertEquals(NETWORK_UUID.toString(), message.getHeaders().get("networkUuid"));
256+
assertEquals(RESULT_UUID.toString(), message.getHeaders().get("resultUuid"));
257+
assertEquals(CONTINGENCY_LIST_NAME, message.getHeaders().get("contingencyListNames"));
258+
assertEquals("me", message.getHeaders().get("receiver"));
259+
247260
webTestClient.put()
248261
.uri("/" + VERSION + "/results/" + RESULT_UUID + "/stop"
249262
+ "?receiver=me")
250263
.exchange()
251264
.expectStatus().isOk();
252265

253-
Message<byte[]> cancelMessage = output.receive(1000, "sa.cancel.destination");
254-
assertEquals(RESULT_UUID.toString(), cancelMessage.getHeaders().get("resultUuid"));
255-
assertEquals("me", cancelMessage.getHeaders().get("receiver"));
266+
message = output.receive(1000, "sa.cancel.destination");
267+
assertEquals(RESULT_UUID.toString(), message.getHeaders().get("resultUuid"));
268+
assertEquals("me", message.getHeaders().get("receiver"));
269+
270+
message = output.receive(1000, "sa.stopped.destination");
271+
assertEquals(RESULT_UUID.toString(), message.getHeaders().get("resultUuid"));
272+
assertEquals("me", message.getHeaders().get("receiver"));
273+
assertEquals(CANCEL_MESSAGE, message.getHeaders().get("message"));
274+
275+
assertNull(output.receive(1000));
276+
}
277+
278+
@Test
279+
public void runTestWithError() {
280+
webTestClient.post()
281+
.uri("/" + VERSION + "/networks/" + NETWORK_UUID + "/run-and-save?contingencyListName=" + CONTINGENCY_LIST_ERROR_NAME
282+
+ "&receiver=me")
283+
.exchange()
284+
.expectStatus().isOk() // Because fully asynchronous (just publish a message)
285+
.expectHeader().contentType(MediaType.APPLICATION_JSON)
286+
.expectBody(UUID.class)
287+
.isEqualTo(RESULT_UUID);
288+
289+
Message<byte[]> message = output.receive(1000, "sa.run.destination");
290+
assertEquals(NETWORK_UUID.toString(), message.getHeaders().get("networkUuid"));
291+
assertEquals(RESULT_UUID.toString(), message.getHeaders().get("resultUuid"));
292+
assertEquals(CONTINGENCY_LIST_ERROR_NAME, message.getHeaders().get("contingencyListNames"));
293+
assertEquals("me", message.getHeaders().get("receiver"));
294+
295+
// Message stopped has been sent
296+
message = output.receive(1000, "sa.stopped.destination");
297+
assertEquals(RESULT_UUID.toString(), message.getHeaders().get("resultUuid"));
298+
assertEquals("me", message.getHeaders().get("receiver"));
299+
assertEquals(FAIL_MESSAGE + " : " + ERROR_MESSAGE, message.getHeaders().get("message"));
300+
301+
assertNull(output.receive(1000));
302+
303+
// No result
304+
webTestClient.get()
305+
.uri("/" + VERSION + "/results/" + RESULT_UUID)
306+
.exchange()
307+
.expectStatus().isNotFound();
256308
}
257309
}

src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisFactoryMock.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class SecurityAnalysisFactoryMock implements SecurityAnalysisFactory {
3030

3131
static final String CONTINGENCY_LIST_NAME = "list1";
3232
static final String CONTINGENCY_LIST2_NAME = "list2";
33+
static final String CONTINGENCY_LIST_ERROR_NAME = "listError";
3334

3435
static final List<Contingency> CONTINGENCIES = List.of(new Contingency("l1", new BranchContingency("l1")),
3536
new Contingency("l2", new BranchContingency("l2")));

0 commit comments

Comments
 (0)