Application is a demo of a product catalog having simplified logic.
- Java 25
- Maven 4 (wrapper)
- Maven BuildTime Profiler Extension
- Spring Boot
- Spring Web MVC
- Spring Cache (Caffeine)
- Spring Data JPA
- Flyway DB migration tool
- H2 DB
- Project Reactor
- Resilience4j
- Lombok
- Docker
- OpenAPI 3 & Swagger UI (springdoc-openapi)
- JUnit Jupiter
- Mockito
- JaCoCo
- CycloneDX SBOM
- OWASP
- Repository is licensed under Apache License 2.0
- Repository uses GitHub Actions (Java_CI_with_Maven)
- Repository uses Renovate dependency updates (via Renovate GitHub App)
- Repository uses Dependabot dependency updates (see dependabot.yml)
- Readme badges are rendered using shields.io
- JaCoCo badges sources are generated by jacoco-badge-generator
- LoC badge is generated by SCC
- ER diagram is generated by mermaid.live
- ASCII Art for SpringBoot banner was generated
with TAAG (font
Calvin S) - SpringBoot custom Favicon was generated with favicon.cc
- Application implements CRUD operations for Categories and Products
- Category and Product services are
@Transactionalto avoid race condition - Application gets currency exchange rates from Frankfurter https://frankfurter.dev
- Frankfurter REST API is called via Spring
RestTemplateand decorated with Resilience4jCircuitBreaker
- Frankfurter REST API is called via Spring
- Rates are cached with
Caffeineduring a period of their validity- Cache eviction is scheduled to
16:01 CET MON-FRI
- Cache eviction is scheduled to
Application DB stores categorized products:
- Categories are multilevel (i.e.
Computers<--Portable computers<--Tablets) - Products can relate to multiple categories (i.e.
MacBookrelates toNotebookand toApple) - Product prices are stored in original and base currency (i.e. original price in
USDand calculated price inEUR)
DB migration is done with Flyway using scripts:
- V1__create_schema.sql
- initial script
target/classes/db/create_schema.sqlis generated with Spring Data JPA when starting application withdevprofile (for details see application-dev.yml)
- initial script
- V2__insert_data.sql
Application uses H2 DB.
See application specific configuration in pcs: section of application.yml
# Build with Maven wrapper
$ ./mvnw packageThe BuildTime Profiler Extension is activated by default. To deactivate the profiler extension for all maven builds just
uncomment the parameter -Dmaven-build-time-profiler.disabled in maven.config.
# Build and tag Docker image with Docker
# Firstly build artifact required by Docker with Maven Wrapper
$ ./mvnw package -DskipTests
# Secondly build with Docker
$ docker build -t mirogaudi/product-catalog-service:1.0.0 .
$ docker tag mirogaudi/product-catalog-service:1.0.0 mirogaudi/product-catalog-service:latest
# Or build Docker image with Maven wrapper via Docker plugin
$ ./mvnw package -Pdocker -DskipTests# Run with Java
$ java -jar target/product-catalog-service-1.0.0.jar# Run with Maven wrapper (via Spring Boot plugin)
$ ./mvnw spring-boot:run# Run with Docker
$ docker run -it -d --rm --name product-catalog-service -p 8080:8080 mirogaudi/product-catalog-service:latestJust run in IDE: ProductCatalogServiceApplication.java
- OpenAPI docs: http://localhost:8080/pcs/v3/api-docs
- Swagger UI: http://localhost:8080/pcs/swagger-ui/index.html
- HTTP client: request-categories.http, request-products.http
- Actuator: http://localhost:9000/actuator
- Swagger UI: http://localhost:8080/pcs/swagger-ui/index.html?urls.primaryName=x-actuator
- HTTP client: request-actuator.http
- H2 console http://localhost:8080/pcs/h2-console
- url:
jdbc:h2:file:./target/db/pcs;AUTO_SERVER=TRUE - username:
sa - password:
<empty>
- url:
# Build performing static code analysis
$ ./mvnw package -Pcheckstyle,pmd,spotbugs -DskipTestsProject uses checkstyle.xml configuration based on customized Checkstyle google_checks.xml.
# Build checking with Checkstyle
$ ./mvnw validate -Pcheckstyle -DskipTests# Build checking with PMD
$ ./mvnw package -Ppmd -DskipTests# Build checking with SpotBugs
$ ./mvnw package -Pspotbugs -DskipTests# Build generating JaCoCo code coverage report and checking code coverage metrics
$ ./mvnw package -Pcode-coverage# Build generating CycloneDX SBOM
$ ./mvnw package -Psbom -DskipTestsGenerated SBOM can be reviewed:
-
or via SBOM Actuator Endpoint http://localhost:9000/actuator/sbom/application
# Build generating OWASP dependency vulnerability report
$ ./mvnw package -Powasp -DskipTestsSnyk analysis can be viewed at snyk.io: Snyk Test Results
Dependencies are to be updated automatically with Renovate/Dependabot or could be updated manually.
# Update Maven wrapper to use Maven a.b.c
$ mvn wrapper:wrapper -Dmaven=<a.b.c># Check for Maven plugins updates
$ ./mvnw versions:display-plugin-updates
# Check for Maven parent updates
$ ./mvnw versions:display-parent-updates
# Check for Maven property-linked dependencies updates
$ ./mvnw versions:display-property-updates
# Check for Maven dependencies updates
$ ./mvnw versions:display-dependency-updatesTo ignore case-insensitive alpha, beta, dev, milestone and release candidate versions in checks above add the following D-parameter:
maven.version.ignore='(?i).*[-.](alpha|beta|dev|m|rc)([-.]?\d+)?'
$ ./mvnw -Dmaven.version.ignore='(?i).*[-.](alpha|beta|dev|m|rc)([-.]?\d+)?' versions:<goal>- update:
- SB to v4 (https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Migration-Guide)
- flywaydb to v12
- springdoc-openapi to v3
- clean up:
- use Flyway with maven plugin instead of dev app props
- test db with integration testing
- check if all transactions are valid and using proxy classes
- use WebClient or declarative web call instead of RestTemplate
- check cache test
- use https://spring.io/guides/gs/cloud-circuit-breaker for Circuit Breaker
- test it
- use logback
- use Rest Assured for integration testing
- use conventional commits https://www.conventionalcommits.org/
- add semantic releases (https://semver.org/) and/or CHANGELOG.md https://keepachangelog.com/
- implement:
- add PATCH call to update price
- add price history