Skip to content

II. Technology

Frederik Wulf edited this page May 5, 2023 · 14 revisions

Find a short introduction which software was used, how and why.

  1. Docker
  2. Postgres
  3. Apache Kafka

Docker

Docker is a platform for creating, and running applications in containers. Containers are lightweight, portable, and isolated environments that can run on any system that supports Docker. Further information can be found here.

In this project docker is used mainly to provide the infrastructure. But it can also be used to start the complete application in a containerized environment.

Docker in Development

For development it is recommended to start at least the infrastructure container (zookeeper, kafka and db). The infrastructure container can be started with docker-compose -f docker-compose.infrastucture.yml up.

If one ore several services are actively developed, its recommended to us the normal docker-compose.yml and start the necessary containers with docker-compose up <container service names to start>. The services which are worked can then be started via the CLI or the IDE.

Example:
Start everything except the Account service docker-compose up db zookeeper kafka web_inventory_service web_shopping_cart_service web_fulfillment_service

Note:
There is no way to exclude one specific file from the compose startup.

The docker container architecture looks like this:

Postgres

PostgreSQL is an open source object-relational database. It offers data storage and scalability, with support for various programming languages and platforms.

Postgres is used as data store in all services in this project. The shopping cart service could benefit from an in-memory caching optimized database like Redis Cashe or Couchebase. Due to the shopping cart data sets limited lifespan (they are deleted 30 minutes after last update), this might be an option. It would also result in faster reads and writes. This is not implemented for reasons of simplicity, but it may be an option for the future.

There are four postgreSQL Server databases, but they are all deployed to a single container, to keep memory requirements as low as possible. This is not a recommended approach for production deployment, where it is better to use four individual servers to keep availability and decoupling as height as possible.

The postgres instance that is started with docker-compose up or docker-compose up db creates the following login credentials:
User: postgres
Password postgres

After running the migrations of each service like explained in the getting started section the following databases should be created:

  • AccountDev
  • InventoryDev
  • OrderDev
  • ShoppingCartDev

Apache Kafka

Apache Kafka is an open-source distributed streaming platform that is made to handle real-time data. It enables fault-tolerant and scalable publishing, subscribing and storing of streams. Kafka uses key-value messages that can originate from different producers. The data can be pusblished into different topics. So called consumers can then read the different topcis.

Zookeeper

To be able to run Kafka there is also the zookeeper service. Zookeeper is also developed by Apache. It serves as centralized service to manage Kafka. This is necessary since there can be multiple Kafka nodes. Then the zookeeper handles synchronization, naming, tracking each Kafka node etc.


Kafka is used in this project to facilitate communication between the services. Each service has an assigned topic, to publish on. Any other service can then listen to the relevant messages. On startup of the kafka container it will create the following topics:

  • account
  • inventory
  • shopping-cart
  • fulfillment

The keys and messages that will be published are the following:

Topic Key Message
account customer-registered { CustomerId: string, Email: string, CreatedAt: string }
customer-edited { CustomerId: string, Email: string, Address: { Street: string, City: string, Zip: string, Country: string }, PersonalInformation: { FirstName: string, LastName: string, DateOfBirth: string }, PaymentInfromation: { Address: { Street: string, City: string, Zip: string, Country: string } }, CreatedAt: string, UpdatedAt: string }
inventory product-added-by-admin { Id: string, Name: string, Desciption: string, Price: { GrossPrice: number, NetPrice: number, SalesTax: number, CurrencyCode: string }, Information: { Key: string, Value: string }[], Stock: number }
product-updated-by-admin { Id: string, Name: string, Desciption: string, Price: { GrossPrice: number, NetPrice: number, SalesTax: number, CurrencyCode: string }, Information: { Key: string, Value: string }[], Stock: number }
product-removed-by-admin { ProductId: string }
product-stock-updated { ProductId: string, Stock: number }
shopping-cart customer-added-product-to-basket { ShoppingCartId: string, Product: { Id: string, Name:string, Description: string, Price: { GrossPrice: number, NetPrice: number, SalesTax: number, CurrencyCode: string } }, Quantity: number }
customer-changed-product-quantity-in-cart { ShoppingCartId: string, Product: { Id: string, Name:string, Description: string, Price: { GrossPrice: number, NetPrice: number, SalesTax: number, CurrencyCode: string } }, NewQuantity: number }
customer-ordered-shopping-cart { ShoppingCartId: string, CustomerId: string, Items: { ProductId: string, Name: string, GrossPrice: number, NetPrice: number, CurrencyCode: string, Quantity: number, TotalPrice: number }[], ShoppingCartCheckout: { CustomerId: string, FirstName: string, LastName: string, Email: string, ShippingAddress: { Street: string, City: string, Zip: string, Country: string }, BillingAddress: { Street: string, City: string, Zip: string, Country: string }, CreatedAt: string, UpdatedAt: string }
shopping-cart-timed-out { Id: string, CustomerId: string, Items: { Product: { Id: string, name: string }[], Status: string, CreatedAt: string, UpdatedAt: string }
fulfillment administrator-shipped-order { OrderId: string, BuyerId: string, ShippedAt: string }
order-cancelled { OrderId: string, BuyerId: string, Items: { ProductId: string, Name: string, Price { GrossPrice: number, NetPrice: number, Tax: number, Currency: string }, Quantity: number, TotalPrice: { GrossPrice: number, NetPrice: number, Tax: number, Currency: string }}[]}
Clone this wiki locally