-
Notifications
You must be signed in to change notification settings - Fork 0
feat(spring-caffeine): initialize Spring Caffeine example project wit… #144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| name: spring-caffeine-example CI Build | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: [master] | ||
| paths: | ||
| - "spring-caffeine-example/**" | ||
| types: | ||
| - opened | ||
| - synchronize | ||
| - reopened | ||
|
|
||
| jobs: | ||
|
|
||
| integration-tests: | ||
| name: Run Unit & Integration Tests | ||
| runs-on: ubuntu-latest | ||
| defaults: | ||
| run: | ||
| working-directory: spring-caffeine-example | ||
| strategy: | ||
| matrix: | ||
| distribution: [ 'temurin' ] | ||
| java: [ '21' ] | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Set up JDK ${{ matrix.java }} | ||
| uses: actions/setup-java@v5.1.0 | ||
| with: | ||
| java-version: ${{ matrix.java }} | ||
| distribution: ${{ matrix.distribution }} | ||
| cache: 'maven' | ||
| - name: Build and analyze | ||
| run: ./mvnw clean verify | ||
|
|
||
| health-check: | ||
| name: Health Check on Services | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout repository and submodules | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| submodules: true | ||
|
|
||
| - name: Extract service names from docker compose | ||
| id: services | ||
| run: | | ||
| echo "services<<EOF" >> $GITHUB_OUTPUT | ||
| docker compose -f ./spring-caffeine-example/compose.yaml config --services >> $GITHUB_OUTPUT | ||
| echo "EOF" >> $GITHUB_OUTPUT | ||
|
|
||
| - name: Start containers with Compose Action | ||
| uses: hoverkraft-tech/compose-action@v2.4.2 | ||
| with: | ||
| compose-file: './spring-caffeine-example/compose.yaml' | ||
| services: ${{ steps.services.outputs.services }} | ||
| up-flags: '--build' | ||
| down-flags: '--volumes' | ||
|
|
||
| - name: Wait for containers to initialize | ||
| run: sleep 10 | ||
|
|
||
| - name: Check container health | ||
| run: | | ||
| ./.github/scripts/check-container-health.sh "${{ steps.services.outputs.services }}" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| # Include any files or directories that you don't want to be copied to your | ||
| # container here (e.g., local build artifacts, temporary files, etc.). | ||
| # | ||
| # For more help, visit the .dockerignore file reference guide at | ||
| # https://docs.docker.com/go/build-context-dockerignore/ | ||
|
|
||
| **/.DS_Store | ||
| **/.classpath | ||
| **/.dockerignore | ||
| **/.env | ||
| **/.factorypath | ||
| **/.git | ||
| **/.gitignore | ||
| **/.idea | ||
| **/.project | ||
| **/.sts4-cache | ||
| **/.settings | ||
| **/.toolstarget | ||
| **/.vs | ||
| **/.vscode | ||
| **/.next | ||
| **/.cache | ||
| **/*.dbmdl | ||
| **/*.jfm | ||
| **/charts | ||
| **/docker-compose* | ||
| **/compose.y*ml | ||
| **/Dockerfile* | ||
| **/secrets.dev.yaml | ||
| **/values.dev.yaml | ||
| **/vendor | ||
| LICENSE | ||
| README.md | ||
| **/*.class | ||
| **/*.iml | ||
| **/*.ipr | ||
| **/*.iws | ||
| **/*.log | ||
| **/.apt_generated | ||
| **/.gradle | ||
| **/.gradletasknamecache | ||
| **/.nb-gradle | ||
| **/.springBeans | ||
| **/build | ||
| **/dist | ||
| **/gradle-app.setting | ||
| **/nbbuild | ||
| **/nbdist | ||
| **/nbproject/private | ||
| **/target | ||
| *.ctxt | ||
| .mtj.tmp | ||
| .mvn/timing.properties | ||
| buildNumber.properties | ||
| dependency-reduced-pom.xml | ||
| hs_err_pid* | ||
| pom.xml.next | ||
| pom.xml.releaseBackup | ||
| pom.xml.tag | ||
| pom.xml.versionsBackup | ||
| release.properties | ||
| replay_pid* |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| /mvnw text eol=lf | ||
| *.cmd text eol=crlf |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| name: CI Build | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - "**" | ||
|
|
||
| jobs: | ||
| build: | ||
| name: Build | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| matrix: | ||
| distribution: [ 'temurin' ] | ||
| java: [ '21' ] | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
|
|
||
| - name: Setup Java 21 | ||
| uses: actions/setup-java@v5 | ||
| with: | ||
| java-version: ${{ matrix.java }} | ||
| distribution: ${{ matrix.distribution }} | ||
| cache: 'maven' | ||
|
|
||
| - name: Grant execute permission for mvnw | ||
| run: chmod +x mvnw | ||
|
|
||
| - name: Build with Maven | ||
| run: ./mvnw clean verify |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| target/ | ||
| .mvn/wrapper/maven-wrapper.jar | ||
| !**/src/main/**/target/ | ||
| !**/src/test/**/target/ | ||
|
|
||
| ### STS ### | ||
| .apt_generated | ||
| .classpath | ||
| .factorypath | ||
| .project | ||
| .settings | ||
| .springBeans | ||
| .sts4-cache | ||
|
|
||
| ### IntelliJ IDEA ### | ||
| .idea | ||
| *.iws | ||
| *.iml | ||
| *.ipr | ||
|
|
||
| ### NetBeans ### | ||
| /nbproject/private/ | ||
| /nbbuild/ | ||
| /dist/ | ||
| /nbdist/ | ||
| /.nb-gradle/ | ||
| build/ | ||
| !**/src/main/**/build/ | ||
| !**/src/test/**/build/ | ||
|
|
||
| ### VS Code ### | ||
| .vscode/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| wrapperVersion=3.3.4 | ||
| distributionType=only-script | ||
| distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,49 @@ | ||||||||||||||||||
| FROM eclipse-temurin:21-jdk-jammy as deps | ||||||||||||||||||
|
|
||||||||||||||||||
| WORKDIR /build | ||||||||||||||||||
|
|
||||||||||||||||||
| COPY --chmod=0755 mvnw mvnw | ||||||||||||||||||
| COPY .mvn/ .mvn/ | ||||||||||||||||||
|
|
||||||||||||||||||
| RUN --mount=type=bind,source=pom.xml,target=pom.xml \ | ||||||||||||||||||
| --mount=type=cache,target=/root/.m2 ./mvnw dependency:go-offline -DskipTests | ||||||||||||||||||
|
|
||||||||||||||||||
| FROM deps as package | ||||||||||||||||||
|
|
||||||||||||||||||
| WORKDIR /build | ||||||||||||||||||
|
|
||||||||||||||||||
| COPY ./src src/ | ||||||||||||||||||
| 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 | ||||||||||||||||||
|
Comment on lines
+16
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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
Suggested change
🧰 Tools🪛 Hadolint (2.14.0)[warning] 16-16: Quote this to prevent word splitting. (SC2046) 🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| FROM package as extract | ||||||||||||||||||
|
|
||||||||||||||||||
| WORKDIR /build | ||||||||||||||||||
|
|
||||||||||||||||||
| RUN java -Djarmode=layertools -jar target/app.jar extract --destination target/extracted | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
| 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/ ./ | ||||||||||||||||||
|
|
||||||||||||||||||
|
Comment on lines
+28
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
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
🧰 Tools🪛 Hadolint (2.14.0)[warning] 42-42: (DL3045) [warning] 43-43: (DL3045) [warning] 44-44: (DL3045) [warning] 45-45: (DL3045) 🤖 Prompt for AI Agents |
||||||||||||||||||
| EXPOSE 7079 | ||||||||||||||||||
|
|
||||||||||||||||||
| ENTRYPOINT [ "java", "org.springframework.boot.loader.launch.JarLauncher" ] | ||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # spring-caffeine-example | ||
|
|
||
| ## Overview | ||
|
|
||
| This project is a simple and practical example demonstrating how to use **Caffeine** as an in-memory cache in a Spring Boot application. | ||
|
|
||
| The main goal is to show how Caffeine can be used to cache: | ||
| - external service calls (e.g. HTTP/Feign clients) | ||
| - database lookups | ||
|
|
||
| The project focuses on using **Caffeine directly**, avoiding unnecessary abstractions, to achieve better performance, predictability, and simplicity. | ||
|
|
||
| --- | ||
|
|
||
| ## Main Endpoint | ||
|
|
||
| | Environment | Curl | | ||
| |-------------|-------------------------------------------------------------| | ||
| | Local | curl --location 'http://localhost:8080/caffeine/v1/request' | | ||
| | Docker | curl --location 'http://localhost:7079/caffeine/v1/request' | | ||
|
|
||
| --- | ||
|
|
||
| ## Related Resources | ||
|
|
||
| | Description | Link | | ||
| |--------------------------|------------------------------------------------| | ||
| | Caffeine Github | https://github.com/ben-manes/caffeine | | ||
| | Introduction to Caffeine | https://www.baeldung.com/java-caching-caffeine | |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| services: | ||
|
|
||
| app: | ||
| container_name: app | ||
| build: | ||
| context: . | ||
| environment: | ||
| SPRING_PROFILES_ACTIVE: prd | ||
| SERVER_PORT: 7079 | ||
| H2_DB_URL: jdbc:h2:mem:caffeine-db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE | ||
| H2_DB_DRIVER: org.h2.Driver | ||
| H2_DB_USERNAME: sa | ||
| H2_DB_PASSWORD: "" | ||
| H2_CONSOLE_ENABLED: false | ||
| H2_CONSOLE_PATH: /h2-console | ||
| H2_INIT_MODE: always | ||
| H2_INIT_SCHEMA: classpath:sql/init.sql | ||
| CAFFEINE_VERSION_URL: localhost:7079/external | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 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.yamlRepository: 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 -iRepository: 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 catRepository: 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.xmlRepository: 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.yamlRepository: igorcampos-dev/spring-integrations-examples Length of output: 1282 The Both environment configurations are affected:
Update the URL to include the protocol: 🤖 Prompt for AI Agents |
||
| CAFFEINE_EXPIRES: 60 #seconds | ||
| CAFFEINE_CAPACITY: 200 | ||
| CAFFEINE_MAXIMUM_SIZE: 500 | ||
| ports: | ||
| - "7079:7079" | ||
There was a problem hiding this comment.
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:
📝 Committable suggestion
🧰 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