Skip to main content

Architecture

Three layers, 16 service modules and 4 shared modules, communicating Experience → Process → System over gRPC, with domain events over Kafka and Apache APISIX transcoding external REST/JSON into gRPC.

Tech stack

ComponentVersion
Quarkus platform3.36.2
Apache Camel4.x (via quarkus-camel-bom)
Java21
Protobuf / gRPC4.33.2 / 1.81.0
Avro1.12.1
Gradle (wrapper)9.5.1
Container imagesJib (quarkus-container-image-jib)
GatewayApache APISIX 3.16
Event busKafka / Redpanda (schema registry: Apicurio in dev)

Cross-cutting in every service: Camel (core/gRPC/Kafka), Quarkus OIDC, OpenTelemetry, Micrometer/Prometheus, SmallRye Health, JSON logging.

The layers

Experience APIs (XAPI) — experience-apis/

Channel-facing, REST-exposed (Camel Platform HTTP + camel-quarkus-openapi-java), gRPC clients only. Modules: customer-portal-xapi, internal-ops-xapi, exco-dashboard-xapi. (All skeletons today.)

Process APIs (PAPI) — process-apis/

Business orchestration — saga, MicroProfile fault tolerance, Quartz scheduling, PDF generation — owning persistence (PostgreSQL via Hibernate Panache + Redis). Modules: payment-processing-papi, trade-finance-papi, statement-management-papi, notification-alert-papi, document-generation-papi. (All skeletons today.)

System APIs (SAPI) — system-apis/

Adapters wrapping external systems of record.

  • cbs-finacle-sapi — Infosys Finacle core-banking adapter (Oracle/JDBC, wraps GAM views; Camel gRPC routes for accounts & facilities). The one substantively implemented service.
  • salesforce-crm-sapi, swift-messaging-sapi, tms-treasury-sapi, calypso-trade-sapi, docusign-sapi, file-transfer-sapi, appian-bpm-sapiskeletons today.

Shared — shared/

  • proto-definitions — gRPC/Protobuf contracts (currently common.proto + the CBS account.proto / facility.proto; the broader set is planned).
  • avro-schemas — Avro schemas for Kafka event serialization (wired, schemas to be authored).
  • domain-events — CloudEvents envelope + topic constants (stub today).
  • apisix-registry — the most-built shared module: at startup each service registers its own gRPC routes + flattened proto with the APISIX Admin API (self-service route registration via @ConfigMapping("apisix.registry")).

Request & event flow

  1. Client → APISIX over HTTP/JSON (proxy :9080, admin :9180).
  2. APISIX → gRPC via the grpc-transcode plugin. Each service registers its routes/proto at startup through apisix-registry (or make init-routes as a manual seeder). Example: GET /api/v1/system/cbs/accounts/:account_id → gRPC AccountService/GetAccountById.
  3. Layer-to-layer gRPC — Experience → Process → System (one direction).
  4. System APIs → external systems (Finacle/Oracle, Salesforce, SWIFT, S3/SFTP…).
  5. Domain events over Kafka (Avro, Apicurio registry) — decoupled side-effects across layers (the event-bus code path is still conceptual; the domain-events/avro-schemas modules are stubs).

:::note No OpenAPI reference This platform has no published OpenAPI document — the machine-readable contracts are the gRPC .proto files in shared/proto-definitions. The Experience layer is "REST/OpenAPI" conceptually (Camel can generate an OpenAPI doc at runtime), but no REST routes are implemented yet. :::

Build & deploy

  • Gradle 9.5.1 monorepo with buildSrc convention plugins (afreximbank.java-conventions, afreximbank.quarkus-service, and per-layer system-api/process-api/experience-api plugins). Versions centralized in gradle/libs.versions.toml.
  • Jib images (imageBuild) on a BellSoft Liberica JRE 21 base, pushed to ECR.
  • Makefile drives everything: make build / build-system|process|experience, make infra-up (13-service Docker Compose dev stack: postgres, redis, redpanda, apicurio, keycloak, openfga, vault, etcd, apisix, prometheus, grafana, tempo), make init-routes, make images-all, and the one-shot make k8s-local (k8s-up → k8s-images → k8s-load-images → k8s-deploy → k8s-status).
  • Local Kubernetes deploys the datasource-free slice (the 5 Process + 3 Experience APIs) via the infra/prod/helm/afxm-enterprise umbrella chart; pods serve health endpoints, proving deploy mechanics (System APIs are disabled locally since they need external systems). See docs/LOCAL-K8S-DEPLOYMENT.md in the repo.