Skip to content

Commit

Permalink
Update demo to latest microcks-testcontainers version and enhance README
Browse files Browse the repository at this point in the history
Signed-off-by: Laurent Broudoux <laurent.broudoux@gmail.com>
  • Loading branch information
lbroudoux committed Mar 26, 2024
1 parent a5fe243 commit 5c518fe
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 35 deletions.
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: maven
directory: /
schedule:
interval: daily

- package-ecosystem: github-actions
directory: /
schedule:
interval: daily
Binary file modified assets/order-service-ecosystem.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
<dependency>
<groupId>io.github.microcks</groupId>
<artifactId>microcks-testcontainers</artifactId>
<version>0.2.5</version>
<version>0.2.6</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
11 changes: 5 additions & 6 deletions src/test/java/org/acme/order/ContainersConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,11 @@ KafkaContainer kafkaContainer() {

@Bean
MicrocksContainersEnsemble microcksEnsemble(DynamicPropertyRegistry registry) {
/*
DockerImageName nativeImage = DockerImageName.parse("quay.io/microcks/microcks-uber:nightly-native")
.asCompatibleSubstituteFor("quay.io/microcks/microcks-uber:1.8.1");
MicrocksContainersEnsemble ensemble = new MicrocksContainersEnsemble(network, nativeImage)
*/
// Uncomment these lines (36-38) if you want to use the native image of Microcks
// and comment the next MicrocksContainersEnsemble declaration line (40).
// DockerImageName nativeImage = DockerImageName.parse("quay.io/microcks/microcks-uber:1.9.0-native")
// .asCompatibleSubstituteFor("quay.io/microcks/microcks-uber:1.9.0");
// MicrocksContainersEnsemble ensemble = new MicrocksContainersEnsemble(network, nativeImage)

MicrocksContainersEnsemble ensemble = new MicrocksContainersEnsemble(network, "quay.io/microcks/microcks-uber:1.9.0")
.withPostman() // We need this to do contract-testing with Postman collection
Expand Down
29 changes: 14 additions & 15 deletions step-1-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,30 @@ We would recommend using [SDKMAN](https://sdkman.io/) to install Java on your ma

### Install Docker

You need to have a Docker environment to use Testcontainers.
You need to have a [Docker](https://docs.docker.com/get-docker/) or [Podman](https://podman.io/) environment to use Testcontainers.

```shell
$ docker version

Client:
Cloud integration: v1.0.35
Version: 24.0.2
API version: 1.43
Go version: go1.20.4
Git commit: cb74dfc
Built: Thu May 25 21:51:16 2023
Cloud integration: v1.0.35+desktop.10
Version: 25.0.3
API version: 1.44
Go version: go1.21.6
Git commit: 4debf41
Built: Tue Feb 6 21:13:26 2024
OS/Arch: darwin/arm64
Context: desktop-linux

Server: Docker Desktop 4.21.1 (114176)
Server: Docker Desktop 4.27.2 (137060)
Engine:
Version: 24.0.2
API version: 1.43 (minimum version 1.12)
Go version: go1.20.4
Git commit: 659604f
Built: Thu May 25 21:50:59 2023
Version: 25.0.3
API version: 1.44 (minimum version 1.24)
Go version: go1.21.6
Git commit: f417435e5f6216828dec57958c490c4f8bae4f98
Built: Wed Feb 7 00:39:16 2024
OS/Arch: linux/arm64
Experimental: false
...
```

## Download the project
Expand All @@ -53,7 +52,7 @@ git clone https://github.com/microcks/microcks-testcontainers-java-spring-demo.g
With Maven:

```shell
./mvnw compile
./mvnw clean package -DskipTests
```

###
Expand Down
27 changes: 14 additions & 13 deletions step-2-exploring-the-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ but also relies on an existing API we have [introduced in a previous post](https
![Order Service ecosystem](./assets/order-service-ecosystem.png)

The `Order Service` application has been designed around 5 main components that are directly mapped on Spring Boot components and classes:
* The `OrderController` (in package `org.acme.order.api`) is responsible for exposing an `Order API` to the outer world.
* The `OrderService` (in package `org.acme.order.service`) is responsible for implementing the business logic around the creation of orders.
* The `PastryAPIClient` (in package `org.acme.order.client`) is responsible for calling the `Pastry API` in *Product Domain* and get details or list of pastries.
* The `OrderEventPublisher` (in package `org.acme.order.service`) is responsible for publishing a message on a `Kafka` topic when a new `Order` is created.
* The `OrderEventListener` (in package `org.acme.order.service`) is responsible for consuming message on a `Kafka` topic when an `Order` has been reviewed.
* The [`OrderController`](src/main/java/org/acme/order/api/OrderController.java) (in package `org.acme.order.api`) is responsible for exposing an `Order API` to the outer world.
* The [`OrderService`](src/main/java/org/acme/order/service/OrderService.java) is responsible for implementing the business logic around the creation of orders.
* The [`PastryAPIClient`](src/main/java/org/acme/order/client/PastryAPIClient.java) is responsible for calling the `Pastry API` in *Product Domain* and get details or list of pastries.
* The [`OrderEventPublisher`](src/main/java/org/acme/order/service/OrderEventPublisher.java) is responsible for publishing a message on a `Kafka` topic when a new `Order` is created.
* The [`OrderEventListener`](src/main/java/org/acme/order/service/OrderEventListener.java) is responsible for consuming message on a `Kafka` topic when an `Order` has been reviewed.

![Order Service architecture](./assets/order-service-architecture.png)

Expand All @@ -21,23 +21,24 @@ dependencies (like a `Payment Service`, a `Customer Service`, a `Shipping Servic

However, this situation is complex enough to highlight the two problems we're addressing:
1) How to **efficiently set up a development environment** that depends on third-party API like the Pastry API?
You certainly want to avoid cloning this component repository, figuring out how to launch it and configure it accordingly. As a developer, developing your own mock of this service makes you also lose time and risk drifting from initial intent,
- You certainly want to avoid cloning this component repository and trying to figure out how to launch and configure it accordingly.
- As a developer, developing your own mock of this service makes you also lose time and risk drifting from initial intent,
2) How to **efficiently validate the conformance** of the `Order API` and `Order Events` against business expectations and API contracts?
Besides the core business logic, you might want to validate the network and protocol serialization layers as well as the respect of semantics.
- Besides the core business logic, you might want to validate the network and protocol serialization layers as well as the respect of semantics.

## Business logic

This application must implement basic flows:
* When creating a new `Order`, the service must check that the products are available before creating and persisting an order. Otherwise, order cannot be placed.
* When the `Order` is actually created, the service must also publish an `OrderEvent` to a specific Kafka topic to propagate this information to other systems that will review the events,
* When the `OrderEvent` has been reviewed, a new message is published on another `Kafka` topic. The `OrderEventListener` must capture-it and update the corresponding `Order` status using the service.
* When creating a new [`Order`](src/main/java/org/acme/order/service/model/Order.java), the service must check that the products are available before creating and persisting an order. Otherwise, order cannot be placed.
* When the [`Order`](src/main/java/org/acme/order/service/model/Order.java) is actually created, the service must also publish an [`OrderEvent`](src/main/java/org/acme/order/service/model/OrderEvent.java) to a specific Kafka topic to propagate this information to other systems that will review the events,
* When the [`OrderEvent`](src/main/java/org/acme/order/service/model/OrderEvent.java) has been reviewed, a new message is published on another `Kafka` topic. The [`OrderEventListener`](src/main/java/org/acme/order/service/OrderEventListener.java) must capture-it and update the corresponding [`Order`](src/main/java/org/acme/order/service/model/Order.java) status using the service.

## Flows specifications

All the interactions are specified using API contracts:
* The Order API is specified using the `src/main/resources/order-service-openapi.yaml` OpenAPI specification,
* The Pastry API is specified using the `src/test/resources/third-parties/apipastries-openapi.yaml` OpenAPI specification,
* The Order Events are specified using the `src/main/resources/order-events-asyncapi.yaml` AsyncAPI specification.
* The Order API is specified using the [`order-service-openapi.yaml`](src/main/resources/order-service-openapi.yaml) OpenAPI specification,
* The Pastry API is specified using the [`apipastries-openapi.yaml`](src/test/resources/third-parties/apipastries-openapi.yaml) OpenAPI specification,
* The Order Events are specified using the [`order-events-asyncapi.yaml`](src/main/resources/order-events-asyncapi.yaml) AsyncAPI specification.

Those specifications will help us for two things:
1) They will be used to provide simulations (or mocks) of third-parties systems - typically the Pastry API provider and the reviewer system that provides updates on `OrderEvents`
Expand Down

0 comments on commit 5c518fe

Please sign in to comment.