This is a proof-of-concept which demonstrates, against an hypothetical Microservice Architecture, the following:
- architecture components containerization through Docker
- testing strategies
- CI with Jenkins
- containers orchestration with Kubernetes
As the project focus is to provide some XP and DevOps practices, the architecture don't comprise the classical infrastructure services needed by a Microservice Architecture (e.g. Auth, Service Discovery, Service Config, etc...) and isn't tied to a specific cloud solution (e.g. Spring Cloud, Kubernetes, AWS).
Despite the premises, as I was interested in learn some ReactJS basics a user interface is provided.
The following is the simple domain problem that the service try to solve:
- A user can manage advertises. An advertise have title and content. Users can list, save, update, delete advertise
- A user can perform a full-text search inside the advertises's title and content. Every word researched must be present in the advertise
- The search-index is automatically synchronized every time that an event (save\update, delete) occurs on an advertise
- React JS
- React Router
- Redux
- Bootstrap
- Spring Boot
- Lombock (for boilerplate code. See here for setup instruction)
- MongoDB
- ElasticSearch
- RabbitMQ
Following are the assumption made for testing:
- Unit tests are solitary (use Mocks) and perform behavior verification
- Integration\Component tests are sociable (use some real collaborators), and perform state verification
- As we want fast test and fast feedback, the external system component are executed with in memory process
- Some test duplication are possible as we want see the testing strategies from different point of view
- Junit
- Mockito
- RestAssured
- Spring Test
- Embedded MongoDB
- Embedded ElasticSearch
- QPID broker
$ mvn test
$ mvn verify
$ mvn verify -Pacceptance-tests -Dacceptance.advertise.url=URL_TO_ADVERTISE_TESTING_ENVIRONMENT -Dacceptance.advertise-search.url=URL_TO_ADVERTISE_SEARCH_TESTING_ENVIRONMENT
From folder microservices/advertise-ui:
$ npm run build
$ mvn clean package
export SPRING_PROFILES_ACTIVE=*a spring profile (e.g testing, prod)*
export MONGODB_ADVERTISE_PASSWORD=*password for advertise db*
export MONGODB_ROOT_USERNAME=*root username for MongoDB*
export MONGODB_ROOT_PASSWORD=*root password for MongoDB*
export RABBITMQ_PASSWORD=*guest password for RabbitMQ*
$ docker-compose -f docker-compose.yml -f docker-compose.dev.yml build
run docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
docker-compose.dev.yml inherits docker-compose.yml with additional possibility to build images locally and expose all containers ports for convenient development.
run docker-compose up
- http://localhost:80 - UI
- http://localhost:8080 - Gateway
- http://localhost:8081 - Advertise microservice
- http://localhost:8082 - Advertise-search microservice
- http://localhost:15672 - RabbitMQ management
You can notice the absence of a pipeline.
I preferred to leave it outside of the topic of this project as every microservices I've developed in the various projects follow an identical DevOps pattern. This means that we can easily adapt the pipeline showed in the https://github.com/ivanp81/address-pipeline repository for the microservices in this project.
The second reason is that I wanted to keep this project in one repostitory so that a reader can see everything together. Actually the pipeline is meant to have a repository per service.
The same consideration are valid for Kubernetes.
The pipeline and the microservice associated are entirely executed on Kubernetes. We can adapt the Kubernetes, service\deployment to the microservices showed in this project.
Also, the intention at this stage of the project is to don't tye the architecture to a cloud solution.
Another reason is that, for more complex use case you need to bring up a pod for every component involved. This require a super powerfull laptop.
- Add a security/authentication service to the architecture
- Try to run a microservices in AWS (EC2\ECS)
The following are some reference articles from which I took inspiration:
- https://martinfowler.com/articles/microservice-testing/
- https://martinfowler.com/articles/practical-test-pyramid.html
- https://martinfowler.com/articles/mocksArentStubs.html
This is the most complete README. I need to collect my idea to write some about the pipeline.
As this is a proof-of-concept mistake and misunderstanding are possible. Every type of feedback is welcome to improve it.