Skip to content

Commit 824af9c

Browse files
committed
Updates coordinates with TTL and merging
Refactors coordinate update logic to include a Time-To-Live (TTL) mechanism for vehicle coordinates, removing outdated entries. Improves data accuracy by merging newly fetched coordinates with existing data, prioritizing the most recent information for each vehicle. Updates application properties to include a configurable TTL value (api.onibus.coordenadas.ttl-minutes).
1 parent e834c1c commit 824af9c

File tree

2 files changed

+72
-33
lines changed

2 files changed

+72
-33
lines changed

src/main/java/com/dmware/api_onibusbh/services/OnibusService.java

Lines changed: 69 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.nio.file.Path;
2727
import java.nio.file.Paths;
2828
import java.nio.file.StandardOpenOption;
29+
import java.time.LocalDateTime;
2930
import java.util.*;
3031
import java.util.function.BinaryOperator;
3132
import java.util.function.Function;
@@ -41,6 +42,9 @@ public class OnibusService {
4142
@Value("${FILE_NAME}")
4243
private String FILE_NAME;
4344

45+
@Value("${api.onibus.coordenadas.ttl-minutes:20}")
46+
private int ttlMinutes;
47+
4448
private final LinhasRepository linhasRepository;
4549
private final ModelMapper modelMapper;
4650
private final ObjectMapper objectMapper;
@@ -108,45 +112,78 @@ public void salvaCoordenadas() {
108112
return;
109113
}
110114

111-
List<CoordenadaDTO> coordenadas = fetchCoordenadas();
112-
if (coordenadas.isEmpty()) {
113-
logger.info("Nenhuma coordenada encontrada para processar.");
114-
return;
115+
List<CoordenadaDTO> todasCoordenadasNovas = fetchCoordenadas();
116+
117+
// Agrupa as coordenadas novas mais recentes por número de linha
118+
Map<Integer, List<CoordenadaDTO>> mapaNovasCoordenadasPorLinha;
119+
if (todasCoordenadasNovas.isEmpty()) {
120+
logger.info("Nenhuma coordenada nova encontrada. Executando apenas limpeza por TTL.");
121+
mapaNovasCoordenadasPorLinha = Collections.emptyMap();
122+
} else {
123+
mapaNovasCoordenadasPorLinha = todasCoordenadasNovas.stream()
124+
.collect(Collectors.toMap(
125+
CoordenadaDTO::getNumeroVeiculo,
126+
Function.identity(),
127+
BinaryOperator.maxBy(Comparator.comparing(CoordenadaDTO::getHorario))
128+
))
129+
.values().stream()
130+
.filter(c -> c.getNumeroLinha() != null)
131+
.collect(Collectors.groupingBy(CoordenadaDTO::getNumeroLinha));
115132
}
116133

117-
// Agrupa as coordenadas mais recentes por número de linha
118-
Map<Integer, List<CoordenadaDTO>> coordenadasPorLinha = coordenadas.stream()
119-
.collect(Collectors.toMap(
120-
CoordenadaDTO::getNumeroVeiculo,
121-
Function.identity(),
122-
BinaryOperator.maxBy(Comparator.comparing(CoordenadaDTO::getHorario))
123-
))
124-
.values().stream()
125-
.filter(c -> c.getNumeroLinha() != null)
126-
.collect(Collectors.groupingBy(CoordenadaDTO::getNumeroLinha));
127-
128-
// Atualiza as linhas existentes com as novas coordenadas
129-
List<LinhaEntity> linhasParaSalvar = linhasExistentes.stream()
130-
.filter(linha -> coordenadasPorLinha.containsKey(linha.getNumeroLinha()))
131-
.peek(linha -> {
132-
List<CoordenadaDTO> coordenadasDaLinha = coordenadasPorLinha.get(linha.getNumeroLinha());
133-
linha.setCoordenadas(coordenadasDaLinha);
134-
135-
List<Character> sentidos = coordenadasDaLinha.stream()
136-
.map(CoordenadaDTO::getSentido)
137-
.filter(sentido -> sentido != null && sentido != '0')
138-
.distinct()
139-
.toList();
134+
LocalDateTime dataLimite = LocalDateTime.now().minusMinutes(ttlMinutes);
135+
List<LinhaEntity> linhasParaSalvar = new ArrayList<>();
136+
137+
for (LinhaEntity linha : linhasExistentes) {
138+
boolean houveAlteracao = false;
139+
140+
// Mapa de veículos atuais da linha (NumeroVeiculo -> DTO)
141+
Map<String, CoordenadaDTO> veiculosMap = new HashMap<>();
142+
if (linha.getCoordenadas() != null) {
143+
for (CoordenadaDTO c : linha.getCoordenadas()) {
144+
if (c.getNumeroVeiculo() != null) {
145+
veiculosMap.put(c.getNumeroVeiculo(), c);
146+
}
147+
}
148+
}
149+
150+
// Merge com as novas coordenadas (se houver para esta linha)
151+
List<CoordenadaDTO> novasDaLinha = mapaNovasCoordenadasPorLinha.get(linha.getNumeroLinha());
152+
if (novasDaLinha != null) {
153+
for (CoordenadaDTO nova : novasDaLinha) {
154+
veiculosMap.put(nova.getNumeroVeiculo(), nova);
155+
houveAlteracao = true;
156+
}
157+
}
140158

141-
linha.setSentidoIsUnique(!sentidos.isEmpty() && sentidos.size() == 1);
142-
})
143-
.toList();
159+
// Filtragem por TTL (remove veículos antigos)
160+
int tamanhoAntes = veiculosMap.size();
161+
List<CoordenadaDTO> veiculosAtualizados = veiculosMap.values().stream()
162+
.filter(c -> c.getHorario() != null && c.getHorario().isAfter(dataLimite))
163+
.collect(Collectors.toList());
164+
165+
if (tamanhoAntes != veiculosAtualizados.size()) houveAlteracao = true;
166+
167+
if (houveAlteracao) {
168+
linha.setCoordenadas(veiculosAtualizados);
169+
170+
List<Character> sentidos = veiculosAtualizados.stream()
171+
.map(CoordenadaDTO::getSentido)
172+
.filter(sentido -> sentido != null && sentido != '0')
173+
.distinct()
174+
.toList();
175+
176+
linha.setSentidoIsUnique(!sentidos.isEmpty() && sentidos.size() == 1);
177+
178+
linhasParaSalvar.add(linha);
179+
}
180+
}
144181

145182
if (!linhasParaSalvar.isEmpty()) {
146183
linhasRepository.saveAll(linhasParaSalvar);
147-
logger.info("Coordenadas salvas com sucesso. Total de linhas atualizadas: {}", linhasParaSalvar.size());
184+
logger.info("Sincronização concluída. Linhas atualizadas: {}", linhasParaSalvar.size());
148185
} else {
149-
logger.info("Nenhuma linha com novas coordenadas para atualizar.");
186+
logger.info("Nenhuma alteração necessária nas linhas.");
150187
}
151188
}
152189

src/main/resources/application.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ spring.data.mongodb.auto-index-creation=true
77
spring.data.mongodb.authentication-database=admin
88
# File
99
BASE_PATH=src/data/coordenadas
10-
FILE_NAME=coordenadas.json
10+
FILE_NAME=coordenadas.json
11+
# Business
12+
api.onibus.coordenadas.ttl-minutes=20

0 commit comments

Comments
 (0)