-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
…rview
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,33 @@ | ||
package io.openbas.rest.scenario; | ||
|
||
import static io.openbas.database.model.User.ROLE_USER; | ||
import static io.openbas.rest.scenario.ScenarioApi.SCENARIO_URI; | ||
import static org.springframework.util.StringUtils.hasText; | ||
|
||
import io.openbas.database.repository.ScenarioRepository; | ||
import io.openbas.rest.helper.RestBehavior; | ||
import io.openbas.rest.scenario.response.ScenarioStatistic; | ||
import io.openbas.rest.scenario.service.ScenarioStatisticService; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import jakarta.transaction.Transactional; | ||
import java.util.LinkedHashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import jakarta.validation.constraints.NotBlank; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.security.access.annotation.Secured; | ||
import org.springframework.security.access.prepost.PreAuthorize; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
@Secured(ROLE_USER) | ||
@RequiredArgsConstructor | ||
public class ScenarioStatisticApi extends RestBehavior { | ||
|
||
private final ScenarioRepository scenarioRepository; | ||
private final ScenarioStatisticService scenarioStatisticService; | ||
|
||
@GetMapping(SCENARIO_URI + "/statistics") | ||
@GetMapping(SCENARIO_URI + "/{scenarioId}/statistics") | ||
@PreAuthorize("isScenarioObserver(#scenarioId)") | ||
@Transactional(rollbackOn = Exception.class) | ||
@Operation(summary = "Retrieve scenario statistics") | ||
public ScenarioStatistic scenarioStatistic() { | ||
ScenarioStatistic statistic = new ScenarioStatistic(); | ||
statistic.setScenariosGlobalCount(this.scenarioRepository.count()); | ||
statistic.setScenariosCategoriesCount(findTopCategories()); | ||
return statistic; | ||
} | ||
|
||
private Map<String, Long> findTopCategories() { | ||
List<Object[]> results = this.scenarioRepository.findTopCategories(3); | ||
Map<String, Long> categoryCount = new LinkedHashMap<>(); | ||
for (Object[] result : results) { | ||
String category = (String) result[0]; | ||
if (hasText(category)) { | ||
Long count = (Long) result[1]; | ||
categoryCount.put(category, count); | ||
} | ||
} | ||
return categoryCount; | ||
public ScenarioStatistic getScenarioStatistics(@PathVariable @NotBlank final String scenarioId) { | ||
return scenarioStatisticService.getStatistics(scenarioId); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package io.openbas.rest.scenario.response; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import jakarta.validation.constraints.NotNull; | ||
import java.time.Instant; | ||
|
||
public record GlobalScoreBySimulationEndDate( | ||
Check warning on line 7 in openbas-api/src/main/java/io/openbas/rest/scenario/response/GlobalScoreBySimulationEndDate.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/response/GlobalScoreBySimulationEndDate.java#L7
|
||
@JsonProperty("simulation_end_date") @NotNull Instant simulationEndDate, | ||
@JsonProperty("global_score_success_percentage") @NotNull | ||
double globalScoreSuccessPercentage) {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,8 @@ | ||
package io.openbas.rest.scenario.response; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import java.util.Map; | ||
import lombok.Data; | ||
import jakarta.validation.constraints.NotNull; | ||
|
||
@Data | ||
public class ScenarioStatistic { | ||
|
||
@JsonProperty("scenarios_global_count") | ||
private long scenariosGlobalCount; | ||
|
||
@JsonProperty("scenarios_attack_scenario_count") | ||
private Map<String, Long> scenariosCategoriesCount; | ||
} | ||
public record ScenarioStatistic( | ||
@JsonProperty("simulations_results_latest") @NotNull | ||
SimulationsResultsLatest simulationsResultsLatest) {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package io.openbas.rest.scenario.response; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import io.openbas.expectation.ExpectationType; | ||
import jakarta.validation.constraints.NotNull; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public record SimulationsResultsLatest( | ||
Check warning on line 9 in openbas-api/src/main/java/io/openbas/rest/scenario/response/SimulationsResultsLatest.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/response/SimulationsResultsLatest.java#L9
|
||
@JsonProperty("global_scores_by_expectation_type") @NotNull | ||
Map<ExpectationType, List<GlobalScoreBySimulationEndDate>> globalScoresByExpectationType) {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package io.openbas.rest.scenario.service; | ||
|
||
import io.openbas.database.raw.RawFinishedExerciseWithInjects; | ||
import io.openbas.database.repository.ExerciseRepository; | ||
import io.openbas.expectation.ExpectationType; | ||
import io.openbas.rest.scenario.response.GlobalScoreBySimulationEndDate; | ||
import io.openbas.rest.scenario.response.ScenarioStatistic; | ||
import io.openbas.rest.scenario.response.SimulationsResultsLatest; | ||
import io.openbas.utils.AtomicTestingUtils.ExpectationResultsByType; | ||
import io.openbas.utils.AtomicTestingUtils.ResultDistribution; | ||
import io.openbas.utils.ResultUtils; | ||
import java.util.*; | ||
import java.util.function.BinaryOperator; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class ScenarioStatisticService { | ||
|
||
private final ExerciseRepository exerciseRepository; | ||
|
||
private final ResultUtils resultUtils; | ||
|
||
public ScenarioStatistic getStatistics(String scenarioId) { | ||
return getLatestSimulationsStatistics(scenarioId); | ||
Check warning on line 26 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L26
|
||
} | ||
|
||
private ScenarioStatistic getLatestSimulationsStatistics(String scenarioId) { | ||
List<RawFinishedExerciseWithInjects> rawFinishedExercises = | ||
exerciseRepository.rawLatestFinishedExercisesWithInjectsByScenarioId(scenarioId); | ||
Check warning on line 31 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L30-L31
|
||
|
||
Map<ExpectationType, List<GlobalScoreBySimulationEndDate>> | ||
initialGlobalScoresByExpectationType = new HashMap<>(); | ||
initialGlobalScoresByExpectationType.put(ExpectationType.PREVENTION, new ArrayList<>()); | ||
initialGlobalScoresByExpectationType.put(ExpectationType.DETECTION, new ArrayList<>()); | ||
initialGlobalScoresByExpectationType.put(ExpectationType.HUMAN_RESPONSE, new ArrayList<>()); | ||
Check warning on line 37 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L34-L37
|
||
|
||
Map<ExpectationType, List<GlobalScoreBySimulationEndDate>> globalScoresByExpectationType = | ||
rawFinishedExercises.stream() | ||
.reduce( | ||
Check warning on line 41 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L39-L41
|
||
initialGlobalScoresByExpectationType, | ||
(scoresByType, rawFinishedExercise) -> | ||
addGlobalScores( | ||
Check warning on line 44 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L44
|
||
scoresByType, | ||
rawFinishedExercise, | ||
resultUtils.getResultsByTypes(rawFinishedExercise.getInject_ids())), | ||
getMapBinaryOperator()); | ||
Check warning on line 48 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L47-L48
|
||
|
||
return new ScenarioStatistic(new SimulationsResultsLatest(globalScoresByExpectationType)); | ||
Check warning on line 50 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L50
|
||
} | ||
|
||
private static Map<ExpectationType, List<GlobalScoreBySimulationEndDate>> addGlobalScores( | ||
Map<ExpectationType, List<GlobalScoreBySimulationEndDate>> globalScoresByExpectationType, | ||
RawFinishedExerciseWithInjects rawFinishedExercise, | ||
List<ExpectationResultsByType> expectationResultsByType) { | ||
|
||
updateGlobalScores( | ||
Check warning on line 58 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L58
|
||
globalScoresByExpectationType, | ||
rawFinishedExercise, | ||
expectationResultsByType, | ||
ExpectationType.PREVENTION); | ||
|
||
updateGlobalScores( | ||
Check warning on line 64 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L64
|
||
globalScoresByExpectationType, | ||
rawFinishedExercise, | ||
expectationResultsByType, | ||
ExpectationType.DETECTION); | ||
|
||
updateGlobalScores( | ||
Check warning on line 70 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L70
|
||
globalScoresByExpectationType, | ||
rawFinishedExercise, | ||
expectationResultsByType, | ||
ExpectationType.HUMAN_RESPONSE); | ||
|
||
return globalScoresByExpectationType; | ||
Check warning on line 76 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L76
|
||
} | ||
|
||
private static void updateGlobalScores( | ||
Map<ExpectationType, List<GlobalScoreBySimulationEndDate>> globalScoresByExpectationType, | ||
RawFinishedExerciseWithInjects rawFinishedExercise, | ||
List<ExpectationResultsByType> expectationResultsByType, | ||
ExpectationType expectationType) { | ||
List<GlobalScoreBySimulationEndDate> globalScores = | ||
getGlobalScoresBySimulationEndDates( | ||
Check warning on line 85 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L84-L85
|
||
rawFinishedExercise, expectationResultsByType, expectationType); | ||
updateGlobalScoresByExpectationType( | ||
Check warning on line 87 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L87
|
||
globalScoresByExpectationType, globalScores, expectationType); | ||
} | ||
Check warning on line 89 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L89
|
||
|
||
private static void updateGlobalScoresByExpectationType( | ||
Map<ExpectationType, List<GlobalScoreBySimulationEndDate>> globalScoresByType, | ||
List<GlobalScoreBySimulationEndDate> globalScores, | ||
ExpectationType expectationType) { | ||
List<GlobalScoreBySimulationEndDate> previousGlobalScores = | ||
globalScoresByType.getOrDefault(expectationType, new ArrayList<>()); | ||
previousGlobalScores.addAll(globalScores); | ||
globalScoresByType.put(expectationType, previousGlobalScores); | ||
} | ||
Check warning on line 99 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L95-L99
|
||
|
||
private static List<GlobalScoreBySimulationEndDate> getGlobalScoresBySimulationEndDates( | ||
RawFinishedExerciseWithInjects rawFinishedExercise, | ||
List<ExpectationResultsByType> expectationResultsByType, | ||
ExpectationType expectationType) { | ||
|
||
return expectationResultsByType.stream() | ||
Check warning on line 106 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L106
|
||
.filter(expectationResultByType -> expectationResultByType.type() == expectationType) | ||
.map( | ||
Check warning on line 108 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L108
|
||
expectationResultByType -> | ||
new GlobalScoreBySimulationEndDate( | ||
rawFinishedExercise.getExercise_end_date(), | ||
getPercentageOfInjectsOnSuccess(expectationResultByType))) | ||
.toList(); | ||
Check warning on line 113 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L110-L113
|
||
} | ||
|
||
private static float getPercentageOfInjectsOnSuccess( | ||
ExpectationResultsByType expectationResultByType) { | ||
if (expectationResultByType.distribution().isEmpty()) { | ||
return 0; | ||
Check warning on line 119 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L119
|
||
} | ||
var totalNumberOfInjects = | ||
expectationResultByType.distribution().stream() | ||
.map(ResultDistribution::value) | ||
.reduce(0, Integer::sum); | ||
var numberOfInjectsOnSuccess = expectationResultByType.distribution().getFirst().value(); | ||
return (float) numberOfInjectsOnSuccess / totalNumberOfInjects; | ||
Check warning on line 126 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L121-L126
|
||
} | ||
|
||
private static BinaryOperator<Map<ExpectationType, List<GlobalScoreBySimulationEndDate>>> | ||
getMapBinaryOperator() { | ||
return (m1, m2) -> { | ||
m1.putAll(m2); | ||
return m1; | ||
Check warning on line 133 in openbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java Codecov / codecov/patchopenbas-api/src/main/java/io/openbas/rest/scenario/service/ScenarioStatisticService.java#L131-L133
|
||
}; | ||
} | ||
} |