Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
*/
package org.gridsuite.monitor.worker.server.orchestrator;

import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.commons.report.TypedValue;
import lombok.RequiredArgsConstructor;
import org.gridsuite.monitor.commons.types.messaging.ProcessExecutionStep;
import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig;
Expand Down Expand Up @@ -33,6 +36,20 @@ public class StepExecutionService implements StepExecutor {
private final Notificator notificationService;
private final ReportRestClient reportRestClient;

private void handleException(ReportNode reportNode, Exception e) {
boolean isApplicationException = PowsyblException.class.isAssignableFrom(e.getClass());
if (!isApplicationException && LOGGER.isErrorEnabled()) {
LOGGER.error(e.toString(), e);
}
Comment thread
FranckLecuyer marked this conversation as resolved.
Resolved
String errorMessage = isApplicationException ? e.getMessage() : "Technical error: " + e;

reportNode.newReportNode()
.withMessageTemplate("monitor.worker.server.step.error")
.withUntypedValue("errorMessage", errorMessage)
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
}

@Override
public <C extends ProcessConfig> void executeStep(StepWithContext<C> stepWithContext) {
ProcessStepExecutionContext<C> context = stepWithContext.stepExecutionContext();
Expand All @@ -49,7 +66,8 @@ public <C extends ProcessConfig> void executeStep(StepWithContext<C> stepWithCon
throw e;
} catch (Exception e) {
status = StepStatus.FAILED;
throw new RuntimeException(e);
handleException(context.getReportNode(), e);
throw e;
} finally {
sendReportSafely(context);
updateStepStatus(context, status);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
package org.gridsuite.monitor.worker.server.process.loadflow.steps;

import com.powsybl.commons.report.ReportNode;
import com.powsybl.commons.report.TypedValue;
import com.powsybl.loadflow.LoadFlow;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.loadflow.LoadFlowResult;
Expand All @@ -17,7 +16,6 @@
import org.gridsuite.monitor.commons.types.result.ResultType;
import org.gridsuite.monitor.worker.server.clients.LoadFlowRestClient;
import org.gridsuite.monitor.worker.server.core.context.ProcessStepExecutionContext;
import org.gridsuite.monitor.worker.server.core.exceptions.ProcessCancelledException;
import org.gridsuite.monitor.worker.server.core.process.AbstractProcessStep;
import org.gridsuite.monitor.worker.server.dto.parameters.loadflow.LoadFlowParametersInfos;
import org.gridsuite.monitor.worker.server.orchestrator.TaskManager;
Expand All @@ -27,7 +25,6 @@

import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CancellationException;

/**
* @author Caroline Jeandat {@literal <caroline.jeandat at rte-france.com>}
Expand All @@ -50,27 +47,16 @@ public void execute(ProcessStepExecutionContext<LoadFlowConfig> context) {

ReportNode reportNode = context.getReportNode();

try {
LoadFlowParametersInfos parametersInfos = loadflowRestClient.getParameters(context.getConfig().loadflowParametersUuid());
LoadFlowParameters loadflowParameters = LoadFlowParametersService.buildParameters(parametersInfos);
LoadFlowRunParameters runParameters = new LoadFlowRunParameters()
.setParameters(loadflowParameters)
.setReportNode(reportNode);
LoadFlowResult result = taskManager.runComputation(context.getProcessExecutionId(),
LoadFlowParametersInfos parametersInfos = loadflowRestClient.getParameters(context.getConfig().loadflowParametersUuid());
LoadFlowParameters loadflowParameters = LoadFlowParametersService.buildParameters(parametersInfos);
LoadFlowRunParameters runParameters = new LoadFlowRunParameters()
.setParameters(loadflowParameters)
.setReportNode(reportNode);
LoadFlowResult result = taskManager.runComputation(context.getProcessExecutionId(),
() -> LoadFlow.find(parametersInfos.getProvider()).runAsync(context.getNetwork(), runParameters));

UUID resultUuid = loadflowRestClient.saveResult(result);
ResultInfos resultInfos = new ResultInfos(resultUuid, ResultType.LOADFLOW);
context.setResultInfos(resultInfos);
} catch (CancellationException | ProcessCancelledException e) {
throw e;
} catch (Exception e) {
reportNode.newReportNode()
.withMessageTemplate("monitor.worker.server.loadflow.step.error")
.withUntypedValue("errorMessage", e.getMessage())
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
throw e;
}
UUID resultUuid = loadflowRestClient.saveResult(result);
ResultInfos resultInfos = new ResultInfos(resultUuid, ResultType.LOADFLOW);
context.setResultInfos(resultInfos);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
package org.gridsuite.monitor.worker.server.process.securityanalysis.steps;

import com.powsybl.commons.report.ReportNode;
import com.powsybl.commons.report.TypedValue;
import com.powsybl.security.SecurityAnalysis;
import com.powsybl.security.SecurityAnalysisReport;
import com.powsybl.security.SecurityAnalysisRunParameters;
Expand All @@ -16,16 +15,15 @@
import org.gridsuite.monitor.commons.types.result.ResultType;
import org.gridsuite.monitor.worker.server.clients.SecurityAnalysisRestClient;
import org.gridsuite.monitor.worker.server.core.context.ProcessStepExecutionContext;
import org.gridsuite.monitor.worker.server.core.exceptions.ProcessCancelledException;
import org.gridsuite.monitor.worker.server.core.process.AbstractProcessStep;
import org.gridsuite.monitor.worker.server.dto.parameters.securityanalysis.SecurityAnalysisInputData;
import org.gridsuite.monitor.worker.server.orchestrator.TaskManager;
import org.gridsuite.monitor.worker.server.process.securityanalysis.SecurityAnalysisStepType;
import org.gridsuite.monitor.worker.server.services.SecurityAnalysisParametersService;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CancellationException;

/**
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
Expand All @@ -52,28 +50,17 @@ public void execute(ProcessStepExecutionContext<SecurityAnalysisConfig> context)

ReportNode reportNode = context.getReportNode();

try {
SecurityAnalysisInputData inputData = securityAnalysisParametersService.buildSecurityAnalysisInputData(
context.getConfig().securityAnalysisParametersUuid(), context.getConfig().loadflowParametersUuid(), context.getNetwork());
SecurityAnalysisInputData inputData = securityAnalysisParametersService.buildSecurityAnalysisInputData(
context.getConfig().securityAnalysisParametersUuid(), context.getConfig().loadflowParametersUuid(), context.getNetwork());

SecurityAnalysisRunParameters runParameters = new SecurityAnalysisRunParameters()
.setSecurityAnalysisParameters(inputData.securityAnalysisParameters())
.setReportNode(reportNode);
SecurityAnalysisReport saReport = taskManager.runComputation(context.getProcessExecutionId(),
SecurityAnalysisRunParameters runParameters = new SecurityAnalysisRunParameters()
.setSecurityAnalysisParameters(inputData.securityAnalysisParameters())
.setReportNode(reportNode);
SecurityAnalysisReport saReport = taskManager.runComputation(context.getProcessExecutionId(),
() -> SecurityAnalysis.find(inputData.provider()).runAsync(context.getNetwork(), inputData.contingencies(), runParameters));

ResultInfos resultInfos = new ResultInfos(UUID.randomUUID(), ResultType.SECURITY_ANALYSIS);
securityAnalysisRestClient.saveResult(resultInfos.resultUUID(), saReport.getResult());
context.setResultInfos(resultInfos);
} catch (CancellationException | ProcessCancelledException e) {
throw e;
} catch (Exception e) {
reportNode.newReportNode()
.withMessageTemplate("monitor.worker.server.securityanalysis.step.error")
.withUntypedValue("errorMessage", e.getMessage())
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
throw e;
}
ResultInfos resultInfos = new ResultInfos(UUID.randomUUID(), ResultType.SECURITY_ANALYSIS);
securityAnalysisRestClient.saveResult(resultInfos.resultUUID(), saReport.getResult());
context.setResultInfos(resultInfos);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
package org.gridsuite.monitor.worker.server.process.shortcircuit.steps;

import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.commons.report.TypedValue;
import com.powsybl.computation.local.LocalComputationManager;
import com.powsybl.shortcircuit.*;
import com.powsybl.shortcircuit.Fault;
import com.powsybl.shortcircuit.ShortCircuitAnalysis;
import com.powsybl.shortcircuit.ShortCircuitAnalysisResult;
import com.powsybl.shortcircuit.ShortCircuitParameters;
import lombok.Getter;
import org.gridsuite.monitor.commons.types.processconfig.ShortCircuitConfig;
import org.gridsuite.monitor.commons.types.result.ResultInfos;
import org.gridsuite.monitor.commons.types.result.ResultType;
import org.gridsuite.monitor.worker.server.clients.ShortCircuitRestClient;
import org.gridsuite.monitor.worker.server.core.context.ProcessStepExecutionContext;
import org.gridsuite.monitor.worker.server.core.exceptions.ProcessCancelledException;
import org.gridsuite.monitor.worker.server.core.process.AbstractProcessStep;
import org.gridsuite.monitor.worker.server.dto.parameters.shortcircuit.ShortCircuitParametersInfos;
import org.gridsuite.monitor.worker.server.orchestrator.TaskManager;
Expand All @@ -35,7 +35,6 @@
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CancellationException;

/**
* @author Caroline Jeandat {@literal <caroline.jeandat at rte-france.com>}
Expand Down Expand Up @@ -72,29 +71,16 @@ public ShortCircuitRunComputationStep(
public void execute(ProcessStepExecutionContext<ShortCircuitConfig> context) {
Objects.requireNonNull(context.getNetwork());

ReportNode reportNode = context.getReportNode();
ShortCircuitParametersInfos parametersInfos = shortCircuitRestClient.getParameters(context.getConfig().shortCircuitParametersUuid());
// TODO: in shortcircuit-server, retrieved parameters are post processed before being passed to the short-circuit calculation

try {
ShortCircuitParametersInfos parametersInfos = shortCircuitRestClient.getParameters(context.getConfig().shortCircuitParametersUuid());
// TODO: in shortcircuit-server, retrieved parameters are post processed before being passed to the short-circuit calculation

String provider = parametersInfos.getProvider() != null ? parametersInfos.getProvider() : getDefaultProvider();
Map<String, String> specificParameters = parametersInfos.getSpecificParametersPerProvider().get(provider);
ShortCircuitParameters commonParameters = shortCircuitParametersService.buildParameters(parametersInfos, provider, specificParameters);
if (context.getDebugFileLocation() == null) {
runComputation(context, provider, commonParameters, specificParameters);
} else {
runComputationWithDebug(context, provider, commonParameters, specificParameters);
}
} catch (CancellationException | ProcessCancelledException e) {
throw e;
} catch (Exception e) {
reportNode.newReportNode()
.withMessageTemplate("monitor.worker.server.shortcircuit.step.error")
.withUntypedValue("errorMessage", e.getMessage())
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
throw e;
String provider = parametersInfos.getProvider() != null ? parametersInfos.getProvider() : getDefaultProvider();
Map<String, String> specificParameters = parametersInfos.getSpecificParametersPerProvider().get(provider);
ShortCircuitParameters commonParameters = shortCircuitParametersService.buildParameters(parametersInfos, provider, specificParameters);
if (context.getDebugFileLocation() == null) {
runComputation(context, provider, commonParameters, specificParameters);
} else {
runComputationWithDebug(context, provider, commonParameters, specificParameters);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
monitor.worker.server.importCase = Import Case : ${caseName}
monitor.worker.server.loadflow.step.error = ${errorMessage}
monitor.worker.server.modifications.error = Some network composite modifications are missing : ${uuids}
monitor.worker.server.modifications.not.applied = Some network composite modifications are not applied intentionally (see process-config) : ${uuids}
monitor.worker.server.process = Process execution id : ${executionId}
monitor.worker.server.securityanalysis.step.error = ${errorMessage}
monitor.worker.server.shortcircuit.step.error = ${errorMessage}
monitor.worker.server.shortcircuit.step.error.VoltageLevelsWithWrongIscValuesSummarize = Some voltage levels have wrong isc values, isc min must be <= isc max: ${voltageLevels}
monitor.worker.server.step.error = ${errorMessage}
monitor.worker.server.stepType = ${stepType}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some keys are not used anymore, like "monitor.worker.server.loadflow.step.error"
same for monitor-worker-server/src/main/resources/org/gridsuite/monitor/worker/server/reports.properties

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
monitor.worker.server.importCase = Import Case : ${caseName}
monitor.worker.server.loadflow.step.error = ${errorMessage}
monitor.worker.server.modifications.error = Some network composite modifications are missing : ${uuids}
monitor.worker.server.modifications.not.applied = Some network composite modifications are not applied intentionally (see process-config) : ${uuids}
monitor.worker.server.process = Process execution id : ${executionId}
monitor.worker.server.securityanalysis.step.error = ${errorMessage}
monitor.worker.server.shortcircuit.step.error = ${errorMessage}
monitor.worker.server.shortcircuit.step.error.VoltageLevelsWithWrongIscValuesSummarize = Some voltage levels have wrong isc values, isc min must be <= isc max: ${voltageLevels}
monitor.worker.server.step.error = ${errorMessage}
monitor.worker.server.stepType = ${stepType}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.gridsuite.monitor.worker.server.core.process.ProcessStep;
import org.gridsuite.monitor.worker.server.core.process.ProcessStepType;
import org.gridsuite.monitor.worker.server.messaging.NotificationService;
import org.gridsuite.monitor.worker.server.utils.ReportTestUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand All @@ -32,6 +33,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
Expand Down Expand Up @@ -120,7 +122,7 @@ void executeStepShouldCompleteSuccessfullyWhenReportSendingFails() {
}

@Test
void executeStepShouldSendFailedStatusWhenExceptionThrown() {
void executeStepShouldSendFailedStatusAndReportErrorWhenExceptionThrown() {
UUID executionId = UUID.randomUUID();
UUID processReportId = UUID.randomUUID();
int stepOrder = 2;
Expand All @@ -134,7 +136,10 @@ void executeStepShouldSendFailedStatusWhenExceptionThrown() {
RuntimeException.class,
() -> stepExecutionService.executeStep(stepWithContext)
);
assertEquals("Step execution failed", thrownException.getCause().getMessage());

assertTrue(ReportTestUtils.assertMessageFoundFromReporter("Technical error: java.lang.RuntimeException: Step execution failed", "monitor.worker.server.step.error", context.getReportNode()));
assertEquals("Step execution failed", thrownException.getMessage());

verify(notificationService, times(2)).updateStepStatus(eq(executionId), eq(ProcessType.SECURITY_ANALYSIS), any(ProcessExecutionStep.class));
InOrder inOrder = inOrder(notificationService);
inOrder.verify(notificationService).updateStepStatus(eq(executionId), eq(ProcessType.SECURITY_ANALYSIS), argThat(step ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,6 @@ void setUp() {

when(stepContext.getConfig()).thenReturn(config);
when(config.shortCircuitParametersUuid()).thenReturn(PARAMS_UUID);

ReportNode reportNode = ReportNode.newRootReportNode()
.withResourceBundles("i18n.reports")
.withMessageTemplate("test")
.build();
when(stepContext.getReportNode()).thenReturn(reportNode);
}

@Test
Expand Down Expand Up @@ -238,6 +232,12 @@ private void assertCancellationDoesNotReportFailure(RuntimeException cancellatio
runComputationStep = new ShortCircuitRunComputationStep(
shortCircuitParametersService, shortCircuitRestClient, s3Service, fileService, taskManager, "ShortCircuit-provider");
when(stepContext.getProcessExecutionId()).thenReturn(executionId);
when(stepContext.getConfig()).thenReturn(config);
ReportNode reportNode = ReportNode.newRootReportNode()
.withResourceBundles("i18n.reports")
.withMessageTemplate("test")
.build();
when(stepContext.getReportNode()).thenReturn(reportNode);
Network network = EurostagTutorialExample1Factory.create();
when(stepContext.getNetwork()).thenReturn(network);
ShortCircuitParameters parameters = new ShortCircuitParameters();
Expand Down

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename it ReportTestUtils ? I think in the future we'd rather have several utils class rather than a single one for all use cases

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Copyright (c) 2026, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.gridsuite.monitor.worker.server.utils;

import com.powsybl.commons.report.ReportNode;
import org.apache.commons.text.StringSubstitutor;

/**
* @author Franck Lecuyer <franck.lecuyer at rte-france.com>
*/
public final class ReportTestUtils {
private ReportTestUtils() {
throw new IllegalCallerException("Utility class");
}

public static boolean assertMessageFoundFromReporter(String expectedMessage, String reportKey, ReportNode reporterModel) {
StringSubstitutor reporterSubstitutor = new StringSubstitutor(reporterModel.getValues());
return containsMessage(expectedMessage, reportKey, reporterModel, reporterSubstitutor);
}

private static boolean containsMessage(String expectedMessage, String reportKey, ReportNode reporter, StringSubstitutor reporterSubstitutor) {
for (ReportNode child : reporter.getChildren()) {
if (reportKey.equals(child.getMessageKey()) && expectedMessage.equals(formatReportMessage(child, reporterSubstitutor))) {
return true;
}
StringSubstitutor childSubstitutor = new StringSubstitutor(child.getValues());
if (containsMessage(expectedMessage, reportKey, child, childSubstitutor)) {
return true;
}
}
return false;
}

private static String formatReportMessage(ReportNode report, StringSubstitutor reporterSubstitutor) {
String reportMessage = new StringSubstitutor(report.getValues()).replace(report.getMessageTemplate());
return reporterSubstitutor.replace(reportMessage).trim();
}
}

Loading