2. Tech Stack & Anatomy of a Service¶
The stack¶
| Layer | What we use |
|---|---|
| Language | Java 21 (Temurin) |
| Framework | Spring Boot 3.4.x |
| Integration | Apache Camel 4.6+ (camel-spring-boot-starter) |
| Build | Maven, via the wrapper ./mvnw — there is no global Maven |
| Messaging | Azure Service Bus (camel-azure-servicebus) |
| Data | PostgreSQL (service state); some Snowflake |
| Scheduling | @Scheduled + ShedLock (so only one pod runs a cron job) |
| Boilerplate | Lombok (getters/builders via annotations) |
| Logging | Logstash logback encoder → JSON logs → Datadog |
| Tracing | Micrometer + Brave (distributed traces) |
| Style | Checkstyle (Google baseline, 4-space indent) — build fails on violations |
Anatomy of a service¶
Every service follows the same package convention:
com.popsockets.integration.<app> (e.g. order_prc). Inside:
com/popsockets/integration/order_prc/
├── route/ # Camel routes — the pipelines (the heart of the service)
├── controller/ # Spring REST controllers (sync HTTP endpoints)
├── service/ # business logic (interfaces here, impl/ underneath)
│ └── impl/
├── dto/ # data objects — the shapes of messages in/out
├── configuration/ # Spring @Configuration beans, clients, wiring
├── actuator/ # custom actuator endpoints (e.g. route control)
├── util/ # helpers
└── exceptions/ # custom exception types
And under src/main/resources/:
application.properties # base config (overridden by Config Server in cloud)
application-dev.yml # per-environment overrides…
application-qa.yml
application-stage.yml
application-prod.yml
logback-spring.xml # log format (JSON)
key/ # AES keys for payload encryption (where used)
Rule of thumb
routes orchestrate, services hold logic, DTOs are the data. If a route is
getting fat, the logic probably belongs in a service.
Where the real work lives¶
Routes are named after the capability they implement, and they read top-to-bottom:
CirroIntegrationRouter— talks to the Cirro warehouse systemNavOrderReleaseRouter— releases orders to NAVPsSftpRouter/SpsSftpRouter— poll SFTP folders for EDI filesIntServiceRouter— calls the internal service layer
Open one, find its configure() method, and follow the from(...) → … → to(...).
That single method is the flow.
Booting one up¶
First run downloads dependencies (~2–3 min); after that boot is a couple of
seconds. Full build & test with ./mvnw clean package. More in
page 5.