├── .github
└── workflows
│ └── maven.yml
├── .gitignore
├── APIs_REST.postman_collection.json
├── cap01
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── app
│ │ │ └── car
│ │ │ └── cap01
│ │ │ ├── Cap01Application.java
│ │ │ ├── domain
│ │ │ ├── Driver.java
│ │ │ └── DriverRepository.java
│ │ │ └── interfaces
│ │ │ └── DriverAPI.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── app
│ └── car
│ └── cap01
│ └── Cap01ApplicationTests.java
├── cap02
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── app
│ │ │ └── car
│ │ │ └── cap02
│ │ │ ├── Cap02Application.java
│ │ │ ├── domain
│ │ │ ├── Driver.java
│ │ │ └── DriverRepository.java
│ │ │ └── interfaces
│ │ │ └── DriverAPI.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── app
│ └── car
│ └── cap02
│ └── Cap02ApplicationTests.java
├── cap03
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── app
│ │ │ └── car
│ │ │ └── cap03
│ │ │ ├── Cap03Application.java
│ │ │ ├── domain
│ │ │ ├── Driver.java
│ │ │ ├── DriverRepository.java
│ │ │ ├── Passenger.java
│ │ │ ├── PassengerRepository.java
│ │ │ ├── TravelRequest.java
│ │ │ ├── TravelRequestRepository.java
│ │ │ ├── TravelRequestStatus.java
│ │ │ └── TravelService.java
│ │ │ └── interfaces
│ │ │ ├── DriverAPI.java
│ │ │ ├── PassengerAPI.java
│ │ │ ├── TravelRequestAPI.java
│ │ │ ├── input
│ │ │ └── TravelRequestInput.java
│ │ │ ├── mapping
│ │ │ └── TravelRequestMapper.java
│ │ │ └── output
│ │ │ └── TravelRequestOutput.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── app
│ └── car
│ └── cap03
│ └── Cap03ApplicationTests.java
├── cap04
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── app
│ │ │ └── car
│ │ │ └── cap04
│ │ │ ├── Cap04Application.java
│ │ │ ├── domain
│ │ │ ├── Driver.java
│ │ │ ├── DriverRepository.java
│ │ │ ├── Passenger.java
│ │ │ ├── PassengerRepository.java
│ │ │ ├── TravelRequest.java
│ │ │ ├── TravelRequestRepository.java
│ │ │ ├── TravelRequestStatus.java
│ │ │ └── TravelService.java
│ │ │ └── interfaces
│ │ │ ├── incoming
│ │ │ ├── DriverAPI.java
│ │ │ ├── PassengerAPI.java
│ │ │ ├── TravelRequestAPI.java
│ │ │ ├── input
│ │ │ │ └── TravelRequestInput.java
│ │ │ ├── mapping
│ │ │ │ └── TravelRequestMapper.java
│ │ │ └── output
│ │ │ │ └── TravelRequestOutput.java
│ │ │ └── outcoming
│ │ │ └── GMapsService.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── app
│ └── car
│ └── cap04
│ └── Cap04ApplicationTests.java
├── cap05
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── app
│ │ │ └── car
│ │ │ └── cap05
│ │ │ ├── Cap05Application.java
│ │ │ ├── domain
│ │ │ ├── Driver.java
│ │ │ ├── DriverRepository.java
│ │ │ ├── Passenger.java
│ │ │ ├── PassengerRepository.java
│ │ │ ├── TravelRequest.java
│ │ │ ├── TravelRequestRepository.java
│ │ │ ├── TravelRequestStatus.java
│ │ │ └── TravelService.java
│ │ │ └── interfaces
│ │ │ ├── incoming
│ │ │ ├── DriverAPI.java
│ │ │ ├── PassengerAPI.java
│ │ │ ├── TravelRequestAPI.java
│ │ │ ├── input
│ │ │ │ └── TravelRequestInput.java
│ │ │ ├── mapping
│ │ │ │ └── TravelRequestMapper.java
│ │ │ └── output
│ │ │ │ └── TravelRequestOutput.java
│ │ │ └── outcoming
│ │ │ └── GMapsService.java
│ └── resources
│ │ └── application.properties
│ └── test
│ ├── java
│ └── app
│ │ └── car
│ │ └── cap05
│ │ ├── Cap05ApplicationTests.java
│ │ ├── infrastructure
│ │ └── FileUtils.java
│ │ └── interfaces
│ │ └── incoming
│ │ ├── PassengerAPITestIT.java
│ │ └── TravelRequestAPITestIT.java
│ └── resources
│ ├── application-test.properties
│ ├── requests
│ ├── passengers_api
│ │ └── create_new_passenger.json
│ └── travel_requests_api
│ │ └── create_new_request.json
│ └── responses
│ └── gmaps
│ └── sample_response.json
├── cap06
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── app
│ │ │ └── car
│ │ │ └── cap06
│ │ │ ├── Cap06Application.java
│ │ │ ├── config
│ │ │ ├── LoadUserConfig.java
│ │ │ └── SecurityConfig.java
│ │ │ ├── domain
│ │ │ ├── Driver.java
│ │ │ ├── DriverRepository.java
│ │ │ ├── Passenger.java
│ │ │ ├── PassengerRepository.java
│ │ │ ├── TravelRequest.java
│ │ │ ├── TravelRequestRepository.java
│ │ │ ├── TravelRequestStatus.java
│ │ │ ├── TravelService.java
│ │ │ ├── User.java
│ │ │ └── UserRepository.java
│ │ │ └── interfaces
│ │ │ ├── incoming
│ │ │ ├── DriverAPI.java
│ │ │ ├── PassengerAPI.java
│ │ │ ├── TravelRequestAPI.java
│ │ │ ├── input
│ │ │ │ └── TravelRequestInput.java
│ │ │ ├── mapping
│ │ │ │ └── TravelRequestMapper.java
│ │ │ └── output
│ │ │ │ └── TravelRequestOutput.java
│ │ │ └── outcoming
│ │ │ └── GMapsService.java
│ └── resources
│ │ ├── application.properties
│ │ └── keystore.p12
│ └── test
│ ├── java
│ └── app
│ │ └── car
│ │ └── cap06
│ │ ├── Cap06ApplicationTests.java
│ │ ├── infrastructure
│ │ └── FileUtils.java
│ │ └── interfaces
│ │ └── incoming
│ │ ├── PassengerAPITestIT.java
│ │ └── TravelRequestAPITestIT.java
│ └── resources
│ ├── application-test.properties
│ ├── requests
│ ├── passengers_api
│ │ └── create_new_passenger.json
│ └── travel_requests_api
│ │ └── create_new_request.json
│ └── responses
│ └── gmaps
│ └── sample_response.json
├── cap07
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── app
│ │ │ └── car
│ │ │ └── cap07
│ │ │ ├── Cap07Application.java
│ │ │ ├── config
│ │ │ ├── AppConfig.java
│ │ │ ├── LoadUserConfig.java
│ │ │ └── SecurityConfig.java
│ │ │ ├── domain
│ │ │ ├── Driver.java
│ │ │ ├── DriverRepository.java
│ │ │ ├── Passenger.java
│ │ │ ├── PassengerRepository.java
│ │ │ ├── TravelRequest.java
│ │ │ ├── TravelRequestRepository.java
│ │ │ ├── TravelRequestStatus.java
│ │ │ ├── TravelService.java
│ │ │ ├── User.java
│ │ │ └── UserRepository.java
│ │ │ └── interfaces
│ │ │ ├── incoming
│ │ │ ├── DriverAPI.java
│ │ │ ├── PassengerAPI.java
│ │ │ ├── TravelRequestAPI.java
│ │ │ ├── errorhandling
│ │ │ │ ├── DefaultErrorHandler.java
│ │ │ │ ├── ErrorData.java
│ │ │ │ ├── ErrorResponse.java
│ │ │ │ └── LocaleResolver.java
│ │ │ ├── input
│ │ │ │ └── TravelRequestInput.java
│ │ │ ├── mapping
│ │ │ │ └── TravelRequestMapper.java
│ │ │ └── output
│ │ │ │ └── TravelRequestOutput.java
│ │ │ └── outcoming
│ │ │ └── GMapsService.java
│ └── resources
│ │ ├── application.properties
│ │ ├── i18n
│ │ ├── messages_en.properties
│ │ └── messages_pt_BR.properties
│ │ └── keystore.p12
│ └── test
│ ├── java
│ └── app
│ │ └── car
│ │ └── cap07
│ │ ├── Cap07ApplicationTests.java
│ │ ├── infrastructure
│ │ └── FileUtils.java
│ │ └── interfaces
│ │ └── incoming
│ │ ├── PassengerAPITestIT.java
│ │ └── TravelRequestAPITestIT.java
│ └── resources
│ ├── application-test.properties
│ ├── requests
│ ├── passengers_api
│ │ └── create_new_passenger.json
│ └── travel_requests_api
│ │ └── create_new_request.json
│ └── responses
│ └── gmaps
│ └── sample_response.json
├── cap08
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── app
│ │ │ └── car
│ │ │ └── cap08
│ │ │ ├── Cap08Application.java
│ │ │ ├── config
│ │ │ ├── AppConfig.java
│ │ │ ├── LoadUserConfig.java
│ │ │ ├── OpenAPIConfig.java
│ │ │ └── SecurityConfig.java
│ │ │ ├── domain
│ │ │ ├── Driver.java
│ │ │ ├── DriverRepository.java
│ │ │ ├── Passenger.java
│ │ │ ├── PassengerRepository.java
│ │ │ ├── TravelRequest.java
│ │ │ ├── TravelRequestRepository.java
│ │ │ ├── TravelRequestStatus.java
│ │ │ ├── TravelService.java
│ │ │ ├── User.java
│ │ │ └── UserRepository.java
│ │ │ └── interfaces
│ │ │ ├── incoming
│ │ │ ├── DriverAPI.java
│ │ │ ├── DriverAPIImpl.java
│ │ │ ├── PassengerAPI.java
│ │ │ ├── TravelRequestAPI.java
│ │ │ ├── errorhandling
│ │ │ │ ├── DefaultErrorHandler.java
│ │ │ │ ├── ErrorData.java
│ │ │ │ ├── ErrorResponse.java
│ │ │ │ └── LocaleResolver.java
│ │ │ ├── input
│ │ │ │ └── TravelRequestInput.java
│ │ │ ├── mapping
│ │ │ │ └── TravelRequestMapper.java
│ │ │ └── output
│ │ │ │ └── TravelRequestOutput.java
│ │ │ └── outcoming
│ │ │ └── GMapsService.java
│ └── resources
│ │ ├── application.properties
│ │ ├── i18n
│ │ ├── messages_en.properties
│ │ └── messages_pt_BR.properties
│ │ └── keystore.p12
│ └── test
│ ├── java
│ └── app
│ │ └── car
│ │ └── cap08
│ │ ├── Cap08ApplicationTests.java
│ │ ├── infrastructure
│ │ └── FileUtils.java
│ │ └── interfaces
│ │ └── incoming
│ │ ├── PassengerAPITestIT.java
│ │ └── TravelRequestAPITestIT.java
│ └── resources
│ ├── application-test.properties
│ ├── requests
│ ├── passengers_api
│ │ └── create_new_passenger.json
│ └── travel_requests_api
│ │ └── create_new_request.json
│ └── responses
│ └── gmaps
│ └── sample_response.json
└── cap09
├── .gitignore
├── .mvn
└── wrapper
│ ├── MavenWrapperDownloader.java
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
├── java
│ └── app
│ │ └── car
│ │ └── cap09
│ │ ├── Cap09Application.java
│ │ ├── config
│ │ ├── AppConfig.java
│ │ ├── LoadUserConfig.java
│ │ ├── OpenAPIConfig.java
│ │ └── SecurityConfig.java
│ │ ├── domain
│ │ ├── Driver.java
│ │ ├── DriverRepository.java
│ │ ├── Passenger.java
│ │ ├── PassengerRepository.java
│ │ ├── TravelRequest.java
│ │ ├── TravelRequestRepository.java
│ │ ├── TravelRequestStatus.java
│ │ ├── TravelService.java
│ │ ├── User.java
│ │ └── UserRepository.java
│ │ └── interfaces
│ │ ├── incoming
│ │ ├── DriverAPI.java
│ │ ├── DriverAPIImpl.java
│ │ ├── PassengerAPI.java
│ │ ├── TravelRequestAPI.java
│ │ ├── errorhandling
│ │ │ ├── DefaultErrorHandler.java
│ │ │ ├── ErrorData.java
│ │ │ ├── ErrorResponse.java
│ │ │ └── LocaleResolver.java
│ │ ├── input
│ │ │ └── TravelRequestInput.java
│ │ ├── mapping
│ │ │ └── TravelRequestMapper.java
│ │ └── output
│ │ │ ├── Drivers.java
│ │ │ └── TravelRequestOutput.java
│ │ └── outcoming
│ │ └── GMapsService.java
└── resources
│ ├── application.properties
│ ├── i18n
│ ├── messages_en.properties
│ └── messages_pt_BR.properties
│ └── keystore.p12
└── test
├── java
└── app
│ └── car
│ └── cap09
│ ├── Cap09ApplicationTests.java
│ ├── infrastructure
│ └── FileUtils.java
│ └── interfaces
│ └── incoming
│ ├── PassengerAPITestIT.java
│ └── TravelRequestAPITestIT.java
└── resources
├── application-test.properties
├── requests
├── passengers_api
│ └── create_new_passenger.json
└── travel_requests_api
│ └── create_new_request.json
└── responses
└── gmaps
└── sample_response.json
/.github/workflows/maven.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3 |
4 | name: Java CI with Maven
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 | pull_request:
10 | branches: [ master ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | - uses: actions/checkout@v2
19 | - name: Set up JDK 21
20 | uses: actions/setup-java@v1
21 | with:
22 | java-version: 21
23 | - name: Build with Maven
24 | run: mvn -B verify --file cap01/pom.xml ; mvn -B verify --file cap02/pom.xml; mvn -B verify --file cap03/pom.xml; mvn -B verify --file cap04/pom.xml; mvn -B verify --file cap05/pom.xml; mvn -B verify --file cap06/pom.xml; mvn -B verify --file cap07/pom.xml; mvn -B verify --file cap08/pom.xml; mvn -B verify --file cap09/pom.xml
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Eclipse
2 | .classpath
3 | .project
4 | .settings/
5 |
6 | # Intellij
7 | .idea/
8 | *.iml
9 | *.iws
10 |
11 | # Mac
12 | .DS_Store
13 |
14 | # Maven
15 | log/
16 | target/
17 |
18 | chaveGoogle.txt
19 |
--------------------------------------------------------------------------------
/cap01/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/cap01/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap01/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/cap01/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/cap01/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.3.1
9 |
10 |
11 | app.car
12 | cap01
13 | 0.0.1-SNAPSHOT
14 | cap01
15 | Demo project for Spring Boot
16 |
17 |
18 | 21
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-data-jpa
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-web
29 |
30 |
31 | org.projectlombok
32 | lombok
33 | true
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-devtools
38 | true
39 |
40 |
41 |
42 | com.h2database
43 | h2
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter-test
49 | test
50 |
51 |
52 | org.junit.vintage
53 | junit-vintage-engine
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | org.springframework.boot
63 | spring-boot-maven-plugin
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/cap01/src/main/java/app/car/cap01/Cap01Application.java:
--------------------------------------------------------------------------------
1 | package app.car.cap01;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Cap01Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Cap01Application.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap01/src/main/java/app/car/cap01/domain/Driver.java:
--------------------------------------------------------------------------------
1 | package app.car.cap01.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.Id;
5 | import lombok.Data;
6 |
7 | import java.time.LocalDate;
8 |
9 | @Data
10 | @Entity
11 | public class Driver {
12 |
13 |
14 | @Id
15 | Long id;
16 | String name;
17 | LocalDate birthDate;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/cap01/src/main/java/app/car/cap01/domain/DriverRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap01.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface DriverRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap01/src/main/java/app/car/cap01/interfaces/DriverAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap01.interfaces;
2 |
3 | import app.car.cap01.domain.Driver;
4 | import app.car.cap01.domain.DriverRepository;
5 | import java.util.List;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.http.MediaType;
8 | import org.springframework.stereotype.Service;
9 | import org.springframework.web.bind.annotation.GetMapping;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RestController;
12 |
13 | @Service
14 | @RestController()
15 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
16 | public class DriverAPI {
17 |
18 | @Autowired
19 | DriverRepository driverRepository;
20 |
21 | @GetMapping("/drivers")
22 | public List listDrivers() {
23 | return driverRepository.findAll();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/cap01/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/cap01/src/test/java/app/car/cap01/Cap01ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package app.car.cap01;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class Cap01ApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap02/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/cap02/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap02/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/cap02/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/cap02/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.3.1
9 |
10 |
11 | app.car
12 | cap02
13 | 0.0.1-SNAPSHOT
14 | cap02
15 | Demo project for Spring Boot
16 |
17 |
18 | 21
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-data-jpa
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-web
29 |
30 |
31 | org.projectlombok
32 | lombok
33 | true
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-devtools
38 | true
39 |
40 |
41 |
42 | com.h2database
43 | h2
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter-test
49 | test
50 |
51 |
52 | org.junit.vintage
53 | junit-vintage-engine
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | org.springframework.boot
63 | spring-boot-maven-plugin
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/cap02/src/main/java/app/car/cap02/Cap02Application.java:
--------------------------------------------------------------------------------
1 | package app.car.cap02;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Cap02Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Cap02Application.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap02/src/main/java/app/car/cap02/domain/Driver.java:
--------------------------------------------------------------------------------
1 | package app.car.cap02.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 | import java.time.LocalDate;
9 |
10 | @Data
11 | @Entity
12 | public class Driver {
13 |
14 |
15 | @Id
16 | @GeneratedValue
17 | Long id;
18 | String name;
19 | LocalDate birthDate;
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/cap02/src/main/java/app/car/cap02/domain/DriverRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap02.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface DriverRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap02/src/main/java/app/car/cap02/interfaces/DriverAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap02.interfaces;
2 |
3 | import app.car.cap02.domain.Driver;
4 | import app.car.cap02.domain.DriverRepository;
5 | import java.util.List;
6 | import java.util.Optional;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.stereotype.Service;
11 | import org.springframework.web.bind.annotation.DeleteMapping;
12 | import org.springframework.web.bind.annotation.GetMapping;
13 | import org.springframework.web.bind.annotation.PatchMapping;
14 | import org.springframework.web.bind.annotation.PathVariable;
15 | import org.springframework.web.bind.annotation.PostMapping;
16 | import org.springframework.web.bind.annotation.PutMapping;
17 | import org.springframework.web.bind.annotation.RequestBody;
18 | import org.springframework.web.bind.annotation.RequestMapping;
19 | import org.springframework.web.bind.annotation.RestController;
20 | import org.springframework.web.server.ResponseStatusException;
21 |
22 | @Service
23 | @RestController()
24 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
25 | public class DriverAPI {
26 |
27 | @Autowired
28 | DriverRepository driverRepository;
29 |
30 | @GetMapping("/drivers")
31 | public List listDrivers() {
32 | return driverRepository.findAll();
33 | }
34 |
35 |
36 | @GetMapping("/drivers/{id}")
37 | public Driver findDriver(@PathVariable("id") Long id){
38 | //return driverRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
39 | return driverRepository.findById(id).get();
40 | }
41 |
42 | @PostMapping("/drivers")
43 | public Driver createDriver(@RequestBody Driver driver) {
44 | return driverRepository.save(driver);
45 | }
46 |
47 | @PutMapping("/drivers/{id}")
48 | public Driver fullUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
49 | Driver foundDriver = findDriver(id);
50 | foundDriver.setBirthDate(driver.getBirthDate());
51 | foundDriver.setName(driver.getName());
52 | return driverRepository.save(foundDriver);
53 | }
54 |
55 | @PatchMapping("/drivers/{id}")
56 | public Driver incrementalUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
57 | Driver foundDriver = findDriver(id);
58 | foundDriver.setBirthDate(Optional.ofNullable(driver.getBirthDate()).orElse(foundDriver.getBirthDate()));
59 | foundDriver.setName(Optional.ofNullable(driver.getName()).orElse(foundDriver.getName()));
60 | return driverRepository.save(foundDriver);
61 | }
62 |
63 | @DeleteMapping("/drivers/{id}")
64 | public void deleteDriver(@PathVariable("id") Long id) {
65 | driverRepository.delete(findDriver(id));
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/cap02/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/cap02/src/test/java/app/car/cap02/Cap02ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package app.car.cap02;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class Cap02ApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap03/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/cap03/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap03/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/cap03/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/cap03/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.3.1
9 |
10 |
11 | app.car
12 | cap03
13 | 0.0.1-SNAPSHOT
14 | cap03
15 | Demo project for Spring Boot
16 |
17 |
18 | 21
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-data-jpa
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-web
29 |
30 |
31 | org.projectlombok
32 | lombok
33 | true
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-devtools
38 | true
39 |
40 |
41 |
42 | com.h2database
43 | h2
44 |
45 |
46 |
47 | org.springframework.hateoas
48 | spring-hateoas
49 |
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-starter-test
54 | test
55 |
56 |
57 | org.junit.vintage
58 | junit-vintage-engine
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | org.springframework.boot
68 | spring-boot-maven-plugin
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/Cap03Application.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Cap03Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Cap03Application.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/domain/Driver.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 | import java.time.LocalDate;
9 |
10 | @Data
11 | @Entity
12 | public class Driver {
13 |
14 |
15 | @Id
16 | @GeneratedValue
17 | Long id;
18 | String name;
19 | LocalDate birthDate;
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/domain/DriverRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface DriverRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/domain/Passenger.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 |
9 | @Data
10 | @Entity
11 | public class Passenger {
12 |
13 |
14 | @Id
15 | @GeneratedValue
16 | Long id;
17 | String name;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/domain/PassengerRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface PassengerRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/domain/TravelRequest.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.domain;
2 |
3 |
4 | import jakarta.persistence.Entity;
5 | import jakarta.persistence.EnumType;
6 | import jakarta.persistence.Enumerated;
7 | import jakarta.persistence.GeneratedValue;
8 | import jakarta.persistence.Id;
9 | import jakarta.persistence.ManyToOne;
10 | import lombok.Data;
11 |
12 | import java.time.LocalDateTime;
13 |
14 | @Data
15 | @Entity
16 | public class TravelRequest {
17 |
18 | @Id
19 | @GeneratedValue
20 | Long id;
21 |
22 | @ManyToOne
23 | Passenger passenger;
24 | String origin;
25 | String destination;
26 |
27 | @Enumerated(EnumType.STRING)
28 | TravelRequestStatus status;
29 | LocalDateTime creationDate;
30 | }
31 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/domain/TravelRequestRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface TravelRequestRepository extends JpaRepository {}
6 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/domain/TravelRequestStatus.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.domain;
2 |
3 | public enum TravelRequestStatus {
4 | CREATED, ACCEPTED, REFUSED;
5 | }
6 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/domain/TravelService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.domain;
2 |
3 |
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.stereotype.Service;
6 |
7 | import java.time.LocalDateTime;
8 |
9 | @Service
10 | public class TravelService {
11 |
12 |
13 | @Autowired
14 | TravelRequestRepository travelRequestRepository;
15 |
16 |
17 | public TravelRequest saveTravelRequest(TravelRequest travelRequest) {
18 | travelRequest.setStatus(TravelRequestStatus.CREATED);
19 | travelRequest.setCreationDate(LocalDateTime.now());
20 | return travelRequestRepository.save(travelRequest);
21 | }
22 |
23 |
24 |
25 |
26 |
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/interfaces/DriverAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.interfaces;
2 |
3 | import app.car.cap03.domain.Driver;
4 | import app.car.cap03.domain.DriverRepository;
5 | import java.util.List;
6 | import java.util.Optional;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.stereotype.Service;
11 | import org.springframework.web.bind.annotation.DeleteMapping;
12 | import org.springframework.web.bind.annotation.GetMapping;
13 | import org.springframework.web.bind.annotation.PatchMapping;
14 | import org.springframework.web.bind.annotation.PathVariable;
15 | import org.springframework.web.bind.annotation.PostMapping;
16 | import org.springframework.web.bind.annotation.PutMapping;
17 | import org.springframework.web.bind.annotation.RequestBody;
18 | import org.springframework.web.bind.annotation.RequestMapping;
19 | import org.springframework.web.bind.annotation.RestController;
20 | import org.springframework.web.server.ResponseStatusException;
21 |
22 | @Service
23 | @RestController()
24 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
25 | public class DriverAPI {
26 |
27 | @Autowired
28 | DriverRepository driverRepository;
29 |
30 | @GetMapping("/drivers")
31 | public List listDrivers() {
32 | return driverRepository.findAll();
33 | }
34 |
35 |
36 | @GetMapping("/drivers/{id}")
37 | public Driver findDriver(@PathVariable("id") Long id){
38 | return driverRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
39 | }
40 |
41 | @PostMapping("/drivers")
42 | public Driver createDriver(@RequestBody Driver driver) {
43 | return driverRepository.save(driver);
44 | }
45 |
46 | @PutMapping("/drivers/{id}")
47 | public Driver fullUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
48 | Driver foundDriver = findDriver(id);
49 | foundDriver.setBirthDate(driver.getBirthDate());
50 | foundDriver.setName(driver.getName());
51 | return driverRepository.save(foundDriver);
52 | }
53 |
54 | @PatchMapping("/drivers/{id}")
55 | public Driver incrementalUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
56 | Driver foundDriver = findDriver(id);
57 | foundDriver.setBirthDate(Optional.ofNullable(driver.getBirthDate()).orElse(foundDriver.getBirthDate()));
58 | foundDriver.setName(Optional.ofNullable(driver.getName()).orElse(foundDriver.getName()));
59 | return driverRepository.save(foundDriver);
60 | }
61 |
62 | @DeleteMapping("/drivers/{id}")
63 | public void deleteDriver(@PathVariable("id") Long id) {
64 | driverRepository.delete(findDriver(id));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/interfaces/PassengerAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.interfaces;
2 |
3 | import app.car.cap03.domain.Passenger;
4 | import app.car.cap03.domain.PassengerRepository;
5 | import java.util.List;
6 | import java.util.Optional;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.stereotype.Service;
11 | import org.springframework.web.bind.annotation.*;
12 | import org.springframework.web.server.ResponseStatusException;
13 |
14 | @Service
15 | @RestController
16 | @RequestMapping(path="/passengers", produces = MediaType.APPLICATION_JSON_VALUE)
17 | public class PassengerAPI {
18 |
19 | @Autowired
20 | PassengerRepository passengerRepository;
21 |
22 | @GetMapping()
23 | public List listPassengers() {
24 | return passengerRepository.findAll();
25 | }
26 |
27 | @GetMapping("/{id}")
28 | public Passenger findPassenger(@PathVariable("id") Long id) {
29 | return passengerRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
30 | }
31 |
32 | @PostMapping
33 | public Passenger createPassenger(@RequestBody Passenger passenger) {
34 | return passengerRepository.save(passenger);
35 | }
36 |
37 | @PutMapping("/{id}")
38 | public Passenger fullUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
39 | Passenger p = findPassenger(id);
40 | p.setName(passenger.getName());
41 | return passengerRepository.save(p);
42 | }
43 |
44 | @PatchMapping("/{id}")
45 | public Passenger incrementalUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
46 | Passenger foundPassenger = findPassenger(id);
47 | foundPassenger.setName(Optional.ofNullable(passenger.getName()).orElse(foundPassenger.getName()));
48 | return passengerRepository.save(foundPassenger);
49 | }
50 |
51 | @DeleteMapping("/{id}")
52 | public void deletePassenger(@PathVariable("id") Long id) {
53 | passengerRepository.delete(findPassenger(id));
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/interfaces/TravelRequestAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.interfaces;
2 |
3 |
4 | import app.car.cap03.domain.TravelRequest;
5 | import app.car.cap03.domain.TravelService;
6 | import app.car.cap03.interfaces.input.TravelRequestInput;
7 | import app.car.cap03.interfaces.mapping.TravelRequestMapper;
8 | import app.car.cap03.interfaces.output.TravelRequestOutput;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.hateoas.EntityModel;
11 | import org.springframework.http.MediaType;
12 | import org.springframework.stereotype.Service;
13 | import org.springframework.web.bind.annotation.PostMapping;
14 | import org.springframework.web.bind.annotation.RequestBody;
15 | import org.springframework.web.bind.annotation.RequestMapping;
16 | import org.springframework.web.bind.annotation.RestController;
17 |
18 | @Service
19 | @RestController
20 | @RequestMapping(path = "/travelRequests", produces = MediaType.APPLICATION_JSON_VALUE)
21 | public class TravelRequestAPI {
22 |
23 | @Autowired
24 | TravelService travelService;
25 |
26 | @Autowired
27 | TravelRequestMapper mapper;
28 |
29 | @PostMapping
30 | public EntityModel makeTravelRequest (@RequestBody TravelRequestInput travelRequestInput) {
31 | TravelRequest request = travelService.saveTravelRequest(mapper.map(travelRequestInput));
32 | TravelRequestOutput output = mapper.map(request);
33 | return mapper.buildOutputModel(request, output);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/interfaces/input/TravelRequestInput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.interfaces.input;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class TravelRequestInput {
7 |
8 | Long passengerId;
9 | String origin;
10 | String destination;
11 | }
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/interfaces/mapping/TravelRequestMapper.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.interfaces.mapping;
2 |
3 | import app.car.cap03.domain.Passenger;
4 | import app.car.cap03.domain.PassengerRepository;
5 | import app.car.cap03.domain.TravelRequest;
6 | import app.car.cap03.interfaces.PassengerAPI;
7 | import app.car.cap03.interfaces.input.TravelRequestInput;
8 | import app.car.cap03.interfaces.output.TravelRequestOutput;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.hateoas.EntityModel;
11 | import org.springframework.hateoas.Link;
12 | import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
13 | import org.springframework.http.HttpStatus;
14 | import org.springframework.stereotype.Component;
15 | import org.springframework.web.server.ResponseStatusException;
16 |
17 | @Component
18 | public class TravelRequestMapper {
19 |
20 | @Autowired
21 | private PassengerRepository passengerRepository;
22 |
23 | public TravelRequest map(TravelRequestInput input) {
24 |
25 | Passenger passenger = passengerRepository.findById(input.getPassengerId())
26 | .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
27 |
28 | TravelRequest travelRequest = new TravelRequest();
29 | travelRequest.setOrigin(input.getOrigin());
30 | travelRequest.setDestination(input.getDestination());
31 | travelRequest.setPassenger(passenger);
32 |
33 | return travelRequest;
34 | }
35 |
36 | public TravelRequestOutput map(TravelRequest travelRequest) {
37 | TravelRequestOutput travelRequestOutput = new TravelRequestOutput();
38 |
39 | travelRequestOutput.setCreationDate(travelRequest.getCreationDate());
40 | travelRequestOutput.setDestination(travelRequest.getDestination());
41 | travelRequestOutput.setId(travelRequest.getId());
42 | travelRequestOutput.setOrigin(travelRequest.getOrigin());
43 | travelRequestOutput.setStatus(travelRequest.getStatus());
44 |
45 | return travelRequestOutput;
46 | }
47 |
48 | public EntityModel buildOutputModel(TravelRequest travelRequest, TravelRequestOutput output) {
49 | EntityModel model = EntityModel.of(output);
50 |
51 | Link passengerLink = WebMvcLinkBuilder
52 | .linkTo(PassengerAPI.class)
53 | .slash(travelRequest.getPassenger().getId())
54 | .withRel("passenger")
55 | .withTitle(travelRequest.getPassenger().getName());
56 | model.add(passengerLink);
57 | return model;
58 | }
59 | }
--------------------------------------------------------------------------------
/cap03/src/main/java/app/car/cap03/interfaces/output/TravelRequestOutput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03.interfaces.output;
2 |
3 | import app.car.cap03.domain.TravelRequestStatus;
4 | import lombok.Data;
5 |
6 | import java.time.LocalDateTime;
7 |
8 | @Data
9 | public class TravelRequestOutput {
10 |
11 | Long id;
12 | String origin;
13 | String destination;
14 | TravelRequestStatus status;
15 | LocalDateTime creationDate;
16 | }
--------------------------------------------------------------------------------
/cap03/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap03/src/main/resources/application.properties
--------------------------------------------------------------------------------
/cap03/src/test/java/app/car/cap03/Cap03ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package app.car.cap03;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class Cap03ApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap04/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/cap04/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap04/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/cap04/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/cap04/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.3.1
9 |
10 |
11 | app.car
12 | cap04
13 | 0.0.1-SNAPSHOT
14 | cap04
15 | Demo project for Spring Boot
16 |
17 |
18 | 21
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-data-jpa
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-web
29 |
30 |
31 | org.projectlombok
32 | lombok
33 | true
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-devtools
38 | true
39 |
40 |
41 |
42 | com.h2database
43 | h2
44 |
45 |
46 |
47 | org.springframework.hateoas
48 | spring-hateoas
49 |
50 |
51 |
52 | com.jayway.jsonpath
53 | json-path
54 |
55 |
56 |
57 |
58 | org.springframework.boot
59 | spring-boot-starter-test
60 | test
61 |
62 |
63 | org.junit.vintage
64 | junit-vintage-engine
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | org.springframework.boot
74 | spring-boot-maven-plugin
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/Cap04Application.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Cap04Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Cap04Application.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/domain/Driver.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 | import java.time.LocalDate;
9 |
10 | @Data
11 | @Entity
12 | public class Driver {
13 |
14 |
15 | @Id
16 | @GeneratedValue
17 | Long id;
18 | String name;
19 | LocalDate birthDate;
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/domain/DriverRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface DriverRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/domain/Passenger.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 |
9 | @Data
10 | @Entity
11 | public class Passenger {
12 |
13 |
14 | @Id
15 | @GeneratedValue
16 | Long id;
17 | String name;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/domain/PassengerRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface PassengerRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/domain/TravelRequest.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.domain;
2 |
3 |
4 | import jakarta.persistence.Entity;
5 | import jakarta.persistence.EnumType;
6 | import jakarta.persistence.Enumerated;
7 | import jakarta.persistence.GeneratedValue;
8 | import jakarta.persistence.Id;
9 | import jakarta.persistence.ManyToOne;
10 | import lombok.Data;
11 |
12 | import java.time.LocalDateTime;
13 |
14 | @Data
15 | @Entity
16 | public class TravelRequest {
17 |
18 | @Id
19 | @GeneratedValue
20 | Long id;
21 |
22 | @ManyToOne
23 | Passenger passenger;
24 | String origin;
25 | String destination;
26 |
27 | @Enumerated(EnumType.STRING)
28 | TravelRequestStatus status;
29 | LocalDateTime creationDate;
30 | }
31 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/domain/TravelRequestRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.domain;
2 |
3 | import java.util.List;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | public interface TravelRequestRepository extends JpaRepository {
7 |
8 | List findByStatus(TravelRequestStatus status);
9 | }
10 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/domain/TravelRequestStatus.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.domain;
2 |
3 | public enum TravelRequestStatus {
4 | CREATED, ACCEPTED, REFUSED;
5 | }
6 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/domain/TravelService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.domain;
2 |
3 |
4 | import app.car.cap04.interfaces.outcoming.GMapsService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Service;
7 |
8 | import java.time.LocalDateTime;
9 | import java.util.List;
10 |
11 | @Service
12 | public class TravelService {
13 |
14 |
15 | @Autowired
16 | TravelRequestRepository travelRequestRepository;
17 |
18 | @Autowired
19 | GMapsService gMapsService;
20 |
21 | private static final int MAX_TRAVEL_TIME = 600;
22 |
23 | public TravelRequest saveTravelRequest(TravelRequest travelRequest) {
24 | travelRequest.setStatus(TravelRequestStatus.CREATED);
25 | travelRequest.setCreationDate(LocalDateTime.now());
26 | return travelRequestRepository.save(travelRequest);
27 | }
28 |
29 |
30 | public List listNearbyTravelRequests(String currentAddress) {
31 | List requests = travelRequestRepository.findByStatus(TravelRequestStatus.CREATED);
32 | return requests
33 | .stream()
34 | .filter(tr -> gMapsService.getDistanceBetweenAddresses(currentAddress, tr.getOrigin()) < MAX_TRAVEL_TIME)
35 | .toList();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/interfaces/incoming/DriverAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.interfaces.incoming;
2 |
3 | import app.car.cap04.domain.Driver;
4 | import app.car.cap04.domain.DriverRepository;
5 | import java.util.List;
6 | import java.util.Optional;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.stereotype.Service;
11 | import org.springframework.web.bind.annotation.DeleteMapping;
12 | import org.springframework.web.bind.annotation.GetMapping;
13 | import org.springframework.web.bind.annotation.PatchMapping;
14 | import org.springframework.web.bind.annotation.PathVariable;
15 | import org.springframework.web.bind.annotation.PostMapping;
16 | import org.springframework.web.bind.annotation.PutMapping;
17 | import org.springframework.web.bind.annotation.RequestBody;
18 | import org.springframework.web.bind.annotation.RequestMapping;
19 | import org.springframework.web.bind.annotation.RestController;
20 | import org.springframework.web.server.ResponseStatusException;
21 |
22 | @Service
23 | @RestController()
24 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
25 | public class DriverAPI {
26 |
27 | @Autowired
28 | DriverRepository driverRepository;
29 |
30 | @GetMapping("/drivers")
31 | public List listDrivers() {
32 | return driverRepository.findAll();
33 | }
34 |
35 |
36 | @GetMapping("/drivers/{id}")
37 | public Driver findDriver(@PathVariable("id") Long id){
38 | return driverRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
39 | }
40 |
41 | @PostMapping("/drivers")
42 | public Driver createDriver(@RequestBody Driver driver) {
43 | return driverRepository.save(driver);
44 | }
45 |
46 | @PutMapping("/drivers/{id}")
47 | public Driver fullUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
48 | Driver foundDriver = findDriver(id);
49 | foundDriver.setBirthDate(driver.getBirthDate());
50 | foundDriver.setName(driver.getName());
51 | return driverRepository.save(foundDriver);
52 | }
53 |
54 | @PatchMapping("/drivers/{id}")
55 | public Driver incrementalUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
56 | Driver foundDriver = findDriver(id);
57 | foundDriver.setBirthDate(Optional.ofNullable(driver.getBirthDate()).orElse(foundDriver.getBirthDate()));
58 | foundDriver.setName(Optional.ofNullable(driver.getName()).orElse(foundDriver.getName()));
59 | return driverRepository.save(foundDriver);
60 | }
61 |
62 | @DeleteMapping("/drivers/{id}")
63 | public void deleteDriver(@PathVariable("id") Long id) {
64 | driverRepository.delete(findDriver(id));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/interfaces/incoming/PassengerAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.interfaces.incoming;
2 |
3 | import app.car.cap04.domain.Passenger;
4 | import app.car.cap04.domain.PassengerRepository;
5 | import java.util.List;
6 | import java.util.Optional;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.stereotype.Service;
11 | import org.springframework.web.bind.annotation.*;
12 | import org.springframework.web.server.ResponseStatusException;
13 |
14 | @Service
15 | @RestController
16 | @RequestMapping(path="/passengers", produces = MediaType.APPLICATION_JSON_VALUE)
17 | public class PassengerAPI {
18 |
19 | @Autowired
20 | PassengerRepository passengerRepository;
21 |
22 | @GetMapping()
23 | public List listPassengers() {
24 | return passengerRepository.findAll();
25 | }
26 |
27 | @GetMapping("/{id}")
28 | public Passenger findPassenger(@PathVariable("id") Long id) {
29 | return passengerRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
30 | }
31 |
32 | @PostMapping
33 | public Passenger createPassenger(@RequestBody Passenger passenger) {
34 | return passengerRepository.save(passenger);
35 | }
36 |
37 | @PutMapping("/{id}")
38 | public Passenger fullUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
39 | Passenger p = findPassenger(id);
40 | p.setName(passenger.getName());
41 | return passengerRepository.save(p);
42 | }
43 |
44 | @PatchMapping("/{id}")
45 | public Passenger incrementalUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
46 | Passenger foundPassenger = findPassenger(id);
47 | foundPassenger.setName(Optional.ofNullable(passenger.getName()).orElse(foundPassenger.getName()));
48 | return passengerRepository.save(foundPassenger);
49 | }
50 |
51 | @DeleteMapping("/{id}")
52 | public void deletePassenger(@PathVariable("id") Long id) {
53 | passengerRepository.delete(findPassenger(id));
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/interfaces/incoming/TravelRequestAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.interfaces.incoming;
2 |
3 |
4 | import app.car.cap04.domain.TravelRequest;
5 | import app.car.cap04.domain.TravelService;
6 | import app.car.cap04.interfaces.incoming.input.TravelRequestInput;
7 | import app.car.cap04.interfaces.incoming.output.TravelRequestOutput;
8 | import app.car.cap04.interfaces.incoming.mapping.TravelRequestMapper;
9 | import java.util.List;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.hateoas.EntityModel;
12 | import org.springframework.http.MediaType;
13 | import org.springframework.stereotype.Service;
14 | import org.springframework.web.bind.annotation.GetMapping;
15 | import org.springframework.web.bind.annotation.PostMapping;
16 | import org.springframework.web.bind.annotation.RequestBody;
17 | import org.springframework.web.bind.annotation.RequestMapping;
18 | import org.springframework.web.bind.annotation.RequestParam;
19 | import org.springframework.web.bind.annotation.RestController;
20 |
21 | @Service
22 | @RestController
23 | @RequestMapping(path = "/travelRequests", produces = MediaType.APPLICATION_JSON_VALUE)
24 | public class TravelRequestAPI {
25 |
26 | @Autowired
27 | TravelService travelService;
28 |
29 | @Autowired
30 | TravelRequestMapper mapper;
31 |
32 | @PostMapping
33 | public EntityModel makeTravelRequest (@RequestBody TravelRequestInput travelRequestInput) {
34 | TravelRequest request = travelService.saveTravelRequest(mapper.map(travelRequestInput));
35 | TravelRequestOutput output = mapper.map(request);
36 | return mapper.buildOutputModel(request, output);
37 | }
38 |
39 |
40 | @GetMapping("/nearby")
41 | public List> listNearbyRequests(@RequestParam String currentAddress) {
42 | List requests = travelService.listNearbyTravelRequests(currentAddress);
43 | return mapper.buildOutputModel(requests);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/interfaces/incoming/input/TravelRequestInput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.interfaces.incoming.input;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class TravelRequestInput {
7 |
8 | Long passengerId;
9 | String origin;
10 | String destination;
11 | }
12 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/interfaces/incoming/mapping/TravelRequestMapper.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.interfaces.incoming.mapping;
2 |
3 | import app.car.cap04.domain.Passenger;
4 | import app.car.cap04.domain.PassengerRepository;
5 | import app.car.cap04.domain.TravelRequest;
6 | import app.car.cap04.interfaces.incoming.PassengerAPI;
7 | import app.car.cap04.interfaces.incoming.input.TravelRequestInput;
8 | import app.car.cap04.interfaces.incoming.output.TravelRequestOutput;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.hateoas.EntityModel;
11 | import org.springframework.hateoas.Link;
12 | import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
13 | import org.springframework.http.HttpStatus;
14 | import org.springframework.stereotype.Component;
15 | import org.springframework.web.server.ResponseStatusException;
16 |
17 | import java.util.List;
18 |
19 | @Component
20 | public class TravelRequestMapper {
21 |
22 | @Autowired
23 | private PassengerRepository passengerRepository;
24 |
25 | public TravelRequest map(TravelRequestInput input) {
26 |
27 | Passenger passenger = passengerRepository.findById(input.getPassengerId())
28 | .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
29 |
30 | TravelRequest travelRequest = new TravelRequest();
31 | travelRequest.setOrigin(input.getOrigin());
32 | travelRequest.setDestination(input.getDestination());
33 | travelRequest.setPassenger(passenger);
34 |
35 | return travelRequest;
36 |
37 | }
38 |
39 | public TravelRequestOutput map(TravelRequest travelRequest) {
40 | TravelRequestOutput travelRequestOutput = new TravelRequestOutput();
41 |
42 | travelRequestOutput.setCreationDate(travelRequest.getCreationDate());
43 | travelRequestOutput.setDestination(travelRequest.getDestination());
44 | travelRequestOutput.setId(travelRequest.getId());
45 | travelRequestOutput.setOrigin(travelRequest.getOrigin());
46 | travelRequestOutput.setStatus(travelRequest.getStatus());
47 |
48 | return travelRequestOutput;
49 | }
50 |
51 | public EntityModel buildOutputModel(TravelRequest travelRequest, TravelRequestOutput output) {
52 | EntityModel model = EntityModel.of(output);
53 |
54 | Link passengerLink = WebMvcLinkBuilder
55 | .linkTo(PassengerAPI.class)
56 | .slash(travelRequest.getPassenger().getId())
57 | .withRel("passenger")
58 | .withTitle(travelRequest.getPassenger().getName());
59 | model.add(passengerLink);
60 | return model;
61 | }
62 |
63 | public List> buildOutputModel(List requests) {
64 | return requests.stream().map(tr -> buildOutputModel(tr, map(tr))).toList();
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/interfaces/incoming/output/TravelRequestOutput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.interfaces.incoming.output;
2 |
3 | import app.car.cap04.domain.TravelRequestStatus;
4 | import lombok.Data;
5 |
6 | import java.time.LocalDateTime;
7 |
8 | @Data
9 | public class TravelRequestOutput {
10 |
11 | Long id;
12 | String origin;
13 | String destination;
14 | TravelRequestStatus status;
15 | LocalDateTime creationDate;
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/cap04/src/main/java/app/car/cap04/interfaces/outcoming/GMapsService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04.interfaces.outcoming;
2 |
3 |
4 | import com.jayway.jsonpath.JsonPath;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.stereotype.Service;
7 | import org.springframework.web.client.RestTemplate;
8 |
9 | import java.util.List;
10 |
11 | @Service
12 | public class GMapsService {
13 |
14 |
15 | @Value("${app.car.domain.googlemaps.apikey}")
16 | private String appKey;
17 |
18 | private static final String GMAPS_TEMPLATE = "https://maps.googleapis.com/maps/api/directions/json?origin={origin}&destination={destination}&key={key}";
19 |
20 | public Integer getDistanceBetweenAddresses(String addressOne, String addressTwo) {
21 |
22 | RestTemplate template = new RestTemplate();
23 | String jsonResult = template.getForObject(GMAPS_TEMPLATE, String.class, addressOne, addressTwo, appKey);
24 |
25 | List results = JsonPath.parse(jsonResult).read("$..legs[*].duration.value");
26 | return results.stream().min(Integer::compareTo).orElse(Integer.MAX_VALUE);
27 | }
28 |
29 |
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/cap04/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | app.car.domain.googlemaps.apikey=chaveGoogle
2 |
3 |
--------------------------------------------------------------------------------
/cap04/src/test/java/app/car/cap04/Cap04ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package app.car.cap04;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class Cap04ApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap05/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/cap05/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap05/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/cap05/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/cap05/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.3.1
9 |
10 |
11 | app.car
12 | cap05
13 | 0.0.1-SNAPSHOT
14 | cap05
15 | Demo project for Spring Boot
16 |
17 |
18 | 21
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-data-jpa
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-web
29 |
30 |
31 | org.projectlombok
32 | lombok
33 | true
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-devtools
38 | true
39 |
40 |
41 |
42 | com.h2database
43 | h2
44 |
45 |
46 |
47 | org.springframework.hateoas
48 | spring-hateoas
49 |
50 |
51 |
52 | com.jayway.jsonpath
53 | json-path
54 |
55 |
56 |
57 | org.springframework.cloud
58 | spring-cloud-contract-wiremock
59 | 4.1.3
60 | test
61 |
62 |
63 |
64 |
65 | io.rest-assured
66 | spring-mock-mvc
67 | 5.4.0
68 | test
69 |
70 |
71 |
72 | commons-io
73 | commons-io
74 | 2.6
75 |
76 |
77 |
78 |
79 |
80 | org.springframework.boot
81 | spring-boot-starter-test
82 | test
83 |
84 |
85 | org.junit.vintage
86 | junit-vintage-engine
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | org.springframework.boot
97 | spring-boot-maven-plugin
98 |
99 |
100 | org.apache.maven.plugins
101 | maven-failsafe-plugin
102 |
103 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/Cap05Application.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Cap05Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Cap05Application.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/domain/Driver.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 | import java.time.LocalDate;
9 |
10 | @Data
11 | @Entity
12 | public class Driver {
13 |
14 |
15 | @Id
16 | @GeneratedValue
17 | Long id;
18 | String name;
19 | LocalDate birthDate;
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/domain/DriverRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface DriverRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/domain/Passenger.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 |
9 | @Data
10 | @Entity
11 | public class Passenger {
12 |
13 |
14 | @Id
15 | @GeneratedValue
16 | Long id;
17 | String name;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/domain/PassengerRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface PassengerRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/domain/TravelRequest.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.domain;
2 |
3 |
4 | import jakarta.persistence.Entity;
5 | import jakarta.persistence.EnumType;
6 | import jakarta.persistence.Enumerated;
7 | import jakarta.persistence.GeneratedValue;
8 | import jakarta.persistence.Id;
9 | import jakarta.persistence.ManyToOne;
10 | import lombok.Data;
11 |
12 | import java.time.LocalDateTime;
13 |
14 | @Data
15 | @Entity
16 | public class TravelRequest {
17 |
18 | @Id
19 | @GeneratedValue
20 | Long id;
21 |
22 | @ManyToOne
23 | Passenger passenger;
24 | String origin;
25 | String destination;
26 |
27 | @Enumerated(EnumType.STRING)
28 | TravelRequestStatus status;
29 | LocalDateTime creationDate;
30 | }
31 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/domain/TravelRequestRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.domain;
2 |
3 | import java.util.List;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | public interface TravelRequestRepository extends JpaRepository {
7 |
8 | List findByStatus(TravelRequestStatus status);
9 | }
10 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/domain/TravelRequestStatus.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.domain;
2 |
3 | public enum TravelRequestStatus {
4 | CREATED, ACCEPTED, REFUSED;
5 | }
6 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/domain/TravelService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.domain;
2 |
3 |
4 | import app.car.cap05.interfaces.outcoming.GMapsService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Service;
7 |
8 | import java.time.LocalDateTime;
9 | import java.util.List;
10 |
11 | @Service
12 | public class TravelService {
13 |
14 |
15 | @Autowired
16 | TravelRequestRepository travelRequestRepository;
17 |
18 | @Autowired
19 | GMapsService gMapsService;
20 |
21 | private static final int MAX_TRAVEL_TIME = 600;
22 |
23 | public TravelRequest saveTravelRequest(TravelRequest travelRequest) {
24 | travelRequest.setStatus(TravelRequestStatus.CREATED);
25 | travelRequest.setCreationDate(LocalDateTime.now());
26 | return travelRequestRepository.save(travelRequest);
27 | }
28 |
29 |
30 | public List listNearbyTravelRequests(String currentAddress) {
31 | List requests = travelRequestRepository.findByStatus(TravelRequestStatus.CREATED);
32 | return requests
33 | .stream()
34 | .filter(tr -> gMapsService.getDistanceBetweenAddresses(currentAddress, tr.getOrigin()) < MAX_TRAVEL_TIME)
35 | .toList();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/interfaces/incoming/DriverAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.interfaces.incoming;
2 |
3 | import app.car.cap05.domain.Driver;
4 | import app.car.cap05.domain.DriverRepository;
5 | import java.util.List;
6 | import java.util.Optional;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.stereotype.Service;
11 | import org.springframework.web.bind.annotation.DeleteMapping;
12 | import org.springframework.web.bind.annotation.GetMapping;
13 | import org.springframework.web.bind.annotation.PatchMapping;
14 | import org.springframework.web.bind.annotation.PathVariable;
15 | import org.springframework.web.bind.annotation.PostMapping;
16 | import org.springframework.web.bind.annotation.PutMapping;
17 | import org.springframework.web.bind.annotation.RequestBody;
18 | import org.springframework.web.bind.annotation.RequestMapping;
19 | import org.springframework.web.bind.annotation.RestController;
20 | import org.springframework.web.server.ResponseStatusException;
21 |
22 | @Service
23 | @RestController()
24 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
25 | public class DriverAPI {
26 |
27 | @Autowired
28 | DriverRepository driverRepository;
29 |
30 | @GetMapping("/drivers")
31 | public List listDrivers() {
32 | return driverRepository.findAll();
33 | }
34 |
35 |
36 | @GetMapping("/drivers/{id}")
37 | public Driver findDriver(@PathVariable("id") Long id){
38 | return driverRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
39 | }
40 |
41 | @PostMapping("/drivers")
42 | public Driver createDriver(@RequestBody Driver driver) {
43 | return driverRepository.save(driver);
44 | }
45 |
46 | @PutMapping("/drivers/{id}")
47 | public Driver fullUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
48 | Driver foundDriver = findDriver(id);
49 | foundDriver.setBirthDate(driver.getBirthDate());
50 | foundDriver.setName(driver.getName());
51 | return driverRepository.save(foundDriver);
52 | }
53 |
54 | @PatchMapping("/drivers/{id}")
55 | public Driver incrementalUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
56 | Driver foundDriver = findDriver(id);
57 | foundDriver.setBirthDate(Optional.ofNullable(driver.getBirthDate()).orElse(foundDriver.getBirthDate()));
58 | foundDriver.setName(Optional.ofNullable(driver.getName()).orElse(foundDriver.getName()));
59 | return driverRepository.save(foundDriver);
60 | }
61 |
62 | @DeleteMapping("/drivers/{id}")
63 | public void deleteDriver(@PathVariable("id") Long id) {
64 | driverRepository.delete(findDriver(id));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/interfaces/incoming/PassengerAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.interfaces.incoming;
2 |
3 | import app.car.cap05.domain.Passenger;
4 | import app.car.cap05.domain.PassengerRepository;
5 | import java.util.List;
6 | import java.util.Optional;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.stereotype.Service;
11 | import org.springframework.web.bind.annotation.*;
12 | import org.springframework.web.server.ResponseStatusException;
13 |
14 | @Service
15 | @RestController
16 | @RequestMapping(path="/passengers", produces = MediaType.APPLICATION_JSON_VALUE)
17 | public class PassengerAPI {
18 |
19 | @Autowired
20 | PassengerRepository passengerRepository;
21 |
22 | @GetMapping()
23 | public List listPassengers() {
24 | return passengerRepository.findAll();
25 | }
26 |
27 | @GetMapping("/{id}")
28 | public Passenger findPassenger(@PathVariable("id") Long id) {
29 | return passengerRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
30 | }
31 |
32 | @PostMapping
33 | public Passenger createPassenger(@RequestBody Passenger passenger) {
34 | return passengerRepository.save(passenger);
35 | }
36 |
37 | @PutMapping("/{id}")
38 | public Passenger fullUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
39 | Passenger p = findPassenger(id);
40 | p.setName(passenger.getName());
41 | return passengerRepository.save(p);
42 | }
43 |
44 | @PatchMapping("/{id}")
45 | public Passenger incrementalUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
46 | Passenger foundPassenger = findPassenger(id);
47 | foundPassenger.setName(Optional.ofNullable(passenger.getName()).orElse(foundPassenger.getName()));
48 | return passengerRepository.save(foundPassenger);
49 | }
50 |
51 | @DeleteMapping("/{id}")
52 | public void deletePassenger(@PathVariable("id") Long id) {
53 | passengerRepository.delete(findPassenger(id));
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/interfaces/incoming/TravelRequestAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.interfaces.incoming;
2 |
3 |
4 | import app.car.cap05.domain.TravelRequest;
5 | import app.car.cap05.domain.TravelService;
6 | import app.car.cap05.interfaces.incoming.input.TravelRequestInput;
7 | import app.car.cap05.interfaces.incoming.mapping.TravelRequestMapper;
8 | import app.car.cap05.interfaces.incoming.output.TravelRequestOutput;
9 | import java.util.List;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.hateoas.EntityModel;
12 | import org.springframework.http.MediaType;
13 | import org.springframework.stereotype.Service;
14 | import org.springframework.web.bind.annotation.GetMapping;
15 | import org.springframework.web.bind.annotation.PostMapping;
16 | import org.springframework.web.bind.annotation.RequestBody;
17 | import org.springframework.web.bind.annotation.RequestMapping;
18 | import org.springframework.web.bind.annotation.RequestParam;
19 | import org.springframework.web.bind.annotation.RestController;
20 |
21 | @Service
22 | @RestController
23 | @RequestMapping(path = "/travelRequests", produces = MediaType.APPLICATION_JSON_VALUE)
24 | public class TravelRequestAPI {
25 |
26 | @Autowired
27 | TravelService travelService;
28 |
29 | @Autowired
30 | TravelRequestMapper mapper;
31 |
32 | @PostMapping
33 | public EntityModel makeTravelRequest (@RequestBody TravelRequestInput travelRequestInput) {
34 | TravelRequest request = travelService.saveTravelRequest(mapper.map(travelRequestInput));
35 | TravelRequestOutput output = mapper.map(request);
36 | return mapper.buildOutputModel(request, output);
37 | }
38 |
39 |
40 | @GetMapping("/nearby")
41 | public List> listNearbyRequests(@RequestParam String currentAddress) {
42 | List requests = travelService.listNearbyTravelRequests(currentAddress);
43 | return mapper.buildOutputModel(requests);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/interfaces/incoming/input/TravelRequestInput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.interfaces.incoming.input;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class TravelRequestInput {
7 |
8 | Long passengerId;
9 | String origin;
10 | String destination;
11 | }
12 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/interfaces/incoming/mapping/TravelRequestMapper.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.interfaces.incoming.mapping;
2 |
3 | import app.car.cap05.domain.Passenger;
4 | import app.car.cap05.domain.PassengerRepository;
5 | import app.car.cap05.domain.TravelRequest;
6 | import app.car.cap05.interfaces.incoming.PassengerAPI;
7 | import app.car.cap05.interfaces.incoming.input.TravelRequestInput;
8 | import app.car.cap05.interfaces.incoming.output.TravelRequestOutput;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.hateoas.EntityModel;
11 | import org.springframework.hateoas.Link;
12 | import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
13 | import org.springframework.http.HttpStatus;
14 | import org.springframework.stereotype.Component;
15 | import org.springframework.web.server.ResponseStatusException;
16 |
17 | import java.util.List;
18 |
19 | @Component
20 | public class TravelRequestMapper {
21 |
22 | @Autowired
23 | private PassengerRepository passengerRepository;
24 |
25 | public TravelRequest map(TravelRequestInput input) {
26 |
27 | Passenger passenger = passengerRepository.findById(input.getPassengerId())
28 | .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
29 |
30 | TravelRequest travelRequest = new TravelRequest();
31 | travelRequest.setOrigin(input.getOrigin());
32 | travelRequest.setDestination(input.getDestination());
33 | travelRequest.setPassenger(passenger);
34 |
35 | return travelRequest;
36 |
37 | }
38 |
39 | public TravelRequestOutput map(TravelRequest travelRequest) {
40 | TravelRequestOutput travelRequestOutput = new TravelRequestOutput();
41 |
42 | travelRequestOutput.setCreationDate(travelRequest.getCreationDate());
43 | travelRequestOutput.setDestination(travelRequest.getDestination());
44 | travelRequestOutput.setId(travelRequest.getId());
45 | travelRequestOutput.setOrigin(travelRequest.getOrigin());
46 | travelRequestOutput.setStatus(travelRequest.getStatus());
47 |
48 | return travelRequestOutput;
49 | }
50 |
51 | public EntityModel buildOutputModel(TravelRequest travelRequest, TravelRequestOutput output) {
52 | EntityModel model = EntityModel.of(output);
53 |
54 | Link passengerLink = WebMvcLinkBuilder
55 | .linkTo(PassengerAPI.class)
56 | .slash(travelRequest.getPassenger().getId())
57 | .withRel("passenger")
58 | .withTitle(travelRequest.getPassenger().getName());
59 | model.add(passengerLink);
60 | return model;
61 | }
62 |
63 | public List> buildOutputModel(List requests) {
64 | return requests.stream().map(tr -> buildOutputModel(tr, map(tr))).toList();
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/interfaces/incoming/output/TravelRequestOutput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.interfaces.incoming.output;
2 |
3 | import app.car.cap05.domain.TravelRequestStatus;
4 | import lombok.Data;
5 |
6 | import java.time.LocalDateTime;
7 |
8 | @Data
9 | public class TravelRequestOutput {
10 |
11 | Long id;
12 | String origin;
13 | String destination;
14 | TravelRequestStatus status;
15 | LocalDateTime creationDate;
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/cap05/src/main/java/app/car/cap05/interfaces/outcoming/GMapsService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.interfaces.outcoming;
2 |
3 |
4 | import com.jayway.jsonpath.JsonPath;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.stereotype.Service;
7 | import org.springframework.web.client.RestTemplate;
8 |
9 | import java.util.List;
10 |
11 | @Service
12 | public class GMapsService {
13 |
14 |
15 | @Value("${app.car.domain.googlemaps.apikey}")
16 | private String appKey;
17 |
18 | @Value("${interfaces.outcoming.gmaps.host:https://maps.googleapis.com}")
19 | private String gMapsHost;
20 |
21 | private static final String GMAPS_TEMPLATE = "/maps/api/directions/json?origin={origin}&destination={destination}&key={key}";
22 |
23 | public Integer getDistanceBetweenAddresses(String addressOne, String addressTwo) {
24 |
25 | RestTemplate template = new RestTemplate();
26 | String jsonResult = template.getForObject(gMapsHost + GMAPS_TEMPLATE, String.class, addressOne, addressTwo, appKey);
27 |
28 | List results = JsonPath.parse(jsonResult).read("$..legs[*].duration.value");
29 | return results.stream().min(Integer::compareTo).orElse(Integer.MAX_VALUE);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/cap05/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | app.car.domain.googlemaps.apikey=chaveGoogle
2 |
3 |
--------------------------------------------------------------------------------
/cap05/src/test/java/app/car/cap05/Cap05ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class Cap05ApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap05/src/test/java/app/car/cap05/infrastructure/FileUtils.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.infrastructure;
2 |
3 | import lombok.SneakyThrows;
4 | import org.springframework.core.io.ClassPathResource;
5 |
6 | import java.io.InputStream;
7 | import java.util.Map;
8 |
9 | public class FileUtils {
10 |
11 | @SneakyThrows
12 | public static String loadFileContents(String fileName) {
13 |
14 | InputStream is = new ClassPathResource(fileName).getInputStream();
15 | byte[] data = new byte[is.available()];
16 | is.read(data);
17 | return new String(data);
18 | }
19 |
20 | public static String loadFileContents(String fileName, Map replacements) {
21 | String fileContents = loadFileContents(fileName);
22 |
23 | for (Map.Entry entry : replacements.entrySet()) {
24 | fileContents = fileContents.replace("{{" + entry.getKey() + "}}", entry.getValue());
25 | }
26 | return fileContents;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/cap05/src/test/java/app/car/cap05/interfaces/incoming/PassengerAPITestIT.java:
--------------------------------------------------------------------------------
1 | package app.car.cap05.interfaces.incoming;
2 |
3 | import static io.restassured.RestAssured.given;
4 | import static org.hamcrest.Matchers.equalTo;
5 | import static org.hamcrest.Matchers.notNullValue;
6 | import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
7 |
8 | import io.restassured.RestAssured;
9 | import org.junit.jupiter.api.BeforeEach;
10 | import org.junit.jupiter.api.Test;
11 | import org.springframework.boot.test.context.SpringBootTest;
12 | import org.springframework.boot.test.web.server.LocalServerPort;
13 |
14 |
15 | @SpringBootTest(webEnvironment = RANDOM_PORT)
16 | class PassengerAPITestIT {
17 |
18 | @LocalServerPort
19 | private int port;
20 |
21 | @BeforeEach
22 | void setup() {
23 | RestAssured.port = port;
24 | }
25 |
26 | @Test
27 | void testCreatePassenger() {
28 |
29 |
30 | String createPassengerJSON = "{\"name\":\"Alexandre Saudate\"}";
31 |
32 |
33 | given()
34 | .contentType(io.restassured.http.ContentType.JSON)
35 | .body(createPassengerJSON)
36 | .post("/passengers")
37 | .then()
38 | .statusCode(200)
39 | .body("id", notNullValue())
40 | .body("name", equalTo("Alexandre Saudate"))
41 | ;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/cap05/src/test/resources/application-test.properties:
--------------------------------------------------------------------------------
1 | interfaces.outcoming.gmaps.host=http://localhost:${wiremock.server.port}
--------------------------------------------------------------------------------
/cap05/src/test/resources/requests/passengers_api/create_new_passenger.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Alexandre Saudate"
3 | }
--------------------------------------------------------------------------------
/cap05/src/test/resources/requests/travel_requests_api/create_new_request.json:
--------------------------------------------------------------------------------
1 | {
2 | "passengerId":"{{passengerId}}",
3 | "origin":"Avenida Paulista, 1000",
4 | "destination":"Avenida Ipiranga, 100"
5 | }
--------------------------------------------------------------------------------
/cap06/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/cap06/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap06/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/cap06/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/cap06/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.3.1
9 |
10 |
11 | app.car
12 | cap06
13 | 0.0.1-SNAPSHOT
14 | cap06
15 | Demo project for Spring Boot
16 |
17 |
18 | 21
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-data-jpa
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-web
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-security
33 |
34 |
35 | org.projectlombok
36 | lombok
37 | true
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-devtools
42 | true
43 |
44 |
45 |
46 | com.h2database
47 | h2
48 |
49 |
50 |
51 | org.springframework.hateoas
52 | spring-hateoas
53 |
54 |
55 |
56 | com.jayway.jsonpath
57 | json-path
58 |
59 |
60 |
61 | org.springframework.cloud
62 | spring-cloud-contract-wiremock
63 | 4.1.3
64 | test
65 |
66 |
67 |
68 | io.rest-assured
69 | spring-mock-mvc
70 | 5.4.0
71 | test
72 |
73 |
74 |
75 | commons-io
76 | commons-io
77 | 2.6
78 |
79 |
80 |
81 |
82 |
83 | org.springframework.boot
84 | spring-boot-starter-test
85 | test
86 |
87 |
88 | org.junit.vintage
89 | junit-vintage-engine
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | org.springframework.boot
100 | spring-boot-maven-plugin
101 |
102 |
103 | org.apache.maven.plugins
104 | maven-failsafe-plugin
105 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/Cap06Application.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Cap06Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Cap06Application.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/config/LoadUserConfig.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.config;
2 |
3 | import app.car.cap06.domain.User;
4 | import app.car.cap06.domain.UserRepository;
5 | import jakarta.annotation.PostConstruct;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.security.crypto.password.PasswordEncoder;
9 |
10 | import java.util.List;
11 |
12 | @Configuration
13 | public class LoadUserConfig {
14 |
15 |
16 | @Autowired
17 | PasswordEncoder passwordEncoder;
18 |
19 | @Autowired
20 | UserRepository userRepository;
21 |
22 | @PostConstruct
23 | public void init() {
24 | User admin = new User();
25 | admin.setPassword(passwordEncoder.encode("password"));
26 | admin.setRoles(List.of("ROLE_ADMIN"));
27 | admin.setUsername("admin");
28 | admin.setEnabled(true);
29 |
30 | userRepository.save(admin);
31 | }
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/domain/Driver.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 | import java.time.LocalDate;
9 |
10 | @Data
11 | @Entity
12 | public class Driver {
13 |
14 |
15 | @Id
16 | @GeneratedValue
17 | Long id;
18 | String name;
19 | LocalDate birthDate;
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/domain/DriverRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface DriverRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/domain/Passenger.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 |
9 | @Data
10 | @Entity
11 | public class Passenger {
12 |
13 |
14 | @Id
15 | @GeneratedValue
16 | Long id;
17 | String name;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/domain/PassengerRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface PassengerRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/domain/TravelRequest.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.domain;
2 |
3 |
4 | import jakarta.persistence.Entity;
5 | import jakarta.persistence.EnumType;
6 | import jakarta.persistence.Enumerated;
7 | import jakarta.persistence.GeneratedValue;
8 | import jakarta.persistence.Id;
9 | import jakarta.persistence.ManyToOne;
10 | import lombok.Data;
11 |
12 | import java.time.LocalDateTime;
13 |
14 | @Data
15 | @Entity
16 | public class TravelRequest {
17 |
18 | @Id
19 | @GeneratedValue
20 | Long id;
21 |
22 | @ManyToOne
23 | Passenger passenger;
24 | String origin;
25 | String destination;
26 |
27 | @Enumerated(EnumType.STRING)
28 | TravelRequestStatus status;
29 | LocalDateTime creationDate;
30 | }
31 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/domain/TravelRequestRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.domain;
2 |
3 | import java.util.List;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | public interface TravelRequestRepository extends JpaRepository {
7 |
8 | List findByStatus(TravelRequestStatus status);
9 | }
10 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/domain/TravelRequestStatus.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.domain;
2 |
3 | public enum TravelRequestStatus {
4 | CREATED, ACCEPTED, REFUSED;
5 | }
6 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/domain/TravelService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.domain;
2 |
3 |
4 | import app.car.cap06.interfaces.outcoming.GMapsService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Service;
7 |
8 | import java.time.LocalDateTime;
9 | import java.util.List;
10 |
11 | @Service
12 | public class TravelService {
13 |
14 |
15 | @Autowired
16 | TravelRequestRepository travelRequestRepository;
17 |
18 | @Autowired
19 | GMapsService gMapsService;
20 |
21 | private static final int MAX_TRAVEL_TIME = 600;
22 |
23 | public TravelRequest saveTravelRequest(TravelRequest travelRequest) {
24 | travelRequest.setStatus(TravelRequestStatus.CREATED);
25 | travelRequest.setCreationDate(LocalDateTime.now());
26 | return travelRequestRepository.save(travelRequest);
27 | }
28 |
29 |
30 | public List listNearbyTravelRequests(String currentAddress) {
31 | List requests = travelRequestRepository.findByStatus(TravelRequestStatus.CREATED);
32 | return requests
33 | .stream()
34 | .filter(tr -> gMapsService.getDistanceBetweenAddresses(currentAddress, tr.getOrigin()) < MAX_TRAVEL_TIME)
35 | .toList();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/domain/User.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.domain;
2 |
3 |
4 | import java.util.List;
5 | import jakarta.persistence.Column;
6 | import jakarta.persistence.ElementCollection;
7 | import jakarta.persistence.Entity;
8 | import jakarta.persistence.GeneratedValue;
9 | import jakarta.persistence.Id;
10 | import jakarta.persistence.Table;
11 | import lombok.Data;
12 |
13 | @Data
14 | @Entity
15 | @Table(name = "users")
16 | public class User {
17 |
18 | @Id
19 | @GeneratedValue
20 | Long id;
21 |
22 | @Column(unique = true)
23 | String username;
24 | String password;
25 |
26 | Boolean enabled;
27 |
28 | @ElementCollection
29 | List roles;
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/domain/UserRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface UserRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/interfaces/incoming/DriverAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.interfaces.incoming;
2 |
3 | import app.car.cap06.domain.Driver;
4 | import app.car.cap06.domain.DriverRepository;
5 | import java.util.List;
6 | import java.util.Optional;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.stereotype.Service;
11 | import org.springframework.web.bind.annotation.DeleteMapping;
12 | import org.springframework.web.bind.annotation.GetMapping;
13 | import org.springframework.web.bind.annotation.PatchMapping;
14 | import org.springframework.web.bind.annotation.PathVariable;
15 | import org.springframework.web.bind.annotation.PostMapping;
16 | import org.springframework.web.bind.annotation.PutMapping;
17 | import org.springframework.web.bind.annotation.RequestBody;
18 | import org.springframework.web.bind.annotation.RequestMapping;
19 | import org.springframework.web.bind.annotation.RestController;
20 | import org.springframework.web.server.ResponseStatusException;
21 |
22 | @Service
23 | @RestController()
24 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
25 | public class DriverAPI {
26 |
27 | @Autowired
28 | DriverRepository driverRepository;
29 |
30 | @GetMapping("/drivers")
31 | public List listDrivers() {
32 | return driverRepository.findAll();
33 | }
34 |
35 |
36 | @GetMapping("/drivers/{id}")
37 | public Driver findDriver(@PathVariable("id") Long id){
38 | return driverRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
39 | }
40 |
41 | @PostMapping("/drivers")
42 | public Driver createDriver(@RequestBody Driver driver) {
43 | return driverRepository.save(driver);
44 | }
45 |
46 | @PutMapping("/drivers/{id}")
47 | public Driver fullUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
48 | Driver foundDriver = findDriver(id);
49 | foundDriver.setBirthDate(driver.getBirthDate());
50 | foundDriver.setName(driver.getName());
51 | return driverRepository.save(foundDriver);
52 | }
53 |
54 | @PatchMapping("/drivers/{id}")
55 | public Driver incrementalUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
56 | Driver foundDriver = findDriver(id);
57 | foundDriver.setBirthDate(Optional.ofNullable(driver.getBirthDate()).orElse(foundDriver.getBirthDate()));
58 | foundDriver.setName(Optional.ofNullable(driver.getName()).orElse(foundDriver.getName()));
59 | return driverRepository.save(foundDriver);
60 | }
61 |
62 | @DeleteMapping("/drivers/{id}")
63 | public void deleteDriver(@PathVariable("id") Long id) {
64 | driverRepository.delete(findDriver(id));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/interfaces/incoming/PassengerAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.interfaces.incoming;
2 |
3 | import app.car.cap06.domain.Passenger;
4 | import app.car.cap06.domain.PassengerRepository;
5 | import java.util.List;
6 | import java.util.Optional;
7 | import jakarta.annotation.security.RolesAllowed;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.http.HttpStatus;
10 | import org.springframework.http.MediaType;
11 | import org.springframework.stereotype.Service;
12 | import org.springframework.web.bind.annotation.*;
13 | import org.springframework.web.server.ResponseStatusException;
14 |
15 | @Service
16 | @RestController
17 | @RequestMapping(path="/passengers", produces = MediaType.APPLICATION_JSON_VALUE)
18 | public class PassengerAPI {
19 |
20 | @Autowired
21 | PassengerRepository passengerRepository;
22 |
23 | @GetMapping()
24 | public List listPassengers() {
25 | return passengerRepository.findAll();
26 | }
27 |
28 | @GetMapping("/{id}")
29 | public Passenger findPassenger(@PathVariable("id") Long id) {
30 | return passengerRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
31 | }
32 |
33 | @PostMapping
34 | @RolesAllowed("ADMIN")
35 | public Passenger createPassenger(@RequestBody Passenger passenger) {
36 | return passengerRepository.save(passenger);
37 | }
38 |
39 | @PutMapping("/{id}")
40 | public Passenger fullUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
41 | Passenger p = findPassenger(id);
42 | p.setName(passenger.getName());
43 | return passengerRepository.save(p);
44 | }
45 |
46 | @PatchMapping("/{id}")
47 | public Passenger incrementalUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
48 | Passenger foundPassenger = findPassenger(id);
49 | foundPassenger.setName(Optional.ofNullable(passenger.getName()).orElse(foundPassenger.getName()));
50 | return passengerRepository.save(foundPassenger);
51 | }
52 |
53 | @DeleteMapping("/{id}")
54 | public void deletePassenger(@PathVariable("id") Long id) {
55 | passengerRepository.delete(findPassenger(id));
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/interfaces/incoming/TravelRequestAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.interfaces.incoming;
2 |
3 |
4 | import app.car.cap06.domain.TravelRequest;
5 | import app.car.cap06.domain.TravelService;
6 | import app.car.cap06.interfaces.incoming.input.TravelRequestInput;
7 | import app.car.cap06.interfaces.incoming.mapping.TravelRequestMapper;
8 | import app.car.cap06.interfaces.incoming.output.TravelRequestOutput;
9 | import java.util.List;
10 |
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.hateoas.EntityModel;
13 | import org.springframework.http.MediaType;
14 | import org.springframework.stereotype.Service;
15 | import org.springframework.web.bind.annotation.GetMapping;
16 | import org.springframework.web.bind.annotation.PostMapping;
17 | import org.springframework.web.bind.annotation.RequestBody;
18 | import org.springframework.web.bind.annotation.RequestMapping;
19 | import org.springframework.web.bind.annotation.RequestParam;
20 | import org.springframework.web.bind.annotation.RestController;
21 |
22 | @Service
23 | @RestController
24 | @RequestMapping(path = "/travelRequests", produces = MediaType.APPLICATION_JSON_VALUE)
25 | public class TravelRequestAPI {
26 |
27 | @Autowired
28 | TravelService travelService;
29 |
30 | @Autowired
31 | TravelRequestMapper mapper;
32 |
33 | @PostMapping
34 | public EntityModel makeTravelRequest (@RequestBody TravelRequestInput travelRequestInput) {
35 | TravelRequest request = travelService.saveTravelRequest(mapper.map(travelRequestInput));
36 | TravelRequestOutput output = mapper.map(request);
37 | return mapper.buildOutputModel(request, output);
38 | }
39 |
40 |
41 | @GetMapping("/nearby")
42 | public List> listNearbyRequests(@RequestParam String currentAddress) {
43 | List requests = travelService.listNearbyTravelRequests(currentAddress);
44 | return mapper.buildOutputModel(requests);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/interfaces/incoming/input/TravelRequestInput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.interfaces.incoming.input;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class TravelRequestInput {
7 |
8 | Long passengerId;
9 | String origin;
10 | String destination;
11 | }
12 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/interfaces/incoming/mapping/TravelRequestMapper.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.interfaces.incoming.mapping;
2 |
3 | import app.car.cap06.domain.Passenger;
4 | import app.car.cap06.domain.PassengerRepository;
5 | import app.car.cap06.domain.TravelRequest;
6 | import app.car.cap06.interfaces.incoming.PassengerAPI;
7 | import app.car.cap06.interfaces.incoming.input.TravelRequestInput;
8 | import app.car.cap06.interfaces.incoming.output.TravelRequestOutput;
9 | import java.util.List;
10 | import java.util.stream.Collectors;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.hateoas.EntityModel;
13 | import org.springframework.hateoas.Link;
14 | import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
15 | import org.springframework.http.HttpStatus;
16 | import org.springframework.stereotype.Component;
17 | import org.springframework.web.server.ResponseStatusException;
18 |
19 | @Component
20 | public class TravelRequestMapper {
21 |
22 | @Autowired
23 | private PassengerRepository passengerRepository;
24 |
25 | public TravelRequest map(TravelRequestInput input) {
26 |
27 | Passenger passenger = passengerRepository.findById(input.getPassengerId())
28 | .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
29 |
30 | TravelRequest travelRequest = new TravelRequest();
31 | travelRequest.setOrigin(input.getOrigin());
32 | travelRequest.setDestination(input.getDestination());
33 | travelRequest.setPassenger(passenger);
34 |
35 | return travelRequest;
36 |
37 | }
38 |
39 | public TravelRequestOutput map(TravelRequest travelRequest) {
40 | TravelRequestOutput travelRequestOutput = new TravelRequestOutput();
41 |
42 | travelRequestOutput.setCreationDate(travelRequest.getCreationDate());
43 | travelRequestOutput.setDestination(travelRequest.getDestination());
44 | travelRequestOutput.setId(travelRequest.getId());
45 | travelRequestOutput.setOrigin(travelRequest.getOrigin());
46 | travelRequestOutput.setStatus(travelRequest.getStatus());
47 |
48 | return travelRequestOutput;
49 | }
50 |
51 | public EntityModel buildOutputModel(TravelRequest travelRequest, TravelRequestOutput output) {
52 | EntityModel model = EntityModel.of(output);
53 |
54 | Link passengerLink = WebMvcLinkBuilder
55 | .linkTo(PassengerAPI.class)
56 | .slash(travelRequest.getPassenger().getId())
57 | .withRel("passenger")
58 | .withTitle(travelRequest.getPassenger().getName());
59 | model.add(passengerLink);
60 | return model;
61 | }
62 |
63 | public List> buildOutputModel(List requests) {
64 | return requests.stream().map(tr -> buildOutputModel(tr, map(tr))).toList();
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/interfaces/incoming/output/TravelRequestOutput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.interfaces.incoming.output;
2 |
3 | import app.car.cap06.domain.TravelRequestStatus;
4 | import lombok.Data;
5 |
6 | import java.time.LocalDateTime;
7 |
8 | @Data
9 | public class TravelRequestOutput {
10 |
11 | Long id;
12 | String origin;
13 | String destination;
14 | TravelRequestStatus status;
15 | LocalDateTime creationDate;
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/cap06/src/main/java/app/car/cap06/interfaces/outcoming/GMapsService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.interfaces.outcoming;
2 |
3 |
4 | import com.jayway.jsonpath.JsonPath;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.stereotype.Service;
7 | import org.springframework.web.client.RestTemplate;
8 |
9 | import java.util.List;
10 |
11 | @Service
12 | public class GMapsService {
13 |
14 |
15 | @Value("${app.car.domain.googlemaps.apikey}")
16 | private String appKey;
17 |
18 | @Value("${interfaces.outcoming.gmaps.host:https://maps.googleapis.com}")
19 | private String gMapsHost;
20 |
21 | private static final String GMAPS_TEMPLATE = "/maps/api/directions/json?origin={origin}&destination={destination}&key={key}";
22 |
23 | public Integer getDistanceBetweenAddresses(String addressOne, String addressTwo) {
24 |
25 | RestTemplate template = new RestTemplate();
26 | String jsonResult = template.getForObject(gMapsHost + GMAPS_TEMPLATE, String.class, addressOne, addressTwo, appKey);
27 |
28 | List results = JsonPath.parse(jsonResult).read("$..legs[*].duration.value");
29 | return results.stream().min(Integer::compareTo).orElse(Integer.MAX_VALUE);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/cap06/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | app.car.domain.googlemaps.apikey=chaveGoogle
2 |
3 | server.ssl.key-store=classpath:keystore.p12
4 | server.ssl.key-store-password=restbook
5 | server.ssl.key-store-type=PKCS12
6 | server.ssl.key-alias=car
7 |
--------------------------------------------------------------------------------
/cap06/src/main/resources/keystore.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap06/src/main/resources/keystore.p12
--------------------------------------------------------------------------------
/cap06/src/test/java/app/car/cap06/Cap06ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class Cap06ApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap06/src/test/java/app/car/cap06/infrastructure/FileUtils.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.infrastructure;
2 |
3 | import lombok.SneakyThrows;
4 | import org.springframework.core.io.ClassPathResource;
5 |
6 | import java.io.InputStream;
7 | import java.util.Map;
8 |
9 | public class FileUtils {
10 |
11 |
12 | @SneakyThrows
13 | public static String loadFileContents(String fileName) {
14 |
15 | InputStream is = new ClassPathResource(fileName).getInputStream();
16 | byte[] data = new byte[is.available()];
17 | is.read(data);
18 | return new String(data);
19 | }
20 |
21 | public static String loadFileContents(String fileName, Map replacements) {
22 | String fileContents = loadFileContents(fileName);
23 |
24 | for (Map.Entry entry : replacements.entrySet()) {
25 | fileContents = fileContents.replace("{{" + entry.getKey() + "}}", entry.getValue());
26 | }
27 | return fileContents;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/cap06/src/test/java/app/car/cap06/interfaces/incoming/PassengerAPITestIT.java:
--------------------------------------------------------------------------------
1 | package app.car.cap06.interfaces.incoming;
2 |
3 | import io.restassured.RestAssured;
4 | import org.junit.jupiter.api.BeforeEach;
5 | import org.junit.jupiter.api.Test;
6 | import org.springframework.boot.test.context.SpringBootTest;
7 | import org.springframework.boot.test.web.server.LocalServerPort;
8 |
9 | import static io.restassured.RestAssured.basic;
10 | import static io.restassured.RestAssured.given;
11 | import static org.hamcrest.Matchers.equalTo;
12 | import static org.hamcrest.Matchers.notNullValue;
13 |
14 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
15 | class PassengerAPITestIT {
16 |
17 | @LocalServerPort
18 | private int port;
19 |
20 | @BeforeEach
21 | void setup() {
22 | RestAssured.baseURI = "https://localhost:" + port;
23 | RestAssured.useRelaxedHTTPSValidation();
24 | RestAssured.authentication = basic("admin", "password");
25 | }
26 |
27 | @Test
28 | void testCreatePassenger() {
29 |
30 |
31 | String createPassengerJSON = "{\"name\":\"Alexandre Saudate\"}";
32 |
33 |
34 | given()
35 | .contentType(io.restassured.http.ContentType.JSON)
36 | .body(createPassengerJSON)
37 | .post("/passengers")
38 | .then()
39 | .statusCode(200)
40 | .body("id", notNullValue())
41 | .body("name", equalTo("Alexandre Saudate"))
42 | ;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/cap06/src/test/resources/application-test.properties:
--------------------------------------------------------------------------------
1 | interfaces.outcoming.gmaps.host=http://localhost:${wiremock.server.port}
--------------------------------------------------------------------------------
/cap06/src/test/resources/requests/passengers_api/create_new_passenger.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Alexandre Saudate"
3 | }
--------------------------------------------------------------------------------
/cap06/src/test/resources/requests/travel_requests_api/create_new_request.json:
--------------------------------------------------------------------------------
1 | {
2 | "passengerId":"{{passengerId}}",
3 | "origin":"Avenida Paulista, 1000",
4 | "destination":"Avenida Ipiranga, 100"
5 | }
--------------------------------------------------------------------------------
/cap07/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/cap07/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap07/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/cap07/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/Cap07Application.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Cap07Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Cap07Application.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/config/AppConfig.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.config;
2 |
3 | import org.springframework.context.MessageSource;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.context.support.ReloadableResourceBundleMessageSource;
7 |
8 | @Configuration
9 | public class AppConfig {
10 |
11 |
12 | @Bean
13 | public MessageSource messageSource() {
14 | var messageSource = new ReloadableResourceBundleMessageSource();
15 | messageSource.setBasename("classpath:i18n/messages");
16 | messageSource.setDefaultEncoding("UTF-8");
17 | return messageSource;
18 | }
19 |
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/config/LoadUserConfig.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.config;
2 |
3 | import app.car.cap07.domain.User;
4 | import app.car.cap07.domain.UserRepository;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.security.crypto.password.PasswordEncoder;
8 |
9 | import jakarta.annotation.PostConstruct;
10 | import java.util.Arrays;
11 | import java.util.List;
12 |
13 | @Configuration
14 | public class LoadUserConfig {
15 |
16 |
17 | @Autowired
18 | PasswordEncoder passwordEncoder;
19 |
20 | @Autowired
21 | UserRepository userRepository;
22 |
23 | @PostConstruct
24 | public void init() {
25 | User admin = new User();
26 | admin.setPassword(passwordEncoder.encode("password"));
27 | admin.setRoles(List.of("ROLE_ADMIN"));
28 | admin.setUsername("admin");
29 | admin.setEnabled(true);
30 |
31 | userRepository.save(admin);
32 | }
33 |
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/config/SecurityConfig.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.config;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
8 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
9 | import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
10 | import org.springframework.security.config.http.SessionCreationPolicy;
11 | import org.springframework.security.core.userdetails.User;
12 | import org.springframework.security.core.userdetails.UserDetailsService;
13 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
14 | import org.springframework.security.crypto.password.PasswordEncoder;
15 | import org.springframework.security.provisioning.InMemoryUserDetailsManager;
16 | import org.springframework.security.provisioning.JdbcUserDetailsManager;
17 | import org.springframework.security.web.DefaultSecurityFilterChain;
18 |
19 | import javax.sql.DataSource;
20 |
21 | import static org.springframework.security.config.Customizer.withDefaults;
22 |
23 | @Configuration
24 | @EnableWebSecurity
25 | @EnableMethodSecurity(jsr250Enabled = true)
26 | public class SecurityConfig {
27 |
28 |
29 | @Autowired
30 | DataSource dataSource;
31 |
32 | @Bean
33 | public DefaultSecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
34 | http.csrf(CsrfConfigurer::disable);
35 | http.sessionManagement(configure -> configure.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
36 | http.authorizeHttpRequests(configure -> configure.anyRequest().authenticated());
37 | http.httpBasic(withDefaults());
38 | http.headers(c1 -> c1.frameOptions(c2 -> c2.disable()));
39 | return http.build();
40 | }
41 |
42 | @Bean
43 | public UserDetailsService userDetailsService() {
44 | var queryUsers = "select username, password, enabled from users where username=?";
45 | var queryRoles = "select u.username, r.roles from user_roles r, users u where r.user_id = u.id and u.username=?";
46 |
47 | var jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
48 | jdbcUserDetailsManager.setUsersByUsernameQuery(queryUsers);
49 | jdbcUserDetailsManager.setAuthoritiesByUsernameQuery(queryRoles);
50 | return jdbcUserDetailsManager;
51 | }
52 |
53 |
54 | @Bean
55 | public PasswordEncoder passwordEncoder() {
56 | return new BCryptPasswordEncoder();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/domain/Driver.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 | import java.time.LocalDate;
9 |
10 | @Data
11 | @Entity
12 | public class Driver {
13 |
14 |
15 | @Id
16 | @GeneratedValue
17 | Long id;
18 | String name;
19 | LocalDate birthDate;
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/domain/DriverRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface DriverRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/domain/Passenger.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 |
9 | @Data
10 | @Entity
11 | public class Passenger {
12 |
13 |
14 | @Id
15 | @GeneratedValue
16 | Long id;
17 | String name;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/domain/PassengerRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface PassengerRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/domain/TravelRequest.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.domain;
2 |
3 |
4 | import jakarta.persistence.Entity;
5 | import jakarta.persistence.EnumType;
6 | import jakarta.persistence.Enumerated;
7 | import jakarta.persistence.GeneratedValue;
8 | import jakarta.persistence.Id;
9 | import jakarta.persistence.ManyToOne;
10 | import lombok.Data;
11 |
12 | import java.time.LocalDateTime;
13 |
14 | @Data
15 | @Entity
16 | public class TravelRequest {
17 |
18 | @Id
19 | @GeneratedValue
20 | Long id;
21 |
22 | @ManyToOne
23 | Passenger passenger;
24 | String origin;
25 | String destination;
26 |
27 | @Enumerated(EnumType.STRING)
28 | TravelRequestStatus status;
29 | LocalDateTime creationDate;
30 | }
31 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/domain/TravelRequestRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.domain;
2 |
3 | import java.util.List;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | public interface TravelRequestRepository extends JpaRepository {
7 |
8 | List findByStatus(TravelRequestStatus status);
9 | }
10 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/domain/TravelRequestStatus.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.domain;
2 |
3 | public enum TravelRequestStatus {
4 | CREATED, ACCEPTED, REFUSED;
5 | }
6 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/domain/TravelService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.domain;
2 |
3 |
4 | import app.car.cap07.interfaces.outcoming.GMapsService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Service;
7 |
8 | import java.time.LocalDateTime;
9 | import java.util.List;
10 |
11 | @Service
12 | public class TravelService {
13 |
14 |
15 | @Autowired
16 | TravelRequestRepository travelRequestRepository;
17 |
18 | @Autowired
19 | GMapsService gMapsService;
20 |
21 | private static final int MAX_TRAVEL_TIME = 600;
22 |
23 | public TravelRequest saveTravelRequest(TravelRequest travelRequest) {
24 | travelRequest.setStatus(TravelRequestStatus.CREATED);
25 | travelRequest.setCreationDate(LocalDateTime.now());
26 | return travelRequestRepository.save(travelRequest);
27 | }
28 |
29 |
30 | public List listNearbyTravelRequests(String currentAddress) {
31 | List requests = travelRequestRepository.findByStatus(TravelRequestStatus.CREATED);
32 | return requests
33 | .stream()
34 | .filter(tr -> gMapsService.getDistanceBetweenAddresses(currentAddress, tr.getOrigin()) < MAX_TRAVEL_TIME)
35 | .toList();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/domain/User.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.domain;
2 |
3 |
4 | import java.util.List;
5 | import jakarta.persistence.Column;
6 | import jakarta.persistence.ElementCollection;
7 | import jakarta.persistence.Entity;
8 | import jakarta.persistence.GeneratedValue;
9 | import jakarta.persistence.Id;
10 | import jakarta.persistence.Table;
11 | import lombok.Data;
12 |
13 | @Data
14 | @Entity
15 | @Table(name = "users")
16 | public class User {
17 |
18 | @Id
19 | @GeneratedValue
20 | Long id;
21 |
22 | @Column(unique = true)
23 | String username;
24 | String password;
25 |
26 | Boolean enabled;
27 |
28 | @ElementCollection
29 | List roles;
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/domain/UserRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface UserRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/interfaces/incoming/DriverAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.interfaces.incoming;
2 |
3 | import app.car.cap07.domain.Driver;
4 | import app.car.cap07.domain.DriverRepository;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.http.HttpStatus;
7 | import org.springframework.http.MediaType;
8 | import org.springframework.stereotype.Service;
9 | import org.springframework.web.bind.annotation.*;
10 | import org.springframework.web.server.ResponseStatusException;
11 |
12 | import java.util.List;
13 | import java.util.Optional;
14 |
15 | @Service
16 | @RestController()
17 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
18 | public class DriverAPI {
19 |
20 | @Autowired
21 | DriverRepository driverRepository;
22 |
23 | @GetMapping("/drivers")
24 | public List listDrivers() {
25 | return driverRepository.findAll();
26 | }
27 |
28 |
29 | @GetMapping("/drivers/{id}")
30 | public Driver findDriver(@PathVariable("id") Long id) {
31 | return driverRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
32 | }
33 |
34 | @PostMapping("/drivers")
35 | public Driver createDriver(@RequestBody Driver driver) {
36 | return driverRepository.save(driver);
37 | }
38 |
39 | @PutMapping("/drivers/{id}")
40 | public Driver fullUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
41 | Driver foundDriver = findDriver(id);
42 | foundDriver.setBirthDate(driver.getBirthDate());
43 | foundDriver.setName(driver.getName());
44 | return driverRepository.save(foundDriver);
45 | }
46 |
47 | @PatchMapping("/drivers/{id}")
48 | public Driver incrementalUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
49 | Driver foundDriver = findDriver(id);
50 | foundDriver.setBirthDate(Optional.ofNullable(driver.getBirthDate()).orElse(foundDriver.getBirthDate()));
51 | foundDriver.setName(Optional.ofNullable(driver.getName()).orElse(foundDriver.getName()));
52 | return driverRepository.save(foundDriver);
53 | }
54 |
55 | @DeleteMapping("/drivers/{id}")
56 | public void deleteDriver(@PathVariable("id") Long id) {
57 | driverRepository.delete(findDriver(id));
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/interfaces/incoming/PassengerAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.interfaces.incoming;
2 |
3 | import app.car.cap07.domain.Passenger;
4 | import app.car.cap07.domain.PassengerRepository;
5 | import java.util.List;
6 | import java.util.Optional;
7 | import jakarta.annotation.security.RolesAllowed;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.http.HttpStatus;
10 | import org.springframework.http.MediaType;
11 | import org.springframework.stereotype.Service;
12 | import org.springframework.web.bind.annotation.*;
13 | import org.springframework.web.server.ResponseStatusException;
14 |
15 | @Service
16 | @RestController
17 | @RequestMapping(path="/passengers", produces = MediaType.APPLICATION_JSON_VALUE)
18 | public class PassengerAPI {
19 |
20 | @Autowired
21 | PassengerRepository passengerRepository;
22 |
23 | @GetMapping()
24 | public List listPassengers() {
25 | return passengerRepository.findAll();
26 | }
27 |
28 | @GetMapping("/{id}")
29 | public Passenger findPassenger(@PathVariable("id") Long id) {
30 | return passengerRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
31 | }
32 |
33 | @PostMapping
34 | @RolesAllowed("ADMIN")
35 | public Passenger createPassenger(@RequestBody Passenger passenger) {
36 | return passengerRepository.save(passenger);
37 | }
38 |
39 | @PutMapping("/{id}")
40 | public Passenger fullUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
41 | Passenger p = findPassenger(id);
42 | p.setName(passenger.getName());
43 | return passengerRepository.save(p);
44 | }
45 |
46 | @PatchMapping("/{id}")
47 | public Passenger incrementalUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
48 | Passenger foundPassenger = findPassenger(id);
49 | foundPassenger.setName(Optional.ofNullable(passenger.getName()).orElse(foundPassenger.getName()));
50 | return passengerRepository.save(foundPassenger);
51 | }
52 |
53 | @DeleteMapping("/{id}")
54 | public void deletePassenger(@PathVariable("id") Long id) {
55 | passengerRepository.delete(findPassenger(id));
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/interfaces/incoming/TravelRequestAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.interfaces.incoming;
2 |
3 |
4 | import app.car.cap07.domain.TravelRequest;
5 | import app.car.cap07.domain.TravelService;
6 | import app.car.cap07.interfaces.incoming.input.TravelRequestInput;
7 | import app.car.cap07.interfaces.incoming.mapping.TravelRequestMapper;
8 | import app.car.cap07.interfaces.incoming.output.TravelRequestOutput;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.hateoas.EntityModel;
11 | import org.springframework.http.MediaType;
12 | import org.springframework.stereotype.Service;
13 | import org.springframework.web.bind.annotation.*;
14 |
15 | import jakarta.validation.Valid;
16 | import java.util.List;
17 |
18 | @Service
19 | @RestController
20 | @RequestMapping(path = "/travelRequests", produces = MediaType.APPLICATION_JSON_VALUE)
21 | public class TravelRequestAPI {
22 |
23 | @Autowired
24 | TravelService travelService;
25 |
26 | @Autowired
27 | TravelRequestMapper mapper;
28 |
29 | @PostMapping
30 | public EntityModel makeTravelRequest (@RequestBody @Valid TravelRequestInput travelRequestInput) {
31 | TravelRequest request = travelService.saveTravelRequest(mapper.map(travelRequestInput));
32 | TravelRequestOutput output = mapper.map(request);
33 | return mapper.buildOutputModel(request, output);
34 | }
35 |
36 |
37 | @GetMapping("/nearby")
38 | public List> listNearbyRequests(@RequestParam String currentAddress) {
39 | List requests = travelService.listNearbyTravelRequests(currentAddress);
40 | return mapper.buildOutputModel(requests);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/interfaces/incoming/errorhandling/DefaultErrorHandler.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.interfaces.incoming.errorhandling;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.context.MessageSource;
5 | import org.springframework.context.i18n.LocaleContextHolder;
6 | import org.springframework.http.HttpStatus;
7 | import org.springframework.validation.FieldError;
8 | import org.springframework.web.bind.MethodArgumentNotValidException;
9 | import org.springframework.web.bind.annotation.ExceptionHandler;
10 | import org.springframework.web.bind.annotation.ResponseStatus;
11 | import org.springframework.web.bind.annotation.RestControllerAdvice;
12 |
13 | import java.util.List;
14 | import java.util.stream.Collectors;
15 |
16 |
17 | @RestControllerAdvice
18 | public class DefaultErrorHandler {
19 |
20 | @Autowired
21 | private MessageSource messageSource;
22 |
23 | @ExceptionHandler(MethodArgumentNotValidException.class)
24 | @ResponseStatus(HttpStatus.BAD_REQUEST)
25 | public ErrorResponse handleMethodArgumentNotValid(MethodArgumentNotValidException ex) {
26 |
27 | List messages = ex
28 | .getBindingResult()
29 | .getFieldErrors()
30 | .stream()
31 | .map(this::getMessage)
32 | .toList();
33 |
34 | return new ErrorResponse(messages);
35 | }
36 |
37 | private ErrorData getMessage(FieldError fieldError) {
38 |
39 | return new ErrorData(messageSource.getMessage(fieldError, LocaleContextHolder.getLocale()));
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/interfaces/incoming/errorhandling/ErrorData.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.interfaces.incoming.errorhandling;
2 |
3 |
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 |
7 | @AllArgsConstructor
8 | @Data
9 | public class ErrorData {
10 |
11 | private final String message;
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/interfaces/incoming/errorhandling/ErrorResponse.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.interfaces.incoming.errorhandling;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 |
6 | import java.util.List;
7 |
8 | @AllArgsConstructor
9 | @Data
10 | public class ErrorResponse {
11 |
12 | List errors;
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/interfaces/incoming/errorhandling/LocaleResolver.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.interfaces.incoming.errorhandling;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.springframework.stereotype.Component;
5 | import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
6 |
7 | import jakarta.servlet.http.HttpServletRequest;
8 | import java.util.List;
9 | import java.util.Locale;
10 | import java.util.Optional;
11 |
12 | @Component
13 | public class LocaleResolver extends AcceptHeaderLocaleResolver {
14 |
15 | private static final Locale DEFAULT_LOCALE = Locale.of("pt", "BR");
16 |
17 | private static final List ACCEPTED_LOCALES = List.of(DEFAULT_LOCALE, Locale.of("en"));
18 |
19 | @Override
20 | public Locale resolveLocale(HttpServletRequest request) {
21 | final String acceptLanguageHeader = request.getHeader("Accept-Language");
22 | if (StringUtils.isBlank(acceptLanguageHeader) || acceptLanguageHeader.trim().equals("*")) {
23 | return DEFAULT_LOCALE;
24 | }
25 | List list = Locale.LanguageRange.parse(acceptLanguageHeader);
26 | Locale locale = Locale.lookup(list, ACCEPTED_LOCALES);
27 | return Optional.ofNullable(locale).orElse(DEFAULT_LOCALE);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/interfaces/incoming/input/TravelRequestInput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.interfaces.incoming.input;
2 |
3 | import lombok.Data;
4 |
5 | import jakarta.validation.constraints.NotEmpty;
6 | import jakarta.validation.constraints.NotNull;
7 |
8 | @Data
9 | public class TravelRequestInput {
10 |
11 |
12 | @NotNull(message = "O campo passengerId não pode ser nulo")
13 | Long passengerId;
14 |
15 | @NotEmpty(message = "O campo origin não pode estar em branco")
16 | String origin;
17 |
18 | @NotEmpty(message = "O campo destination não pode estar em branco")
19 | String destination;
20 | }
21 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/interfaces/incoming/mapping/TravelRequestMapper.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.interfaces.incoming.mapping;
2 |
3 | import app.car.cap07.domain.Passenger;
4 | import app.car.cap07.domain.PassengerRepository;
5 | import app.car.cap07.domain.TravelRequest;
6 | import app.car.cap07.interfaces.incoming.PassengerAPI;
7 | import app.car.cap07.interfaces.incoming.input.TravelRequestInput;
8 | import app.car.cap07.interfaces.incoming.output.TravelRequestOutput;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.hateoas.EntityModel;
11 | import org.springframework.hateoas.Link;
12 | import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
13 | import org.springframework.http.HttpStatus;
14 | import org.springframework.stereotype.Component;
15 | import org.springframework.web.server.ResponseStatusException;
16 |
17 | import java.util.List;
18 |
19 | @Component
20 | public class TravelRequestMapper {
21 |
22 | @Autowired
23 | private PassengerRepository passengerRepository;
24 |
25 | public TravelRequest map(TravelRequestInput input) {
26 |
27 | Passenger passenger = passengerRepository.findById(input.getPassengerId())
28 | .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
29 |
30 | TravelRequest travelRequest = new TravelRequest();
31 | travelRequest.setOrigin(input.getOrigin());
32 | travelRequest.setDestination(input.getDestination());
33 | travelRequest.setPassenger(passenger);
34 |
35 | return travelRequest;
36 |
37 | }
38 |
39 | public TravelRequestOutput map(TravelRequest travelRequest) {
40 | TravelRequestOutput travelRequestOutput = new TravelRequestOutput();
41 |
42 | travelRequestOutput.setCreationDate(travelRequest.getCreationDate());
43 | travelRequestOutput.setDestination(travelRequest.getDestination());
44 | travelRequestOutput.setId(travelRequest.getId());
45 | travelRequestOutput.setOrigin(travelRequest.getOrigin());
46 | travelRequestOutput.setStatus(travelRequest.getStatus());
47 |
48 | return travelRequestOutput;
49 | }
50 |
51 | public EntityModel buildOutputModel(TravelRequest travelRequest, TravelRequestOutput output) {
52 | EntityModel model = EntityModel.of(output);
53 |
54 | Link passengerLink = WebMvcLinkBuilder
55 | .linkTo(PassengerAPI.class)
56 | .slash(travelRequest.getPassenger().getId())
57 | .withRel("passenger")
58 | .withTitle(travelRequest.getPassenger().getName());
59 | model.add(passengerLink);
60 | return model;
61 | }
62 |
63 | public List> buildOutputModel(List requests) {
64 | return requests.stream().map(tr -> buildOutputModel(tr, map(tr))).toList();
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/interfaces/incoming/output/TravelRequestOutput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.interfaces.incoming.output;
2 |
3 | import app.car.cap07.domain.TravelRequestStatus;
4 | import lombok.Data;
5 |
6 | import java.time.LocalDateTime;
7 |
8 | @Data
9 | public class TravelRequestOutput {
10 |
11 | Long id;
12 | String origin;
13 | String destination;
14 | TravelRequestStatus status;
15 | LocalDateTime creationDate;
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/cap07/src/main/java/app/car/cap07/interfaces/outcoming/GMapsService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.interfaces.outcoming;
2 |
3 |
4 | import com.jayway.jsonpath.JsonPath;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.stereotype.Service;
7 | import org.springframework.web.client.RestTemplate;
8 |
9 | import java.util.List;
10 |
11 | @Service
12 | public class GMapsService {
13 |
14 |
15 | @Value("${app.car.domain.googlemaps.apikey}")
16 | private String appKey;
17 |
18 | @Value("${interfaces.outcoming.gmaps.host:https://maps.googleapis.com}")
19 | private String gMapsHost;
20 |
21 | private static final String GMAPS_TEMPLATE = "/maps/api/directions/json?origin={origin}&destination={destination}&key={key}";
22 |
23 | public Integer getDistanceBetweenAddresses(String addressOne, String addressTwo) {
24 |
25 | RestTemplate template = new RestTemplate();
26 | String jsonResult = template.getForObject(gMapsHost + GMAPS_TEMPLATE, String.class, addressOne, addressTwo, appKey);
27 |
28 | List results = JsonPath.parse(jsonResult).read("$..legs[*].duration.value");
29 | return results.stream().min(Integer::compareTo).orElse(Integer.MAX_VALUE);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/cap07/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | app.car.domain.googlemaps.apikey=chaveGoogle
2 |
3 | server.ssl.key-store=classpath:keystore.p12
4 | server.ssl.key-store-password=restbook
5 | server.ssl.key-store-type=PKCS12
6 | server.ssl.key-alias=car
7 |
--------------------------------------------------------------------------------
/cap07/src/main/resources/i18n/messages_en.properties:
--------------------------------------------------------------------------------
1 | NotNull=The field {0} must not be null
2 | NotEmpty=The field {0} must not be empty
--------------------------------------------------------------------------------
/cap07/src/main/resources/i18n/messages_pt_BR.properties:
--------------------------------------------------------------------------------
1 | NotNull=O campo {0} não pode ser nulo
2 | NotEmpty=O campo {0} não pode estar em branco
--------------------------------------------------------------------------------
/cap07/src/main/resources/keystore.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap07/src/main/resources/keystore.p12
--------------------------------------------------------------------------------
/cap07/src/test/java/app/car/cap07/Cap07ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class Cap07ApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap07/src/test/java/app/car/cap07/infrastructure/FileUtils.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.infrastructure;
2 |
3 | import lombok.SneakyThrows;
4 | import org.springframework.core.io.ClassPathResource;
5 |
6 | import java.io.InputStream;
7 | import java.util.Map;
8 |
9 | public class FileUtils {
10 |
11 |
12 | @SneakyThrows
13 | public static String loadFileContents(String fileName) {
14 |
15 | InputStream is = new ClassPathResource(fileName).getInputStream();
16 | byte[] data = new byte[is.available()];
17 | is.read(data);
18 | return new String(data);
19 | }
20 |
21 | public static String loadFileContents(String fileName, Map replacements) {
22 | String fileContents = loadFileContents(fileName);
23 |
24 | for (Map.Entry entry : replacements.entrySet()) {
25 | fileContents = fileContents.replace("{{" + entry.getKey() + "}}", entry.getValue());
26 | }
27 | return fileContents;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/cap07/src/test/java/app/car/cap07/interfaces/incoming/PassengerAPITestIT.java:
--------------------------------------------------------------------------------
1 | package app.car.cap07.interfaces.incoming;
2 |
3 | import io.restassured.RestAssured;
4 | import org.junit.jupiter.api.BeforeEach;
5 | import org.junit.jupiter.api.Test;
6 | import org.springframework.boot.test.context.SpringBootTest;
7 | import org.springframework.boot.test.web.server.LocalServerPort;
8 |
9 |
10 | import static io.restassured.RestAssured.basic;
11 | import static io.restassured.RestAssured.given;
12 | import static org.hamcrest.Matchers.equalTo;
13 | import static org.hamcrest.Matchers.notNullValue;
14 |
15 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
16 | class PassengerAPITestIT {
17 |
18 | @LocalServerPort
19 | private int port;
20 |
21 | @BeforeEach
22 | void setup() {
23 | RestAssured.baseURI = "https://localhost:" + port;
24 | RestAssured.useRelaxedHTTPSValidation();
25 | RestAssured.authentication = basic("admin", "password");
26 | }
27 |
28 | @Test
29 | void testCreatePassenger() {
30 |
31 |
32 | String createPassengerJSON = "{\"name\":\"Alexandre Saudate\"}";
33 |
34 |
35 | given()
36 | .contentType(io.restassured.http.ContentType.JSON)
37 | .body(createPassengerJSON)
38 | .post("/passengers")
39 | .then()
40 | .statusCode(200)
41 | .body("id", notNullValue())
42 | .body("name", equalTo("Alexandre Saudate"))
43 | ;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/cap07/src/test/resources/application-test.properties:
--------------------------------------------------------------------------------
1 | interfaces.outcoming.gmaps.host=http://localhost:${wiremock.server.port}
--------------------------------------------------------------------------------
/cap07/src/test/resources/requests/passengers_api/create_new_passenger.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Alexandre Saudate"
3 | }
--------------------------------------------------------------------------------
/cap07/src/test/resources/requests/travel_requests_api/create_new_request.json:
--------------------------------------------------------------------------------
1 | {
2 | "passengerId":"{{passengerId}}",
3 | "origin":"Avenida Paulista, 1000",
4 | "destination":"Avenida Ipiranga, 100"
5 | }
--------------------------------------------------------------------------------
/cap08/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/cap08/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap08/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/cap08/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/Cap08Application.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Cap08Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Cap08Application.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/config/AppConfig.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.config;
2 |
3 | import org.springframework.context.MessageSource;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.context.support.ReloadableResourceBundleMessageSource;
7 | import org.springframework.context.support.ResourceBundleMessageSource;
8 |
9 | @Configuration
10 | public class AppConfig {
11 |
12 |
13 | @Bean
14 | public MessageSource messageSource() {
15 | ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
16 | messageSource.setBasename("classpath:i18n/messages");
17 | messageSource.setDefaultEncoding("UTF-8");
18 | return messageSource;
19 | }
20 |
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/config/LoadUserConfig.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.config;
2 |
3 | import app.car.cap08.domain.User;
4 | import app.car.cap08.domain.UserRepository;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.security.crypto.password.PasswordEncoder;
8 |
9 | import jakarta.annotation.PostConstruct;
10 | import java.util.Arrays;
11 |
12 | @Configuration
13 | public class LoadUserConfig {
14 |
15 |
16 | @Autowired
17 | PasswordEncoder passwordEncoder;
18 |
19 | @Autowired
20 | UserRepository userRepository;
21 |
22 | @PostConstruct
23 | public void init() {
24 | app.car.cap08.domain.User admin = new User();
25 | admin.setPassword(passwordEncoder.encode("password"));
26 | admin.setRoles(Arrays.asList("ROLE_ADMIN"));
27 | admin.setUsername("admin");
28 | admin.setEnabled(true);
29 |
30 | userRepository.save(admin);
31 | }
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/config/OpenAPIConfig.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.config;
2 |
3 | import io.swagger.v3.oas.models.OpenAPI;
4 | import io.swagger.v3.oas.models.info.Contact;
5 | import io.swagger.v3.oas.models.info.Info;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 |
9 | @Configuration
10 | public class OpenAPIConfig {
11 |
12 |
13 | @Bean
14 | public OpenAPI openAPIDocumentation() {
15 | return new OpenAPI()
16 | .info(
17 | new Info()
18 | .title("C.A.R. API")
19 | .description("API do sistema C.A.R., de facilitação de mobilidade urbana")
20 | .version("v1.0")
21 | .contact(new Contact()
22 | .name("Alexandre Saudate")
23 | .email("alesaudate@gmail.com")
24 | )
25 | );
26 | }
27 |
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/config/SecurityConfig.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.config;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.http.HttpMethod;
7 | import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
10 | import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
11 | import org.springframework.security.config.http.SessionCreationPolicy;
12 | import org.springframework.security.core.userdetails.UserDetailsService;
13 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
14 | import org.springframework.security.crypto.password.PasswordEncoder;
15 | import org.springframework.security.provisioning.JdbcUserDetailsManager;
16 | import org.springframework.security.web.DefaultSecurityFilterChain;
17 |
18 | import javax.sql.DataSource;
19 |
20 | import static org.springframework.security.config.Customizer.withDefaults;
21 |
22 |
23 | @Configuration
24 | @EnableWebSecurity
25 | @EnableMethodSecurity(jsr250Enabled = true)
26 | public class SecurityConfig {
27 |
28 |
29 | @Autowired
30 | DataSource dataSource;
31 |
32 | @Bean
33 | public DefaultSecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
34 | http.csrf(CsrfConfigurer::disable);
35 | http.sessionManagement(configure -> configure.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
36 | http.authorizeHttpRequests(configure ->
37 | configure
38 | .requestMatchers(HttpMethod.GET, "/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs/**")
39 | .permitAll());
40 | http.authorizeHttpRequests(configure -> configure.anyRequest().authenticated());
41 | http.httpBasic(withDefaults());
42 | http.headers(c1 -> c1.frameOptions(c2 -> c2.disable()));
43 | return http.build();
44 | }
45 |
46 |
47 | @Bean
48 | public UserDetailsService userDetailsService() {
49 | var jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
50 | jdbcUserDetailsManager.setUsersByUsernameQuery("select username, password, enabled from users where username=?");
51 | jdbcUserDetailsManager.setAuthoritiesByUsernameQuery("select u.username, r.roles from user_roles r, users u where r.user_id = u.id and u.username=?");
52 | return jdbcUserDetailsManager;
53 | }
54 |
55 |
56 | @Bean
57 | public PasswordEncoder passwordEncoder() {
58 | return new BCryptPasswordEncoder();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/domain/Driver.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.domain;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import jakarta.persistence.Entity;
5 | import jakarta.persistence.GeneratedValue;
6 | import jakarta.persistence.Id;
7 | import jakarta.validation.constraints.Size;
8 | import lombok.Data;
9 |
10 | import java.time.LocalDate;
11 |
12 | @Data
13 | @Entity
14 | @Schema(description = "Representa um motorista dentro da plataforma")
15 | public class Driver {
16 |
17 |
18 | @Id
19 | @GeneratedValue
20 | Long id;
21 |
22 | @Schema(description = "Nome do motorista")
23 | @Size(min=5, max = 255)
24 | String name;
25 |
26 | @Schema(description = "Data de nascimento do motorista")
27 | LocalDate birthDate;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/domain/DriverRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface DriverRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/domain/Passenger.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 |
9 | @Data
10 | @Entity
11 | public class Passenger {
12 |
13 |
14 | @Id
15 | @GeneratedValue
16 | Long id;
17 | String name;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/domain/PassengerRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface PassengerRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/domain/TravelRequest.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.domain;
2 |
3 |
4 | import jakarta.persistence.Entity;
5 | import jakarta.persistence.EnumType;
6 | import jakarta.persistence.Enumerated;
7 | import jakarta.persistence.GeneratedValue;
8 | import jakarta.persistence.Id;
9 | import jakarta.persistence.ManyToOne;
10 | import lombok.Data;
11 |
12 | import java.time.LocalDateTime;
13 |
14 | @Data
15 | @Entity
16 | public class TravelRequest {
17 |
18 | @Id
19 | @GeneratedValue
20 | Long id;
21 |
22 | @ManyToOne
23 | Passenger passenger;
24 | String origin;
25 | String destination;
26 |
27 | @Enumerated(EnumType.STRING)
28 | TravelRequestStatus status;
29 | LocalDateTime creationDate;
30 | }
31 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/domain/TravelRequestRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.domain;
2 |
3 | import java.util.List;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | public interface TravelRequestRepository extends JpaRepository {
7 |
8 | List findByStatus(TravelRequestStatus status);
9 | }
10 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/domain/TravelRequestStatus.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.domain;
2 |
3 | public enum TravelRequestStatus {
4 | CREATED, ACCEPTED, REFUSED;
5 | }
6 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/domain/TravelService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.domain;
2 |
3 |
4 | import app.car.cap08.interfaces.outcoming.GMapsService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Service;
7 |
8 | import java.time.LocalDateTime;
9 | import java.util.List;
10 |
11 | @Service
12 | public class TravelService {
13 |
14 |
15 | @Autowired
16 | TravelRequestRepository travelRequestRepository;
17 |
18 | @Autowired
19 | GMapsService gMapsService;
20 |
21 | private static final int MAX_TRAVEL_TIME = 600;
22 |
23 | public TravelRequest saveTravelRequest(TravelRequest travelRequest) {
24 | travelRequest.setStatus(TravelRequestStatus.CREATED);
25 | travelRequest.setCreationDate(LocalDateTime.now());
26 | return travelRequestRepository.save(travelRequest);
27 | }
28 |
29 |
30 | public List listNearbyTravelRequests(String currentAddress) {
31 | List requests = travelRequestRepository.findByStatus(TravelRequestStatus.CREATED);
32 | return requests
33 | .stream()
34 | .filter(tr -> gMapsService.getDistanceBetweenAddresses(currentAddress, tr.getOrigin()) < MAX_TRAVEL_TIME)
35 | .toList();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/domain/User.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.domain;
2 |
3 |
4 | import jakarta.persistence.Column;
5 | import jakarta.persistence.ElementCollection;
6 | import jakarta.persistence.Entity;
7 | import jakarta.persistence.GeneratedValue;
8 | import jakarta.persistence.Id;
9 | import jakarta.persistence.Table;
10 | import lombok.Data;
11 |
12 | import java.util.List;
13 |
14 | @Data
15 | @Entity
16 | @Table(name = "users")
17 | public class User {
18 |
19 | @Id
20 | @GeneratedValue
21 | Long id;
22 |
23 | @Column(unique = true)
24 | String username;
25 | String password;
26 |
27 | Boolean enabled;
28 |
29 | @ElementCollection
30 | List roles;
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/domain/UserRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface UserRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/interfaces/incoming/DriverAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.incoming;
2 |
3 | import app.car.cap08.domain.Driver;
4 | import app.car.cap08.interfaces.incoming.errorhandling.ErrorResponse;
5 | import io.swagger.v3.oas.annotations.Operation;
6 | import io.swagger.v3.oas.annotations.Parameter;
7 | import io.swagger.v3.oas.annotations.media.Content;
8 | import io.swagger.v3.oas.annotations.media.Schema;
9 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
10 | import io.swagger.v3.oas.annotations.tags.Tag;
11 |
12 | import java.util.List;
13 |
14 | @Tag(name = "Driver API", description = "Manipula dados de motoristas.")
15 | public interface DriverAPI {
16 |
17 |
18 | @Operation(description = "Lista todos os motoristas disponíveis")
19 | List listDrivers() ;
20 |
21 |
22 | @Operation(
23 | description = "Localiza um motorista específico",
24 | responses = {
25 | @ApiResponse(responseCode = "200", description = "Caso o motorista tenha sido encontrado na base"),
26 | @ApiResponse(responseCode = "404",
27 | description = "Caso o motorista não tenha sido encontrado",
28 | content = @Content(schema = @Schema(implementation = ErrorResponse.class))
29 | )
30 | })
31 | Driver findDriver(
32 | @Parameter(description = "ID do motorista a ser localizado") Long id) ;
33 |
34 | Driver createDriver(
35 | @Parameter(description = "Dados do motorista a ser criado") Driver driver) ;
36 |
37 | Driver fullUpdateDriver(Long id, Driver driver);
38 |
39 | Driver incrementalUpdateDriver(Long id, Driver driver) ;
40 |
41 | void deleteDriver(Long id) ;
42 |
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/interfaces/incoming/DriverAPIImpl.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.incoming;
2 |
3 | import app.car.cap08.domain.Driver;
4 | import app.car.cap08.domain.DriverRepository;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.http.HttpStatus;
7 | import org.springframework.http.MediaType;
8 | import org.springframework.stereotype.Service;
9 | import org.springframework.web.bind.annotation.*;
10 | import org.springframework.web.server.ResponseStatusException;
11 |
12 | import java.util.List;
13 | import java.util.Optional;
14 |
15 | @Service
16 | @RestController()
17 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
18 | public class DriverAPIImpl implements DriverAPI {
19 |
20 | @Autowired
21 | DriverRepository driverRepository;
22 |
23 | @GetMapping("/drivers")
24 | public List listDrivers() {
25 | return driverRepository.findAll();
26 | }
27 |
28 | @GetMapping("/drivers/{id}")
29 | public Driver findDriver(
30 | @PathVariable("id") Long id) {
31 | return driverRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
32 | }
33 |
34 | @PostMapping("/drivers")
35 | public Driver createDriver(
36 | @RequestBody Driver driver) {
37 | return driverRepository.save(driver);
38 | }
39 |
40 | @PutMapping("/drivers/{id}")
41 | public Driver fullUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
42 | Driver foundDriver = findDriver(id);
43 | foundDriver.setBirthDate(driver.getBirthDate());
44 | foundDriver.setName(driver.getName());
45 | return driverRepository.save(foundDriver);
46 | }
47 |
48 | @PatchMapping("/drivers/{id}")
49 | public Driver incrementalUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
50 | Driver foundDriver = findDriver(id);
51 | foundDriver.setBirthDate(Optional.ofNullable(driver.getBirthDate()).orElse(foundDriver.getBirthDate()));
52 | foundDriver.setName(Optional.ofNullable(driver.getName()).orElse(foundDriver.getName()));
53 | return driverRepository.save(foundDriver);
54 | }
55 |
56 | @DeleteMapping("/drivers/{id}")
57 | public void deleteDriver(@PathVariable("id") Long id) {
58 | driverRepository.delete(findDriver(id));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/interfaces/incoming/PassengerAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.incoming;
2 |
3 | import app.car.cap08.domain.Passenger;
4 | import app.car.cap08.domain.PassengerRepository;
5 | import java.util.List;
6 | import java.util.Optional;
7 | import jakarta.annotation.security.RolesAllowed;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.http.HttpStatus;
10 | import org.springframework.http.MediaType;
11 | import org.springframework.stereotype.Service;
12 | import org.springframework.web.bind.annotation.*;
13 | import org.springframework.web.server.ResponseStatusException;
14 |
15 | @Service
16 | @RestController
17 | @RequestMapping(path="/passengers", produces = MediaType.APPLICATION_JSON_VALUE)
18 | public class PassengerAPI {
19 |
20 | @Autowired
21 | PassengerRepository passengerRepository;
22 |
23 | @GetMapping()
24 | public List listPassengers() {
25 | return passengerRepository.findAll();
26 | }
27 |
28 | @GetMapping("/{id}")
29 | public Passenger findPassenger(@PathVariable("id") Long id) {
30 | return passengerRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
31 | }
32 |
33 | @PostMapping
34 | @RolesAllowed("ADMIN")
35 | public Passenger createPassenger(@RequestBody Passenger passenger) {
36 | return passengerRepository.save(passenger);
37 | }
38 |
39 | @PutMapping("/{id}")
40 | public Passenger fullUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
41 | Passenger p = findPassenger(id);
42 | p.setName(passenger.getName());
43 | return passengerRepository.save(p);
44 | }
45 |
46 | @PatchMapping("/{id}")
47 | public Passenger incrementalUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
48 | Passenger foundPassenger = findPassenger(id);
49 | foundPassenger.setName(Optional.ofNullable(passenger.getName()).orElse(foundPassenger.getName()));
50 | return passengerRepository.save(foundPassenger);
51 | }
52 |
53 | @DeleteMapping("/{id}")
54 | public void deletePassenger(@PathVariable("id") Long id) {
55 | passengerRepository.delete(findPassenger(id));
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/interfaces/incoming/TravelRequestAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.incoming;
2 |
3 |
4 | import app.car.cap08.domain.TravelRequest;
5 | import app.car.cap08.domain.TravelService;
6 | import app.car.cap08.interfaces.incoming.input.TravelRequestInput;
7 | import app.car.cap08.interfaces.incoming.mapping.TravelRequestMapper;
8 | import app.car.cap08.interfaces.incoming.output.TravelRequestOutput;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.hateoas.EntityModel;
11 | import org.springframework.http.MediaType;
12 | import org.springframework.stereotype.Service;
13 | import org.springframework.web.bind.annotation.*;
14 |
15 | import jakarta.validation.Valid;
16 | import java.util.List;
17 |
18 | @Service
19 | @RestController
20 | @RequestMapping(path = "/travelRequests", produces = MediaType.APPLICATION_JSON_VALUE)
21 | public class TravelRequestAPI {
22 |
23 | @Autowired
24 | TravelService travelService;
25 |
26 | @Autowired
27 | TravelRequestMapper mapper;
28 |
29 | @PostMapping
30 | public EntityModel makeTravelRequest (@RequestBody @Valid TravelRequestInput travelRequestInput) {
31 | TravelRequest request = travelService.saveTravelRequest(mapper.map(travelRequestInput));
32 | TravelRequestOutput output = mapper.map(request);
33 | return mapper.buildOutputModel(request, output);
34 | }
35 |
36 |
37 | @GetMapping("/nearby")
38 | public List> listNearbyRequests(@RequestParam String currentAddress) {
39 | List requests = travelService.listNearbyTravelRequests(currentAddress);
40 | return mapper.buildOutputModel(requests);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/interfaces/incoming/errorhandling/DefaultErrorHandler.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.incoming.errorhandling;
2 |
3 | import io.swagger.v3.oas.annotations.media.Content;
4 | import io.swagger.v3.oas.annotations.media.Schema;
5 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
6 | import io.swagger.v3.oas.annotations.responses.ApiResponses;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.context.MessageSource;
9 | import org.springframework.context.i18n.LocaleContextHolder;
10 | import org.springframework.http.HttpStatus;
11 | import org.springframework.validation.FieldError;
12 | import org.springframework.web.bind.MethodArgumentNotValidException;
13 | import org.springframework.web.bind.annotation.ExceptionHandler;
14 | import org.springframework.web.bind.annotation.ResponseStatus;
15 | import org.springframework.web.bind.annotation.RestControllerAdvice;
16 |
17 | import java.util.List;
18 | import java.util.stream.Collectors;
19 |
20 |
21 | @RestControllerAdvice
22 | public class DefaultErrorHandler {
23 |
24 | @Autowired
25 | private MessageSource messageSource;
26 |
27 | @ExceptionHandler(MethodArgumentNotValidException.class)
28 | @ResponseStatus(HttpStatus.BAD_REQUEST)
29 | @ApiResponses(
30 | @ApiResponse(responseCode = "400", content = @Content(
31 | mediaType = "application/json",
32 | schema = @Schema(implementation = ErrorResponse.class)
33 | ))
34 | )
35 | public ErrorResponse handleMethodArgumentNotValid(MethodArgumentNotValidException ex) {
36 |
37 | List messages = ex
38 | .getBindingResult()
39 | .getFieldErrors()
40 | .stream()
41 | .map(this::getMessage)
42 | .collect(Collectors.toList());
43 |
44 | return new ErrorResponse(messages);
45 | }
46 |
47 | private ErrorData getMessage(FieldError fieldError) {
48 |
49 | return new ErrorData(messageSource.getMessage(fieldError, LocaleContextHolder.getLocale()));
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/interfaces/incoming/errorhandling/ErrorData.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.incoming.errorhandling;
2 |
3 |
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 |
7 | @AllArgsConstructor
8 | @Data
9 | public class ErrorData {
10 |
11 | private final String message;
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/interfaces/incoming/errorhandling/ErrorResponse.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.incoming.errorhandling;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 |
6 | import java.util.List;
7 |
8 | @AllArgsConstructor
9 | @Data
10 | public class ErrorResponse {
11 |
12 | List errors;
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/interfaces/incoming/errorhandling/LocaleResolver.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.incoming.errorhandling;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.springframework.stereotype.Component;
5 | import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
6 |
7 | import jakarta.servlet.http.HttpServletRequest;
8 | import java.util.Arrays;
9 | import java.util.List;
10 | import java.util.Locale;
11 | import java.util.Optional;
12 |
13 | @Component
14 | public class LocaleResolver extends AcceptHeaderLocaleResolver {
15 |
16 | private static final Locale DEFAULT_LOCALE = Locale.of("pt", "BR");
17 |
18 | private static final List ACCEPTED_LOCALES = Arrays.asList(
19 |
20 | DEFAULT_LOCALE,
21 | new Locale("en")
22 | );
23 |
24 | @Override
25 | public Locale resolveLocale(HttpServletRequest request) {
26 | final String acceptLanguageHeader = request.getHeader("Accept-Language");
27 | if (StringUtils.isBlank(acceptLanguageHeader) || acceptLanguageHeader.trim().equals("*")) {
28 | return DEFAULT_LOCALE;
29 | }
30 | List list = Locale.LanguageRange.parse(acceptLanguageHeader);
31 | Locale locale = Locale.lookup(list, ACCEPTED_LOCALES);
32 | return Optional.ofNullable(locale).orElse(DEFAULT_LOCALE);
33 | }
34 |
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/interfaces/incoming/input/TravelRequestInput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.incoming.input;
2 |
3 | import lombok.Data;
4 |
5 | import jakarta.validation.constraints.NotEmpty;
6 | import jakarta.validation.constraints.NotNull;
7 |
8 | @Data
9 | public class TravelRequestInput {
10 |
11 |
12 | @NotNull(message = "O campo passengerId não pode ser nulo")
13 | Long passengerId;
14 |
15 | @NotEmpty(message = "O campo origin não pode estar em branco")
16 | String origin;
17 |
18 | @NotEmpty(message = "O campo destination não pode estar em branco")
19 | String destination;
20 | }
21 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/interfaces/incoming/mapping/TravelRequestMapper.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.incoming.mapping;
2 |
3 | import app.car.cap08.domain.Passenger;
4 | import app.car.cap08.domain.PassengerRepository;
5 | import app.car.cap08.domain.TravelRequest;
6 | import app.car.cap08.interfaces.incoming.PassengerAPI;
7 | import app.car.cap08.interfaces.incoming.input.TravelRequestInput;
8 | import app.car.cap08.interfaces.incoming.output.TravelRequestOutput;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.hateoas.EntityModel;
11 | import org.springframework.hateoas.Link;
12 | import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
13 | import org.springframework.http.HttpStatus;
14 | import org.springframework.stereotype.Component;
15 | import org.springframework.web.server.ResponseStatusException;
16 |
17 | import java.util.List;
18 |
19 | @Component
20 | public class TravelRequestMapper {
21 |
22 | @Autowired
23 | private PassengerRepository passengerRepository;
24 |
25 | public TravelRequest map(TravelRequestInput input) {
26 |
27 | Passenger passenger = passengerRepository.findById(input.getPassengerId())
28 | .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
29 |
30 | TravelRequest travelRequest = new TravelRequest();
31 | travelRequest.setOrigin(input.getOrigin());
32 | travelRequest.setDestination(input.getDestination());
33 | travelRequest.setPassenger(passenger);
34 |
35 | return travelRequest;
36 |
37 | }
38 |
39 | public TravelRequestOutput map(TravelRequest travelRequest) {
40 | TravelRequestOutput travelRequestOutput = new TravelRequestOutput();
41 |
42 | travelRequestOutput.setCreationDate(travelRequest.getCreationDate());
43 | travelRequestOutput.setDestination(travelRequest.getDestination());
44 | travelRequestOutput.setId(travelRequest.getId());
45 | travelRequestOutput.setOrigin(travelRequest.getOrigin());
46 | travelRequestOutput.setStatus(travelRequest.getStatus());
47 |
48 | return travelRequestOutput;
49 | }
50 |
51 | public EntityModel buildOutputModel(TravelRequest travelRequest, TravelRequestOutput output) {
52 | EntityModel model = EntityModel.of(output);
53 |
54 | Link passengerLink = WebMvcLinkBuilder
55 | .linkTo(PassengerAPI.class)
56 | .slash(travelRequest.getPassenger().getId())
57 | .withRel("passenger")
58 | .withTitle(travelRequest.getPassenger().getName());
59 | model.add(passengerLink);
60 | return model;
61 | }
62 |
63 | public List> buildOutputModel(List requests) {
64 | return requests.stream().map(tr -> buildOutputModel(tr, map(tr))).toList();
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/interfaces/incoming/output/TravelRequestOutput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.incoming.output;
2 |
3 | import app.car.cap08.domain.TravelRequestStatus;
4 | import lombok.Data;
5 |
6 | import java.time.LocalDateTime;
7 |
8 | @Data
9 | public class TravelRequestOutput {
10 |
11 | Long id;
12 | String origin;
13 | String destination;
14 | TravelRequestStatus status;
15 | LocalDateTime creationDate;
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/cap08/src/main/java/app/car/cap08/interfaces/outcoming/GMapsService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.outcoming;
2 |
3 |
4 | import com.jayway.jsonpath.JsonPath;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.stereotype.Service;
7 | import org.springframework.web.client.RestTemplate;
8 |
9 | import java.util.List;
10 |
11 | @Service
12 | public class GMapsService {
13 |
14 |
15 | @Value("${app.car.domain.googlemaps.apikey}")
16 | private String appKey;
17 |
18 | @Value("${interfaces.outcoming.gmaps.host:https://maps.googleapis.com}")
19 | private String gMapsHost;
20 |
21 | private static final String GMAPS_TEMPLATE = "/maps/api/directions/json?origin={origin}&destination={destination}&key={key}";
22 |
23 | public Integer getDistanceBetweenAddresses(String addressOne, String addressTwo) {
24 |
25 | RestTemplate template = new RestTemplate();
26 | String jsonResult = template.getForObject(gMapsHost + GMAPS_TEMPLATE, String.class, addressOne, addressTwo, appKey);
27 |
28 | List results = JsonPath.parse(jsonResult).read("$..legs[*].duration.value");
29 | return results.stream().min(Integer::compareTo).orElse(Integer.MAX_VALUE);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/cap08/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | app.car.domain.googlemaps.apikey=chaveGoogle
2 |
3 | server.ssl.key-store=classpath:keystore.p12
4 | server.ssl.key-store-password=restbook
5 | server.ssl.key-store-type=PKCS12
6 | server.ssl.key-alias=car
7 |
--------------------------------------------------------------------------------
/cap08/src/main/resources/i18n/messages_en.properties:
--------------------------------------------------------------------------------
1 | NotNull=The field {0} must not be null
2 | NotEmpty=The field {0} must not be empty
--------------------------------------------------------------------------------
/cap08/src/main/resources/i18n/messages_pt_BR.properties:
--------------------------------------------------------------------------------
1 | NotNull=O campo {0} não pode ser nulo
2 | NotEmpty=O campo {0} não pode estar em branco
--------------------------------------------------------------------------------
/cap08/src/main/resources/keystore.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap08/src/main/resources/keystore.p12
--------------------------------------------------------------------------------
/cap08/src/test/java/app/car/cap08/Cap08ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class Cap08ApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap08/src/test/java/app/car/cap08/infrastructure/FileUtils.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.infrastructure;
2 |
3 | import lombok.SneakyThrows;
4 | import org.springframework.core.io.ClassPathResource;
5 |
6 | import java.io.InputStream;
7 | import java.util.Map;
8 |
9 | public class FileUtils {
10 |
11 |
12 | @SneakyThrows
13 | public static String loadFileContents(String fileName) {
14 |
15 | InputStream is = new ClassPathResource(fileName).getInputStream();
16 | byte[] data = new byte[is.available()];
17 | is.read(data);
18 | return new String(data);
19 | }
20 |
21 | public static String loadFileContents(String fileName, Map replacements) {
22 | String fileContents = loadFileContents(fileName);
23 |
24 | for (Map.Entry entry : replacements.entrySet()) {
25 | fileContents = fileContents.replace("{{" + entry.getKey() + "}}", entry.getValue());
26 | }
27 | return fileContents;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/cap08/src/test/java/app/car/cap08/interfaces/incoming/PassengerAPITestIT.java:
--------------------------------------------------------------------------------
1 | package app.car.cap08.interfaces.incoming;
2 |
3 | import io.restassured.RestAssured;
4 | import org.junit.jupiter.api.BeforeEach;
5 | import org.junit.jupiter.api.Test;
6 | import org.springframework.boot.test.context.SpringBootTest;
7 | import org.springframework.boot.test.web.server.LocalServerPort;
8 |
9 | import static io.restassured.RestAssured.basic;
10 | import static io.restassured.RestAssured.given;
11 | import static org.hamcrest.Matchers.equalTo;
12 | import static org.hamcrest.Matchers.notNullValue;
13 |
14 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
15 | class PassengerAPITestIT {
16 |
17 | @LocalServerPort
18 | private int port;
19 |
20 | @BeforeEach
21 | void setup() {
22 | RestAssured.baseURI = "https://localhost:" + port;
23 | RestAssured.useRelaxedHTTPSValidation();
24 | RestAssured.authentication = basic("admin", "password");
25 | }
26 |
27 | @Test
28 | void testCreatePassenger() {
29 |
30 |
31 | String createPassengerJSON = "{\"name\":\"Alexandre Saudate\"}";
32 |
33 |
34 | given()
35 | .contentType(io.restassured.http.ContentType.JSON)
36 | .body(createPassengerJSON)
37 | .post("/passengers")
38 | .then()
39 | .statusCode(200)
40 | .body("id", notNullValue())
41 | .body("name", equalTo("Alexandre Saudate"))
42 | ;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/cap08/src/test/resources/application-test.properties:
--------------------------------------------------------------------------------
1 | interfaces.outcoming.gmaps.host=http://localhost:${wiremock.server.port}
--------------------------------------------------------------------------------
/cap08/src/test/resources/requests/passengers_api/create_new_passenger.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Alexandre Saudate"
3 | }
--------------------------------------------------------------------------------
/cap08/src/test/resources/requests/travel_requests_api/create_new_request.json:
--------------------------------------------------------------------------------
1 | {
2 | "passengerId":"{{passengerId}}",
3 | "origin":"Avenida Paulista, 1000",
4 | "destination":"Avenida Ipiranga, 100"
5 | }
--------------------------------------------------------------------------------
/cap09/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/cap09/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap09/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/cap09/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/Cap09Application.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Cap09Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Cap09Application.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/config/AppConfig.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.config;
2 |
3 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
4 | import org.springframework.context.MessageSource;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.context.support.ReloadableResourceBundleMessageSource;
8 |
9 | @Configuration
10 | @EnableAutoConfiguration
11 | public class AppConfig {
12 |
13 |
14 | @Bean
15 | public MessageSource messageSource() {
16 | ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
17 | messageSource.setBasename("classpath:i18n/messages");
18 | messageSource.setDefaultEncoding("UTF-8");
19 | return messageSource;
20 | }
21 |
22 |
23 |
24 |
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/config/LoadUserConfig.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.config;
2 |
3 | import app.car.cap09.domain.User;
4 | import app.car.cap09.domain.UserRepository;
5 | import jakarta.annotation.PostConstruct;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.security.crypto.password.PasswordEncoder;
9 |
10 | import java.util.List;
11 |
12 | @Configuration
13 | public class LoadUserConfig {
14 |
15 |
16 | @Autowired
17 | PasswordEncoder passwordEncoder;
18 |
19 | @Autowired
20 | UserRepository userRepository;
21 |
22 | @PostConstruct
23 | public void init() {
24 | User admin = new User();
25 | admin.setPassword(passwordEncoder.encode("password"));
26 | admin.setRoles(List.of("ROLE_ADMIN"));
27 | admin.setUsername("admin");
28 | admin.setEnabled(true);
29 |
30 | userRepository.save(admin);
31 | }
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/config/OpenAPIConfig.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.config;
2 |
3 | import io.swagger.v3.oas.models.OpenAPI;
4 | import io.swagger.v3.oas.models.info.Contact;
5 | import io.swagger.v3.oas.models.info.Info;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 |
9 | @Configuration
10 | public class OpenAPIConfig {
11 |
12 |
13 | @Bean
14 | public OpenAPI openAPIDocumentation() {
15 | return new OpenAPI()
16 | .info(
17 | new Info()
18 | .title("C.A.R. API")
19 | .description("API do sistema C.A.R., de facilitação de mobilidade urbana")
20 | .version("v1.0")
21 | .contact(new Contact()
22 | .name("Alexandre Saudate")
23 | .email("alesaudate@gmail.com")
24 | )
25 | );
26 | }
27 |
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/domain/Driver.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.domain;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import jakarta.persistence.Entity;
5 | import jakarta.persistence.GeneratedValue;
6 | import jakarta.persistence.Id;
7 | import jakarta.validation.constraints.Size;
8 | import lombok.Data;
9 |
10 | import java.time.LocalDate;
11 |
12 | @Data
13 | @Entity
14 | @Schema(description = "Representa um motorista dentro da plataforma")
15 | public class Driver {
16 |
17 |
18 | @Id
19 | @GeneratedValue
20 | Long id;
21 |
22 | @Schema(description = "Nome do motorista")
23 | @Size(min=5, max = 255)
24 | String name;
25 |
26 | @Schema(description = "Data de nascimento do motorista")
27 | LocalDate birthDate;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/domain/DriverRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface DriverRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/domain/Passenger.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.domain;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.Id;
6 | import lombok.Data;
7 |
8 |
9 | @Data
10 | @Entity
11 | public class Passenger {
12 |
13 |
14 | @Id
15 | @GeneratedValue
16 | Long id;
17 | String name;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/domain/PassengerRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface PassengerRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/domain/TravelRequest.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.domain;
2 |
3 |
4 | import jakarta.persistence.Entity;
5 | import jakarta.persistence.EnumType;
6 | import jakarta.persistence.Enumerated;
7 | import jakarta.persistence.GeneratedValue;
8 | import jakarta.persistence.Id;
9 | import jakarta.persistence.ManyToOne;
10 | import lombok.Data;
11 |
12 | import java.time.LocalDateTime;
13 |
14 | @Data
15 | @Entity
16 | public class TravelRequest {
17 |
18 | @Id
19 | @GeneratedValue
20 | Long id;
21 |
22 | @ManyToOne
23 | Passenger passenger;
24 | String origin;
25 | String destination;
26 |
27 | @Enumerated(EnumType.STRING)
28 | TravelRequestStatus status;
29 | LocalDateTime creationDate;
30 | }
31 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/domain/TravelRequestRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.domain;
2 |
3 | import java.util.List;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | public interface TravelRequestRepository extends JpaRepository {
7 |
8 | List findByStatus(TravelRequestStatus status);
9 | }
10 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/domain/TravelRequestStatus.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.domain;
2 |
3 | public enum TravelRequestStatus {
4 | CREATED, ACCEPTED, REFUSED;
5 | }
6 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/domain/TravelService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.domain;
2 |
3 |
4 | import app.car.cap09.interfaces.outcoming.GMapsService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Service;
7 |
8 | import java.time.LocalDateTime;
9 | import java.util.List;
10 |
11 | @Service
12 | public class TravelService {
13 |
14 |
15 | @Autowired
16 | TravelRequestRepository travelRequestRepository;
17 |
18 | @Autowired
19 | GMapsService gMapsService;
20 |
21 | private static final int MAX_TRAVEL_TIME = 600;
22 |
23 | public TravelRequest saveTravelRequest(TravelRequest travelRequest) {
24 | travelRequest.setStatus(TravelRequestStatus.CREATED);
25 | travelRequest.setCreationDate(LocalDateTime.now());
26 | return travelRequestRepository.save(travelRequest);
27 | }
28 |
29 |
30 | public List listNearbyTravelRequests(String currentAddress) {
31 | List requests = travelRequestRepository.findByStatus(TravelRequestStatus.CREATED);
32 | return requests
33 | .stream()
34 | .filter(tr -> gMapsService.getDistanceBetweenAddresses(currentAddress, tr.getOrigin()) < MAX_TRAVEL_TIME)
35 | .toList();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/domain/User.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.domain;
2 |
3 |
4 | import java.util.List;
5 | import jakarta.persistence.Column;
6 | import jakarta.persistence.ElementCollection;
7 | import jakarta.persistence.Entity;
8 | import jakarta.persistence.GeneratedValue;
9 | import jakarta.persistence.Id;
10 | import jakarta.persistence.Table;
11 | import lombok.Data;
12 |
13 | @Data
14 | @Entity
15 | @Table(name = "users")
16 | public class User {
17 |
18 | @Id
19 | @GeneratedValue
20 | Long id;
21 |
22 | @Column(unique = true)
23 | String username;
24 | String password;
25 |
26 | Boolean enabled;
27 |
28 | @ElementCollection
29 | List roles;
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/domain/UserRepository.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.domain;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface UserRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/incoming/DriverAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming;
2 |
3 | import app.car.cap09.domain.Driver;
4 | import app.car.cap09.interfaces.incoming.errorhandling.ErrorResponse;
5 | import app.car.cap09.interfaces.incoming.output.Drivers;
6 | import io.swagger.v3.oas.annotations.Operation;
7 | import io.swagger.v3.oas.annotations.Parameter;
8 | import io.swagger.v3.oas.annotations.media.Content;
9 | import io.swagger.v3.oas.annotations.media.Schema;
10 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
11 | import io.swagger.v3.oas.annotations.tags.Tag;
12 | import org.springframework.hateoas.CollectionModel;
13 | import org.springframework.hateoas.EntityModel;
14 |
15 | @Tag(name = "Driver API", description = "Manipula dados de motoristas.")
16 | public interface DriverAPI {
17 |
18 |
19 | @Operation(description = "Lista todos os motoristas disponíveis")
20 | Drivers listDrivers(int page);
21 |
22 |
23 | @Operation(
24 | description = "Localiza um motorista específico",
25 | responses = {
26 | @ApiResponse(responseCode = "200", description = "Caso o motorista tenha sido encontrado na base"),
27 | @ApiResponse(responseCode = "404",
28 | description = "Caso o motorista não tenha sido encontrado",
29 | content = @Content(schema = @Schema(implementation = ErrorResponse.class))
30 | )
31 | })
32 | Driver findDriver(
33 | @Parameter(description = "ID do motorista a ser localizado") Long id) ;
34 |
35 | Driver createDriver(
36 | @Parameter(description = "Dados do motorista a ser criado") Driver driver) ;
37 |
38 | Driver fullUpdateDriver(Long id, Driver driver);
39 |
40 | Driver incrementalUpdateDriver(Long id, Driver driver) ;
41 |
42 | void deleteDriver(Long id) ;
43 |
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/incoming/DriverAPIImpl.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming;
2 |
3 | import app.car.cap09.domain.Driver;
4 | import app.car.cap09.domain.DriverRepository;
5 | import app.car.cap09.interfaces.incoming.output.Drivers;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.data.domain.Page;
8 | import org.springframework.data.domain.PageRequest;
9 | import org.springframework.hateoas.EntityModel;
10 | import org.springframework.hateoas.Link;
11 | import org.springframework.http.HttpStatus;
12 | import org.springframework.http.MediaType;
13 | import org.springframework.stereotype.Service;
14 | import org.springframework.web.bind.annotation.*;
15 | import org.springframework.web.server.ResponseStatusException;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 | import java.util.Optional;
20 |
21 | import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
22 | import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
23 |
24 | @Service
25 | @RestController()
26 | @RequestMapping(path = "/drivers", produces = MediaType.APPLICATION_JSON_VALUE)
27 | public class DriverAPIImpl implements DriverAPI {
28 |
29 | private static final int PAGE_SIZE = 10;
30 |
31 | @Autowired
32 | DriverRepository driverRepository;
33 |
34 | @GetMapping
35 | public Drivers listDrivers(@RequestParam(name = "page", defaultValue = "0") int page) {
36 | Page driverPage = driverRepository.findAll(PageRequest.of(page, PAGE_SIZE));
37 |
38 | List> driverList = driverPage.stream().map(EntityModel::of).toList();
39 |
40 | Link lastPageLink = linkTo(methodOn(DriverAPIImpl.class)
41 | .listDrivers(driverPage.getTotalPages() - 1))
42 | .withRel("lastPage");
43 |
44 | return new Drivers(driverList, lastPageLink);
45 | }
46 |
47 | @GetMapping("/{id}")
48 | public Driver findDriver(
49 | @PathVariable("id") Long id) {
50 | return driverRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
51 | }
52 |
53 | @PostMapping
54 | public Driver createDriver(
55 | @RequestBody Driver driver) {
56 | return driverRepository.save(driver);
57 | }
58 |
59 | @PutMapping("/{id}")
60 | public Driver fullUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
61 | Driver foundDriver = findDriver(id);
62 | foundDriver.setBirthDate(driver.getBirthDate());
63 | foundDriver.setName(driver.getName());
64 | return driverRepository.save(foundDriver);
65 | }
66 |
67 | @PatchMapping("/{id}")
68 | public Driver incrementalUpdateDriver(@PathVariable("id") Long id, @RequestBody Driver driver) {
69 | Driver foundDriver = findDriver(id);
70 | foundDriver.setBirthDate(Optional.ofNullable(driver.getBirthDate()).orElse(foundDriver.getBirthDate()));
71 | foundDriver.setName(Optional.ofNullable(driver.getName()).orElse(foundDriver.getName()));
72 | return driverRepository.save(foundDriver);
73 | }
74 |
75 | @DeleteMapping("/{id}")
76 | public void deleteDriver(@PathVariable("id") Long id) {
77 | driverRepository.delete(findDriver(id));
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/incoming/PassengerAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming;
2 |
3 | import app.car.cap09.domain.Passenger;
4 | import app.car.cap09.domain.PassengerRepository;
5 | import java.util.List;
6 | import java.util.Optional;
7 | import jakarta.annotation.security.RolesAllowed;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.http.HttpStatus;
10 | import org.springframework.http.MediaType;
11 | import org.springframework.stereotype.Service;
12 | import org.springframework.web.bind.annotation.*;
13 | import org.springframework.web.server.ResponseStatusException;
14 |
15 | @Service
16 | @RestController
17 | @RequestMapping(path="/passengers", produces = MediaType.APPLICATION_JSON_VALUE)
18 | public class PassengerAPI {
19 |
20 | @Autowired
21 | PassengerRepository passengerRepository;
22 |
23 | @GetMapping()
24 | public List listPassengers() {
25 | return passengerRepository.findAll();
26 | }
27 |
28 | @GetMapping("/{id}")
29 | public Passenger findPassenger(@PathVariable("id") Long id) {
30 | return passengerRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
31 | }
32 |
33 | @PostMapping
34 | @RolesAllowed("ADMIN")
35 | public Passenger createPassenger(@RequestBody Passenger passenger) {
36 | return passengerRepository.save(passenger);
37 | }
38 |
39 | @PutMapping("/{id}")
40 | public Passenger fullUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
41 | Passenger p = findPassenger(id);
42 | p.setName(passenger.getName());
43 | return passengerRepository.save(p);
44 | }
45 |
46 | @PatchMapping("/{id}")
47 | public Passenger incrementalUpdatePassenger(@PathVariable("id") Long id, @RequestBody Passenger passenger) {
48 | Passenger foundPassenger = findPassenger(id);
49 | foundPassenger.setName(Optional.ofNullable(passenger.getName()).orElse(foundPassenger.getName()));
50 | return passengerRepository.save(foundPassenger);
51 | }
52 |
53 | @DeleteMapping("/{id}")
54 | public void deletePassenger(@PathVariable("id") Long id) {
55 | passengerRepository.delete(findPassenger(id));
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/incoming/TravelRequestAPI.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming;
2 |
3 |
4 | import app.car.cap09.domain.TravelRequest;
5 | import app.car.cap09.domain.TravelService;
6 | import app.car.cap09.interfaces.incoming.input.TravelRequestInput;
7 | import app.car.cap09.interfaces.incoming.mapping.TravelRequestMapper;
8 | import app.car.cap09.interfaces.incoming.output.TravelRequestOutput;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.hateoas.EntityModel;
11 | import org.springframework.http.MediaType;
12 | import org.springframework.stereotype.Service;
13 | import org.springframework.web.bind.annotation.*;
14 |
15 | import jakarta.validation.Valid;
16 | import java.util.List;
17 |
18 | @Service
19 | @RestController
20 | @RequestMapping(path = "/travelRequests", produces = MediaType.APPLICATION_JSON_VALUE)
21 | public class TravelRequestAPI {
22 |
23 | @Autowired
24 | TravelService travelService;
25 |
26 | @Autowired
27 | TravelRequestMapper mapper;
28 |
29 | @PostMapping
30 | public EntityModel makeTravelRequest (@RequestBody @Valid TravelRequestInput travelRequestInput) {
31 | TravelRequest request = travelService.saveTravelRequest(mapper.map(travelRequestInput));
32 | TravelRequestOutput output = mapper.map(request);
33 | return mapper.buildOutputModel(request, output);
34 | }
35 |
36 |
37 | @GetMapping("/nearby")
38 | public List> listNearbyRequests(@RequestParam String currentAddress) {
39 | List requests = travelService.listNearbyTravelRequests(currentAddress);
40 | return mapper.buildOutputModel(requests);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/incoming/errorhandling/DefaultErrorHandler.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming.errorhandling;
2 |
3 | import io.swagger.v3.oas.annotations.media.Content;
4 | import io.swagger.v3.oas.annotations.media.Schema;
5 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
6 | import io.swagger.v3.oas.annotations.responses.ApiResponses;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.context.MessageSource;
9 | import org.springframework.context.i18n.LocaleContextHolder;
10 | import org.springframework.http.HttpStatus;
11 | import org.springframework.validation.FieldError;
12 | import org.springframework.web.bind.MethodArgumentNotValidException;
13 | import org.springframework.web.bind.annotation.ExceptionHandler;
14 | import org.springframework.web.bind.annotation.ResponseStatus;
15 | import org.springframework.web.bind.annotation.RestControllerAdvice;
16 |
17 | import java.util.List;
18 | import java.util.stream.Collectors;
19 |
20 |
21 | @RestControllerAdvice
22 | public class DefaultErrorHandler {
23 |
24 | @Autowired
25 | private MessageSource messageSource;
26 |
27 | @ExceptionHandler(MethodArgumentNotValidException.class)
28 | @ResponseStatus(HttpStatus.BAD_REQUEST)
29 | @ApiResponses(
30 | @ApiResponse(responseCode = "400", content = @Content(
31 | mediaType = "application/json",
32 | schema = @Schema(implementation = ErrorResponse.class)
33 | ))
34 | )
35 | public ErrorResponse handleMethodArgumentNotValid(MethodArgumentNotValidException ex) {
36 |
37 | List messages = ex
38 | .getBindingResult()
39 | .getFieldErrors()
40 | .stream()
41 | .map(this::getMessage)
42 | .toList();
43 |
44 | return new ErrorResponse(messages);
45 | }
46 |
47 | private ErrorData getMessage(FieldError fieldError) {
48 |
49 | return new ErrorData(messageSource.getMessage(fieldError, LocaleContextHolder.getLocale()));
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/incoming/errorhandling/ErrorData.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming.errorhandling;
2 |
3 |
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 |
7 | @AllArgsConstructor
8 | @Data
9 | public class ErrorData {
10 |
11 | private final String message;
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/incoming/errorhandling/ErrorResponse.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming.errorhandling;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 |
6 | import java.util.List;
7 |
8 | @AllArgsConstructor
9 | @Data
10 | public class ErrorResponse {
11 |
12 | List errors;
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/incoming/errorhandling/LocaleResolver.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming.errorhandling;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.springframework.http.HttpHeaders;
5 | import org.springframework.stereotype.Component;
6 | import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
7 |
8 | import jakarta.servlet.http.HttpServletRequest;
9 |
10 | import java.util.Arrays;
11 | import java.util.List;
12 | import java.util.Locale;
13 | import java.util.Optional;
14 |
15 | @Component
16 | public class LocaleResolver extends AcceptHeaderLocaleResolver {
17 |
18 | private static final Locale DEFAULT_LOCALE = Locale.of("pt", "BR");
19 |
20 | private static final List ACCEPTED_LOCALES = Arrays.asList(
21 |
22 | DEFAULT_LOCALE,
23 | new Locale("en")
24 | );
25 |
26 | @Override
27 | public Locale resolveLocale(HttpServletRequest request) {
28 | final String acceptLanguageHeader = request.getHeader("Accept-Language");
29 | if (StringUtils.isBlank(acceptLanguageHeader) || acceptLanguageHeader.trim().equals("*")) {
30 | return DEFAULT_LOCALE;
31 | }
32 | List list = Locale.LanguageRange.parse(acceptLanguageHeader);
33 | Locale locale = Locale.lookup(list, ACCEPTED_LOCALES);
34 | return Optional.ofNullable(locale).orElse(DEFAULT_LOCALE);
35 | }
36 |
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/incoming/input/TravelRequestInput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming.input;
2 |
3 | import lombok.Data;
4 |
5 | import jakarta.validation.constraints.NotEmpty;
6 | import jakarta.validation.constraints.NotNull;
7 |
8 | @Data
9 | public class TravelRequestInput {
10 |
11 |
12 | @NotNull(message = "O campo passengerId não pode ser nulo")
13 | Long passengerId;
14 |
15 | @NotEmpty(message = "O campo origin não pode estar em branco")
16 | String origin;
17 |
18 | @NotEmpty(message = "O campo destination não pode estar em branco")
19 | String destination;
20 | }
21 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/incoming/mapping/TravelRequestMapper.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming.mapping;
2 |
3 | import app.car.cap09.domain.Passenger;
4 | import app.car.cap09.domain.PassengerRepository;
5 | import app.car.cap09.domain.TravelRequest;
6 | import app.car.cap09.interfaces.incoming.PassengerAPI;
7 | import app.car.cap09.interfaces.incoming.input.TravelRequestInput;
8 | import app.car.cap09.interfaces.incoming.output.TravelRequestOutput;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.hateoas.EntityModel;
11 | import org.springframework.hateoas.Link;
12 | import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
13 | import org.springframework.http.HttpStatus;
14 | import org.springframework.stereotype.Component;
15 | import org.springframework.web.server.ResponseStatusException;
16 |
17 | import java.util.List;
18 |
19 | @Component
20 | public class TravelRequestMapper {
21 |
22 | @Autowired
23 | private PassengerRepository passengerRepository;
24 |
25 | public TravelRequest map(TravelRequestInput input) {
26 |
27 | Passenger passenger = passengerRepository.findById(input.getPassengerId())
28 | .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
29 |
30 | TravelRequest travelRequest = new TravelRequest();
31 | travelRequest.setOrigin(input.getOrigin());
32 | travelRequest.setDestination(input.getDestination());
33 | travelRequest.setPassenger(passenger);
34 |
35 | return travelRequest;
36 |
37 | }
38 |
39 | public TravelRequestOutput map(TravelRequest travelRequest) {
40 | TravelRequestOutput travelRequestOutput = new TravelRequestOutput();
41 |
42 | travelRequestOutput.setCreationDate(travelRequest.getCreationDate());
43 | travelRequestOutput.setDestination(travelRequest.getDestination());
44 | travelRequestOutput.setId(travelRequest.getId());
45 | travelRequestOutput.setOrigin(travelRequest.getOrigin());
46 | travelRequestOutput.setStatus(travelRequest.getStatus());
47 |
48 | return travelRequestOutput;
49 | }
50 |
51 | public EntityModel buildOutputModel(TravelRequest travelRequest, TravelRequestOutput output) {
52 | EntityModel model = EntityModel.of(output);
53 |
54 | Link passengerLink = WebMvcLinkBuilder
55 | .linkTo(PassengerAPI.class)
56 | .slash(travelRequest.getPassenger().getId())
57 | .withRel("passenger")
58 | .withTitle(travelRequest.getPassenger().getName());
59 | model.add(passengerLink);
60 | return model;
61 | }
62 |
63 | public List> buildOutputModel(List requests) {
64 | return requests.stream().map(tr -> buildOutputModel(tr, map(tr))).toList();
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/incoming/output/Drivers.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming.output;
2 |
3 | import app.car.cap09.domain.Driver;
4 | import lombok.Getter;
5 | import org.springframework.hateoas.EntityModel;
6 | import org.springframework.hateoas.Link;
7 | import java.util.List;
8 |
9 |
10 | @Getter
11 | public class Drivers{
12 |
13 | private List> drivers;
14 |
15 | private Link[] links;
16 |
17 | public Drivers(List> content, Link... links) {
18 | this.drivers = content;
19 | this.links = links;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/incoming/output/TravelRequestOutput.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming.output;
2 |
3 | import app.car.cap09.domain.TravelRequestStatus;
4 | import lombok.Data;
5 |
6 | import java.time.LocalDateTime;
7 |
8 | @Data
9 | public class TravelRequestOutput {
10 |
11 | Long id;
12 | String origin;
13 | String destination;
14 | TravelRequestStatus status;
15 | LocalDateTime creationDate;
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/cap09/src/main/java/app/car/cap09/interfaces/outcoming/GMapsService.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.outcoming;
2 |
3 |
4 | import com.jayway.jsonpath.JsonPath;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.stereotype.Service;
7 | import org.springframework.web.client.RestTemplate;
8 |
9 | import java.util.List;
10 |
11 | @Service
12 | public class GMapsService {
13 |
14 |
15 | @Value("${app.car.domain.googlemaps.apikey}")
16 | private String appKey;
17 |
18 | @Value("${interfaces.outcoming.gmaps.host:https://maps.googleapis.com}")
19 | private String gMapsHost;
20 |
21 | private static final String GMAPS_TEMPLATE = "/maps/api/directions/json?origin={origin}&destination={destination}&key={key}";
22 |
23 | public Integer getDistanceBetweenAddresses(String addressOne, String addressTwo) {
24 |
25 | RestTemplate template = new RestTemplate();
26 | String jsonResult = template.getForObject(gMapsHost + GMAPS_TEMPLATE, String.class, addressOne, addressTwo, appKey);
27 |
28 | List results = JsonPath.parse(jsonResult).read("$..legs[*].duration.value");
29 | return results.stream().min(Integer::compareTo).orElse(Integer.MAX_VALUE);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/cap09/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | app.car.domain.googlemaps.apikey=chaveGoogle
2 |
3 | server.ssl.key-store=classpath:keystore.p12
4 | server.ssl.key-store-password=restbook
5 | server.ssl.key-store-type=PKCS12
6 | server.ssl.key-alias=car
7 |
--------------------------------------------------------------------------------
/cap09/src/main/resources/i18n/messages_en.properties:
--------------------------------------------------------------------------------
1 | NotNull=The field {0} must not be null
2 | NotEmpty=The field {0} must not be empty
--------------------------------------------------------------------------------
/cap09/src/main/resources/i18n/messages_pt_BR.properties:
--------------------------------------------------------------------------------
1 | NotNull=O campo {0} não pode ser nulo
2 | NotEmpty=O campo {0} não pode estar em branco
--------------------------------------------------------------------------------
/cap09/src/main/resources/keystore.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alesaudate/rest-v2/e63f1ca04a94b9f740dd59218ddca102abe68111/cap09/src/main/resources/keystore.p12
--------------------------------------------------------------------------------
/cap09/src/test/java/app/car/cap09/Cap09ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class Cap09ApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/cap09/src/test/java/app/car/cap09/infrastructure/FileUtils.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.infrastructure;
2 |
3 | import lombok.SneakyThrows;
4 | import org.springframework.core.io.ClassPathResource;
5 |
6 | import java.io.InputStream;
7 | import java.util.Map;
8 |
9 | public class FileUtils {
10 |
11 |
12 | @SneakyThrows
13 | public static String loadFileContents(String fileName) {
14 |
15 | InputStream is = new ClassPathResource(fileName).getInputStream();
16 | byte[] data = new byte[is.available()];
17 | is.read(data);
18 | return new String(data);
19 | }
20 |
21 | public static String loadFileContents(String fileName, Map replacements) {
22 | String fileContents = loadFileContents(fileName);
23 |
24 | for (Map.Entry entry : replacements.entrySet()) {
25 | fileContents = fileContents.replace("{{" + entry.getKey() + "}}", entry.getValue());
26 | }
27 | return fileContents;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/cap09/src/test/java/app/car/cap09/interfaces/incoming/PassengerAPITestIT.java:
--------------------------------------------------------------------------------
1 | package app.car.cap09.interfaces.incoming;
2 |
3 | import io.restassured.RestAssured;
4 | import org.junit.jupiter.api.BeforeEach;
5 | import org.junit.jupiter.api.Test;
6 | import org.springframework.boot.test.context.SpringBootTest;
7 | import org.springframework.boot.test.web.server.LocalServerPort;
8 |
9 | import static io.restassured.RestAssured.basic;
10 | import static io.restassured.RestAssured.given;
11 | import static org.hamcrest.Matchers.equalTo;
12 | import static org.hamcrest.Matchers.notNullValue;
13 |
14 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
15 | class PassengerAPITestIT {
16 |
17 | @LocalServerPort
18 | private int port;
19 |
20 | @BeforeEach
21 | void setup() {
22 | RestAssured.baseURI = "https://localhost:" + port;
23 | RestAssured.useRelaxedHTTPSValidation();
24 | RestAssured.authentication = basic("admin", "password");
25 | }
26 |
27 | @Test
28 | void testCreatePassenger() {
29 |
30 |
31 | String createPassengerJSON = "{\"name\":\"Alexandre Saudate\"}";
32 |
33 |
34 | given()
35 | .contentType(io.restassured.http.ContentType.JSON)
36 | .body(createPassengerJSON)
37 | .post("/passengers")
38 | .then()
39 | .statusCode(200)
40 | .body("id", notNullValue())
41 | .body("name", equalTo("Alexandre Saudate"))
42 | ;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/cap09/src/test/resources/application-test.properties:
--------------------------------------------------------------------------------
1 | interfaces.outcoming.gmaps.host=http://localhost:${wiremock.server.port}
--------------------------------------------------------------------------------
/cap09/src/test/resources/requests/passengers_api/create_new_passenger.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Alexandre Saudate"
3 | }
--------------------------------------------------------------------------------
/cap09/src/test/resources/requests/travel_requests_api/create_new_request.json:
--------------------------------------------------------------------------------
1 | {
2 | "passengerId":"{{passengerId}}",
3 | "origin":"Avenida Paulista, 1000",
4 | "destination":"Avenida Ipiranga, 100"
5 | }
--------------------------------------------------------------------------------