Skip to content

Commit 7183a30

Browse files
committed
Enables caching and improves data fetching
Adds Spring Boot's caching abstraction to improve the performance of data fetching operations. Implements caching for Dicionario and Linhas endpoints to reduce the load on the external API and database. The cache is automatically evicted based on configured schedules and when data changes. Adds cache annotations and configuration. Also updates controller injection to constructor injection
1 parent d819612 commit 7183a30

22 files changed

+332
-325
lines changed

pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@
9494
<artifactId>bucket4j-core</artifactId>
9595
<version>8.10.1</version>
9696
</dependency>
97+
<dependency>
98+
<groupId>org.springframework.boot</groupId>
99+
<artifactId>spring-boot-starter-cache</artifactId>
100+
</dependency>
97101
</dependencies>
98102

99103
<build>

src/main/java/com/dmware/api_onibusbh/ApiOnibusbhApplication.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import io.swagger.v3.oas.annotations.info.Info;
55
import org.springframework.boot.SpringApplication;
66
import org.springframework.boot.autoconfigure.SpringBootApplication;
7+
import org.springframework.cache.annotation.EnableCaching;
78
import org.springframework.scheduling.annotation.EnableScheduling;
89

910
@SpringBootApplication
1011
@EnableScheduling
12+
@EnableCaching
1113
@OpenAPIDefinition(info = @Info(title = "API Onibus BH", version = "1.0", description = "API para consulta de dados relacionados aos onibus de Belo Horizonte"))
1214
public class ApiOnibusbhApplication {
1315

src/main/java/com/dmware/api_onibusbh/config/AsyncConfiguration.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
@Configuration
99
@EnableAsync
1010
public class AsyncConfiguration {
11-
@Bean
12-
public ThreadPoolTaskExecutor asyncTaskExecutor() {
13-
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
14-
executor.setCorePoolSize(5);
15-
executor.setMaxPoolSize(10);
16-
executor.setQueueCapacity(25);
17-
executor.setThreadNamePrefix("AsyncTask-");
18-
executor.initialize();
19-
return executor;
20-
}
11+
@Bean
12+
public ThreadPoolTaskExecutor asyncTaskExecutor() {
13+
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
14+
executor.setCorePoolSize(5);
15+
executor.setMaxPoolSize(10);
16+
executor.setQueueCapacity(25);
17+
executor.setThreadNamePrefix("AsyncTask-");
18+
executor.initialize();
19+
return executor;
20+
}
2121
}

src/main/java/com/dmware/api_onibusbh/config/ModelMapperConfig.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
@Configuration
88
public class ModelMapperConfig {
9-
@Bean
10-
public ModelMapper modelMapper() {
11-
return new ModelMapper();
12-
}
9+
@Bean
10+
public ModelMapper modelMapper() {
11+
return new ModelMapper();
12+
}
1313
}

src/main/java/com/dmware/api_onibusbh/config/RequestLoggingFilter.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
3131
if (transactionId == null || transactionId.isEmpty()) {
3232
transactionId = UUID.randomUUID().toString();
3333
}
34-
34+
3535
MDC.put(TRANSACTION_ID_KEY, transactionId);
3636

3737
try {
@@ -45,11 +45,11 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
4545
filterChain.doFilter(request, response);
4646

4747
long duration = System.currentTimeMillis() - startTime;
48-
49-
logger.info("Requisição finalizada: {} {} - Status: {} - Tempo: {}ms",
50-
request.getMethod(),
51-
request.getRequestURI(),
52-
response.getStatus(),
48+
49+
logger.info("Requisição finalizada: {} {} - Status: {} - Tempo: {}ms",
50+
request.getMethod(),
51+
request.getRequestURI(),
52+
response.getStatus(),
5353
duration,
5454
kv("status_code", response.getStatus()),
5555
kv("duration_ms", duration)

src/main/java/com/dmware/api_onibusbh/controllers/DicionarioController.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
package com.dmware.api_onibusbh.controllers;
22

3-
import java.util.List;
4-
5-
import org.springframework.beans.factory.annotation.Autowired;
6-
import org.springframework.http.HttpStatus;
7-
import org.springframework.http.ResponseEntity;
8-
import org.springframework.web.bind.annotation.GetMapping;
9-
import org.springframework.web.bind.annotation.RequestMapping;
10-
import org.springframework.web.bind.annotation.RestController;
11-
123
import com.dmware.api_onibusbh.dto.DicionarioDTO;
134
import com.dmware.api_onibusbh.infra.CustomApiResponse;
145
import com.dmware.api_onibusbh.services.DicionarioService;
15-
166
import io.swagger.v3.oas.annotations.Operation;
177
import io.swagger.v3.oas.annotations.responses.ApiResponse;
188
import io.swagger.v3.oas.annotations.responses.ApiResponses;
199
import io.swagger.v3.oas.annotations.tags.Tag;
10+
import org.springframework.http.HttpStatus;
11+
import org.springframework.http.ResponseEntity;
12+
import org.springframework.web.bind.annotation.GetMapping;
13+
import org.springframework.web.bind.annotation.RequestMapping;
14+
import org.springframework.web.bind.annotation.RestController;
15+
16+
import java.util.List;
2017

2118
@RestController
2219
@RequestMapping(path = "/api/v1/dicionario")
2320
@Tag(name = "Dicionário", description = "Dicionário de dados para as coordenadas")
2421
public class DicionarioController {
2522

26-
@Autowired
27-
private DicionarioService dicionarioService;
23+
private final DicionarioService dicionarioService;
24+
25+
public DicionarioController(DicionarioService dicionarioService) {
26+
this.dicionarioService = dicionarioService;
27+
}
2828

2929
@Operation(summary = "Retorna o dicionário para as siglas utilizadas na listagem de coordenadas")
3030
@ApiResponses(value = {
Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,66 @@
11
package com.dmware.api_onibusbh.controllers;
22

3-
import java.util.List;
4-
5-
import org.springframework.beans.factory.annotation.Autowired;
6-
import org.springframework.http.HttpStatus;
7-
import org.springframework.http.ResponseEntity;
8-
import org.springframework.web.bind.annotation.GetMapping;
9-
import org.springframework.web.bind.annotation.PathVariable;
10-
import org.springframework.web.bind.annotation.RequestMapping;
11-
import org.springframework.web.bind.annotation.RestController;
12-
133
import com.dmware.api_onibusbh.dto.LinhaDTO;
144
import com.dmware.api_onibusbh.infra.CustomApiResponse;
155
import com.dmware.api_onibusbh.infra.ErrorResponse;
166
import com.dmware.api_onibusbh.services.LinhasService;
17-
187
import io.swagger.v3.oas.annotations.Operation;
198
import io.swagger.v3.oas.annotations.media.Content;
209
import io.swagger.v3.oas.annotations.media.Schema;
2110
import io.swagger.v3.oas.annotations.responses.ApiResponse;
2211
import io.swagger.v3.oas.annotations.responses.ApiResponses;
2312
import io.swagger.v3.oas.annotations.tags.Tag;
13+
import org.springframework.http.HttpStatus;
14+
import org.springframework.http.ResponseEntity;
15+
import org.springframework.web.bind.annotation.GetMapping;
16+
import org.springframework.web.bind.annotation.PathVariable;
17+
import org.springframework.web.bind.annotation.RequestMapping;
18+
import org.springframework.web.bind.annotation.RestController;
19+
20+
import java.util.List;
2421

2522
@RestController
2623
@RequestMapping(path = "/api/v1/linhas", produces = "application/json")
2724
@Tag(name = "Linhas", description = "API para listagem de linhas")
2825
public class LinhasController {
2926

30-
@Autowired
31-
private LinhasService linhasService;
27+
private final LinhasService linhasService;
28+
29+
public LinhasController(LinhasService linhasService) {
30+
this.linhasService = linhasService;
31+
}
3232

33-
@Operation(summary = "Listar todas as linhas")
34-
@ApiResponses(value = {
35-
@ApiResponse(responseCode = "200", description = "Linhas listadas"),
36-
@ApiResponse(responseCode = "404", description = "Nenhuma linha encontrada", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
37-
})
38-
@GetMapping("/")
39-
public ResponseEntity<CustomApiResponse<List<LinhaDTO>>> listarLinhas() {
40-
return CustomApiResponse.of("Lista de linhas", HttpStatus.OK, linhasService.fetchLinhas());
41-
}
33+
@Operation(summary = "Listar todas as linhas")
34+
@ApiResponses(value = {
35+
@ApiResponse(responseCode = "200", description = "Linhas listadas"),
36+
@ApiResponse(responseCode = "404", description = "Nenhuma linha encontrada", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
37+
})
38+
@GetMapping("/")
39+
public ResponseEntity<CustomApiResponse<List<LinhaDTO>>> listarLinhas() {
40+
return CustomApiResponse.of("Lista de linhas", HttpStatus.OK, linhasService.fetchLinhas());
41+
}
4242

43-
@Operation(summary = "Listar todas as linhas com coordenadas não vazias")
44-
@ApiResponses(value = {
45-
@ApiResponse(responseCode = "200", description = "Linhas com coordenadas listadas"),
46-
@ApiResponse(responseCode = "404", description = "Nenhuma linha com coordenadas encontrada", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
47-
})
48-
@GetMapping("/coordenadas")
49-
public ResponseEntity<CustomApiResponse<List<LinhaDTO>>> listarLinhasComCoordenadas() {
50-
return CustomApiResponse.of(
51-
"Lista de linhas com coordenadas",
52-
HttpStatus.OK,
53-
linhasService.fetchLinhasCoordenadasNotEmpty());
54-
}
43+
@Operation(summary = "Listar todas as linhas com coordenadas não vazias")
44+
@ApiResponses(value = {
45+
@ApiResponse(responseCode = "200", description = "Linhas com coordenadas listadas"),
46+
@ApiResponse(responseCode = "404", description = "Nenhuma linha com coordenadas encontrada", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
47+
})
48+
@GetMapping("/coordenadas")
49+
public ResponseEntity<CustomApiResponse<List<LinhaDTO>>> listarLinhasComCoordenadas() {
50+
return CustomApiResponse.of(
51+
"Lista de linhas com coordenadas",
52+
HttpStatus.OK,
53+
linhasService.fetchLinhasCoordenadasNotEmpty());
54+
}
5555

56-
@Operation(summary = "Listar uma linha pelo número")
57-
@ApiResponses(value = {
58-
@ApiResponse(responseCode = "200", description = "Linha listada"),
59-
@ApiResponse(responseCode = "404", description = "Nenhuma linha encontrada", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
60-
})
61-
@GetMapping("/{numeroLinha}")
62-
public ResponseEntity<CustomApiResponse<LinhaDTO>> listarLinhaPorNumero(
63-
@PathVariable("numeroLinha") Integer numeroLinha) {
64-
return CustomApiResponse.of("Linha", HttpStatus.OK, linhasService.listarLinhaPorNumero(numeroLinha));
65-
}
56+
@Operation(summary = "Listar uma linha pelo número")
57+
@ApiResponses(value = {
58+
@ApiResponse(responseCode = "200", description = "Linha listada"),
59+
@ApiResponse(responseCode = "404", description = "Nenhuma linha encontrada", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
60+
})
61+
@GetMapping("/{numeroLinha}")
62+
public ResponseEntity<CustomApiResponse<LinhaDTO>> listarLinhaPorNumero(
63+
@PathVariable("numeroLinha") Integer numeroLinha) {
64+
return CustomApiResponse.of("Linha", HttpStatus.OK, linhasService.listarLinhaPorNumero(numeroLinha));
65+
}
6666
}
Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,57 @@
11
package com.dmware.api_onibusbh.controllers;
22

3-
import java.util.List;
4-
import java.util.Optional;
5-
6-
import org.springframework.beans.factory.annotation.Autowired;
7-
import org.springframework.http.HttpStatus;
8-
import org.springframework.http.ResponseEntity;
9-
import org.springframework.web.bind.annotation.GetMapping;
10-
import org.springframework.web.bind.annotation.PathVariable;
11-
import org.springframework.web.bind.annotation.RequestMapping;
12-
import org.springframework.web.bind.annotation.RestController;
13-
143
import com.dmware.api_onibusbh.dto.CoordenadaDTO;
154
import com.dmware.api_onibusbh.dto.OnibusDTO;
165
import com.dmware.api_onibusbh.infra.CustomApiResponse;
176
import com.dmware.api_onibusbh.infra.ErrorResponse;
187
import com.dmware.api_onibusbh.services.OnibusService;
19-
208
import io.swagger.v3.oas.annotations.Operation;
219
import io.swagger.v3.oas.annotations.media.Content;
2210
import io.swagger.v3.oas.annotations.media.Schema;
2311
import io.swagger.v3.oas.annotations.responses.ApiResponse;
2412
import io.swagger.v3.oas.annotations.responses.ApiResponses;
2513
import io.swagger.v3.oas.annotations.tags.Tag;
14+
import org.springframework.http.HttpStatus;
15+
import org.springframework.http.ResponseEntity;
16+
import org.springframework.web.bind.annotation.GetMapping;
17+
import org.springframework.web.bind.annotation.PathVariable;
18+
import org.springframework.web.bind.annotation.RequestMapping;
19+
import org.springframework.web.bind.annotation.RestController;
20+
21+
import java.util.List;
22+
import java.util.Optional;
2623

2724
@RestController
2825
@RequestMapping(path = "/api/v1/onibus", produces = "application/json")
2926
@Tag(name = "Onibus", description = "API para buscar as coordenadas dos veículos")
3027
public class OnibusController {
3128

32-
@Autowired
33-
private OnibusService onibusService;
34-
35-
@Operation(summary = "Listar todos as coordenadas, por linha")
36-
@ApiResponses(value = {
37-
@ApiResponse(responseCode = "200", description = "Coordenadas listadas"),
38-
@ApiResponse(responseCode = "404", description = "Nenhuma coordenada encontrada", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
39-
})
40-
@GetMapping("/")
41-
public ResponseEntity<CustomApiResponse<List<OnibusDTO>>> listarOnibus() {
42-
return CustomApiResponse.of("Lista de Onibus", HttpStatus.OK, onibusService.listarTodosOnibus());
43-
}
44-
45-
@Operation(summary = "Listar as coordenadas de uma linha")
46-
@ApiResponses(value = {
47-
@ApiResponse(responseCode = "200", description = "Coordenadas listadas"),
48-
@ApiResponse(responseCode = "404", description = "Nenhuma coordenada encontrada", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
49-
})
50-
@GetMapping(value = { "/linha/{numeroLinha}", "/linha/{numeroLinha}/{sentido}" })
51-
public ResponseEntity<CustomApiResponse<List<CoordenadaDTO>>> listarOnibusPorLinha(
52-
@PathVariable("numeroLinha") Integer numeroLinha,
53-
@PathVariable("sentido") Optional<Integer> sentido) {
54-
return CustomApiResponse.of("Coordenadas da linha", HttpStatus.OK,
55-
onibusService.listarPorNumeroLinha(numeroLinha, sentido));
56-
}
29+
private final OnibusService onibusService;
30+
31+
public OnibusController(OnibusService onibusService) {
32+
this.onibusService = onibusService;
33+
}
34+
35+
@Operation(summary = "Listar todos as coordenadas, por linha")
36+
@ApiResponses(value = {
37+
@ApiResponse(responseCode = "200", description = "Coordenadas listadas"),
38+
@ApiResponse(responseCode = "404", description = "Nenhuma coordenada encontrada", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
39+
})
40+
@GetMapping("/")
41+
public ResponseEntity<CustomApiResponse<List<OnibusDTO>>> listarOnibus() {
42+
return CustomApiResponse.of("Lista de Onibus", HttpStatus.OK, onibusService.listarTodosOnibus());
43+
}
44+
45+
@Operation(summary = "Listar as coordenadas de uma linha")
46+
@ApiResponses(value = {
47+
@ApiResponse(responseCode = "200", description = "Coordenadas listadas"),
48+
@ApiResponse(responseCode = "404", description = "Nenhuma coordenada encontrada", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
49+
})
50+
@GetMapping(value = {"/linha/{numeroLinha}", "/linha/{numeroLinha}/{sentido}"})
51+
public ResponseEntity<CustomApiResponse<List<CoordenadaDTO>>> listarOnibusPorLinha(
52+
@PathVariable("numeroLinha") Integer numeroLinha,
53+
@PathVariable("sentido") Optional<Integer> sentido) {
54+
return CustomApiResponse.of("Coordenadas da linha", HttpStatus.OK,
55+
onibusService.listarPorNumeroLinha(numeroLinha, sentido));
56+
}
5757
}

0 commit comments

Comments
 (0)