message broker sifatida redis qo'shildi
This commit is contained in:
24
README.MD
24
README.MD
@@ -72,7 +72,7 @@ Notifications should be published to the RabbitMQ exchange with the following JS
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Python example
|
Python example rabbitmq broker
|
||||||
```python
|
```python
|
||||||
from kombu import Connection, Exchange, Producer
|
from kombu import Connection, Exchange, Producer
|
||||||
|
|
||||||
@@ -93,6 +93,28 @@ producer.publish(message)
|
|||||||
print("Message sent to all workers!")
|
print("Message sent to all workers!")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Python example redis broker
|
||||||
|
```python
|
||||||
|
import redis
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Redis ulanishi
|
||||||
|
r = redis.StrictRedis(host='127.0.0.1', port=6379, db=0)
|
||||||
|
|
||||||
|
# Xabar tayyorlash
|
||||||
|
message = {
|
||||||
|
'type': 'email',
|
||||||
|
'message': "Subject: test\r\n\r\nclasscom.uz sayti va mobil ilovasiga ro'yxatdan o'tishingiz uchun tasdiqlash kodi: 1234",
|
||||||
|
'to': ["JscorpTech@gmail.com", "admin@jscorp.uz"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Xabarni JSON formatga o‘tkazib, Redis listga push qilish
|
||||||
|
r.rpush('notification', json.dumps(message))
|
||||||
|
|
||||||
|
print("Message pushed to Redis list!")
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
Available notification types:
|
Available notification types:
|
||||||
- `email`: For email notifications
|
- `email`: For email notifications
|
||||||
- `sms`: For SMS notifications
|
- `sms`: For SMS notifications
|
||||||
|
|||||||
46
internal/broker/rabbitmq.go
Normal file
46
internal/broker/rabbitmq.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package broker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/JscorpTech/notification/internal/domain"
|
||||||
|
"github.com/JscorpTech/notification/internal/rabbitmq"
|
||||||
|
)
|
||||||
|
|
||||||
|
type rabbitMQBroker struct {
|
||||||
|
Ctx context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRabbitMQBroker(ctx context.Context) domain.BrokerPort {
|
||||||
|
return &rabbitMQBroker{
|
||||||
|
Ctx: ctx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r rabbitMQBroker) Subscribe(topic string, handler func(domain.NotificationMsg)) {
|
||||||
|
conn, ch, err := rabbitmq.Connect()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
defer ch.Close()
|
||||||
|
|
||||||
|
ch.ExchangeDeclare(topic, "direct", true, false, false, false, nil)
|
||||||
|
q, _ := ch.QueueDeclare(topic, true, false, false, false, nil)
|
||||||
|
ch.QueueBind(q.Name, topic, topic, false, nil)
|
||||||
|
|
||||||
|
msgs, _ := ch.Consume(q.Name, "", true, false, false, false, nil)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for msg := range msgs {
|
||||||
|
var notification domain.NotificationMsg
|
||||||
|
if err := json.Unmarshal(msg.Body, ¬ification); err != nil {
|
||||||
|
fmt.Print(err.Error())
|
||||||
|
}
|
||||||
|
go handler(notification)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
39
internal/broker/redis.go
Normal file
39
internal/broker/redis.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package broker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/JscorpTech/notification/internal/domain"
|
||||||
|
"github.com/JscorpTech/notification/internal/redis"
|
||||||
|
)
|
||||||
|
|
||||||
|
type redisBroker struct {
|
||||||
|
Ctx context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRedisBroker(ctx context.Context) domain.BrokerPort {
|
||||||
|
return &redisBroker{
|
||||||
|
Ctx: ctx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r redisBroker) Subscribe(topic string, handler func(domain.NotificationMsg)) {
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
var notification domain.NotificationMsg
|
||||||
|
val, err := redis.RDB.BLPop(r.Ctx, 0, topic).Result()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal([]byte(val[1]), ¬ification); err != nil {
|
||||||
|
fmt.Print(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go handler(notification)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,14 +2,12 @@ package consumer
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"os"
|
||||||
|
|
||||||
|
"github.com/JscorpTech/notification/internal/broker"
|
||||||
"github.com/JscorpTech/notification/internal/domain"
|
"github.com/JscorpTech/notification/internal/domain"
|
||||||
"github.com/JscorpTech/notification/internal/notifier"
|
"github.com/JscorpTech/notification/internal/notifier"
|
||||||
"github.com/JscorpTech/notification/internal/rabbitmq"
|
|
||||||
"github.com/streadway/amqp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type notificationConsumer struct {
|
type notificationConsumer struct {
|
||||||
@@ -23,39 +21,26 @@ func NewNotificationConsumer(ctx context.Context) domain.NotificationConsumerPor
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *notificationConsumer) Start() {
|
func (n *notificationConsumer) Start() {
|
||||||
conn, ch, err := rabbitmq.Connect()
|
|
||||||
if err != nil {
|
brokerName := os.Getenv("BROKER")
|
||||||
log.Fatal(err)
|
if brokerName == "" {
|
||||||
|
brokerName = "redis"
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
var brokerService domain.BrokerPort
|
||||||
defer ch.Close()
|
switch brokerName {
|
||||||
|
case "redis":
|
||||||
exchangeName := "notification"
|
brokerService = broker.NewRedisBroker(n.Ctx)
|
||||||
queueName := "notification"
|
case "rabbitmq":
|
||||||
routingKey := "notification"
|
brokerService = broker.NewRabbitMQBroker(n.Ctx)
|
||||||
|
default:
|
||||||
ch.ExchangeDeclare(exchangeName, "direct", true, false, false, false, nil)
|
brokerService = broker.NewRedisBroker(n.Ctx)
|
||||||
q, _ := ch.QueueDeclare(queueName, true, false, false, false, nil)
|
|
||||||
ch.QueueBind(q.Name, routingKey, exchangeName, false, nil)
|
|
||||||
|
|
||||||
msgs, _ := ch.Consume(q.Name, "", true, false, false, false, nil)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for msg := range msgs {
|
|
||||||
go n.Handler(msg)
|
|
||||||
}
|
}
|
||||||
}()
|
brokerService.Subscribe(os.Getenv("TOPIC"), n.Handler)
|
||||||
|
|
||||||
fmt.Println("🚀 Server started. Ctrl+C to quit.")
|
fmt.Println("🚀 Server started. Ctrl+C to quit.")
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notificationConsumer) Handler(msg amqp.Delivery) {
|
func (n *notificationConsumer) Handler(notification domain.NotificationMsg) {
|
||||||
var notification domain.NotificationMsg
|
|
||||||
err := json.Unmarshal(msg.Body, ¬ification)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Print(err.Error())
|
|
||||||
}
|
|
||||||
var ntf domain.NotifierPort
|
var ntf domain.NotifierPort
|
||||||
switch notification.Type {
|
switch notification.Type {
|
||||||
case "sms":
|
case "sms":
|
||||||
|
|||||||
6
internal/domain/broker.go
Normal file
6
internal/domain/broker.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package domain
|
||||||
|
|
||||||
|
type BrokerPort interface {
|
||||||
|
Subscribe(string, func(NotificationMsg))
|
||||||
|
// Publish()
|
||||||
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
package domain
|
package domain
|
||||||
|
|
||||||
import "github.com/streadway/amqp"
|
|
||||||
|
|
||||||
type NotificationConsumerPort interface {
|
type NotificationConsumerPort interface {
|
||||||
Start()
|
Start()
|
||||||
Handler(amqp.Delivery)
|
Handler(NotificationMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
type SMSServicePort interface {
|
type SMSServicePort interface {
|
||||||
|
|||||||
43
test.py
43
test.py
@@ -1,17 +1,36 @@
|
|||||||
from kombu import Connection, Exchange, Producer
|
# from kombu import Connection, Exchange, Producer
|
||||||
|
|
||||||
# RabbitMQ ulanishi
|
# # RabbitMQ ulanishi
|
||||||
rabbit_url = 'amqp://guest:guest@127.0.0.1:5672/'
|
# rabbit_url = 'amqp://guest:guest@127.0.0.1:5672/'
|
||||||
connection = Connection(rabbit_url)
|
# connection = Connection(rabbit_url)
|
||||||
channel = connection.channel()
|
# channel = connection.channel()
|
||||||
|
|
||||||
exchange = Exchange('notification', type='direct')
|
# exchange = Exchange('notification', type='direct')
|
||||||
|
|
||||||
# Producer yaratish
|
# # Producer yaratish
|
||||||
producer = Producer(channel, exchange=exchange, routing_key="notification")
|
# producer = Producer(channel, exchange=exchange, routing_key="notification")
|
||||||
|
|
||||||
# Xabar yuborish
|
# # Xabar yuborish
|
||||||
message = {'type': 'email', 'message': "Subject: test\r\n\r\nclasscom.uz sayti va mobil ilovasiga ro'yxatdan o'tishingingiz uchun tasdiqlash kodi: 1234", "to": ["JscorpTech@gmail.com", "admin@jscorp.uz"]}
|
# message = {'type': 'email', 'message': "Subject: test\r\n\r\nclasscom.uz sayti va mobil ilovasiga ro'yxatdan o'tishingingiz uchun tasdiqlash kodi: 1234", "to": ["JscorpTech@gmail.com", "admin@jscorp.uz"]}
|
||||||
producer.publish(message)
|
# producer.publish(message)
|
||||||
|
|
||||||
print("Message sent to all workers!")
|
# print("Message sent to all workers!")
|
||||||
|
|
||||||
|
|
||||||
|
import redis
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Redis ulanishi
|
||||||
|
r = redis.StrictRedis(host='127.0.0.1', port=6379, db=0)
|
||||||
|
|
||||||
|
# Xabar tayyorlash
|
||||||
|
message = {
|
||||||
|
'type': 'email',
|
||||||
|
'message': "Subject: test\r\n\r\nclasscom.uz sayti va mobil ilovasiga ro'yxatdan o'tishingiz uchun tasdiqlash kodi: 1234",
|
||||||
|
'to': ["JscorpTech@gmail.com", "admin@jscorp.uz"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Xabarni JSON formatga o‘tkazib, Redis listga push qilish
|
||||||
|
r.rpush('notification', json.dumps(message))
|
||||||
|
|
||||||
|
print("Message pushed to Redis list!")
|
||||||
|
|||||||
Reference in New Issue
Block a user