Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
- changed-files:
- any-glob-to-any-file: 'spring-batch-file-examples/**/*'

"project: springwolf-example":
- changed-files:
- any-glob-to-any-file: 'spring-wolf-example/**/*'

"type: dependency-upgrade":
- changed-files:
- any-glob-to-any-file: "**/pom.xml"
Expand Down
68 changes: 68 additions & 0 deletions .github/workflows/springwolf-example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: springwolf-example CI Build

on:
pull_request:
branches: [master]
paths:
- "springwolf-example/**"
types:
- opened
- synchronize
- reopened

jobs:

integration-tests:
name: Run Unit & Integration Tests
runs-on: ubuntu-latest
defaults:
run:
working-directory: springwolf-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 ./springwolf-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: './springwolf-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 }}"
Comment thread
igorcampos-dev marked this conversation as resolved.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Below you will find a summary table of each subproject. For more details, please
| [Spring Boot + Postgres](./spring-postgres-example) | Demonstrates a basic integration between Spring Boot and Postgres. |
| [Spring Boot + Mysql](./spring-mysql-example) | Demonstrates a basic integration between Spring Boot and Mysql. |
| [Spring Boot + Grafana + Prometheus](./spring-prometheus-grafana-example) | Demonstrates a basic integration between Spring Boot With Grafana and Prometheus. |

| [Spring Boot + Spring Wolf](./spring-wolf-example) | Demonstrates a basic integration between Spring Boot and Spring Wolf. |
---

## Tech Stack
Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<module>spring-oracle-example</module>
<module>spring-batch-file-examples</module>
<module>spring-batch-db-examples</module>
<module>spring-wolf-example</module>
</modules>

</project>
62 changes: 62 additions & 0 deletions spring-wolf-example/.dockerignore
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*
2 changes: 2 additions & 0 deletions spring-wolf-example/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/mvnw text eol=lf
*.cmd text eol=crlf
30 changes: 30 additions & 0 deletions spring-wolf-example/.github/maven.yml
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
Comment thread
igorcampos-dev marked this conversation as resolved.
33 changes: 33 additions & 0 deletions spring-wolf-example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
HELP.md
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/
3 changes: 3 additions & 0 deletions spring-wolf-example/.mvn/wrapper/maven-wrapper.properties
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
47 changes: 47 additions & 0 deletions spring-wolf-example/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
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

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

EXPOSE 7075

ENTRYPOINT [ "java", "org.springframework.boot.loader.launch.JarLauncher" ]
Comment thread
igorcampos-dev marked this conversation as resolved.
50 changes: 50 additions & 0 deletions spring-wolf-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# spring-wolf-example

## Overview

This project demonstrates how to use **Spring Wolf** to document and expose asynchronous APIs built with Spring Boot.
It includes examples of asynchronous communication using **Kafka**, and will later include **Google Pub/Sub** and **AWS SQS**.

Spring Wolf automatically generates an **AsyncAPI specification** and provides a UI to visualize producers, consumers,
and message schemas in real time.

---

## Tech Stack

- Spring Boot
- Spring Wolf
- Java 21
- Docker
- Kafka (implemented)
- Google Pub/Sub (pending)
- AWS SQS (pending)

---

## Current Progress

| Tool / Integration | Status | Notes |
|--------------------|---------------|----------------------------------------|
| Kafka | ✔ Implemented | Consumer + Producer examples completed |
| Google Pub/Sub | ⏳ Pending | Planned for future implementation |
| AWS SQS | ⏳ Pending | Planned for future implementation |

---

## Endpoints

| Environment | URL |
|-------------|----------------------------------------------------------------|
| Docker | http://localhost:7075/springwolf/asyncapi-ui.html |
| Local | http://localhost:8080/springwolf/asyncapi-ui.html |

---

## Related Resources

| Description | Link |
|--------------------------------|----------------------------------------------------------------------------------------------------------------|
| Spring Wolf Documentation | https://springwolf.dev |
| AsyncAPI Specification | https://www.asyncapi.com |
| Spring Wolf With Kafka Example | [here](https://github.com/springwolf/springwolf-core/tree/master/springwolf-examples/springwolf-kafka-example) |
Comment thread
igorcampos-dev marked this conversation as resolved.
61 changes: 61 additions & 0 deletions spring-wolf-example/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
services:

app:
container_name: app
build:
context: .
ports:
- "7075:7075"
environment:
SERVER_PORT: 7075
SPRING_WOLF_ENABLED: true
KAFKA_SIMPLE_TOPIC: spring-kafka-simple-topic
KAFKA_SERVER: kafka:9092
depends_on:
- kafka
networks:
- kafka-net

kafka:
image: apache/kafka:4.1.1
container_name: kafka
ports:
- "9092:9092"
- "9093:9093"
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:9093
KAFKA_LISTENERS: CONTROLLER://0.0.0.0:9094,PLAINTEXT://0.0.0.0:9092,PLAINTEXT_HOST://0.0.0.0:9093
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9094
KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'false'
networks:
- kafka-net

kafka-init:
container_name: kafka-init
image: apache/kafka:4.1.1
depends_on:
kafka:
condition: service_started
command: [ "/bin/bash", "-c", "/create_topic.sh" ]
Comment thread
igorcampos-dev marked this conversation as resolved.
environment:
KAFKA_HOST: kafka
KAFKA_PORT: 9092
KAFKA_TOPIC_CREATE: spring-kafka-simple-topic
volumes:
- type: bind
source: ./docker/kafka/create_topic.sh
target: /create_topic.sh
init: true
networks:
- kafka-net
Comment thread
igorcampos-dev marked this conversation as resolved.

networks:
kafka-net:
driver: bridge
Loading