Skip to content

Commit

Permalink
feat : Implement Notify and Listen Support (#1639)
Browse files Browse the repository at this point in the history
* feat : Implement Notify and Listen Support

* removes flyway support as it is not necessary

* polish

* implements notification and listener

* remove junk
  • Loading branch information
rajadilipkolli authored Jan 12, 2025
1 parent eb7522c commit bbd40ea
Show file tree
Hide file tree
Showing 25 changed files with 1,143 additions and 0 deletions.
1 change: 1 addition & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
* [r2dbc](r2dbc/README.md)
* [r2dbc-jooq](r2dbc/boot-jooq-r2dbc-sample/README.md)
* [PostgreSQL JSON and enum column support](r2dbc/boot-r2dbc-json-column/README.md)
* [PostgreSQL Notify and Listen support using reactive spring boot](r2dbc/boot-r2dbc-notify-listen/README.md)
* [r2dbc-boot](r2dbc/boot-r2dbc-sample/README.md)
* [reactive-cache](r2dbc/boot-r2dbc-reactive-cache/README.md)
* [scheduler](scheduler/README.md)
Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
<module>jpa/multitenancy/schema</module>
<module>r2dbc/boot-jooq-r2dbc-sample</module>
<module>r2dbc/boot-r2dbc-json-column</module>
<module>r2dbc/boot-r2dbc-notify-listen</module>
<module>r2dbc/boot-r2dbc-sample</module>
<module>r2dbc/boot-r2dbc-reactive-cache</module>
<module>scheduler/boot-scheduler-jobrunr</module>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
107 changes: 107 additions & 0 deletions r2dbc/boot-r2dbc-notify-listen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Spring Boot R2DBC Notify/Listen Example

This project demonstrates how to implement PostgreSQL's NOTIFY/LISTEN feature using Spring Boot and R2DBC. It showcases real-time notifications between database and application using PostgreSQL's pub/sub capabilities.

---
## Features

- Reactive PostgreSQL connectivity using R2DBC
- Implementation of PostgreSQL NOTIFY/LISTEN mechanism
- Real-time event notifications
- Reactive endpoints for publishing and receiving notifications

---
## Prerequisites

- JDK 21
- Maven
- Docker and Docker Compose
- PostgreSQL (or use provided Docker Compose)

---

## Getting Started

1. Start PostgreSQL using Docker Compose:
```bash
docker-compose up -d
```

2. Build the application:
```bash
./mvnw clean package
```

3. Run the application:
```bash
./mvnw spring-boot:run
```
---
## Architecture

```mermaid
sequenceDiagram
participant Client
participant Application
participant Listener
participant PostgreSQL
Note over Application: Application starts
Application->>PostgreSQL: Connect to database
Application->>PostgreSQL: LISTEN channel_name
Note over Client: Trigger notification
Client->>Application: POST /api/notify
Application->>PostgreSQL: NOTIFY channel_name, 'message'
PostgreSQL-->>Listener: Notification event
Listener-->>Application: Process notification
Application-->>Client: Notification processed
Note over Client: Subscribe to events
Client->>Application: WebSocket connection
Application-->>Client: Stream notifications
```
---
## Usage

1. To publish a notification:
```bash
curl -X POST http://localhost:8080/api/notify \
-H "Content-Type: application/json" \
-d '{"channel": "events", "message": "Hello World!"}'
```

2. To subscribe to notifications:
- Connect to WebSocket endpoint: `ws://localhost:8080/notifications`
- Or use Server-Sent Events endpoint: `http://localhost:8080/notifications/sse`

---

## Configuration

Key configuration properties in `application.properties`:

```properties
# R2DBC PostgreSQL Configuration
spring.r2dbc.url=r2dbc:postgresql://localhost:5432/postgres
spring.r2dbc.username=postgres
spring.r2dbc.password=postgres

# Notification Channel Configuration
app.notification.channel=events
```
---
## How It Works

1. The application establishes a connection to PostgreSQL using R2DBC
2. It sets up LISTEN on specified channels
3. When a notification is published:
- Application executes NOTIFY command
- PostgreSQL broadcasts to all listeners
- Listeners receive and process notifications
4. Connected clients receive notifications via WebSocket/SSE

---
## Contributing

Feel free to submit issues and enhancement requests!
17 changes: 17 additions & 0 deletions r2dbc/boot-r2dbc-notify-listen/docker/docker-compose-app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: '3.8'
services:

boot-r2dbc-sample:
build: ..
ports:
- "18080:8080"
- "18787:8787"
restart: always
depends_on:
- postgresqldb
environment:
- SPRING_PROFILES_ACTIVE=docker
- SPRING_DATASOURCE_DRIVER_CLASS_NAME=org.postgresql.Driver
- SPRING_DATASOURCE_URL=jdbc:postgresql://postgresqldb:5432/appdb
- SPRING_DATASOURCE_USERNAME=appuser
- SPRING_DATASOURCE_PASSWORD=secret
42 changes: 42 additions & 0 deletions r2dbc/boot-r2dbc-notify-listen/docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
services:

postgresqldb:
image: postgres:17.2-alpine
hostname: postgresqldb
extra_hosts: [ 'host.docker.internal:host-gateway' ]
environment:
- POSTGRES_USER=appuser
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=appdb
ports:
- "5432:5432"
networks:
- boot-r2dbc-network

pgadmin:
image: dpage/pgadmin4
extra_hosts: [ 'host.docker.internal:host-gateway' ]
environment:
- [email protected]
- PGADMIN_DEFAULT_PASSWORD=admin
- PGADMIN_CONFIG_SERVER_MODE=False
- PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED=False
ports:
- "5050:80"
depends_on:
postgresqldb:
condition: service_started
volumes:
- ./docker_pgadmin_servers.json:/pgadmin4/servers.json
entrypoint:
- "/bin/sh"
- "-c"
- "/bin/echo 'postgresqldb:5432:*:appuser:secret' > /tmp/pgpassfile && chmod 600 /tmp/pgpassfile && /entrypoint.sh"
restart: unless-stopped
networks:
- boot-r2dbc-network


networks:
boot-r2dbc-network:
driver: bridge
14 changes: 14 additions & 0 deletions r2dbc/boot-r2dbc-notify-listen/docker/docker_pgadmin_servers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"Servers": {
"1": {
"Name": "Docker Compose DB",
"Group": "Servers",
"Port": 5432,
"Username": "appuser",
"Host": "postgresqldb",
"SSLMode": "prefer",
"MaintenanceDB": "appdb",
"PassFile": "/tmp/pgpassfile"
}
}
}
Loading

0 comments on commit bbd40ea

Please sign in to comment.