Application uses Gradle build system.
Run gradlew tasks to see a list of all available tasks.
Run gradlew build to build the application and execute all tests.
Run gradlew run to start the application, it will listen on port 8080.
Logging output is available in the file bankaccount.log in the current directory.
Logging levels can be adjusted in the src/main/resources/logback.xml file
Following endpoints work:
To retrieve account balance for a respective account:
GET http://localhost:8080/api/account-balance?sortCode=40-40-40&accountNumber=12345678
GET http://localhost:8080/api/account-balance?sortCode=50-50-50&accountNumber=98765432
To action a transfer:
POST http://localhost:8080/api/transfer
with a payload like this:
{
"sourceAccountBalance": {
"amount": 103,
"currency": "GBP"
},
"targetAccountBalance": {
"amount": 476,
"currency": "GBP"
}
}
I am using Jersey framework for REST endpoints, with the embedded jetty web server.
For dependency injection, I am using Jersey's HK2 package.
Logback via slf4j for all logging.
For testing - JUnit5 and Mockito.
Due to dependency injection, a simple wiring config is required. This is encapsulated in the BankAccountConfig and BankAccountBinder classes.
Other classes then simply use the @Inject annotation to plug in any beans they need.
InMemoryAccountRepository class simply uses a pre-defined list of accounts.
I have specifically not implemented any addition or deletion of accounts, as this was not requested.
AccountLockingService is used to perform account locking in order to enable concurrent access.
In order to keep locking manageable, finite number of locks is used. This will result in situations where sometimes multiple accounts are locked by a single lock. However, if number of accounts is fairly low, then this number can be increases and mitigate/remove this issue.
ReadWriteLock locks are used to ensure concurrent read access when no writing occurs.
As mentioned - account repository implementation is read-only.
Transfers should be logged in some persistent store, so that there is a trace/audit trail. I.e. some kind of ledger implementation.