Skip to content

Commit

Permalink
+
Browse files Browse the repository at this point in the history
  • Loading branch information
pieceowater committed Nov 30, 2024
1 parent f730015 commit 9cea3cf
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 140 deletions.
227 changes: 97 additions & 130 deletions README.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
2 changes: 1 addition & 1 deletion cmd/example/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down
2 changes: 1 addition & 1 deletion cmd/example/transport.go
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -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

Expand Down
12 changes: 6 additions & 6 deletions gossiper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down
2 changes: 1 addition & 1 deletion internal/db/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down

0 comments on commit 9cea3cf

Please sign in to comment.