This guide helps AI assistants work efficiently with the CALM Hub backend codebase.
- Language: Java 21
- Framework: Quarkus 3.29+ (Reactive REST, CDI)
- Build Tool: Maven (via parent POM)
- Databases:
- MongoDB (production default)
- NitriteDB (embedded, standalone mode)
- Testing: JUnit 5, TestContainers
- API Docs: OpenAPI/Swagger UI
- Security: Keycloak integration (secure profile)
# Build & Test
../mvnw clean package # Full build
../mvnw -P integration verify # Include integration tests
../mvnw test # Unit tests only
# Development Mode (Hot Reload)
../mvnw quarkus:dev # Default (MongoDB)
../mvnw quarkus:dev -Dcalm.database.mode=standalone # Standalone (NitriteDB)
../mvnw quarkus:dev -Dquarkus.profile=secure # Secure mode (Keycloak)
# Docker
docker-compose up # From deploy/ - production-like
cd local-dev && docker-compose up # MongoDB for development
# Packaging
../mvnw package # Create quarkus-app/
java -jar target/quarkus-app/quarkus-run.jar # Run packaged app
# Docker Build
docker buildx build --platform linux/amd64,linux/arm64 \
-f src/main/docker/Dockerfile.jvm -t calm-hub --push .src/
├── main/java/org/finos/calm/
│ ├── resources/ # REST API endpoints
│ ├── services/ # Business logic
│ ├── store/ # Data access layer
│ │ ├── interfaces # Store abstractions
│ │ ├── mongo/ # MongoDB implementations
│ │ ├── nitrite/ # NitriteDB implementations
│ │ └── producer/ # CDI producers for store selection
│ ├── domain/ # Domain models
│ └── config/ # Configuration beans
├── test/java/ # Unit tests
└── integration-test/java/ # Integration tests (TestContainers)
@Path("/api/v1/architectures")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ArchitectureResource {
@Inject
ArchitectureService service;
@GET
public List<Architecture> listArchitectures() {
return service.findAll();
}
}CALM Hub supports pluggable storage backends via CDI Producers:
Configuration Property: calm.database.mode (default: mongo)
Modes:
- mongo (default) - MongoDB production storage
- standalone - NitriteDB embedded storage (no external DB needed)
How It Works:
- Store interfaces defined in
org.finos.calm.store - Implementations in
store/mongo/andstore/nitrite/ - Producers in
store/producer/select implementation at runtime
Example Producer Pattern:
@ApplicationScoped
public class ArchitectureStoreProducer {
@Inject
@ConfigProperty(name = "calm.database.mode", defaultValue = "mongo")
String databaseMode;
@Inject MongoArchitectureStore mongoStore;
@Inject NitriteArchitectureStore nitriteStore;
@Produces
@ApplicationScoped
public ArchitectureStore produceStore() {
return "standalone".equals(databaseMode)
? nitriteStore
: mongoStore;
}
}Default Profile (no auth):
- All endpoints open
- Good for development
Secure Profile (Keycloak):
- OAuth2/OIDC authentication
- Requires Keycloak running on https://localhost:9443
- Self-signed certificates for local dev
- Hot reload for Java code changes
- Accessible at http://localhost:8080
- Swagger UI at http://localhost:8080/q/swagger-ui
- Dev UI at http://localhost:8080/q/dev
- Create implementation package:
org.finos.calm.store.newmode - Implement store interfaces
- Update Producer classes to inject and conditionally return new implementation
- Add mode to configuration documentation
- Located in
src/integration-test/java/ - Use TestContainers (requires Docker)
- Run via Maven only:
../mvnw -P integration verify - Cannot run from IDE unless Docker configured
- OpenAPI spec auto-generated by Quarkus
- Available at
/q/swagger-uiin dev/secure mode - Annotations:
@Operation,@APIResponse, etc.
../mvnw test # All unit tests
../mvnw test -Dtest=ClassName # Specific test class../mvnw -P integration verify # Requires Docker runningsrc/test/java/- Unit tests (fast, no containers)src/integration-test/java/- Integration tests (TestContainers)
- Create resource class in
resources/ - Implement service logic in
services/ - Add store methods if needed in
store/ - Write unit tests in
test/ - Add integration test in
integration-test/ - Document with OpenAPI annotations
- Create package:
org.finos.calm.store.mybackend - Implement all store interfaces
- Update all Producer classes to include new implementation
- Add conditional logic based on
calm.database.mode - Document in README.md
- Start dev MongoDB:
cd local-dev && docker-compose up - Connection details in
application.properties - Database name:
calm-hub(default)
- Generate certificates (see README.md)
- Start Keycloak:
cd keycloak-dev && docker-compose up - Login to Keycloak: https://localhost:9443 (admin/password)
- Switch to
calm-hub-realm - Use
demouser for testing - Run app:
../mvnw quarkus:dev -Dquarkus.profile=secure
pom.xml- Maven dependencies and build configsrc/main/resources/application.properties- Default configsrc/main/resources/application-secure.properties- Secure profile config
calm-hub depends on:
└── cli (via parent POM, but loosely coupled)
CALM Hub is largely independent - it's a standalone REST API server.
- TestContainers Errors: Ensure Docker is running before integration tests
- Port Conflicts: Check if port 8080 is free (or change
quarkus.http.port) - MongoDB Connection: Start MongoDB before dev mode (unless using standalone)
- Certificate Issues: Use exact CN in URLs when using self-signed certs
- Profile Selection: Remember to pass
-Dquarkus.profile=securefor secure mode
If using Java 24 or later, you may see thread-local access warnings during tests:
java.lang.IllegalAccessError: module java.base does not open java.lang to unnamed module
These warnings are harmless and don't affect test results. To suppress them, add JVM options:
../mvnw test -Dquarkus.args="--add-opens java.base/java.lang=ALL-UNNAMED"Recommended: Use Java 21 LTS for development (as specified in pom.xml).
- Use
@ConfigPropertyto inject config values - Profile-specific:
%profile.property.name=value - Environment overrides:
PROPERTY_NAME=value
- Use
@Injectfor dependency injection - Scopes:
@ApplicationScoped,@RequestScoped - Producers:
@Producesfor factory methods
@Pathfor routing@GET,@POST,@PUT,@DELETEfor HTTP methods@PathParam,@QueryParamfor parameters
- README.md - Detailed setup and deployment guide
- Quarkus Docs - Framework documentation
- Root README - Monorepo overview
- Swagger UI: http://localhost:8080/q/swagger-ui (when running)