Skip to content

Latest commit

Β 

History

History
522 lines (431 loc) Β· 19.7 KB

File metadata and controls

522 lines (431 loc) Β· 19.7 KB

OBP-Rabbit-Cats-Adapter Architecture

Overview

This adapter bridges the Open Bank Project (OBP) API and Core Banking Systems (CBS) using RabbitMQ for messaging. The architecture is designed with clear separation of concerns to maximize reusability and minimize bank-specific customization.

Design Principles

  1. Separation of Concerns: CBS-specific code is isolated from generic OBP message handling
  2. Plugin Architecture: Multiple CBS implementations can coexist
  3. Observability First: Telemetry is a first-class concern, separate from business logic
  4. Functional Programming: Uses Cats Effect for pure functional effects
  5. Type Safety: Leverages Scala's type system to prevent errors at compile time

Architecture Layers

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         OBP-API                             β”‚
β”‚                      (RabbitMQ Client)                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚ RabbitMQ Messages
                      β”‚ (obp.request / obp.response)
                      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   ADAPTER - NORTH SIDE                      β”‚
β”‚                  (Generic, Reusable)                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚   RabbitMQ Consumer/Producer (messaging/)           β”‚   β”‚
β”‚  β”‚   - Queue management                                β”‚   β”‚
β”‚  β”‚   - Message routing                                 β”‚   β”‚
β”‚  β”‚   - Correlation ID tracking                         β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                          β”‚                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚   OBP Message Models (models/)                      β”‚   β”‚
β”‚  β”‚   - CallContext, OutboundAdapterCallContext         β”‚   β”‚
β”‚  β”‚   - InboundAdapterCallContext                       β”‚   β”‚
β”‚  β”‚   - BankCommons, AccountCommons, etc.               β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                          β”‚                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚   Message Handlers (handlers/)                      β”‚   β”‚
β”‚  β”‚   - Route messages by type (obp.getBank, etc.)      β”‚   β”‚
β”‚  β”‚   - Orchestrate CBS calls                           β”‚   β”‚
β”‚  β”‚   - Build responses                                 β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚ LocalAdapter Interface
                       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚               ADAPTER - INTERFACE LAYER                     β”‚
β”‚                  (contracts/)                               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  trait LocalAdapter {                                       β”‚
β”‚    def getBank(...): IO[LocalAdapterResult[BankCommons]]          β”‚
β”‚    def getBankAccount(...): IO[...]                        β”‚
β”‚    def makePayment(...): IO[...]                           β”‚
β”‚    // ... all CBS operations                               β”‚
β”‚  }                                                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚ Implementation
                       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   ADAPTER - SOUTH SIDE                      β”‚
β”‚              (CBS-Specific, Customizable)                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚  β”‚   REST CBS   β”‚  β”‚   SOAP CBS   β”‚  β”‚   Mock CBS   β”‚     β”‚
β”‚  β”‚   Adapter    β”‚  β”‚   Adapter    β”‚  β”‚   Adapter    β”‚     β”‚
β”‚  β”‚              β”‚  β”‚              β”‚  β”‚              β”‚     β”‚
β”‚  β”‚ implements   β”‚  β”‚ implements   β”‚  β”‚ implements   β”‚     β”‚
β”‚  β”‚ LocalAdapter β”‚  β”‚ LocalAdapter β”‚  β”‚ LocalAdapter β”‚     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚         β”‚                  β”‚                  β”‚             β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
β”‚                            β”‚                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚ HTTP/SOAP/DB/etc.
                             β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚  Core Banking   β”‚
                    β”‚     System      β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   CROSS-CUTTING CONCERNS                    β”‚
β”‚                     (telemetry/)                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  trait Telemetry {                                          β”‚
β”‚    - Message metrics                                        β”‚
β”‚    - CBS operation metrics                                  β”‚
β”‚    - Performance monitoring                                 β”‚
β”‚    - Error tracking                                         β”‚
β”‚    - Distributed tracing                                    β”‚
β”‚  }                                                          β”‚
β”‚                                                             β”‚
β”‚  Implementations:                                           β”‚
β”‚    - ConsoleTelemetry (dev)                                β”‚
β”‚    - PrometheusTelemetry (production)                      β”‚
β”‚    - DatadogTelemetry (production)                         β”‚
β”‚    - NoOpTelemetry (testing)                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Directory Structure

src/main/scala/com/tesobe/obp/adapter/
β”œβ”€β”€ config/                    # Configuration (generic)
β”‚   └── Config.scala          # RabbitMQ, CBS, app config
β”‚
β”œβ”€β”€ models/                    # OBP Message Models (generic)
β”‚   └── OBPModels.scala       # All OBP data types
β”‚
β”œβ”€β”€ messaging/                 # RabbitMQ handling (generic)
β”‚   β”œβ”€β”€ RabbitMQConsumer.scala
β”‚   β”œβ”€β”€ RabbitMQProducer.scala
β”‚   └── MessageRouter.scala
β”‚
β”œβ”€β”€ handlers/                  # Message handlers (generic)
β”‚   β”œβ”€β”€ BankHandlers.scala
β”‚   β”œβ”€β”€ AccountHandlers.scala
β”‚   β”œβ”€β”€ TransactionHandlers.scala
β”‚   └── CustomerHandlers.scala
β”‚
β”œβ”€β”€ interfaces/                # Contracts (generic)
β”‚   └── LocalAdapter.scala    # THE interface CBS must implement
β”‚
β”œβ”€β”€ cbs/                       # CBS implementations (bank-specific)
β”‚   └── implementations/
β”‚       β”œβ”€β”€ RestLocalAdapter.scala     # HTTP REST implementation
β”‚       β”œβ”€β”€ SoapLocalAdapter.scala     # SOAP implementation
β”‚       β”œβ”€β”€ MockLocalAdapter.scala     # Testing/demo
β”‚       └── YourBankAdapter.scala    # Bank-specific impl
β”‚
β”œβ”€β”€ telemetry/                 # Observability (generic framework)
β”‚   β”œβ”€β”€ Telemetry.scala       # Interface
β”‚   β”œβ”€β”€ ConsoleTelemetry.scala
β”‚   β”œβ”€β”€ PrometheusTelemetry.scala
β”‚   └── CompositeTelemetry.scala  # Combine multiple
β”‚
└── AdapterMain.scala          # Main entry point

Key Interfaces

1. LocalAdapter (interfaces/LocalAdapter.scala)

Purpose: Define what operations a CBS must support

Bank Developers: Implement this trait for your specific CBS

trait LocalAdapter {
  def name: String
  def version: String

  // Core operations
  def getBank(bankId: String, callContext: CallContext): IO[LocalAdapterResult[BankCommons]]
  def getBankAccount(...): IO[LocalAdapterResult[BankAccountCommons]]
  def makePayment(...): IO[LocalAdapterResult[TransactionCommons]]
  // ... 30+ operations covering OBP functionality
}

Key Points:

  • All methods return IO[LocalAdapterResult[T]] for pure functional effects
  • LocalAdapterResult is a sealed trait with Success and Error cases
  • CallContext contains correlation ID, user info, auth context
  • Bank-specific logic stays in your implementation

2. Telemetry (telemetry/Telemetry.scala)

Purpose: Observability and monitoring

Operations Teams: Choose or implement telemetry backend

trait Telemetry {
  // Message lifecycle
  def recordMessageReceived(...)
  def recordMessageProcessed(...)
  def recordMessageFailed(...)

  // CBS operations
  def recordCBSOperationStart(...)
  def recordCBSOperationSuccess(...)
  def recordCBSOperationFailure(...)

  // Business metrics
  def recordPaymentSuccess(...)
  def recordAccountCreated(...)

  // Tracing
  def startSpan(...): IO[String]
  def endSpan(...)
}

Key Points:

  • Telemetry is injected, not hardcoded
  • Multiple implementations can coexist
  • NoOp implementation for testing
  • Console implementation for development

Message Flow

1. Inbound Message from OBP

OBP-API sends message to RabbitMQ (obp.request queue)
    ↓
RabbitMQConsumer receives message
    ↓
Telemetry.recordMessageReceived()
    ↓
MessageRouter extracts message type (e.g., "obp.getBank")
    ↓
Route to appropriate Handler (e.g., BankHandlers)
    ↓
Handler calls LocalAdapter.getBank()
    ↓
LocalAdapter implementation makes CBS call
    ↓
Response wrapped in LocalAdapterResult
    ↓
Handler builds InboundAdapterCallContext
    ↓
RabbitMQProducer sends response to obp.response queue
    ↓
Telemetry.recordMessageProcessed()

2. Error Handling

If CBS call fails:
    ↓
LocalAdapterResult.Error returned
    ↓
Telemetry.recordCBSOperationFailure()
    ↓
Handler builds error InboundAdapterCallContext
    ↓
Error response sent to OBP with proper error codes
    ↓
Telemetry.recordMessageFailed()

Implementing a New Local Adapter

Step 1: Create Implementation Class

package com.tesobe.obp.adapter.cbs.implementations

import com.tesobe.obp.adapter.interfaces._
import com.tesobe.obp.adapter.models._
import cats.effect.IO

class MyBankAdapter(
  baseUrl: String,
  apiKey: String,
  telemetry: Telemetry
) extends LocalAdapter {

  override def name: String = "MyBank-REST-Adapter"
  override def version: String = "1.0.0"

  override def getBank(bankId: String, callContext: CallContext): IO[LocalAdapterResult[BankCommons]] = {
    for {
      // Start telemetry
      _ <- telemetry.recordCBSOperationStart("getBank", callContext.correlationId)

      // Make CBS HTTP call
      result <- httpClient.get(s"$baseUrl/banks/$bankId")
        .map(response =>
          // Map CBS response to OBP BankCommons
          LocalAdapterResult.success(
            BankCommons(
              bankId = response.id,
              shortName = response.name,
              fullName = response.fullName,
              // ... map all fields
            ),
            callContext
          )
        )
        .handleErrorWith(error =>
          IO.pure(LocalAdapterResult.error(
            "BANK_NOT_FOUND",
            error.getMessage,
            callContext
          ))
        )

      // End telemetry
      _ <- telemetry.recordCBSOperationSuccess("getBank", callContext.correlationId, duration)
    } yield result
  }

  // Implement all other LocalAdapter methods...
}

Step 2: Register Adapter

// In AdapterMain.scala or config
val localAdapter: LocalAdapter = config.cbsType match {
  case "mybank" => new MyBankAdapter(config.baseUrl, config.apiKey, telemetry)
  case "mock" => new MockLocalAdapter(telemetry)
  case _ => throw new IllegalArgumentException(s"Unknown CBS type: ${config.cbsType}")
}

Step 3: Run Adapter

export MYBANK_CBS_URL=https://cbs.mybank.com/api
export MYBANK_CBS_API_KEY=secret123
export RABBITMQ_HOST=localhost
export RABBITMQ_REQUEST_QUEUE=obp.request
export RABBITMQ_RESPONSE_QUEUE=obp.response

java -jar obp-rabbit-cats-adapter.jar

Configuration

Environment Variables

RabbitMQ Configuration:

  • RABBITMQ_HOST - RabbitMQ server host
  • RABBITMQ_PORT - RabbitMQ server port (default: 5672)
  • RABBITMQ_USERNAME - Username for authentication
  • RABBITMQ_PASSWORD - Password for authentication
  • RABBITMQ_REQUEST_QUEUE - Queue to consume messages from
  • RABBITMQ_RESPONSE_QUEUE - Queue to send responses to

CBS Configuration: Your bank-specific local adapter will define what configuration it needs.

Telemetry Configuration:

  • TELEMETRY_TYPE - Telemetry implementation (console/prometheus/datadog/noop)
  • ENABLE_METRICS - Enable metrics collection (true/false)

Testing Strategy

1. Unit Tests

Test local adapter implementations in isolation:

class MyBankAdapterSpec extends CatsEffectSuite {
  test("getBank returns bank when CBS responds successfully") {
    val adapter = new MyBankAdapter(mockHttpClient, NoOpTelemetry)
    val result = adapter.getBank("bank-id", CallContext("corr-123"))

    result.map {
      case LocalAdapterResult.Success(bank, _, _) =>
        assertEquals(bank.bankId, "bank-id")
      case _ => fail("Expected success")
    }
  }
}

2. Integration Tests

Test with mock RabbitMQ and mock CBS:

test("adapter processes obp.getBank message end-to-end") {
  // Set up mock RabbitMQ, mock CBS, real handlers
  // Send message, verify response
}

3. CBS Stub for Development

Use MockLocalAdapter for development without real CBS:

class MockLocalAdapter extends LocalAdapter {
  def getBank(...) = IO.pure(
    LocalAdapterResult.success(
      BankCommons(
        bankId = "mock-bank",
        shortName = "Mock",
        fullName = "Mock Bank for Testing"
      ),
      callContext
    )
  )
}

Monitoring and Observability

Metrics to Track

  1. Message Processing:

    • Messages received/processed/failed per minute
    • Processing duration (p50, p95, p99)
    • Queue depth
  2. CBS Operations:

    • Operation success/failure rate
    • Operation duration by type
    • Retry count
    • Error rate by error code
  3. Business Metrics:

    • Payments processed
    • Accounts created
    • Transaction volume
  4. System Health:

    • Memory usage
    • CPU usage
    • Connection status (RabbitMQ, CBS)

Logging

All logs include:

  • Correlation ID (for request tracing)
  • Timestamp
  • Log level
  • Component name
  • Message

Example:

[INFO][CID: 1flssoftxq0cr1nssr68u0mioj] Message received: type=obp.getBank queue=obp.request
[INFO][CID: 1flssoftxq0cr1nssr68u0mioj] CBS operation started: getBank
[INFO][CID: 1flssoftxq0cr1nssr68u0mioj] CBS operation success: getBank duration=45ms
[INFO][CID: 1flssoftxq0cr1nssr68u0mioj] Message processed: type=obp.getBank duration=52ms

Deployment

Docker

FROM openjdk:11-jre-slim
COPY target/obp-rabbit-cats-adapter.jar /app/adapter.jar
CMD ["java", "-jar", "/app/adapter.jar"]

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: obp-adapter
spec:
  replicas: 3
  template:
    spec:
      containers:
        - name: adapter
          image: obp-rabbit-cats-adapter:latest
          env:
            - name: RABBITMQ_HOST
              value: rabbitmq-service
            - name: MYBANK_CBS_URL
              value: https://cbs.internal
          resources:
            requests:
              memory: "512Mi"
              cpu: "500m"

Benefits of This Architecture

For Bank Developers

βœ… Only implement LocalAdapter trait - Clear contract
βœ… No RabbitMQ knowledge needed - Already handled
βœ… No OBP message format knowledge needed - Already handled
βœ… Focus on CBS integration - Your domain expertise
βœ… Telemetry included - Observability for free

For Operations Teams

βœ… Standard RabbitMQ setup - Same for all banks
βœ… Pluggable telemetry - Use your monitoring stack
βœ… Clear metrics - Know what's happening
βœ… Health checks - Easy monitoring
βœ… Containerizable - Deploy anywhere

For OBP Team

βœ… Reusable core - Generic message handling
βœ… Multiple CBS support - One adapter, many banks
βœ… Consistent interface - All adapters work the same
βœ… Type-safe - Compiler catches errors
βœ… Functional - Pure, testable, composable

Next Steps

  1. Implement your local adapter - Extend LocalAdapter trait
  2. Configure environment - Set CBS credentials and endpoints
  3. Choose telemetry backend - Console for dev, Prometheus for prod
  4. Deploy and monitor - Use provided metrics
  5. Iterate - Add more CBS operations as needed

Support