The purpose of this repository is to demonstrate a possible resolution for the following exercise: Develop an API for other backend services to fetch and store product purchases. For now, the API only needs to serve operations through a HTTP server that connects to a database that provides the company’s purchases. Another team will develop the database implementation only after your team creates the service. You will implement the class that serves the requests and the method signatures for the database DAO, which the other team will respect. Following is the schema for the data objects:
Purchase(id:Long, productType:String, expires:DateTime, purchaseDetails:Details) Details(id:Long, description:String, quantity:Integer, value:Double)
The first operation retrieves purchase details related to valid company purchases.
- it fetches a collection of all existing purchases from the database;
- aggregates the results that are valid for the current time;
- subsequently calls the database with a collection of the aggregated purchase ids;
- the database yields all queried purchase details;
- it then transforms the data into a textual data format and returns to the calling entity.
The second operation is responsible for storing - or handling updates - on the product purchases.
The database implementation is being developed by another team which stated that the expected SLA will be around 2 seconds.
The service should expose metrics to be collected by external services. Be free to expose all the metrics you think that has value to the server.
Expose relevant operations in the context of a microservice. Take into account that this microservice should be able to scale.
The application is composed be the fallowing modules:
- discovery-service for locating services for the purpose of load balancing and failover of middle-tier servers
- edge-service for providing dynamic routing, monitoring, resiliency
- purchase-service for managing purchases (main scope for the exercise)
- hystrix-dashboard for to monitor purchase-service Hystrix metrics in real time
The application uses the following set of light-weight technologies and frameworks:
- Spring Boot for Bootstrapping and Boilerplates
- Spring MVC for REST Services
- Spring Cloud Netflix (Eureka, Hystrix, Zuul)
- Spring aop with JamonPerformanceMonitorInterceptor to capturing performance metrics of the API
- Spring REST Docs
- Mockito for mocking and testing
- Apidocs for generating more readable api documentation
- Docker for deploy
Before running the above application, you'll need to install the following on your machine:
- Maven 3.0.3 or later
- docker and docker-compose
Once you have the above software installed, you can run the application using one of the fallowing methods:
Using docker and run this command by the following order
- Go to the root directory of the application and type:
mvn clean install - docker-compose up
Step by step application start
- Start the
discovery-serviceproject. You can start it by navigating to its subdirectory and type:mvn spring-boot:run - Start the
purchase-serviceproject. You can start it by navigating to its subdirectory and type:mvn spring-boot:run - Start the
edge-serviceproject. You can start it by navigating to its subdirectory and type:mvn spring:boot:run - Start the
hystrix-dashboardproject. You can start it by navigating to its subdirectory and type:mvn spring:boot:run
You can interact with the api using a http rest client. All the documentation is in the fallowing urls:
In github pages: https://pmribeiro.github.io/store-product-purchases/
or after you start the application: http://localhost:8080/purchase-service/apidocs/index.html
To check system usage metrics you can access hystrix dashboard using this urls:
running with docker: http://localhost:7979/hystrix/monitor?stream=http%3A%2F%2Fedge-service%3A8080%2Fpurchase-service%2Fhystrix.stream&delay=1&title=purchase-service
running with step by step application start: http://localhost:7979/hystrix/monitor?stream=http%3A%2F%2Flocalhost%3A8080%2Fpurchase-service%2Fhystrix.stream&delay=1&title=purchase-service
If the team responsible for implement the DAO must respect interface defined in pt.pmribeiro.webstore.dao.IPurchaseDAO file in the purchase-service project.
The DAO part of the purchase-service is a in memory mock and because of this fact the application at this stage can't be test for scalability. To test scalability we can consider that the DAO part is a external API and implement declarative REST client load balancing using Ribbon or make a mock implementation using a real database using spring data.
- IPurchaseDAO: change methods signature to return Future to monitor the quality of service with timeout. SLA <= 2s
- DTO's: use spring validators annotation
- PurchaseService: needs more info to decide to use parallelStream or stream -> for now consider its a big stream
Adapt the application to use the fallowing patterns:
- Domain Driven Design
- Command Query Responsibility Segregation
- Event Sourcing
Using the following technology and frameworks:
- Apache Kafka or rabbitmq for Messaging (most probably kafka because of the speed and storage capabilities)
- Couchbase for persistence
- Spring Cloud Stream for event-driven microservices framework
- Spring Cloud Data Flow for orchestration of microservice based data pipelines
- Spring Cloud Config for centralized external configuration management
With this second approach will allow:
- the application to be more scalable in terms of querying and writings because they will be different micro services.
- to recreate scenarios for debugging and auditing
- more flexibility to incorporate new functionalities
