Stateless central server application that manages DevStack project lifecycles. The system will expose RESTful APIs for third-party client applications and future CLI tools, while minimizing server-side data storage and leveraging external identity providers.
- Prerequisites
- Quick Start
- Build Options
- Running the Application
- Security & Authentication
- Development Workflow
- Docker Support
- Advanced Usage
- Troubleshooting
Before using the Makefile, ensure you have the following installed:
- Java 21+ - The project uses Java 21
- Maven - Maven wrapper (
mvnw) is included in the project - Make - For running Makefile commands
- GraalVM with native-image - Required for native binary compilation
- Docker - Required for Docker image building
# Install GraalVM native-image component
gu install native-imageThe easiest way to get started is using the Makefile:
# Show all available commands
make help
# Build and run the application
make quick-startThis will build the JAR and start the application on http://localhost:8080.
Build a traditional Spring Boot JAR file:
make jar- Output:
core/target/core-0.0.3.jar - Includes all dependencies
- Standard Spring Boot startup time
Build a native binary using GraalVM (requires GraalVM installation):
make native- Output:
core/target/core - Fast startup time
- Lower memory footprint
- Requires GraalVM with native-image
Build a native Docker image using GraalVM (requires GraalVM installation):
make docker-native- Output: Docker image
devstack-api-service-native:latest - Ultra-fast startup time
- Minimal container size
- Requires GraalVM with native-image
Build JAR, native binary, and Docker images (if GraalVM is available):
make allmake run-jarmake run-nativemake run-dockermake run-docker-nativeOnce running, the application is available at:
- Main Application: http://localhost:8080
- Swagger UI: http://localhost:8080/swagger-ui.html
- Actuator Health: http://localhost:8080/actuator/health
The service is an OAuth2 Resource Server that validates incoming JWT access tokens. Authentication is configured entirely through environment variables.
The API accepts tokens from more than one trusted identity provider. Each issuer
pairs an issuer URI (the token iss claim) with the JWK set URI used to validate
the token signature. The incoming token's iss claim selects the matching issuer.
| Variable | Description |
|---|---|
OAUTH2_ISSUER_V1 |
Issuer URI (iss claim) of the first trusted identity provider |
OAUTH2_JWK_SET_URI_V1 |
JWK set URI used to verify signatures for issuer V1 |
OAUTH2_ISSUER_V2 |
Issuer URI (iss claim) of the second trusted identity provider |
OAUTH2_JWK_SET_URI_V2 |
JWK set URI used to verify signatures for issuer V2 |
Audiences are shared across all configured issuers. A valid token must carry at
least one of these values in its aud claim.
| Variable | Description |
|---|---|
OAUTH2_AUDIENCE |
First accepted audience value |
OAUTH2_AUDIENCE2 |
Second accepted audience value |
Calls to the Marketplace service normally perform an On-Behalf-Of (OBO) token exchange. When the incoming token already targets the configured bypass audience and scope, the OBO exchange is skipped and the token is forwarded as-is.
| Variable | Description |
|---|---|
MARKETPLACE_BYPASS_AUDIENCE |
Audience that must be present in the token aud claim to skip the OBO exchange |
MARKETPLACE_BYPASS_SCOPE |
Scope that must be present in the token scp claim to skip the OBO exchange |
If either bypass value is unset, the OBO exchange is always performed.
Clean, compile, and test in one command:
make devmake test# Format code
make format
# Run static analysis
make lintComplete build with verification:
make cimake dockerBuilds a standard Docker image with the Spring Boot JAR.
make docker-nativeBuilds a native Docker image using GraalVM for ultra-fast startup and minimal size.
make run-dockermake run-docker-nativeThe Docker images will be tagged as:
- Standard:
devstack-api-service:latest - Native:
devstack-api-service-native:latest
# Clean build artifacts
make clean
# Clean everything including Docker images
make clean-all# Show build information
make info
# Show project structure
make structureYou can still use Maven directly if needed:
# Standard build
./mvnw clean package
# Native build
./mvnw clean package -Pnative -DskipTestsError: Java 17 or higher is required
Solution: Install Java 17+ and ensure it's in your PATH.
Error: native-image not found. Please install GraalVM and native-image
Solution: Install GraalVM and run gu install native-image.
Permission denied: ./mvnw
Solution: The Makefile automatically fixes this, but you can manually run:
chmod +x ./mvnwPort 8080 was already in use
Solution: Stop other applications using port 8080 or change the port in application.properties.
- Skip Tests for Faster Builds: Tests are automatically skipped in JAR/native builds
- Native Build Memory: Native builds require significant memory (4GB+ recommended)
- Docker Layer Caching: Docker builds reuse layers for faster subsequent builds
- Native Docker Benefits: Native Docker images start ~10x faster and use ~50% less memory
- Choose the Right Build: Use standard Docker for development, native Docker for production
ods-api-service/
├── Makefile # Build automation
├── pom.xml # Parent POM
├── mvnw # Maven wrapper
├── api-xxx # Api module
├── external-service-yyy # External service module
├── core/ # Main application module
│ ├── pom.xml # Core module POM
│ ├── src/ # Source code
│ └── target/ # Build output
└── docker/ # Docker configuration
├── Dockerfile # Standard container definition
└── Docker.native # Native container definition
- Use
make devfor development builds - Run
make formatandmake lintbefore committing - Ensure
make cipasses before submitting PRs
