Bank Account

Implementation of a small core banking solution

• Creates accounts to keep track of current accounts, balances, and transaction history

• Capable of publishing messages into RabbitMQ for other consumers

 

Technologies

• Java 14

• SpringBoot

• MyBatis

• Gradle

• Postgres

• RabbitMQ

• JUnit

• Lombok

 

Build & Run

Run project on your IDE.

On sources root folder, open your terminal:

  • Start containers:
foo@bar:~$ cd src/main/resources/container

foo@bar:~$ docker-compose up -d

If needed, install Lombok -> https://projectlombok.org/setup/overview


  • Stop containers and remove volumes:
foo@bar:~$ cd src/main/resources/container

foo@bar:~$ docker-compose down -v

 

Connect to Postgres/RabbitMQ

  • Postgres

Port: 5432

User: postgres

Password: postgres


  • RabbitMQ

http://localhost:15672/#/exchanges

User: guest

Password: guest

destination: processed_messages

 

Tests

On sources root folder, open your terminal:

  • Generate test coverage reports:

Ubuntu:

foo@bar:~$ ./gradlew clean build

foo@bar:~$ ./gradlew jacocoTestReport

Windows:

foo@bar:~$ gradlew clean build

foo@bar:~$ gradlew jacocoTestReport

Test results wil be located on folder build/reports/jacoco/test/html/index.html

 

API Contract

[POST] - Create account

/api/v1/account
Body

customerId number

country string

currencies array[string] * Accepted values: EUR | SEK | GBP | USD

  {
    "customerId": 123,
    "country": "Brazil",
    "currencies": ["EUR", "SEK", "GBP", "USD"]
  }
Response
{
  "accountId": 1,
  "customerId": 123,
  "balances": [
      {
          "accountId": 1,
          "availableAmount": 0,
          "currency": "EUR"
      },
      {
          "accountId": 1,
          "availableAmount": 0,
          "currency": "SEK"
      },
      {
          "accountId": 1,
          "availableAmount": 0,
          "currency": "GBP"
      },
      {
          "accountId": 1,
          "availableAmount": 0,
          "currency": "USD"
      }
  ]
}

 

[GET] - Find account by ID

/api/v1/account/{accountId}
Path

accountId number

Response
{
  "accountId": 1,
  "customerId": 123,
  "balances": [
      {
          "accountId": 1,
          "availableAmount": 0,
          "currency": "EUR"
      },
      {
          "accountId": 1,
          "availableAmount": 0,
          "currency": "SEK"
      },
      {
          "accountId": 1,
          "availableAmount": 0,
          "currency": "GBP"
      },
      {
          "accountId": 1,
          "availableAmount": 0,
          "currency": "USD"
      }
  ]
}

 

[POST] - Create transaction

/api/v1/transaction
Body

accountId number

amount string

currency string * Accepted values: EUR | SEK | GBP | USD

direction string * Accepted values: IN | OUT

description string

  {
    "accountId": 1,
    "amount": "100.00",
    "currency": "EUR",
    "direction": "IN",
    "description": "TEST"
  }
Response
{
  "accountId": 1,
  "customerId": 123,
  "balances": [
      {
          "accountId": 1,
          "availableAmount": 100.00,
          "currency": "EUR"
      },
      {
          "accountId": 1,
          "availableAmount": 0,
          "currency": "SEK"
      },
      {
          "accountId": 1,
          "availableAmount": 0,
          "currency": "GBP"
      },
      {
          "accountId": 1,
          "availableAmount": 0,
          "currency": "USD"
      }
  ]
}

 

[GET] - Find account transactions

/api/v1/transaction/{accountId}/transactions
Path

accountId number

Response
[
  {
      "accountId": 1,
      "transactionId": 1,
      "amount": 100.00,
      "currency": "EUR",
      "direction": "IN",
      "description": "TEST"
  },
  {
      "accountId": 1,
      "transactionId": 2,
      "amount": 10.00,
      "currency": "EUR",
      "direction": "OUT",
      "description": "TEST"
  },
  {
      "accountId": 1,
      "transactionId": 3,
      "amount": 100.00,
      "currency": "SEK",
      "direction": "IN",
      "description": "TEST"
  },
  {
      "accountId": 1,
      "transactionId": 4,
      "amount": 100.00,
      "currency": "GBP",
      "direction": "IN",
      "description": "TEST"
  },
  {
      "accountId": 1,
      "transactionId": 5,
      "amount": 100.00,
      "currency": "USD",
      "direction": "IN",
      "description": "TEST"
  }
]

 

Considerations about the project

  • Numbers were used for IDs, so they would be auto-generated and incremented
  • Lombok was used to avoid boiler-plate code
  • Classes generated by Lombok were removed from test coverage
  • Database is preloaded with a few records for testing
  • When a message is successfully sent to RabbitMQ, the message will be printed on console
  • Unit tests were created using mocks

 

RPS - Requests per second

RPS = (Total RAM / Task memory usage) * (1 / Task duration)

RPS = (8 GB / 2 GB) * (1 / 0.6sec)

RPS = 6.66666 requests per second

 

Scaling horizontally

  • How many users will be sending requests?
  • When is the busiest season for the application?
  • Is the application hosted on the cloud?
  • What's the cost of scaling horizontally x vertically?
  • Is the application using internal cache?