Authentication, Authorization, SQL, Async tasks, Unit Tests, Code Coverage.
- Building an Application with Spring Boot
- Spring Boot Examples
- Spring Boot – Starters
- Spring Boot Actuator
- Using Logback with Spring Boot
- @Controller and @RestController Annotations in Spring Boot
- Spring Data JPA - Reference Documentation
- Jackson Project Home @github
- Java Map Class
- Spring Boot Connect to PostgreSQL Database Examples
- Spring Boot PostgreSQL
- Spring Boot + PostgreSQL + JPA/Hibernate CRUD Restful API Tutorial
- Java 8 – Convert Optional to String
- Personalizar las relaciones con @JoinColumn
- Securing a Web Application
- Hashing a Password in Java
- Password authentication in Java
- Pagination and Sorting using Spring Data JPA
- Spring @Async Annotation for Asynchronous Processing
- Introduction to Spring Testing
- AssertJ Core
- How to configure maven surefire plugin work with JUnit 5
| Attribute | Type | Description |
|---|---|---|
| id | int | User unique identifier. |
| name | string | User name. |
| password | string | User hashed password. |
| Attribute | Type | Description |
|---|---|---|
| id | int | Job id. |
| createdAt | date | Job creation date. |
| startedAt | date | Job start date. |
| endedAt | date | Job end date. |
| status | int | Job status (Pending, Started, Ended, Failed). |
| Attribute | Type | Description |
|---|---|---|
| id | int | Person unique identifier. |
| name | string | Person name. |
| Attribute | Type | Description |
|---|---|---|
| id | int | Property unique identifier. |
| ownerId | int | Owner unique identifier. |
| name | string | Property name. |
| Methd | Endpoint | Description |
|---|---|---|
| POST | /api/v1/auth/signup/ | Create an User. |
| POST | /api/v1/auth/logout/ | Logout endpoint. |
| POST | /api/v1/auth/login/ | Login endpoint. |
| GET | /api/v1/auth/session/ | Get session details. |
| PUT | /api/v1/auth/session/ | Update your User. |
| Methd | Endpoint | Description |
|---|---|---|
| GET | /api/v1/jobs/ | List the latest jobs. |
| GET | /api/v1/jobs/:id | Get one job by id. |
| Methd | Endpoint | Description |
|---|---|---|
| GET | /api/v1/persons/ | Lists persons. |
| POST | /api/v1/persons/ | Create a person. |
| GET | /api/v1/persons/:id/ | Person details. |
| PUT | /api/v1/persons/:id/ | Update person. |
| DELETE | /api/v1/persons/:id/ | Delete a person. |
| Methd | Endpoint | Description |
|---|---|---|
| GET | /api/v1/properties/ | Lists properties. |
| POST | /api/v1/properties/ | Create a Property. |
| GET | /api/v1/properties/:id/ | Property details. |
| PUT | /api/v1/properties/:id/ | Update Property. |
| DELETE | /api/v1/properties/:id/ | Delete a Property. |
| File | Description |
|---|---|
| pom.xml | Maven Configuration. |
| application.properties | Application Properties. |
| Application.java | Application Context. |
| GlobalProperties.java | Application Configuration. |
| File | Description |
|---|---|
| RootController.java | Root Endpoint. |
| PersonController.java | Person API Resource. |
| PropertyController.java | Property API Resource. |
| UserController.java | User API Resource. |
| JobController.java | Job API Resource. |
| File | Description |
|---|---|
| Person.java | Person model. |
| Property.java | Property model. |
| User.java | User model. |
| Job.java | Job model. |
| File | Description |
|---|---|
| PersonTasks.java | Person tasks. |
| PropertyTasks.java | Property tasks. |
| File | Description |
|---|---|
| PersonRepository.java | Person model repository. |
| PropertyRepository.java | Property model repository. |
| UserRepository.java | User model repository. |
| JobRepository.java | Job model repository. |
| File | Description |
|---|---|
| PersonService.java | Person business logic. |
| PropertyService.java | Property business logic. |
| UserService.java | User business logic. |
| JobService.java | Job business logic. |
| File | Description |
|---|---|
| GlobalErrorHandler.java | Catches exceptions globally and generates pretty JSON responses. |
| ErrorResponse.java | Pretty representation of a Java exception. |
| PersonNotFoundError.java | Person not found. |
| PropertyNotFoundError.java | Property not found. |
| UserNotFoundError.java | User not found. |
| JobNotFoundError.java | Job not found. |
| File | Description |
|---|---|
| PersonApiTests.java | Testing the Person API. |
| PersonControllerTests.java | Testing the Person controller. |
| PersonRepositoryTests.java | Testing the Person repository. |
| PersonServiceTests.java | Testing the Person service. |
| File | Description |
|---|---|
| HashUtil.java | Utilities for hashsing password. |
Starting related servies
docker-compose up[...]
db_1 | 2022-11-24 22:30:48.577 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
db_1 | 2022-11-24 22:30:48.577 UTC [1] LOG: listening on IPv6 address "::", port 5432
db_1 | 2022-11-24 22:30:48.602 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1 | 2022-11-24 22:30:48.639 UTC [48] LOG: database system was shut down at 2022-11-24 22:30:48 UTC
db_1 | 2022-11-24 22:30:48.659 UTC [1] LOG: database system is ready to accept connectionsRunning the application with Maven:
SALT="asdfasdf" DEBUG="true" ENVIRONMENT="martin" ./mvnw spring-boot:runChecking the application health status:
curl -s http://localhost:8080/actuator/health{
"environment": "martin",
"debug": "true"
}Running unit tests:
./mvnw clean testOpening the Code Coverage HTML:
google-chrome target/site/jacoco/index.html Requests before authenticating are restricted.
curl --cookie-jar "/tmp/london" -X POST -s http://localhost:8080/api/v1/login/ -d 'username=user&password=password'HTTP/1.1 403
Set-Cookie: JSESSIONID=773BEA4F294E1D05CD15CC80870F4F19; Path=/; HttpOnly
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
[...]Sign up as a new User.
curl --cookie-jar "/tmp/london" -X POST -s http://localhost:8080/api/v1/signup/ -H 'content-type: application/json' -d '{"name": "lorem", "password": "ipsum"}'{
"id": 1,
"name": "Lorem Ipsum"
}Authenticating using username and password:
Retrieving a non-existent Person:
curl --cookie-jar "/tmp/london" -s http://localhost:8080/api/v1/persons/123/{
"timestamp": "2022-11-25T14:58:55.492+00:00",
"type": "com.martincastroalvarez.london.PersonNotFoundError",
"message": null
}Creating a Person:
curl --cookie-jar "/tmp/london" -X POST -s http://localhost:8080/api/v1/persons/ -H 'content-type: application/json' -d '{"name": "Lorem Ipsum"}'{
"id": 1,
"name": "Lorem Ipsum"
}Listing existing Persons:
curl --cookie-jar "/tmp/london" -X GET -s "http://localhost:8080/api/v1/persons/?sort_key="name&limit=10&offset=0"[
{
"id": 3,
"name": "Lorem Ipsum"
},
{
"id": 1,
"name": "Sit Amet"
},
{
"id": 2,
"name": "Nisman"
}
]Updating an existing Person:
curl --cookie-jar "/tmp/london" -X PUT -s http://localhost:8080/api/v1/persons/1 -H 'content-type: application/json' -d '{"name": "Sit Amet"}'{
"id": 1,
"name": "Sit Amet"
}Getting Person details:
curl --cookie-jar "/tmp/london" -s http://localhost:8080/api/v1/persons/2{
"id" : 2,
"name" : "Nisman"
}Deleting a Person:
curl --cookie-jar "/tmp/london" -X DELETE -s http://localhost:8080/api/v1/persons/3{
"id" : 21,
"createdAt" : null,
"endedAt" : null,
"startedAt" : null,
"status" : null,
"message" : null
}Searching for Persons by name:
curl --cookie-jar "/tmp/london" -X GET -s "http://localhost:8080/api/v1/persons/?name=Sit&sort_key=name"[
{
"id": 1,
"name": "Sit Amet"
}
]Listing jobs:
curl --cookie-jar "/tmp/london" -X GET -s "http://localhost:8080/api/v1/persons/?name=Sit&sort_key=name"[
{
"id": 1,
"name": "Sit Amet"
}
]Listing jobs:
curl --cookie-jar "/tmp/london" -X GET -s "http://localhost:8080/api/v1/jobs/?limit=2&offset=0"[
{
"id": 12,
"createdAt": null,
"endedAt": "2022-11-25T22:54:34.484+00:00",
"startedAt": "2022-11-25T22:54:34.461+00:00",
"status": "FAILED",
"message": "Person now found!"
},
{
"id": 13,
"createdAt": null,
"endedAt": "2022-11-25T22:58:39.070+00:00",
"startedAt": "2022-11-25T22:58:39.045+00:00",
"status": "FAILED",
"message": "Person now found!"
},
{
"id": 11,
"createdAt": null,
"endedAt": "2022-11-25T22:54:11.839+00:00",
"startedAt": "2022-11-25T22:54:11.819+00:00",
"status": "FAILED",
"message": "Person now found!"
}
]Retrieving a non-existent Propertes:
curl --cookie-jar "/tmp/london" -s http://localhost:8080/api/v1/properties/123/{
"timestamp": "2022-11-25T14:58:55.492+00:00",
"type": "com.martincastroalvarez.london.PropertyNotFoundError",
"message": null
}Creating a Property:
curl --cookie-jar "/tmp/london" -X POST -s http://localhost:8080/api/v1/properties/ -H 'content-type: application/json' -d '{"name": "Lorem Ipsum", "ownerId": 1}'{
"id" : 10,
"owner" : {
"id" : 1,
"name" : "Sit Amet"
},
"name" : "Lorem Ipsum"
}Listing existing properties:
curl --cookie-jar "/tmp/london" -X GET -s "http://localhost:8080/api/v1/properties/?sort_key=name"[
{
"id" : 10,
"owner" : {
"id" : 1,
"name" : "Sit Amet"
},
"name" : "Lorem Ipsum"
}
]Updating an existing Property:
curl --cookie-jar "/tmp/london" -X PUT -s http://localhost:8080/api/v1/properties/1 -H 'content-type: application/json' -d '{"name": "Sit Amet", "ownerId": 2}'{
"id" : 10,
"owner" : {
"id" : 2,
"name" : "Nisman"
},
"name" : "Sit Amet"
}Getting Property details:
curl --cookie-jar "/tmp/london" -s http://localhost:8080/api/v1/properties/1{
"id" : 2,
"name" : "Nisman"
}Deleting a Property:
curl --cookie-jar "/tmp/london" -X DELETE -s http://localhost:8080/api/v1/properties/10{
"id" : 43,
"createdAt" : null,
"endedAt" : null,
"startedAt" : null,
"status" : null,
"message" : null
}
