11package com .park .utmstack .service .compliance .config ;
22
3- import com .park .utmstack .service .dto .compliance .UtmComplianceControlEvaluationsDto ;
3+ import com .park .utmstack .domain .compliance .UtmComplianceQueryConfig ;
4+ import com .park .utmstack .repository .compliance .UtmComplianceQueryConfigRepository ;
5+ import com .park .utmstack .service .dto .compliance .*;
46import com .park .utmstack .service .elasticsearch .ElasticsearchService ;
57import org .springframework .stereotype .Service ;
68
7- import java .util .List ;
9+ import java .time .Instant ;
10+ import java .time .ZoneOffset ;
11+ import java .util .*;
12+ import java .util .function .Function ;
13+ import java .util .stream .Collectors ;
814
915@ Service
1016public class UtmComplianceControlEvaluationsService {
1117
1218 private final ElasticsearchService elasticsearchService ;
19+ private final UtmComplianceQueryConfigRepository queryConfigRepository ;
1320
14- public UtmComplianceControlEvaluationsService (ElasticsearchService elasticsearchService ) {
21+ public UtmComplianceControlEvaluationsService (ElasticsearchService elasticsearchService ,
22+ UtmComplianceQueryConfigRepository QueryConfigRepository ) {
1523 this .elasticsearchService = elasticsearchService ;
24+ this .queryConfigRepository = QueryConfigRepository ;
1625 }
1726
1827 public List <UtmComplianceControlEvaluationsDto > findByControlId (Long controlId ) {
1928 return elasticsearchService .getControlEvaluations (controlId );
2029 }
2130
2231 public UtmComplianceControlEvaluationsDto getLastEvaluationForControl (Long controlId ) {
23- return elasticsearchService .getLastEvaluation (controlId );
32+ return elasticsearchService .getLatestControlEvaluation (controlId );
33+ }
34+
35+ /*public ControlEvaluationsResponseDto getEvaluationsWithRange(Long controlId) {
36+ var evaluations = findByControlId(controlId);
37+
38+ if (evaluations.isEmpty()) {
39+ return new ControlEvaluationsResponseDto(null, null, evaluations);
40+ }
41+
42+ var timestamps = evaluations.stream()
43+ .map(UtmComplianceControlEvaluationsDto::getTimestamp)
44+ .toList();
45+
46+ Instant min = timestamps.stream().min(Instant::compareTo).get();
47+ Instant max = timestamps.stream().max(Instant::compareTo).get();
48+
49+ LocalDate start = min.atZone(ZoneOffset.UTC).toLocalDate();
50+ LocalDate end = max.atZone(ZoneOffset.UTC).toLocalDate();
51+
52+ return new ControlEvaluationsResponseDto(start, end, evaluations);
53+ }*/
54+
55+ /*public ControlEvaluationsResponseDto getEvaluationsWithRange(Long controlId) {
56+
57+ // 1. Evaluaciones crudas desde OpenSearch - UtmComplianceControlEvaluationsDto
58+ var evaluations = findByControlId(controlId);
59+
60+ if (evaluations.isEmpty()) {
61+ return new ControlEvaluationsResponseDto(
62+ null,
63+ null,
64+ List.of()
65+ );
66+ }
67+
68+ // 2. Extraer todos los queryConfigId de todas las evaluaciones
69+ var queryConfigIds = evaluations.stream()
70+ .flatMap(ev -> ev.getQueryEvaluations().stream())
71+ .map(UtmComplianceQueryEvaluationDto::getQueryConfigId)
72+ .collect(Collectors.toSet());
73+
74+ // 3. Lookup masivo en DB - UtmComplianceQueryConfig
75+ var configs = queryConfigRepository.findAllById(queryConfigIds);
76+ var configMap = configs.stream()
77+ .collect(Collectors.toMap(
78+ UtmComplianceQueryConfig::getId,
79+ Function.identity()
80+ ));
81+
82+ // 4. Enriquecer cada query evaluation
83+ evaluations.forEach(controlEval -> {
84+ controlEval.getQueryEvaluations().forEach(queryEval -> {
85+ var cfg = configMap.get(queryEval.getQueryConfigId());
86+ if (cfg != null) {
87+ queryEval.setQueryDescription(cfg.getQueryDescription());
88+ queryEval.setEvaluationRule(cfg.getEvaluationRule().name());
89+ queryEval.setIndexPatternId(cfg.getIndexPattern().getId());
90+ queryEval.setIndexPatternName(cfg.getIndexPattern().getPattern());
91+ }
92+ });
93+ });
94+
95+ // 5. Aplanar todas las queryEvaluations para agrupar por indexPattern
96+ var allQueryEvaluations = evaluations.stream()
97+ .flatMap(ev -> ev.getQueryEvaluations().stream())
98+ .toList();
99+
100+ // 6. Agrupar por indexPattern
101+ var groupedEvaluations = allQueryEvaluations.stream()
102+ .collect(Collectors.groupingBy(UtmComplianceQueryEvaluationDto::getIndexPatternId))
103+ .entrySet().stream()
104+ .map(entry -> {
105+ var first = entry.getValue().get(0);
106+ var dto = new IndexPatternQueriesGroupDto();
107+ dto.setIndexPatternId(entry.getKey());
108+ dto.setIndexPatternName(first.getIndexPatternName());
109+ dto.setQueries(entry.getValue());
110+ return dto;
111+ })
112+ .toList();
113+
114+ // 7. Calcular rango de fechas
115+ var timestamps = evaluations.stream()
116+ .map(UtmComplianceControlEvaluationsDto::getTimestamp)
117+ .toList();
118+
119+ Instant min = timestamps.stream().min(Instant::compareTo).get();
120+ Instant max = timestamps.stream().max(Instant::compareTo).get();
121+
122+ LocalDate startDate = min.atZone(ZoneOffset.UTC).toLocalDate();
123+ LocalDate endDate = max.atZone(ZoneOffset.UTC).toLocalDate();
124+
125+ var groupedDto = new UtmComplianceControlEvaluationsGroupedDto();
126+ groupedDto.setControlId(evaluations.get(0).getControlId());
127+ groupedDto.setControlName(evaluations.get(0).getControlName());
128+ groupedDto.setStatus(evaluations.get(0).getStatus());
129+ groupedDto.setTimestamp(evaluations.get(0).getTimestamp());
130+ groupedDto.setQueryEvaluations(groupedEvaluations);
131+
132+
133+ // 8. Devolver DTO final enriquecido y agrupado
134+ return new ControlEvaluationsResponseDto(
135+ startDate,
136+ endDate,
137+ List.of(groupedDto)
138+ );
139+
140+ }*/
141+
142+ public ControlEvaluationsResponseDto getEvaluationsWithRange (Long controlId ) {
143+ //TODO: Elena Ordenar por fecha descendente
144+ var evaluations = findByControlId (controlId );
145+
146+ if (evaluations .isEmpty ()) {
147+ return new ControlEvaluationsResponseDto (null , null , List .of ());
148+ }
149+
150+ var queryConfigIds = evaluations .stream ()
151+ .flatMap (ev -> ev .getQueryEvaluations ().stream ())
152+ .map (UtmComplianceQueryEvaluationDto ::getQueryConfigId )
153+ .collect (Collectors .toSet ());
154+
155+ var configMap = queryConfigRepository .findAllById (queryConfigIds ).stream ()
156+ .collect (Collectors .toMap (UtmComplianceQueryConfig ::getId , Function .identity ()));
157+
158+ //evaluations = enrichQueries(evaluations, configMap);
159+
160+ List <UtmComplianceControlEvaluationsGroupedDto > groupedList =
161+ enrichQueries (evaluations , configMap ).stream ()
162+ .map (evaluation -> {
163+ var grouped = groupByIndexPattern (evaluation );
164+ return buildGroupedDto (evaluation , grouped );
165+ })
166+ .toList ();
167+
168+ var timestamps = evaluations .stream ()
169+ .map (UtmComplianceControlEvaluationsDto ::getTimestamp )
170+ .toList ();
171+
172+ return new ControlEvaluationsResponseDto (
173+ timestamps .stream ().min (Instant ::compareTo )
174+ .get ().atZone (ZoneOffset .UTC ).toLocalDate (),
175+ timestamps .stream ().max (Instant ::compareTo )
176+ .get ().atZone (ZoneOffset .UTC ).toLocalDate (),
177+ groupedList );
178+ }
179+
180+
181+ private List <UtmComplianceControlEvaluationsDto > enrichQueries (
182+ List <UtmComplianceControlEvaluationsDto > evaluations ,
183+ Map <Long , UtmComplianceQueryConfig > configMap
184+ ) {
185+ evaluations .forEach (controlEval ->
186+ controlEval .getQueryEvaluations ().forEach (queryEval -> {
187+ var cfg = configMap .get (queryEval .getQueryConfigId ());
188+ if (cfg != null ) {
189+ queryEval .setQueryDescription (cfg .getQueryDescription ());
190+ queryEval .setEvaluationRule (cfg .getEvaluationRule ().name ());
191+ queryEval .setIndexPatternId (cfg .getIndexPattern ().getId ());
192+ queryEval .setIndexPatternName (cfg .getIndexPattern ().getPattern ());
193+ }
194+ })
195+ );
196+ return evaluations ;
197+ }
198+
199+ private List <IndexPatternQueriesGroupDto > groupByIndexPattern (
200+ UtmComplianceControlEvaluationsDto evaluation
201+ ) {
202+ return evaluation .getQueryEvaluations ().stream ()
203+ .collect (Collectors .groupingBy (UtmComplianceQueryEvaluationDto ::getIndexPatternId ))
204+ .entrySet ().stream ()
205+ .map (entry -> {
206+ var first = entry .getValue ().get (0 );
207+ var dto = new IndexPatternQueriesGroupDto ();
208+ dto .setIndexPatternId (entry .getKey ());
209+ dto .setIndexPatternName (first .getIndexPatternName ());
210+ dto .setQueries (entry .getValue ());
211+ return dto ;
212+ })
213+ .toList ();
214+ }
215+
216+ private UtmComplianceControlEvaluationsGroupedDto buildGroupedDto (
217+ UtmComplianceControlEvaluationsDto evaluation ,
218+ List <IndexPatternQueriesGroupDto > groupedEvaluations
219+ ) {
220+ var dto = new UtmComplianceControlEvaluationsGroupedDto ();
221+ dto .setControlId (evaluation .getControlId ());
222+ dto .setControlName (evaluation .getControlName ());
223+ dto .setStatus (evaluation .getStatus ());
224+ dto .setTimestamp (evaluation .getTimestamp ());
225+ dto .setQueryEvaluations (groupedEvaluations );
226+
227+ return dto ;
24228 }
25229}
0 commit comments