Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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: 'springwolf-example/**/*'
Comment thread
igorcampos-dev marked this conversation as resolved.
Outdated

"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.
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-example-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