Skip to content

Conversation

@igorcampos-dev
Copy link
Owner

@igorcampos-dev igorcampos-dev commented Dec 14, 2025

…h caching implementation and Docker support

Summary by CodeRabbit

Release Notes

  • New Features

    • Added a new Spring Boot example project demonstrating in-memory caching integration.
  • Chores

    • Configured CI/CD pipelines and Docker containerization for the new example project.
    • Updated project documentation with the new example entry and setup instructions.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 14, 2025

Walkthrough

Adds a new spring-caffeine-example module to the repository, including complete Spring Boot application code demonstrating in-memory caching with Caffeine, GitHub Actions CI/CD workflows, Docker configuration, and Maven wrapper setup. Updates root configuration files to register the new project.

Changes

Cohort / File(s) Summary
Repository Configuration
.github/labeler.yml, README.md, pom.xml
Added spring-caffeine-example project entry to labeler configuration, updated README with new project link, and registered new module in root Maven POM.
GitHub Actions Workflows
.github/workflows/spring-caffeine-example.yml, spring-caffeine-example/.github/workflows/maven.yml
Added main CI workflow for integration tests and health checks with Docker Compose, and local Maven build workflow for the example project.
Docker & Compose Configuration
spring-caffeine-example/Dockerfile, spring-caffeine-example/.dockerignore, spring-caffeine-example/compose.yaml
Introduced multi-stage Dockerfile for Spring Boot application with dependency layer extraction, Docker ignore patterns, and docker-compose configuration with H2 database and port 7079 mapping.
Maven Wrapper & Build Config
spring-caffeine-example/mvnw, spring-caffeine-example/mvnw.cmd, spring-caffeine-example/.mvn/wrapper/maven-wrapper.properties, spring-caffeine-example/.gitignore, spring-caffeine-example/.gitattributes
Added Maven Wrapper scripts for cross-platform Maven execution, wrapper properties pointing to Maven 3.9.11, and git/IDE ignore rules.
Project POM
spring-caffeine-example/pom.xml
Defined Maven module configuration with Spring Boot 4.0.0 parent, dependencies for H2, Lombok, Caffeine, OpenFeign, and Spring WebMVC.
Java Application Code
spring-caffeine-example/src/main/java/com/io/example/\*
Implemented Spring Boot entry point, REST controllers (CaffeineController, ExternalApiController), Feign client for external API, service layer with cache integration, repository for database access, configuration classes, and DTOs (CaffeineResponseDto, ExternalApiResponseDto).
Configuration & Resources
spring-caffeine-example/src/main/resources/application.yaml, spring-caffeine-example/src/main/resources/application-prd.yaml, spring-caffeine-example/src/main/resources/sql/init.sql
Added Spring Boot application configuration for local and production profiles with H2 datasource, Caffeine cache settings, external API URL, and SQL initialization script for caffeine_description table.
Project Documentation
spring-caffeine-example/README.md
Added documentation explaining the Caffeine caching example, endpoints, sample curl commands, and related resources.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Maven Wrapper scripts (mvnw, mvnw.cmd): Large shell/batch scripts with complex download, validation, and extraction logic; verify cross-platform compatibility and credential handling
  • Multi-stage Dockerfile: Review layer extraction strategy, non-root user configuration (UID argument), and base image choices
  • Caching implementation (CaffeineServiceImpl): Verify proper use of Caffeine cache API, null safety, and side-effectful logging patterns
  • Feign client integration (CaffeineVersionClient): Confirm external URL property binding and error handling
  • CI/CD workflow orchestration: Ensure health-check script integration and Docker Compose service discovery work as intended
  • Spring configuration wiring: Verify @ConfigurationProperties binding and bean initialization order

Possibly related PRs

  • chore(geral): aditionate labeler #10: Modifies .github/labeler.yml to add spring-caffeine-example project entry, directly affecting the same configuration file for project-specific labeling rules.
  • Feature/geral #6: Adds Maven Wrapper files (mvnw, mvnw.cmd, .mvn/wrapper/maven-wrapper.properties) with identical wrapper scripts and configuration logic for Maven distribution management.
  • Create README.md #17: Updates root README.md to include reference to the new spring-caffeine-example project in the projects table, creating a linkage in documentation.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: initializing a new Spring Caffeine example project with caching and Docker support.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch release/spring-caffeine-example

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@igorcampos-dev igorcampos-dev merged commit 8798332 into master Dec 14, 2025
4 of 5 checks passed
@igorcampos-dev igorcampos-dev deleted the release/spring-caffeine-example branch December 14, 2025 17:48
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 16

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a7ca3f6 and d594d40.

📒 Files selected for processing (29)
  • .github/labeler.yml (1 hunks)
  • .github/workflows/spring-caffeine-example.yml (1 hunks)
  • README.md (1 hunks)
  • pom.xml (1 hunks)
  • spring-caffeine-example/.dockerignore (1 hunks)
  • spring-caffeine-example/.gitattributes (1 hunks)
  • spring-caffeine-example/.github/workflows/maven.yml (1 hunks)
  • spring-caffeine-example/.gitignore (1 hunks)
  • spring-caffeine-example/.mvn/wrapper/maven-wrapper.properties (1 hunks)
  • spring-caffeine-example/Dockerfile (1 hunks)
  • spring-caffeine-example/README.md (1 hunks)
  • spring-caffeine-example/compose.yaml (1 hunks)
  • spring-caffeine-example/mvnw (1 hunks)
  • spring-caffeine-example/mvnw.cmd (1 hunks)
  • spring-caffeine-example/pom.xml (1 hunks)
  • spring-caffeine-example/src/main/java/com/io/example/SpringCaffeineExampleApplication.java (1 hunks)
  • spring-caffeine-example/src/main/java/com/io/example/client/CaffeineVersionClient.java (1 hunks)
  • spring-caffeine-example/src/main/java/com/io/example/config/CacheConfig.java (1 hunks)
  • spring-caffeine-example/src/main/java/com/io/example/controller/CaffeineController.java (1 hunks)
  • spring-caffeine-example/src/main/java/com/io/example/dto/CaffeineResponseDto.java (1 hunks)
  • spring-caffeine-example/src/main/java/com/io/example/external/controller/ExternalApiController.java (1 hunks)
  • spring-caffeine-example/src/main/java/com/io/example/external/dto/ExternalApiResponseDto.java (1 hunks)
  • spring-caffeine-example/src/main/java/com/io/example/properties/CaffeineProperties.java (1 hunks)
  • spring-caffeine-example/src/main/java/com/io/example/repository/CaffeineDescriptionRepository.java (1 hunks)
  • spring-caffeine-example/src/main/java/com/io/example/service/CaffeineService.java (1 hunks)
  • spring-caffeine-example/src/main/java/com/io/example/service/CaffeineServiceImpl.java (1 hunks)
  • spring-caffeine-example/src/main/resources/application-prd.yaml (1 hunks)
  • spring-caffeine-example/src/main/resources/application.yaml (1 hunks)
  • spring-caffeine-example/src/main/resources/sql/init.sql (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: igorcampos-dev
Repo: igorcampos-dev/spring-integrations-examples PR: 21
File: spring-kafka-example/README.md:12-17
Timestamp: 2025-07-22T01:35:41.406Z
Learning: User igorcampos-dev prefers minimal, high-level documentation in README files without detailed version specifications, choosing to keep tech stack information simple rather than adding precise version numbers.
Learnt from: igorcampos-dev
Repo: igorcampos-dev/spring-integrations-examples PR: 21
File: spring-kafka-example/compose.yaml:30-32
Timestamp: 2025-07-22T01:30:57.054Z
Learning: User igorcampos-dev prefers to maintain environment parity between local development and production, avoiding development-specific configurations like ALLOW_PLAINTEXT_LISTENER even when they might provide clearer intent or safety nets.
Learnt from: igorcampos-dev
Repo: igorcampos-dev/spring-integrations-examples PR: 26
File: spring-kafka-example/compose.yaml:3-4
Timestamp: 2025-07-24T01:40:49.337Z
Learning: User igorcampos-dev requires hard-coded container names in Docker Compose files (like `container_name: app`) for CI pipeline validation purposes, which is a valid operational requirement that overrides the general best practice of avoiding hard-coded container names.
📚 Learning: 2025-07-27T19:51:52.736Z
Learnt from: igorcampos-dev
Repo: igorcampos-dev/spring-integrations-examples PR: 40
File: spring-kafka-example/src/main/java/com/io/example/consumer/KafkaConsumerService.java:3-3
Timestamp: 2025-07-27T19:51:52.736Z
Learning: In the spring-integrations-examples project, user igorcampos-dev uses SuppressWarnings("unused") annotations to suppress IntelliJ IDEA alerts, and these annotations should not be suggested for removal as they serve a specific purpose in their development workflow.

Applied to files:

  • spring-caffeine-example/.dockerignore
  • spring-caffeine-example/.gitignore
📚 Learning: 2025-07-27T19:57:31.204Z
Learnt from: igorcampos-dev
Repo: igorcampos-dev/spring-integrations-examples PR: 40
File: spring-kafka-example/src/main/java/com/io/example/consumer/KafkaConsumerServiceImpl.java:18-22
Timestamp: 2025-07-27T19:57:31.204Z
Learning: In the spring-integrations-examples project, user igorcampos-dev prefers to keep simple example implementations minimal without additional error handling complexity, as the examples are for demonstration purposes rather than production use.

Applied to files:

  • README.md
  • spring-caffeine-example/README.md
  • spring-caffeine-example/pom.xml
  • pom.xml
  • spring-caffeine-example/src/main/java/com/io/example/SpringCaffeineExampleApplication.java
🧬 Code graph analysis (4)
spring-caffeine-example/src/main/java/com/io/example/external/dto/ExternalApiResponseDto.java (2)
spring-wolf-example/src/main/java/com/io/example/dto/KafkaDto.java (1)
  • KafkaDto (3-3)
spring-kafka-example/src/main/java/com/io/example/controller/dto/response/SimpleTopicDtoResponse.java (1)
  • SimpleTopicDtoResponse (3-3)
spring-caffeine-example/src/main/java/com/io/example/dto/CaffeineResponseDto.java (2)
spring-wolf-example/src/main/java/com/io/example/dto/KafkaDto.java (1)
  • KafkaDto (3-3)
spring-kafka-example/src/main/java/com/io/example/controller/dto/response/SimpleTopicDtoResponse.java (1)
  • SimpleTopicDtoResponse (3-3)
spring-caffeine-example/src/main/java/com/io/example/repository/CaffeineDescriptionRepository.java (2)
spring-batch-db-examples/src/main/java/com/io/example/repository/query/TestEntityQuery.java (1)
  • RequiredArgsConstructor (6-27)
spring-batch-db-examples/src/main/java/com/io/example/repository/TestEntityRepository.java (1)
  • Repository (7-9)
spring-caffeine-example/src/main/java/com/io/example/external/controller/ExternalApiController.java (1)
spring-caffeine-example/src/main/java/com/io/example/controller/CaffeineController.java (1)
  • RestController (12-25)
🪛 Checkov (3.2.334)
spring-caffeine-example/Dockerfile

[low] 1-49: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)

🪛 Hadolint (2.14.0)
spring-caffeine-example/Dockerfile

[warning] 16-16: Quote this to prevent word splitting.

(SC2046)


[warning] 42-42: COPY to a relative destination without WORKDIR set.

(DL3045)


[warning] 43-43: COPY to a relative destination without WORKDIR set.

(DL3045)


[warning] 44-44: COPY to a relative destination without WORKDIR set.

(DL3045)


[warning] 45-45: COPY to a relative destination without WORKDIR set.

(DL3045)

🪛 LanguageTool
spring-caffeine-example/README.md

[uncategorized] ~28-~28: The official name of this software platform is spelled with a capital “H”.
Context: ...---------------------------| | Caffeine Github | https://github.com/ben-manes...

(GITHUB)

🪛 markdownlint-cli2 (0.18.1)
README.md

30-30: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

spring-caffeine-example/README.md

19-19: Bare URL used

(MD034, no-bare-urls)


20-20: Bare URL used

(MD034, no-bare-urls)


28-28: Bare URL used

(MD034, no-bare-urls)


29-29: Bare URL used

(MD034, no-bare-urls)

🪛 OSV Scanner (2.3.0)
spring-caffeine-example/pom.xml

[HIGH] 1-1: commons-fileupload:commons-fileupload 1.5: Apache Commons FileUpload, Apache Commons FileUpload: FileUpload DoS via part headers

(GHSA-vv7r-c36w-3prj)

🪛 YAMLlint (1.37.1)
spring-caffeine-example/src/main/resources/application.yaml

[warning] 29-29: too few spaces before comment: expected 2

(comments)


[error] 32-32: too many blank lines (1 > 0)

(empty-lines)

spring-caffeine-example/.github/workflows/maven.yml

[warning] 3-3: truthy value should be one of [false, true]

(truthy)


[error] 14-14: too many spaces inside brackets

(brackets)


[error] 14-14: too many spaces inside brackets

(brackets)


[error] 15-15: too many spaces inside brackets

(brackets)


[error] 15-15: too many spaces inside brackets

(brackets)

.github/workflows/spring-caffeine-example.yml

[warning] 3-3: truthy value should be one of [false, true]

(truthy)


[error] 23-23: too many spaces inside brackets

(brackets)


[error] 23-23: too many spaces inside brackets

(brackets)


[error] 24-24: too many spaces inside brackets

(brackets)


[error] 24-24: too many spaces inside brackets

(brackets)

spring-caffeine-example/src/main/resources/application-prd.yaml

[error] 32-32: too many blank lines (1 > 0)

(empty-lines)

🔇 Additional comments (27)
.github/labeler.yml (1)

29-31: LGTM!

The new spring-caffeine-example labeler entry follows the established pattern, uses the correct glob syntax, and is properly positioned in alphabetical order.

spring-caffeine-example/.gitattributes (1)

1-2: LGTM!

The line-ending configuration is correct for Maven wrapper scripts. Unix shell scripts require LF endings, while Windows batch files require CRLF.

README.md (1)

30-30: LGTM!

The new table entry follows the consistent format of existing entries and provides appropriate high-level documentation for the Spring Boot + Caffeine integration example.

pom.xml (1)

26-26: LGTM!

The new module is correctly added to the Maven multi-module build configuration.

spring-caffeine-example/src/main/resources/application-prd.yaml (1)

1-31: LGTM!

The production configuration properly externalizes all environment-specific values through environment variables, following 12-factor app principles.

spring-caffeine-example/src/main/java/com/io/example/SpringCaffeineExampleApplication.java (1)

1-15: LGTM!

Clean and minimal Spring Boot application entry point with proper Feign client support enabled.

spring-caffeine-example/.github/workflows/maven.yml (1)

1-30: LGTM!

The CI workflow is correctly configured to build the project using Java 21 and the Maven wrapper. The workflow structure, steps, and matrix configuration are all appropriate.

spring-caffeine-example/src/main/resources/sql/init.sql (1)

1-7: LGTM!

The SQL initialization script provides a clean, minimal schema and seed data appropriate for this demonstration project. The table structure is well-suited for H2 database integration.

spring-caffeine-example/README.md (1)

1-29: LGTM! Documentation aligns with project preferences.

The README is concise and high-level, effectively documenting the purpose and usage of the Caffeine caching example without over-explaining implementation details.

spring-caffeine-example/src/main/java/com/io/example/service/CaffeineService.java (1)

1-7: LGTM!

The interface is clean and follows standard Spring service patterns with a clear, single-responsibility method signature.

spring-caffeine-example/compose.yaml (1)

3-4: LGTM!

The hard-coded container name is appropriate for CI pipeline validation purposes.

spring-caffeine-example/src/main/resources/application.yaml (2)

1-24: LGTM!

The Spring Boot, datasource, H2, and SQL initialization configurations are properly structured and follow best practices.


25-26: Verify the URL format includes the protocol.

Similar to the Docker compose configuration, the caffeine-version-url is missing the protocol (http:// or https://). This should be consistent with how the Feign client expects URL configuration.

spring-caffeine-example/src/main/java/com/io/example/dto/CaffeineResponseDto.java (1)

1-3: LGTM!

The record is clean and follows established patterns in the codebase for DTOs.

spring-caffeine-example/.dockerignore (1)

1-62: LGTM!

The .dockerignore file comprehensively excludes appropriate artifacts, helping to minimize the Docker build context.

spring-caffeine-example/src/main/java/com/io/example/repository/CaffeineDescriptionRepository.java (1)

1-24: LGTM!

The repository uses the modern JdbcClient API appropriately with clean text block SQL. The hard-coded ID parameter is acceptable for a demonstration example.

spring-caffeine-example/src/main/java/com/io/example/external/dto/ExternalApiResponseDto.java (1)

1-3: LGTM!

The record follows the established pattern for DTOs in the project.

spring-caffeine-example/.gitignore (1)

1-32: LGTM!

The .gitignore file comprehensively covers Maven build artifacts and all major IDE configurations. The negation patterns for source directories are appropriate.

spring-caffeine-example/src/main/java/com/io/example/service/CaffeineServiceImpl.java (2)

21-24: LGTM!

The implementation correctly delegates to cached helper methods and constructs the response DTO. The caching pattern with side-effectful logging on first fetch clearly demonstrates cache behavior.


26-40: LGTM!

Both getVersion() and getDescription() correctly implement the cache-aside pattern using Caffeine's get() method with a loading function. The logging statements effectively demonstrate when cache misses occur.

spring-caffeine-example/Dockerfile (3)

1-11: LGTM!

The dependency stage efficiently uses build caching and bind mounts to fetch dependencies offline. The Maven wrapper setup is correct.


21-26: LGTM!

The extraction stage correctly uses Spring Boot's layertools to extract layers, which optimizes Docker image caching and reduces layer sizes.


31-40: LGTM!

The non-root user setup follows security best practices, with configurable UID via build argument and proper user restrictions (no password, no login shell, no home directory).

spring-caffeine-example/pom.xml (1)

28-80: No action needed. This project uses Spring Boot 4.0.0, which does not include commons-fileupload as a transitive dependency. Spring Framework 6 (the foundation of Boot 4.0.0) removed the CommonsMultipartResolver integration entirely, and commons-fileupload is not pulled in by any of the declared starters (spring-boot-starter-webmvc, spring-boot-starter-jdbc, or spring-boot-h2console). While GHSA-vv7r-c36w-3prj is a legitimate high-severity vulnerability in commons-fileupload < 1.6.0, it does not affect this codebase since the library is neither explicitly declared nor transitively included.

Likely an incorrect or invalid review comment.

.github/workflows/spring-caffeine-example.yml (1)

39-68: Health check job structure looks good.

The approach of extracting service names dynamically and using compose-action with build flags is appropriate. The fixed 10-second sleep is acceptable for this example project, though for production CI you might consider polling-based readiness checks.

spring-caffeine-example/mvnw.cmd (1)

1-189: Standard Maven Wrapper script.

This is the official Apache Maven Wrapper startup batch script, version 3.3.4. The script correctly handles distribution download, SHA-256 validation, credential cleanup, and supports both standard Maven and mvnd variants. No issues identified.

spring-caffeine-example/mvnw (1)

1-295: Standard Maven Wrapper script.

This is the official Apache Maven Wrapper shell script (version 3.3.4) with comprehensive cross-platform support including Cygwin/MinGW compatibility, multiple download methods (wget/curl/Java fallback), SHA-256 validation, and proper credential sanitization before exec. No issues identified.

Comment on lines +23 to +24
distribution: [ 'temurin' ]
java: [ '21' ]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Fix bracket spacing for YAML lint compliance.

YAMLlint reports extra spaces inside brackets on these lines.

Apply this diff:

-        distribution: [ 'temurin' ]
-        java: [ '21' ]
+        distribution: ['temurin']
+        java: ['21']
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
distribution: [ 'temurin' ]
java: [ '21' ]
distribution: ['temurin']
java: ['21']
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 23-23: too many spaces inside brackets

(brackets)


[error] 23-23: too many spaces inside brackets

(brackets)


[error] 24-24: too many spaces inside brackets

(brackets)


[error] 24-24: too many spaces inside brackets

(brackets)

🤖 Prompt for AI Agents
.github/workflows/spring-caffeine-example.yml lines 23-24: the array brackets
contain extra spaces which fails YAML lint; remove the spaces inside the
brackets so the arrays use compact form (e.g. change "distribution: [ 'temurin'
]" to "distribution: ['temurin']" and "java: [ '21' ]" to "java: ['21']").

H2_CONSOLE_PATH: /h2-console
H2_INIT_MODE: always
H2_INIT_SCHEMA: classpath:sql/init.sql
CAFFEINE_VERSION_URL: localhost:7079/external
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check Feign client configuration and URL usage

# Find Feign client configurations
echo "=== Searching for FeignClient declarations ==="
rg -n "FeignClient\|@FeignClient" --type java -A 3

echo ""
echo "=== Searching for caffeine-version-url property usage ==="
rg -n "caffeine-version-url\|CAFFEINE_VERSION_URL" --type yaml --type java --type properties

echo ""
echo "=== Checking compose.yaml for all environment variables ==="
cat spring-caffeine-example/compose.yaml

Repository: igorcampos-dev/spring-integrations-examples

Length of output: 936


🏁 Script executed:

#!/bin/bash
# Find files in spring-caffeine-example module
echo "=== Files in spring-caffeine-example ==="
find spring-caffeine-example -type f -name "*.java" -o -name "*.properties" -o -name "*.yml" | head -20

echo ""
echo "=== Search for Feign dependency ==="
rg -l "feign\|Feign" spring-caffeine-example

echo ""
echo "=== Search for property usage with broader patterns ==="
rg -n "CAFFEINE_VERSION\|caffeine" spring-caffeine-example --type java -i

echo ""
echo "=== Check if this is a client calling an external service ==="
rg -n "@RestClient\|@FeignClient\|RestTemplate\|WebClient" spring-caffeine-example --type java -i

Repository: igorcampos-dev/spring-integrations-examples

Length of output: 1372


🏁 Script executed:

#!/bin/bash
echo "=== CaffeineVersionClient.java ==="
cat spring-caffeine-example/src/main/java/com/io/example/client/CaffeineVersionClient.java

echo ""
echo "=== CaffeineProperties.java ==="
cat spring-caffeine-example/src/main/java/com/io/example/properties/CaffeineProperties.java

echo ""
echo "=== Check application properties files ==="
find spring-caffeine-example/src -name "application*.properties" -o -name "application*.yml" | xargs cat

Repository: igorcampos-dev/spring-integrations-examples

Length of output: 1014


🏁 Script executed:

#!/bin/bash
echo "=== Search for external.caffeine-version-url references ==="
rg -n "external.caffeine-version-url\|external\.caffeine" spring-caffeine-example

echo ""
echo "=== Check for all application config files ==="
find spring-caffeine-example -type f \( -name "*.properties" -o -name "*.yml" -o -name "*.yaml" \) | grep -v ".mvn\|wrapper\|workflows"

echo ""
echo "=== Check Dockerfile for property configuration ==="
cat spring-caffeine-example/Dockerfile

echo ""
echo "=== Check pom.xml for spring-cloud-openfeign ==="
grep -A 5 -B 5 "feign\|openfeign" spring-caffeine-example/pom.xml

Repository: igorcampos-dev/spring-integrations-examples

Length of output: 2574


🏁 Script executed:

#!/bin/bash
echo "=== application.yaml ==="
cat spring-caffeine-example/src/main/resources/application.yaml

echo ""
echo "=== application-prd.yaml ==="
cat spring-caffeine-example/src/main/resources/application-prd.yaml

Repository: igorcampos-dev/spring-integrations-examples

Length of output: 1282


The CAFFEINE_VERSION_URL is missing the protocol (http:// or https://), which will cause Feign client connection failures.

Both environment configurations are affected:

  • Local: localhost:8080/external in application.yaml
  • Production: localhost:7079/external in compose.yaml (mapped via application-prd.yaml)

Update the URL to include the protocol: http://localhost:7079/external

🤖 Prompt for AI Agents
In spring-caffeine-example/compose.yaml around line 18, the CAFFEINE_VERSION_URL
value lacks an HTTP scheme which will break Feign client calls; update the
environment value to include the protocol (e.g. change to
"http://localhost:7079/external") so the service has a fully qualified URL, and
ensure any other environment configs (local/production) are likewise updated to
include "http://" or "https://" as appropriate.

Comment on lines +16 to +19
RUN --mount=type=bind,source=pom.xml,target=pom.xml \
--mount=type=cache,target=/root/.m2 \
./mvnw package -DskipTests && \
mv target/$(./mvnw help:evaluate -Dexpression=project.artifactId -q -DforceStdout)-$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout).jar target/app.jar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix shell quoting to prevent word splitting.

Line 19 uses unquoted command substitutions that could cause word splitting issues if the artifact ID or version contains spaces or special characters.

Apply this diff:

     ./mvnw package -DskipTests && \
-    mv target/$(./mvnw help:evaluate -Dexpression=project.artifactId -q -DforceStdout)-$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout).jar target/app.jar
+    mv "target/$(./mvnw help:evaluate -Dexpression=project.artifactId -q -DforceStdout)-$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout).jar" target/app.jar
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
RUN --mount=type=bind,source=pom.xml,target=pom.xml \
--mount=type=cache,target=/root/.m2 \
./mvnw package -DskipTests && \
mv target/$(./mvnw help:evaluate -Dexpression=project.artifactId -q -DforceStdout)-$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout).jar target/app.jar
RUN --mount=type=bind,source=pom.xml,target=pom.xml \
--mount=type=cache,target=/root/.m2 \
./mvnw package -DskipTests && \
mv "target/$(./mvnw help:evaluate -Dexpression=project.artifactId -q -DforceStdout)-$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout).jar" target/app.jar
🧰 Tools
🪛 Hadolint (2.14.0)

[warning] 16-16: Quote this to prevent word splitting.

(SC2046)

🤖 Prompt for AI Agents
In spring-caffeine-example/Dockerfile around lines 16 to 19, the mv command uses
unquoted command substitutions which can lead to word splitting if artifactId or
version contain spaces or special characters; update the Dockerfile to capture
the two evaluated values into variables or directly quote the command
substitution expansions so the resulting filename is treated as a single
argument (e.g., wrap each $(...) expansion in double quotes or assign them to
variables and then reference the variables quoted) and ensure the mv source and
destination arguments are properly quoted to prevent splitting and unexpected
behavior.

Comment on lines +28 to +46
FROM eclipse-temurin:21-jre-jammy AS final


ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
USER appuser

COPY --from=extract build/target/extracted/dependencies/ ./
COPY --from=extract build/target/extracted/spring-boot-loader/ ./
COPY --from=extract build/target/extracted/snapshot-dependencies/ ./
COPY --from=extract build/target/extracted/application/ ./

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Add WORKDIR and HEALTHCHECK for production readiness.

The final stage has two issues:

  1. Missing WORKDIR before COPY commands (lines 42-45), which means files are copied to the root directory
  2. Missing HEALTHCHECK instruction for container health monitoring

Apply this diff:

 FROM eclipse-temurin:21-jre-jammy AS final
 
+WORKDIR /app
 
 ARG UID=10001
 RUN adduser \
     --disabled-password \
     --gecos "" \
     --home "/nonexistent" \
     --shell "/sbin/nologin" \
     --no-create-home \
     --uid "${UID}" \
     appuser
 USER appuser
 
 COPY --from=extract build/target/extracted/dependencies/ ./
 COPY --from=extract build/target/extracted/spring-boot-loader/ ./
 COPY --from=extract build/target/extracted/snapshot-dependencies/ ./
 COPY --from=extract build/target/extracted/application/ ./
 
 EXPOSE 7079
 
+HEALTHCHECK --interval=30s --timeout=3s --start-period=30s --retries=3 \
+  CMD java -cp . org.springframework.boot.actuate.health.HealthEndpoint || exit 1
+
 ENTRYPOINT [ "java", "org.springframework.boot.loader.launch.JarLauncher" ]

Note: For the HEALTHCHECK to work properly, you'll need Spring Boot Actuator. If not using Actuator, consider a simple HTTP health check using curl or wget.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Hadolint (2.14.0)

[warning] 42-42: COPY to a relative destination without WORKDIR set.

(DL3045)


[warning] 43-43: COPY to a relative destination without WORKDIR set.

(DL3045)


[warning] 44-44: COPY to a relative destination without WORKDIR set.

(DL3045)


[warning] 45-45: COPY to a relative destination without WORKDIR set.

(DL3045)

🤖 Prompt for AI Agents
In spring-caffeine-example/Dockerfile around lines 28 to 46, the final stage is
missing a WORKDIR before the COPYs and lacks a HEALTHCHECK; add a WORKDIR (e.g.
/app) before the COPY lines and ensure the directory exists/has correct
ownership (create and chown if necessary or set before switching to the
unprivileged USER), then add a HEALTHCHECK that probes your app (preferably
Spring Boot Actuator /actuator/health on the container port) with sensible
interval/timeout/retries or a simple curl/wget HTTP check if Actuator is not
available; keep the USER placement and permissions consistent so the health
probe can run and files are placed under the intended app directory.

Comment on lines +7 to +14
@FeignClient(
name = "caffeineVersionClient",
url = "${external.caffeine-version-url}"
)
public interface CaffeineVersionClient {

@GetMapping("/v1/caffeine-version")
ExternalApiResponseDto getVersionCaffeine();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, find and check the pom.xml or gradle build files to see actual versions
find . -name "pom.xml" -o -name "build.gradle" -o -name "build.gradle.kts" | head -20

Repository: igorcampos-dev/spring-integrations-examples

Length of output: 615


🏁 Script executed:

# Check the parent pom.xml for version properties
cat ./pom.xml | grep -A 50 "<properties>" | head -60

Repository: igorcampos-dev/spring-integrations-examples

Length of output: 69


🏁 Script executed:

# Read the parent pom.xml to see version definitions
wc -l ./pom.xml

Repository: igorcampos-dev/spring-integrations-examples

Length of output: 99


🏁 Script executed:

# Read parent pom.xml
cat -n ./pom.xml

Repository: igorcampos-dev/spring-integrations-examples

Length of output: 1378


🏁 Script executed:

# Read spring-caffeine-example pom.xml
wc -l ./spring-caffeine-example/pom.xml && echo "---" && cat -n ./spring-caffeine-example/pom.xml

Repository: igorcampos-dev/spring-integrations-examples

Length of output: 3617


🌐 Web query:

Spring Boot 4.0.0 release date

💡 Result:

Spring Boot 4.0.0 was released on November 20, 2025. [1][2]

Sources:
[1] Spring blog — "Spring Boot 4.0.0 available now."
[2] endoflife.date — Spring Boot release listing.


🌐 Web query:

Spring Cloud OpenFeign 5.0.0 release date

💡 Result:

I couldn't find a GA release for Spring Cloud OpenFeign 5.0.0. The latest published release is 5.0.0-M4 (milestone) on 17 Oct 2025. [1][2]

Sources:

  • spring-cloud-openfeign releases (GitHub) — 5.0.0-M4 (17 Oct 2025). [1]
  • Spring blog / Spring Cloud 2025.1.0 announcement (mentions OpenFeign updates). [2]

Feign client implementation is correct, but the project has a critical dependency version issue.

The interface follows standard Spring Cloud OpenFeign patterns with externalized URL configuration. However, there is a build configuration problem: spring.cloud.openfeign.version is set to 5.0.0 in the pom.xml, but Spring Cloud OpenFeign 5.0.0 GA has not been released. Only 5.0.0-M4 (milestone release from October 17, 2025) is currently available. This will cause dependency resolution to fail.

Update the version to 5.0.0-M4 or use the latest stable release (e.g., 4.1.0). For production applications, also consider adding a fallback or fallbackFactory for resilience.

🤖 Prompt for AI Agents
In
spring-caffeine-example/src/main/java/com/io/example/client/CaffeineVersionClient.java
around lines 7 to 14: the Feign client is fine but your build will fail because
pom.xml pins spring.cloud.openfeign.version to a non-existent 5.0.0 GA; update
the spring.cloud.openfeign.version property in pom.xml to a valid release (e.g.,
5.0.0-M4 or the latest stable 4.1.0), run mvn -U verify to refresh dependencies,
and for production consider adding a fallback or fallbackFactory to this
@FeignClient declaration for resilience.

Comment on lines +7 to +10
@Data
@Component
@ConfigurationProperties(prefix = "caffeine")
public class CaffeineProperties {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider using @EnableConfigurationProperties instead of @component.

Using @Component with @ConfigurationProperties works but is not the recommended pattern. The preferred approach is to remove @Component and enable this configuration class using @EnableConfigurationProperties(CaffeineProperties.class) in a configuration class (e.g., CacheConfig).

Apply this diff to CaffeineProperties.java:

 @Data
-@Component
 @ConfigurationProperties(prefix = "caffeine")
 public class CaffeineProperties {

Then update CacheConfig.java to enable the properties:

+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+
 @Configuration
+@EnableConfigurationProperties(CaffeineProperties.class)
 @RequiredArgsConstructor
 public class CacheConfig {

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
spring-caffeine-example/src/main/java/com/io/example/properties/CaffeineProperties.java
around lines 7-10, remove the @Component annotation and keep
@ConfigurationProperties(prefix = "caffeine") (so the class is a plain
configuration properties bean), then update your configuration class (e.g.,
CacheConfig.java) to include @Configuration and
@EnableConfigurationProperties(CaffeineProperties.class) so Spring will bind and
register the properties bean via the configuration class instead of component
scanning.

Comment on lines +11 to +13
private long expireAfterWrite;
private int initialCapacity;
private long maximumSize;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider adding validation constraints.

The configuration properties lack validation, which could lead to runtime issues if invalid values are provided (e.g., negative numbers, zero capacity).

Consider adding validation annotations:

+import jakarta.validation.constraints.Min;
+
 public class CaffeineProperties {
+    @Min(1)
     private long expireAfterWrite;
+    @Min(1)
     private int initialCapacity;
+    @Min(1)
     private long maximumSize;
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
spring-caffeine-example/src/main/java/com/io/example/properties/CaffeineProperties.java
around lines 11-13, the three numeric configuration fields currently have no
validation; add bean-validation to prevent invalid values at startup: annotate
the class with @org.springframework.validation.annotation.Validated (or ensure
@Validated is applied where the @ConfigurationProperties bean is registered) and
add appropriate Jakarta validation annotations on fields (e.g.,
@jakarta.validation.constraints.PositiveOrZero on expireAfterWrite,
@jakarta.validation.constraints.Min(1) on initialCapacity to forbid zero, and
@jakarta.validation.constraints.Positive on maximumSize or @PositiveOrZero if
zero is allowed) and import the constraint annotations; keep existing
getters/setters and ensure the configuration binding will fail fast on invalid
values.

@RequiredArgsConstructor
public class CaffeineServiceImpl implements CaffeineService{

private final Cache<@NonNull String, String> caffeineCache;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Reconsider the @nonnull annotation on the generic type parameter.

Similar to the issue in CacheConfig, the @NonNull annotation on Cache<@NonNull String, String> is redundant since Caffeine rejects null keys by default.

-private final Cache<@NonNull String, String> caffeineCache;
+private final Cache<String, String> caffeineCache;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private final Cache<@NonNull String, String> caffeineCache;
private final Cache<String, String> caffeineCache;
🤖 Prompt for AI Agents
In
spring-caffeine-example/src/main/java/com/io/example/service/CaffeineServiceImpl.java
around line 17, remove the redundant @NonNull annotation on the generic key type
(Cache<@NonNull String, String>) because Caffeine already disallows null keys;
change the field declaration to use a plain Cache<String, String> instead and
update any imports/usages accordingly to avoid unused annotation imports or
compiler warnings.

expireAfterWrite: ${CAFFEINE_EXPIRES}
initialCapacity: ${CAFFEINE_CAPACITY}
maximumSize: ${CAFFEINE_MAXIMUM_SIZE}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove trailing blank line.

YAMLlint flags an extra blank line at the end of the file.

Apply this diff:

   maximumSize: ${CAFFEINE_MAXIMUM_SIZE}
-
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
maximumSize: ${CAFFEINE_MAXIMUM_SIZE}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 32-32: too many blank lines (1 > 0)

(empty-lines)

🤖 Prompt for AI Agents
In spring-caffeine-example/src/main/resources/application-prd.yaml around line
32, the file contains an extra trailing blank line flagged by YAMLlint; remove
the empty final line so the file ends immediately after the last content line
(ensure exactly one newline at EOF if your editor requires it) and save the
file.

Comment on lines +28 to +32
caffeine:
expireAfterWrite: 60 # seconds
initialCapacity: 200
maximumSize: 500

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Optional: Clean up YAML formatting.

Minor formatting issues flagged by YAMLlint:

  • Line 29: Comment should have 2 spaces before it (currently has 1)
  • Line 32: Extra blank line at end of file

Apply this diff:

 caffeine:
-  expireAfterWrite: 60 # seconds
+  expireAfterWrite: 60  # seconds
   initialCapacity: 200
   maximumSize: 500
-
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
caffeine:
expireAfterWrite: 60 # seconds
initialCapacity: 200
maximumSize: 500
caffeine:
expireAfterWrite: 60 # seconds
initialCapacity: 200
maximumSize: 500
🧰 Tools
🪛 YAMLlint (1.37.1)

[warning] 29-29: too few spaces before comment: expected 2

(comments)


[error] 32-32: too many blank lines (1 > 0)

(empty-lines)

🤖 Prompt for AI Agents
In spring-caffeine-example/src/main/resources/application.yaml around lines 28
to 32, the YAML has minor formatting issues: the inline comment on line 29 needs
one additional space before the "#" (make it two spaces before the comment text)
and the trailing extra blank line at the end of the file (line 32) should be
removed; update the file to add the extra space before the comment and delete
the final blank line so the file ends immediately after the last configuration
entry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants