Giter Site home page Giter Site logo

turao / n26-transactions Goto Github PK

View Code? Open in Web Editor NEW
0.0 2.0 0.0 204 KB

This was a take-home project I did for my N26 job interview - Some sort of in-mem storage for Transactions w/ O(1) statistics

Java 99.58% Dockerfile 0.42%
n26 java spring ddd transactions

n26-transactions's Introduction

N26 Transactions

Table of Contents

  1. Description
  2. Build, Test, and Run
  3. Design
  4. Requirements

๐Ÿ’ณ Description

The N26 Transactions application is a Spring-Boot application that provides a RESTful API for computing real-time transaction statistics. For this application, ONLY recent transactions (less than a minute old) MUST be considered. All other transactions MUST be discarded.

The application provides the following endpoints:

  • POST /transactions: Inserts a new Transaction. Called whenever a transaction is made.
  • DELETE /transactions: Discards all existing Transactions.
  • GET /statistics: Returns Statistics from all recent Transactions (less than a minute old).

๐Ÿ’ป Build, Test, and Run

Docker (recommended)

Installation steps may differ from machine to machine. Please follow instructions accordingly: For reference, I have built this project using:

A Dockerfile has been added to the project's root directory, easing dependency management and deployment.

  • Building the Docker image: docker build . -t n26
  • Running the Docker image: docker run n26 -p 8080

A docker-compose file has (also) been added to the project's root directory. This time, the intention is to allow other developers to code within a containerized environment. This is the quickest way to develop, at the expense of not having a really good integration with IDEs and text editors...

  • Developing from within a "N26 container": docker-compose run --service-ports dev /bin/bash
    • Once inside the container, all Maven commands apply (e.g. mvn test)

Locally

Installation steps may differ from machine to machine. Please follow instructions accordingly: For reference, I have built this project using:

Commands:

  • Building the project (with locally installed dependencies): mvn clean install
  • Testing the project (with locally installed dependencies): mvn test
  • Running the project (with locally installed dependencies): mvn spring-boot:run

Additional Notes

The N26 Transactions application uses Spring's TaskExecutor and Java's ScheduledExecutorService classes so as to provide support for asynchronous methods and scheduled tasks, respectively.

Both can be configured using environment variables - or directly, in the application.yaml file. Environment variables supported are:

  • EXECUTORS_TASK_CORE_POOL_SIZE: The ThreadPoolExecutor's core pool size. Default is 1.
  • EXECUTORS_SCHEDULER_CORE_POOL_SIZE: The ScheduledExecutorService's core pool size. Default is 1.

Code Coverage reports are automatically generated and published under target/site/jacoco/index.html.

API documentation is automatically generated (following the OpenAPI 3 spec) and published. Swagger UI is also provided so as to facilitate manual testing.

  • API documentation endpoint: Go to /v3/api-docs/
  • Swagger UI endpoint: Go to /swagger-ui/index.html?configUrl=/v3/api-docs/swagger-config

๐Ÿ“ Design

This project follows a standard clean architecture approach, with hints of Domain-Driven design, and CQRS concepts.

architecture

This diagram only acts as a simple sketch and may not be a 1:1 representation of the current architecture.

Two domain entities are clearly identifiable:

  • Transaction, containing the Amount value object (since we need custom business policies for scaling and rounding of numbers), and a timestamp, identifying when the Transaction has been created (in the real world, not in the application).
  • Statistics containing the well-defined set of transaction statistics (sum, average, maximum, minimum, count).

A few events have been identified and implemented as use cases. All use cases implement either Command or Query interfaces, so as to make methods' intentions (modification/querying) a bit more explicit.

transaction-design

The following use cases have been identified:

  • Insert Transaction: creates and inserts a new Transaction into the Transaction storage
    • side-effects:
      • schedules the new transaction for expiration
      • updates statistics
  • Remove All Transaction: removes all transactions from the Transaction storage
    • side-effects:
      • updates statistics
  • Get Statistics: queries the Transaction storage for most recent (less than a minute old) statistics
    • I've decided to filter all transactions before returning the relevant ones. This makes the time complexity O(N). However, we can simply not do that (filter). Tests will pass and time complexity will go down to O(1). However, this will make the "60-second" constraint very implicit. I have decided in favor of explicitness.

  • Schedule Transaction For Expiration: schedules a Transaction to be expired as soon as it reaches its "relevancy deadline" (in this case, 60 seconds after its creation timestamp)
  • Expire Transaction: removes a transaction from the Transaction storage
    • side-effects:
      • updates statistics

Spring's ApplicationEvents would allow for inversion of control and a cleaner implementation. I've decided not to use events yet, so as to keep this layer as decoupled as possible from the framework. I believe the decision to use events should be taken at a later point in time.

Use of Spring, Lombok, or any other framework or library is strongly discouraged within domain and usecases boundaries/directories. Framework-specifics and libraries do appear at infrastructure level, though.

At Infrastructure level, three adapters are implemented:

  • TransactionController: handles web requests (and exceptions) for all /transactions endpoints
  • StatisticsController: handles web requests (and exceptions) for all /statistics endpoints
  • InMemoryTransactionRepository: stores (in-memory) all Transactions

Storage of Transactions has been implemented using a ConcurrentHashMap so as to allow O(1) time complexity for insertions (soft requirement). Lookups and deletions also have O(1) time complexity, allowing for an expiration mechanism to discard any unecessary Transactions as soon as they get over the 60 second mark (project requirement). Therefore, the storage's space complexity can be estimated to be linear to all relevant transactions at a given point in time - i.e. O(N).

Finally, Statistics are stored as a single value object and are not impacted by concurrent writes/reads due to its immutability properties.

๐Ÿ“œ Features

  • Application runs in Maven
    • mvn clean install and mvn clean integration-test complete succesfully
  • API is thread-safe (i.e. supports concurrent requests)
    • TransactionRepository stores Transaction objects in a ConcurrentHashMap, Statistics are immutable by nature (value objects)

  • Works without a database (including in-memory databases)
    • SeeInMemoryTransactionRepository class

  • Service does not store all transactions in memory all the time
  • Irrelevant transactions are discarded
    • See ScheduleTransactionForExpiration and ExpireTransaction use cases

  • Project has unit tests
    • Lots of them!

  • Project has integration tests
    • See tests @ src/it


Full disclosure: No one asked me to make this repo private nor answered me when I asked about making this publicly available.

n26-transactions's People

Contributors

turao avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.