Skip to content

Commit

Permalink
[cache-invalidation] Use Quarkus instead of WildFly
Browse files Browse the repository at this point in the history
  • Loading branch information
Naros committed Sep 27, 2024
1 parent 5539e37 commit 3ee7462
Show file tree
Hide file tree
Showing 24 changed files with 359 additions and 420 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/cache-invalidation-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: 21
- uses: actions/checkout@v3
- name: Cache local Maven repository
uses: actions/cache@v2
Expand All @@ -23,4 +28,4 @@ jobs:
restore-keys: |
${{ runner.os }}-maven-
- name: Check changes in [cache-invalidation] example
run: cd cache-invalidation && mvn clean package -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dmaven.wagon.http.pool=false -Dmaven.wagon.httpconnectionManager.ttlSeconds=120
run: cd cache-invalidation && mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dmaven.wagon.http.pool=false -Dmaven.wagon.httpconnectionManager.ttlSeconds=120
26 changes: 0 additions & 26 deletions cache-invalidation/Dockerfile

This file was deleted.

165 changes: 88 additions & 77 deletions cache-invalidation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,98 +3,109 @@
This demo shows how Debezium can be used to invalidate items in the JPA 2nd level cache after external data changes,
e.g. a manual record update in the database, bypassing the application layer.

The application runs on WildFly and uses Postgres as a database.
The application uses Quarkus, Hibernate, and PostgreSQL as a database.
The domain model is centered around purchase orders of given items.
The `Item` entity is marked as cacheable, i.e. after updates to an item (e.g. its base price),
it must be purged from the 2nd-level cache in order to correctly calculate the price of future orders of that item.

## Manual Testing

To run the app, follow these steps:

export DEBEZIUM_VERSION=2.1
mvn clean package
docker-compose up --build

Place an order for item 10003 using curl:

curl -H "Content-Type: application/json" \
1. First start the database container.
```bash
mvn docker:start
```
This will start the `quay.io/debezium/example-postgres:latest` container that will be used to store our JPA entities and the database that the Debezium will capture changes from, too.

2. Run the application using the Quarkus development mode.
```bash
mvn clean quarkus:dev
```
The application will start in the development mode and run until you press `Ctrl+C` to stop the application.

3. Place an order for item 1003 using curl:
```bash
curl -H "Content-Type: application/json" \
-X POST \
--data @resources/data/create-order-request.json \
http://localhost:8080/cache-invalidation/rest/orders

Or, if [httpie](https://httpie.org/) is your preferred CLI HTTP client:

cat resources/data/create-order-request.json | http POST http://localhost:8080/cache-invalidation/rest/orders

Update the price of item 10003 directly in the database:

docker-compose exec postgres bash -c 'psql -U $POSTGRES_USER $POSTGRES_DB -c "UPDATE item SET price = 20.99 where id = 10003"'

Use the application's REST API to verify that the item has been purged from the cache:

curl -H "Content-Type: application/json" \
http://localhost:8080/rest/orders
```
Or, if [httpie](https://httpie.org/) is your preferred CLI HTTP client:
```bash
cat resources/data/create-order-request.json | http POST http://localhost:8080/rest/orders
```

4. Update the price of item 10003 directly in the database:
```bash
docker exec postgres-server-test-database-1 bash -c 'psql -U $POSTGRES_USER $POSTGRES_DB -c "UPDATE item SET price = 20.99 where id = 10003"'
```

5. Now use the REST endpoint to verify that the item has been purged from the cache:
```bash
curl -H "Content-Type: application/json" \
-X GET \
http://localhost:8080/cache-invalidation/rest/cache/item/10003

Or via httpie:

http GET http://localhost:8080/cache-invalidation/rest/cache/item/10003

Place another order of that item and observe how the calculated total price reflects the change applied above.
Also observe in the application's log how the `item` table is queried.

Now update the item again, using the application's REST API this time:

curl -H "Content-Type: application/json" \
http://localhost:8080/rest/cache/item/10003
```
or via httpie:
```bash
http GET http://localhost:8080/rest/cache/item/10003
```

6. Place another order of that item and observe how the calculated total price reflects the change applied above.
Also observe the application's log how the `item` table is queried.

7. Now, update the item again using the application's REST endpoint this time:
```bash
curl -H "Content-Type: application/json" \
-X PUT \
--data @resources/data/update-item-request.json \
http://localhost:8080/cache-invalidation/rest/items/10003

Or via httpie:

cat resources/data/update-item-request.json | http PUT http://localhost:8080/cache-invalidation/rest/items/10003

The Debezium event handler will detect that this transaction is issued by the application itself, resulting in the item to not be removed from the cache:

curl -H "Content-Type: application/json" \
http://localhost:8080/rest/items/10003
```
or via httpie:
```bash
cat resources/data/update-item-request.json | http PUT http://localhost:8080/rest/items/10003
```

8. The Debezium CDC event handler detects this transaction is issued by the application, which results in the item not being removed from the cache:
You can test this use case using curl:
```bash
curl -H "Content-Type: application/json" \
-X GET \
http://localhost:8080/cache-invalidation/rest/cache/item/10003

Or via httpie:

http GET http://localhost:8080/cache-invalidation/rest/cache/item/10003

If you place yet another order, you'll see how the `Item` entity is obtained from the cache, avoiding the roundtrip to the database.

Finally, shut down database and application server:

docker-compose down

## Build
http://localhost:8080/rest/cache/item/10003
```
or using httpie:
```bash
http GET http://localhost:8080/rest/cache/item/10003
```

Run
9. If you place another order, the `Item` entity is obtained from the cache, avoiding the database round-trip.

mvn clean package
10. Press `Ctrl+C` in the terminal to stop the Quarkus running application.

11. Execute `mvn docker:stop`, to stop the PostgreSQL database container.

This will build the application, deploy it to WildFly via Docker and run an integration test against it.

## Development

During development, start up database and WildFly like so:

mvn docker:build docker:start

After code changes the application can be re-deployed like so:

mvn wildfly:redeploy

To get a session in Postgres run:

docker run -it --rm --link postgres-1:postgres quay.io/debezium/example-postgres:${DEBEZIUM_VERSION} psql -h postgres -U postgresuser --dbname inventory

Run

mvn docker:stop

to shut down all the started containers.
### Start-up steps:
1.
2. First start the PostgreSQL database container using maven:
```bash
mvn docker:start
```

2. Next start the application in Quarkus development mode:
```bash
mvn clean quarkus:dev
```

### Accessing the database

To obtain a database session in PostgreSQL, run:
```bash
docker run -it --rm --link postgres-1:postgres quay.io/debezium/example-postgres:latest psql -h postgres -U postgresuser --dbname inventory
```

### Shutdown steps

1. Stop the Quarkus application by pressing `Ctrl+C` in the terminal.
2. Execute `mvn docker:stop` to stop the PostgreSQL database container.
20 changes: 0 additions & 20 deletions cache-invalidation/docker-compose.yaml

This file was deleted.

Loading

0 comments on commit 3ee7462

Please sign in to comment.