Skip to content

MartinCastroAlvarez/java-spring-boot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Java Sprint Boot

Authentication, Authorization, SQL, Async tasks, Unit Tests, Code Coverage.

wallpaper

Rerferences

Data Model

User

Attribute Type Description
id int User unique identifier.
name string User name.
password string User hashed password.

Job

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).

Person

Attribute Type Description
id int Person unique identifier.
name string Person name.

Property

Attribute Type Description
id int Property unique identifier.
ownerId int Owner unique identifier.
name string Property name.

API Documentation

Users

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.

Users

Methd Endpoint Description
GET /api/v1/jobs/ List the latest jobs.
GET /api/v1/jobs/:id Get one job by id.

Persons

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.

Properties

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.

Software Architecture

Configuration

File Description
pom.xml Maven Configuration.
application.properties Application Properties.
Application.java Application Context.
GlobalProperties.java Application Configuration.

Controllers

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.

Models

File Description
Person.java Person model.
Property.java Property model.
User.java User model.
Job.java Job model.

Tasks

File Description
PersonTasks.java Person tasks.
PropertyTasks.java Property tasks.

Repositories

File Description
PersonRepository.java Person model repository.
PropertyRepository.java Property model repository.
UserRepository.java User model repository.
JobRepository.java Job model repository.

Services

File Description
PersonService.java Person business logic.
PropertyService.java Property business logic.
UserService.java User business logic.
JobService.java Job business logic.

Exceptions

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.

Unit Tests

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.

Utils

File Description
HashUtil.java Utilities for hashsing password.

Instructions

Installation

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 connections

Running the application with Maven:

SALT="asdfasdf" DEBUG="true" ENVIRONMENT="martin" ./mvnw spring-boot:run

Checking the application health status:

curl -s http://localhost:8080/actuator/health
{
  "environment": "martin",
  "debug": "true"
}

Running unit tests:

./mvnw clean test

Opening the Code Coverage HTML:

google-chrome target/site/jacoco/index.html 

jacoco.png

Authentication

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:

TODO

Persons

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"
  }
]

Jobs

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"
  }
]

Jobs

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!"
  }
]

Properties

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
}