Layer 5 — Integration Services: Spring Boot

Multiple external system adapters. One dedicated Spring Boot service each. Every failure is recoverable.


Table of Contents

  1. 8.1 Design: One Adapter Per System Boundary
  2. 8.2 Adapter Pattern
    1. Resilience Pattern (per adapter)
  3. 8.3 OpenAPI Contract Strategy

8.1 Design: One Adapter Per System Boundary

Anchita uses a set of dedicated Spring Boot integration adapters — one per external system family — rather than a shared integration gateway:

integration-service/
├── core-banking-adapter/       — Core Banking System (customer, account lookup)
├── treasury-platform-adapter/  — Treasury Management Platform (entitlements)
├── wire-transfer-adapter/      — Wire Transfer System (profiles, accounts)
├── anchita-portal-adapter/       — Anchita Digital Banking Portal (all segments; tier-based feature gating)
├── document-mgmt-adapter/      — Document Management System
├── directory-auth-adapter/     — Directory Authentication Service (LDAP)
├── token-auth-adapter/         — Token Authentication System (MFA tokens)
├── rtp-network-adapter/        — Instant Payments Network
├── payment-processing-adapter/ — Payment Processing Platform (Bill Pay)
├── financial-data-adapter/     — Financial Data Service (Bill Pay user)
└── [remaining adapters...]

Each adapter is independently deployable — failures in one adapter do not affect other adapters. This avoids the single point of failure that a shared integration gateway would represent.


8.2 Adapter Pattern

Each adapter follows the same Spring Boot pattern with Resilience4j circuit breaker and retry:

@Service
public class CoreBankingAdapter {

    private final RestClient restClient;
    private final CircuitBreaker circuitBreaker;  // Resilience4j

    @Retry(name = "coreBanking", fallbackMethod = "fallbackLookup")
    @CircuitBreaker(name = "coreBanking")
    public CompanyRecord lookupCompany(String customerId) {
        return restClient.get()
                .uri("/api/v2/customers/{id}", customerId)
                .retrieve()
                .body(CompanyRecord.class);
    }

    private CompanyRecord fallbackLookup(String customerId, Exception ex) {
        // Throw ApplicationFailure → Temporal retries or routes to error recovery
        throw ApplicationFailure.newFailure(
                "Core Banking lookup failed: " + ex.getMessage(),
                "INTEGRATION_FAILURE"
        );
    }
}

Resilience Pattern (per adapter)

Mechanism Configuration Behaviour
Circuit breaker (Resilience4j) Opens after 5 consecutive failures; half-open after 30s Prevents cascading failures; fails fast when the downstream is down
Retry (Temporal built-in) Up to 3 attempts with exponential backoff Handles transient network failures transparently
Dead letter After all retries exhausted → ApplicationFailure Temporal routes to the error recovery signal; operator is notified
Activity timeout 30s default, configurable per system Prevents indefinite blocking on a slow downstream

This chain means: transient failures are automatically retried; persistent failures surface to the operator as an actionable error recovery task in the React workspace, with the error message and recommended action.


8.3 OpenAPI Contract Strategy

Each external system has an OpenAPI 3.0 YAML spec in the repository. These are the same contracts used in the mock/test environment and production — only the base URL changes:

# core-banking-api.yaml
openapi: 3.0.0
info:
  title: Core Banking System API
  version: 2.0.0
paths:
  /customers/{customerId}:
    get:
      summary: Retrieve customer profile
      parameters:
        - name: customerId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Customer profile
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompanyRecord'
  /accounts/{accountId}:
    get:
      summary: Retrieve account details

Spring Boot generates typed client stubs from these specs using openapi-generator-maven-plugin. This means:

  • The adapter code never uses raw strings for request/response fields
  • Schema changes in the spec break the build immediately — not at runtime
  • The same spec can be used to generate mock servers for integration testing
  • Contract documentation is always in sync with the implementation

Contract-first design: Each external system integration starts with an OpenAPI 3.0 spec. Spring Boot generates typed client stubs from the spec — the contract is the source of truth, and the same spec governs both mock/test environments and production.


↑ Back to top

Anchita Platform — Fictional Reference Architecture for Cloud-Native Institutional Banking