Skip to content

Services (Spring Boot)

The LabOps demo runs two backend services. Both follow the same shape — Spring Boot 3.4 / Java 17 / Maven — but are designed to demonstrate two distinct OAuth2 grant flows through APIM.

tickets-api

Pathservices/tickets-api/
PurposeTicket CRUD; user-scoped via OIDC Auth Code + PKCE
Imageghcr.io/zeshaq/wso2-demo-app/tickets-api
Listens:8080
DBH2 in-memory (Postgres-compat mode) until #11

Endpoints

MethodPathPurposeFuture scope
GET/healthActuator healthPublic
GET/api/v1/ticketsList ticketstickets:read
GET/api/v1/tickets/{id}One tickettickets:read
POST/api/v1/ticketsCreatetickets:write
PUT/api/v1/tickets/{id}Updatetickets:write
DELETE/api/v1/tickets/{id}Deletetickets:admin

Ticket entity

id          Long   (auto)
title       String (required, max 200)
description String (nullable, max 4000)
status      enum   OPEN | IN_PROGRESS | CLOSED  (default OPEN)
assignee    String (nullable)
createdAt   Instant
updatedAt   Instant

assets-api

Pathservices/assets-api/
PurposeLab asset CRUD; M2M write + user read
Imageghcr.io/zeshaq/wso2-demo-app/assets-api
Listens:8080
DBH2 in-memory (Postgres-compat mode) until #11

Endpoints

MethodPathPurposeFuture scope
GET/healthActuator healthPublic
GET/api/v1/assetsPaginated listassets:read
GET/api/v1/assets/{id}One assetassets:read
POST/api/v1/assetsCreateassets:admin (M2M client_credentials)
DELETE/api/v1/assets/{id}Deleteassets:admin

Asset entity

id           Long    (auto)
assetTag     String  (required, unique, max 64)   e.g. "LB-RACK-01-PSU-2"
name         String  (required, max 200)
category     enum    COMPUTE | STORAGE | NETWORK | POWER | OTHER
location     String  (nullable, max 200)
serialNumber String  (nullable, max 100)
inService    boolean (default true)
createdAt    Instant
updatedAt    Instant

Why two services

The demo needs to show two OAuth2 grant shapes side-by-side through one APIM gateway:

  • tickets-api → user-scoped, Authorization Code + PKCE via WSO2 IS, scopes tickets:read|write|admin
  • assets-api → M2M client_credentials for partner systems, the labops-cli, and the gitlab-sync MI flow; plus user-scoped read for the dashboard

Two services let one APIM deployment expose both shapes, and let us attach a response-transformation mediation policy to the assets-api so internal fields are stripped before they reach untrusted clients.

Build, run, test

sh
# from services/<service>/
mvn -B -ntp -DskipTests package         # build the JAR
mvn -B -ntp test                         # run unit + integration tests
mvn spring-boot:run                      # run locally on :8080
sh
# Container
docker build -t labops/<service>:dev .
docker run --rm -p 8080:8080 labops/<service>:dev

Configuration

Phase 2 uses H2 with in-memory data. Future env vars (introduced incrementally):

VariablePhasePurpose
SPRING_DATASOURCE_URL#11Postgres JDBC URL (templated by Helm)
SPRING_DATASOURCE_USERNAME#11DB user (from k8s Secret)
SPRING_DATASOURCE_PASSWORD#11DB password (external-secrets-managed)
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI#18WSO2 IS issuer for JWT validation

How the services fit in

React SPA / labops-cli

APIM Gateway   ◄── token issued by WSO2 IS (Key Manager)

tickets-api / assets-api   ◄── this page

Postgres (spoke-dc)

See Architecture for the full picture.

Built with VitePress · Hosted on Cloudflare Pages