Skip to content

Commit feaf8bd

Browse files
generalize services classes (#115)
Signed-off-by: Mathieu DEHARBE <mathieu.deharbe@rte-france.com>
1 parent 2403651 commit feaf8bd

30 files changed

+1074
-649
lines changed

src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import io.swagger.v3.oas.annotations.responses.ApiResponse;
1818
import io.swagger.v3.oas.annotations.responses.ApiResponses;
1919
import io.swagger.v3.oas.annotations.tags.Tag;
20+
import org.gridsuite.securityanalysis.server.computation.utils.ReportContext;
2021
import org.gridsuite.securityanalysis.server.dto.*;
2122
import org.gridsuite.securityanalysis.server.service.SecurityAnalysisParametersService;
2223
import org.gridsuite.securityanalysis.server.service.SecurityAnalysisResultService;
@@ -35,7 +36,7 @@
3536
import java.util.List;
3637
import java.util.UUID;
3738

38-
import static org.gridsuite.securityanalysis.server.service.NotificationService.HEADER_USER_ID;
39+
import static org.gridsuite.securityanalysis.server.computation.service.NotificationService.HEADER_USER_ID;
3940
import static org.springframework.http.MediaType.*;
4041

4142
/**
@@ -77,7 +78,7 @@ public ResponseEntity<SecurityAnalysisResult> run(@Parameter(description = "Netw
7778
@Parameter(description = "parametersUuid") @RequestParam(name = "parametersUuid", required = false) UUID parametersUuid,
7879
@Parameter(description = "loadFlow parameters uuid") @RequestParam(name = "loadFlowParametersUuid") UUID loadFlowParametersUuid,
7980
@RequestHeader(HEADER_USER_ID) String userId) {
80-
SecurityAnalysisResult result = workerService.run(securityAnalysisParametersService.createRunContext(networkUuid, variantId, new RunContextParametersInfos(contigencyListNames, parametersUuid, loadFlowParametersUuid), null, new ReportInfos(reportUuid, reporterId, reportType), userId));
81+
SecurityAnalysisResult result = workerService.run(securityAnalysisParametersService.createRunContext(networkUuid, variantId, new RunContextParametersInfos(contigencyListNames, parametersUuid, loadFlowParametersUuid), null, new ReportContext(reportUuid, reporterId, reportType), userId));
8182
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result);
8283
}
8384

@@ -103,7 +104,7 @@ public ResponseEntity<UUID> runAndSave(@Parameter(description = "Network UUID")
103104
variantId,
104105
new RunContextParametersInfos(contigencyListNames, parametersUuid, loadFlowParametersUuid),
105106
receiver,
106-
new ReportInfos(reportUuid, reporterId, reportType),
107+
new ReportContext(reportUuid, reporterId, reportType),
107108
userId
108109
)
109110
);
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* Copyright (c) 2024, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
package org.gridsuite.securityanalysis.server.computation.service;
8+
9+
import io.micrometer.core.instrument.Counter;
10+
import io.micrometer.core.instrument.MeterRegistry;
11+
import io.micrometer.observation.Observation;
12+
import io.micrometer.observation.ObservationRegistry;
13+
import lombok.NonNull;
14+
15+
/**
16+
* @author Mathieu Deharbe <mathieu.deharbe at rte-france.com
17+
* @param <R> powsybl Result class specific to the computation
18+
* @param <P> powsybl and gridsuite parameters specifics to the computation
19+
*/
20+
public abstract class AbstractComputationObserver<R, P> {
21+
protected static final String OBSERVATION_PREFIX = "app.computation.";
22+
protected static final String PROVIDER_TAG_NAME = "provider";
23+
protected static final String TYPE_TAG_NAME = "type";
24+
protected static final String STATUS_TAG_NAME = "status";
25+
protected static final String COMPUTATION_COUNTER_NAME = OBSERVATION_PREFIX + "count";
26+
protected final ObservationRegistry observationRegistry;
27+
protected final MeterRegistry meterRegistry;
28+
29+
protected AbstractComputationObserver(@NonNull ObservationRegistry observationRegistry, @NonNull MeterRegistry meterRegistry) {
30+
this.observationRegistry = observationRegistry;
31+
this.meterRegistry = meterRegistry;
32+
}
33+
34+
protected abstract String getComputationType();
35+
36+
protected Observation createObservation(String name, AbstractComputationRunContext<P> runContext) {
37+
return Observation.createNotStarted(OBSERVATION_PREFIX + name, observationRegistry)
38+
.lowCardinalityKeyValue(PROVIDER_TAG_NAME, runContext.getProvider())
39+
.lowCardinalityKeyValue(TYPE_TAG_NAME, getComputationType());
40+
}
41+
42+
public <E extends Throwable> void observe(String name, AbstractComputationRunContext<P> runContext, Observation.CheckedRunnable<E> callable) throws E {
43+
createObservation(name, runContext).observeChecked(callable);
44+
}
45+
46+
public <T, E extends Throwable> T observe(String name, AbstractComputationRunContext<P> runContext, Observation.CheckedCallable<T, E> callable) throws E {
47+
return createObservation(name, runContext).observeChecked(callable);
48+
}
49+
50+
public <T extends R, E extends Throwable> T observeRun(
51+
String name, AbstractComputationRunContext<P> runContext, Observation.CheckedCallable<T, E> callable) throws E {
52+
T result = createObservation(name, runContext).observeChecked(callable);
53+
incrementCount(runContext, result);
54+
return result;
55+
}
56+
57+
private void incrementCount(AbstractComputationRunContext<P> runContext, R result) {
58+
Counter.builder(COMPUTATION_COUNTER_NAME)
59+
.tag(PROVIDER_TAG_NAME, runContext.getProvider())
60+
.tag(TYPE_TAG_NAME, getComputationType())
61+
.tag(STATUS_TAG_NAME, getResultStatus(result))
62+
.register(meterRegistry)
63+
.increment();
64+
}
65+
66+
protected abstract String getResultStatus(R res);
67+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright (c) 2024, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
package org.gridsuite.securityanalysis.server.computation.service;
8+
9+
import java.util.List;
10+
import java.util.UUID;
11+
12+
/**
13+
* @author Mathieu Deharbe <mathieu.deharbe at rte-france.com
14+
* @param <S> status specific to the computation
15+
*/
16+
public abstract class AbstractComputationResultService<S> {
17+
18+
public abstract void insertStatus(List<UUID> resultUuids, S status);
19+
20+
public abstract void delete(UUID resultUuid);
21+
22+
public abstract void deleteAll();
23+
24+
public abstract S findStatus(UUID resultUuid);
25+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Copyright (c) 2024, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
package org.gridsuite.securityanalysis.server.computation.service;
8+
9+
import lombok.AllArgsConstructor;
10+
import lombok.Getter;
11+
import lombok.Setter;
12+
import org.gridsuite.securityanalysis.server.computation.utils.ReportContext;
13+
14+
import java.util.UUID;
15+
16+
/**
17+
* @author Mathieu Deharbe <mathieu.deharbe at rte-france.com
18+
* @param <P> parameters structure specific to the computation
19+
*/
20+
@Getter
21+
@AllArgsConstructor
22+
public abstract class AbstractComputationRunContext<P> {
23+
private final UUID networkUuid;
24+
private final String variantId;
25+
private final String receiver;
26+
private final ReportContext reportContext;
27+
private final String userId;
28+
@Setter protected String provider;
29+
@Setter protected P parameters;
30+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* Copyright (c) 2024, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
package org.gridsuite.securityanalysis.server.computation.service;
8+
9+
import com.fasterxml.jackson.databind.ObjectMapper;
10+
import lombok.Getter;
11+
12+
import java.util.List;
13+
import java.util.Objects;
14+
import java.util.UUID;
15+
16+
/**
17+
* @author Mathieu Deharbe <mathieu.deharbe at rte-france.com
18+
* @param <R> run context specific to a computation, including parameters
19+
* @param <T> run service specific to a computation
20+
* @param <S> enum status specific to a computation
21+
*/
22+
public abstract class AbstractComputationService<R extends AbstractComputationRunContext<?>, T extends AbstractComputationResultService<S>, S> {
23+
24+
protected ObjectMapper objectMapper;
25+
protected NotificationService notificationService;
26+
@Getter
27+
protected String defaultProvider;
28+
29+
protected UuidGeneratorService uuidGeneratorService;
30+
protected T resultService;
31+
32+
protected AbstractComputationService(NotificationService notificationService,
33+
T resultService,
34+
ObjectMapper objectMapper,
35+
UuidGeneratorService uuidGeneratorService,
36+
String defaultProvider) {
37+
this.notificationService = Objects.requireNonNull(notificationService);
38+
this.objectMapper = Objects.requireNonNull(objectMapper);
39+
this.uuidGeneratorService = Objects.requireNonNull(uuidGeneratorService);
40+
this.defaultProvider = Objects.requireNonNull(defaultProvider);
41+
this.resultService = Objects.requireNonNull(resultService);
42+
}
43+
44+
public void stop(UUID resultUuid, String receiver) {
45+
notificationService.sendCancelMessage(new CancelContext(resultUuid, receiver).toMessage());
46+
}
47+
48+
public abstract List<String> getProviders();
49+
50+
public abstract UUID runAndSaveResult(R runContext);
51+
52+
public void deleteResult(UUID resultUuid) {
53+
resultService.delete(resultUuid);
54+
}
55+
56+
public void deleteResults(List<UUID> resultUuids) {
57+
if (resultUuids != null && !resultUuids.isEmpty()) {
58+
resultUuids.forEach(resultService::delete);
59+
} else {
60+
deleteResults();
61+
}
62+
}
63+
64+
public void deleteResults() {
65+
resultService.deleteAll();
66+
}
67+
68+
public void setStatus(List<UUID> resultUuids, S status) {
69+
resultService.insertStatus(resultUuids, status);
70+
}
71+
72+
public S getStatus(UUID resultUuid) {
73+
return resultService.findStatus(resultUuid);
74+
}
75+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* Copyright (c) 2023, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
package org.gridsuite.securityanalysis.server.computation.service;
8+
9+
import com.fasterxml.jackson.core.JsonProcessingException;
10+
import com.fasterxml.jackson.databind.ObjectMapper;
11+
import lombok.Getter;
12+
import org.springframework.messaging.Message;
13+
import org.springframework.messaging.support.MessageBuilder;
14+
15+
import java.io.UncheckedIOException;
16+
import java.util.Map;
17+
import java.util.Objects;
18+
import java.util.UUID;
19+
20+
import static org.gridsuite.securityanalysis.server.computation.service.NotificationService.*;
21+
22+
/**
23+
* @author Mathieu Deharbe <mathieu.deharbe at rte-france.com
24+
* @param <R> run context specific to a computation, including parameters
25+
*/
26+
@Getter
27+
public abstract class AbstractResultContext<R extends AbstractComputationRunContext<?>> {
28+
29+
protected static final String RESULT_UUID_HEADER = "resultUuid";
30+
31+
protected static final String NETWORK_UUID_HEADER = "networkUuid";
32+
33+
protected static final String REPORT_UUID_HEADER = "reportUuid";
34+
35+
public static final String VARIANT_ID_HEADER = "variantId";
36+
37+
public static final String REPORTER_ID_HEADER = "reporterId";
38+
39+
public static final String REPORT_TYPE_HEADER = "reportType";
40+
41+
protected static final String MESSAGE_ROOT_NAME = "parameters";
42+
43+
protected final UUID resultUuid;
44+
45+
protected final R runContext;
46+
47+
protected AbstractResultContext(UUID resultUuid, R runContext) {
48+
this.resultUuid = Objects.requireNonNull(resultUuid);
49+
this.runContext = Objects.requireNonNull(runContext);
50+
}
51+
52+
public Message<String> toMessage(ObjectMapper objectMapper) {
53+
String parametersJson;
54+
try {
55+
parametersJson = objectMapper.writeValueAsString(runContext.getParameters());
56+
} catch (JsonProcessingException e) {
57+
throw new UncheckedIOException(e);
58+
}
59+
return MessageBuilder.withPayload(parametersJson)
60+
.setHeader(RESULT_UUID_HEADER, resultUuid.toString())
61+
.setHeader(NETWORK_UUID_HEADER, runContext.getNetworkUuid().toString())
62+
.setHeader(VARIANT_ID_HEADER, runContext.getVariantId())
63+
.setHeader(HEADER_RECEIVER, runContext.getReceiver())
64+
.setHeader(HEADER_PROVIDER, runContext.getProvider())
65+
.setHeader(HEADER_USER_ID, runContext.getUserId())
66+
.setHeader(REPORT_UUID_HEADER, runContext.getReportContext().getReportId() != null ? runContext.getReportContext().getReportId().toString() : null)
67+
.setHeader(REPORTER_ID_HEADER, runContext.getReportContext().getReportName())
68+
.setHeader(REPORT_TYPE_HEADER, runContext.getReportContext().getReportType())
69+
.copyHeaders(getSpecificMsgHeaders())
70+
.build();
71+
}
72+
73+
protected Map<String, String> getSpecificMsgHeaders() {
74+
return Map.of();
75+
}
76+
}

0 commit comments

Comments
 (0)