From 9cea3cf2ea1877481eaf095a3cb71463a1ee311c Mon Sep 17 00:00:00 2001 From: pieceowater Date: Sat, 30 Nov 2024 20:31:14 +0500 Subject: [PATCH] + --- README.md | 227 +++++++++++++++++---------------------- cmd/example/server.go | 2 +- cmd/example/transport.go | 2 +- go.mod | 2 +- gossiper.go | 12 +-- internal/db/database.go | 2 +- 6 files changed, 107 insertions(+), 140 deletions(-) diff --git a/README.md b/README.md index 3f36481..843d33b 100644 --- a/README.md +++ b/README.md @@ -1,179 +1,146 @@ # Gossiper -`gossiper` is a lightweight Go package designed to simplify working with environment variables, RabbitMQ, and validation tools. It streamlines the process of managing configurations and consuming messages from RabbitMQ dynamically. +`gossiper` is a modern Go library designed to simplify server management and transport mechanisms for gRPC, REST, and RabbitMQ in distributed systems. The package allows developers to manage servers, routes, and database connections with ease, while supporting a pluggable architecture for extending functionality. ## Installation ```bash -go get github.com/pieceowater-dev/lotof.lib.gossiper +go get github.com/pieceowater-dev/lotof.lib.gossiper/v2 ``` -## Usage +Features -Instead of placing the entire configuration inside `main.go`, it's better to separate the configuration into its own file and import it in `main.go`. This helps keep the code organized, especially as the application grows. +- Centralized server management with ServerManager +- Support for gRPC and REST servers +- RabbitMQ server integration +- Transport factory for creating gRPC-based communication channels +- Simplified database connection management +- Modular and extendable design -### Step 1: Create a Config File +## Usage Examples -Create a file named `config.go` where you can define the configuration for the environment variables and RabbitMQ consumers. +### Server Management -```go +gossiper provides a ServerManager to manage multiple servers, such as gRPC and REST, in one place. + +### Example: Managing Multiple Servers + +```golang package main -import "github.com/pieceowater-dev/lotof.lib.gossiper" - -func GetConfig() gossiper.Config { - return gossiper.Config{ - Env: gossiper.EnvConfig{ - Required: []string{"RABBITMQ_DSN"}, - }, - AMQPConsumer: gossiper.AMQPConsumerConfig{ - DSNEnv: "RABBITMQ_DSN", - Queues: []gossiper.QueueConfig{ - { - Name: "template_queue", - Durable: true, - AutoDelete: false, - Exclusive: false, - NoWait: false, - Args: nil, - }, - }, - Consume: []gossiper.AMQPConsumeConfig{ - { - Queue: "template_queue", - Consumer: "example_consumer", - AutoAck: true, - Exclusive: false, - NoLocal: false, - NoWait: false, - Args: nil, - }, - }, - }, +import ( + "github.com/gin-gonic/gin" + "github.com/pieceowater-dev/lotof.lib.gossiper/v2" + "google.golang.org/grpc" +) + +func main() { + serverManager := gossiper.NewServerManager() + + // Initialize gRPC Server + grpcInitRoute := func(server *grpc.Server) { + // Define gRPC services here } + serverManager.AddServer(gossiper.NewGRPCServ("50051", grpc.NewServer(), grpcInitRoute)) + + // Initialize REST Server + restInitRoute := func(router *gin.Engine) { + router.GET("/health", func(c *gin.Context) { + c.JSON(200, gin.H{"status": "ok"}) + }) + } + serverManager.AddServer(gossiper.NewRESTServ("8080", gin.Default(), restInitRoute)) + + // Start all servers + serverManager.StartAll() + defer serverManager.StopAll() } ``` -### Step 2: Import Config into `main.go` +### Transport Factory -Now, in your `main.go`, import the configuration and use it in the `gossiper.Setup` function. +The TransportFactory simplifies the creation of transport mechanisms for communication, such as gRPC. -```go +Example: Creating a gRPC Transport +```golang package main import ( - "encoding/json" - "github.com/pieceowater-dev/lotof.lib.gossiper" - "log" + "github.com/pieceowater-dev/lotof.lib.gossiper/v2" ) -func HandleMessage(msg gossiper.AMQMessage) any { - log.Printf("Received message: %s", msg.Pattern) - return "OK" -} - func main() { - // Import the configuration from config.go - conf := GetConfig() - - // Initialize and start the consumers - gossiper.Setup(conf, nil, func(msg []byte) any { - var customMessage gossiper.AMQMessage - err := json.Unmarshal(msg, &customMessage) - if err != nil { - log.Println("Failed to unmarshal custom message:", err) - return nil - } - return HandleMessage(customMessage) - }) - - log.Println("Application started") + factory := gossiper.NewTransportFactory() + grpcTransport := factory.CreateTransport( + gossiper.GRPC, + "localhost:50051", + ) + + // Use grpcTransport to send requests or create clients + _ = grpcTransport } ``` -## Configuration +## Core API -### `gossiper.Config` -This struct is the core configuration and includes: +### Server Management -- **EnvConfig**: Manages environment variables. -- **AMQPConsumerConfig**: Configures RabbitMQ consumers. +#### ServerManager -### `EnvConfig` +Manages the lifecycle of multiple servers (start, stop). +- NewServerManager +Creates a new server manager instance. +- AddServer +Adds a new server (e.g., gRPC, REST) to the manager. +- StartAll / StopAll +Starts or stops all servers managed by the instance. -```go -type EnvConfig struct { - Required []string -} -``` +#### Servers -- **Required** (`[]string`): Specifies a list of environment variables that are mandatory for the application to run. If any variable is missing, the application will return an error. +gRPC Server -### `AMQPConsumerConfig` +- NewGRPCServ +Creates a new gRPC server instance. -```go -type AMQPConsumerConfig struct { - DSNEnv string - Queues []QueueConfig - Consume []AMQPConsumeConfig -} -``` +REST Server -- **DSNEnv** (`string`): The environment variable name that stores the RabbitMQ DSN (Data Source Name). This value is retrieved from the environment. -- **Queues** (`[]QueueConfig`): A list of queues that should be declared in RabbitMQ. Each queue has its own configuration. -- **Consume** (`[]AMQPConsumeConfig`): Defines the consumers and how they should consume messages from RabbitMQ. +- NewRESTServ +Creates a new REST server using the Gin framework. -### `QueueConfig` +RabbitMQ Server -```go -type QueueConfig struct { - Name string - Durable bool - AutoDelete bool - Exclusive bool - NoWait bool - Args amqp.Table -} -``` +- NewRMQServ +Creates a new RabbitMQ server instance. -- **Name** (`string`): The name of the RabbitMQ queue. -- **Durable** (`bool`): If `true`, the queue will survive broker restarts. -- **AutoDelete** (`bool`): If `true`, the queue will be automatically deleted when the last consumer disconnects. -- **Exclusive** (`bool`): If `true`, the queue can only be used by the current connection and will be deleted when the connection is closed. -- **NoWait** (`bool`): If `true`, the server will not respond to the queue declaration. The client won’t wait for confirmation that the queue was created. -- **Args** (`amqp.Table`): Custom arguments to pass when creating the queue. Usually `nil`. - -### `AMQPConsumeConfig` - -```go -type AMQPConsumeConfig struct { - Queue string - Consumer string - AutoAck bool - Exclusive bool - NoLocal bool - NoWait bool - Args amqp.Table -} -``` +#### Transport -- **Queue** (`string`): The name of the queue to consume from. -- **Consumer** (`string`): The consumer tag to identify this consumer. -- **AutoAck** (`bool`): If `true`, messages will be automatically acknowledged after being delivered. Otherwise, manual acknowledgment is required. -- **Exclusive** (`bool`): If `true`, the queue can only be consumed by this consumer. -- **NoLocal** (`bool`): If `true`, messages published on this connection are not delivered to this consumer (rarely used). -- **NoWait** (`bool`): If `true`, the server will not send a response to the consumer setup request. -- **Args** (`amqp.Table`): Additional arguments for consumer setup. +TransportFactory -### Example `.env` file +The TransportFactory provides a unified way to create communication transports. +- Supported Transports: +- GRPC: For gRPC communication. +### Example: +```golang +factory := gossiper.NewTransportFactory() +transport := factory.CreateTransport(gossiper.GRPC, "localhost:50051") ``` -RABBITMQ_DSN=amqp://guest:guest@localhost:5672/ -``` -### Logging +#### Database + +#### NewDB -`gossiper` logs every message received and any errors encountered during message unmarshalling. +Initializes a database connection. +- Supported Database Types: +- PostgresDB: For PostgreSQL connections. + +#### Example: +```golang +db, err := gossiper.NewDB(gossiper.PostgresDB, "your-dsn", true) +if err != nil { + panic(err) +} +``` ### Contributing diff --git a/cmd/example/server.go b/cmd/example/server.go index 26192b1..9af05ec 100644 --- a/cmd/example/server.go +++ b/cmd/example/server.go @@ -2,7 +2,7 @@ package main import ( "github.com/gin-gonic/gin" - "github.com/pieceowater-dev/lotof.lib.gossiper" + "github.com/pieceowater-dev/lotof.lib.gossiper/v2" "google.golang.org/grpc" ) diff --git a/cmd/example/transport.go b/cmd/example/transport.go index 5ac505d..25821eb 100644 --- a/cmd/example/transport.go +++ b/cmd/example/transport.go @@ -1,7 +1,7 @@ package main import ( - gossiper "github.com/pieceowater-dev/lotof.lib.gossiper" + "github.com/pieceowater-dev/lotof.lib.gossiper/v2" ) type SomeService struct { diff --git a/go.mod b/go.mod index 26e0f51..f5eb2b6 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/pieceowater-dev/lotof.lib.gossiper +module github.com/pieceowater-dev/lotof.lib.gossiper/v2 go 1.23.0 diff --git a/gossiper.go b/gossiper.go index e28c287..20f2820 100644 --- a/gossiper.go +++ b/gossiper.go @@ -2,12 +2,12 @@ package gossiper import ( "github.com/gin-gonic/gin" - "github.com/pieceowater-dev/lotof.lib.gossiper/internal/db" - "github.com/pieceowater-dev/lotof.lib.gossiper/internal/servers" - grpcServ "github.com/pieceowater-dev/lotof.lib.gossiper/internal/servers/grpc" - rmqServ "github.com/pieceowater-dev/lotof.lib.gossiper/internal/servers/rabbitmq" - restServ "github.com/pieceowater-dev/lotof.lib.gossiper/internal/servers/rest" - "github.com/pieceowater-dev/lotof.lib.gossiper/internal/transport" + "github.com/pieceowater-dev/lotof.lib.gossiper/v2/internal/db" + "github.com/pieceowater-dev/lotof.lib.gossiper/v2/internal/servers" + grpcServ "github.com/pieceowater-dev/lotof.lib.gossiper/v2/internal/servers/grpc" + rmqServ "github.com/pieceowater-dev/lotof.lib.gossiper/v2/internal/servers/rabbitmq" + restServ "github.com/pieceowater-dev/lotof.lib.gossiper/v2/internal/servers/rest" + "github.com/pieceowater-dev/lotof.lib.gossiper/v2/internal/transport" "google.golang.org/grpc" ) diff --git a/internal/db/database.go b/internal/db/database.go index b754610..5805e5a 100644 --- a/internal/db/database.go +++ b/internal/db/database.go @@ -2,7 +2,7 @@ package db import ( "fmt" - postgresql "github.com/pieceowater-dev/lotof.lib.gossiper/internal/db/pg" + postgresql "github.com/pieceowater-dev/lotof.lib.gossiper/v2/internal/db/pg" "gorm.io/gorm" )