Giter Site home page Giter Site logo

payment-processor's Introduction

Challenge

๐Ÿ’ป How to execute

IMPORTANT: I wasn't able to make the producer application (localhost:9000/start) to publish messages on kafka. I monitored the topics with Conduktor and no message was being published, so I created my own publisher in class com.abraham.payments.configuration.TestProducers. It starts with the application and keeps publishes 3 payments with random data every second:

  • An online payment
  • An offline payment
  • A failing payment (payment whose processing will cause a database failure) so error logging integration can be tested

First, to build the application, in the root directory execute:

./mvnw clean install

To run the application execute the following:

Move to the 'docker' directory and run:

docker-compose up

wait until all dockers have started. Then move to the 'payments-boot' module and run:

../mvnw spring-boot:run

that would start the application and start producing and consuming messages.

IMPORTANT: You will see some failures during application execution. This is normal as we are purposely producing payments whose processing will cause these failures as stated at the beginning of this section

Aplication was built with:

  • OpenJDK Runtime Environment 18.9 (build 11+28)
  • Apache Maven 3.8.3

๐Ÿ“ Notes

Some notes or explanation of your solution...

Architecture

Application is built based on Hexagonal architecture with 3 layers (from inside to outside):

  • domain: which hosts the business logic in the domain model
  • application: represents the use-cases of the application. It uses the domain to solve the business-logic. It orchestrates the flow of the application but without coupling to the infrastructure solutions.
  • adapters: provide the integration of the infrastructure solutions (kafka, rest, postgresql ...) with the use-cases

I separated the adapters, having the 'payments-event' as input adapter consuming the events from kafka and 'payments-infrastructure' as the output adapter with the database and restclients integrations.

The 'payments-boot' module purpose is to configure the application startup and to hold the integration tests (some of which require of all the layers' dependencies)

I made them different modules as this makes very explicit the boundaries of each layer and the dependency tree. As each module has its dependencies defined in the pom, this prevents using them in the wrong place (i.e. capturing and managing database exceptions in the application layer). Also, due to dependency graph, this leads to the creation of interfaces in the inner layers that outside layers has to implement allowing not only better unit-testing but also the Dependency Inversion Principle

Testing

Based on the test pyramid I developed unit and integration tests. Each class has its own unit tests representing the different use-cases. Regarding integration testing there is a test to test database queries and model definition. Also, there is a whole-application integration test to test application startup, kafka consuming functionality, restclients invocation ... There is no regression testing as it would make more sense outside the microservice (even though the producers that generate the data are kind of a regression test) Rest integrations (third-party payment validation API and error logging API) could be tested with some kind of API contract approach

๐Ÿ“Œ Things to improve

If u have more time or want to improve something...

If I had more time I would:

  • Add Mapstruct (https://mapstruct.org/) for mappings instead of writing them manually
  • Add circuit breaker with resilience4j (https://resilience4j.readme.io/docs/circuitbreaker) for the external calls
  • Add SpotBugs and Sonar analysis maven plugins on mvn compile task (as part of the shift-left movement)
  • Improve data quality (enum check, negative integer values, non-nullable ...)
  • Move host and path fields of restClients to properties file

payment-processor's People

Contributors

jabraham8 avatar

Watchers

James Cloos 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.