Skip to content

Commit

Permalink
Single mongo connect middleware, with connect info unified interface
Browse files Browse the repository at this point in the history
  • Loading branch information
kneerunjun committed May 2, 2024
1 parent 0515584 commit 1957b98
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 41 deletions.
85 changes: 46 additions & 39 deletions mongo.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,61 +15,68 @@ import (
"go.mongodb.org/mongo-driver/mongo/readpref"
)

// USes connection string and db name to connect
func MongoConnectURI(uri, dbname string) gin.HandlerFunc {
return func(c *gin.Context) {
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri))
if err != nil || client == nil {
httperr.HttpErrOrOkDispatch(c, httperr.ErrGatewayConnect(err), log.WithFields(log.Fields{
"stack": "MongoConnect",
"uri": uri,
}))
return
}
c.Set("mongo-client", client)
c.Set("mongo-database", client.Database(dbname))
}
// MongoConnectInfo: unified common interface that lets you connect to mongo irespective of how you choose the connection params
type MongoConnectInfo interface {
Connect() (*mongo.Client, error) // ApplyURI to connect to mongo, user password combination
URi() string
}

/* Mongo connection using the complete connection string */
type MongoConnectString string

func (mcs MongoConnectString) Connect() (*mongo.Client, error) {
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
return mongo.Connect(ctx, options.Client().ApplyURI(string(mcs)))
}
func (mcs MongoConnectString) URi() string {
return string(mcs)
}

/* Mongo connection using mongo connection params */
type MongoConnectParams struct {
Server string
User string
Passwd string
}

func (mcp MongoConnectParams) URi() string {
return fmt.Sprintf("mongodb://%s:%s@%s", mcp.User, mcp.Passwd, mcp.Server)
}

// Uses server, user password,dbname to connect to the mongo client
func MongoConnect(server, user, passwd, dbname string) gin.HandlerFunc {
func (mcp MongoConnectParams) Connect() (*mongo.Client, error) {
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
return mongo.Connect(ctx, options.Client().ApplyURI(mcp.URi()))
}

/* Use this as middleware, pass the connnect info and database name */

func MongoConnect(mcinfo MongoConnectInfo, dbname string) gin.HandlerFunc {
return func(c *gin.Context) {
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
client, err := mongo.Connect(ctx, options.Client().ApplyURI(fmt.Sprintf("mongodb://%s:%s@%s", user, passwd, server)))
cl, err := mcinfo.Connect()
if err != nil {
httperr.HttpErrOrOkDispatch(c, httperr.ErrGatewayConnect(err), log.WithFields(log.Fields{
"stack": "MongoConnect",
"login": user,
"server": server,
}))
return
}
if client.Ping(ctx, readpref.Primary()) != nil {
httperr.HttpErrOrOkDispatch(c, httperr.ErrGatewayConnect(err), log.WithFields(log.Fields{
"stack": "MongoConnect",
"login": user,
"server": server,
"stack": "MongoConnect",
"uri": mcinfo.URi(),
}))
return
}
c.Set("mongo-client", client)
c.Set("mongo-database", client.Database(dbname))
c.Set("mongo-client", cl)
c.Set("mongo-database", cl.Database(dbname))
}
}

// MongoPingTest : will do a simple ping test to see if the server is reachable
func MongoPingTest(server, user, passwd string) error {
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
client, err := mongo.Connect(ctx, options.Client().ApplyURI(fmt.Sprintf("mongodb://%s:%s@%s", user, passwd, server)))
if err != nil || client == nil {
return fmt.Errorf("failed to connect to mongo server %s", err)
func MongoPingTest(mcinfo MongoConnectInfo) error {
cl, err := mcinfo.Connect()
if err != nil {
return err
}
err = client.Ping(ctx, readpref.Primary())
ctx := context.Background()
err = cl.Ping(ctx, readpref.Primary())
if err != nil {
return fmt.Errorf("failed to ping server %s", err)
}
log.Info("database is reachable..")
defer client.Disconnect(ctx) // purpose of this connection is served
defer cl.Disconnect(ctx) // purpose of this connection is served
return nil
}
26 changes: 26 additions & 0 deletions mongo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package utilities

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestMongoPing(t *testing.T) {
data := []MongoConnectInfo{
MongoConnectString("mongodb://eensyaquap-dev:[email protected]:32701"),
MongoConnectParams{
Server: "aqua.eensymachines.in:32701",
User: "eensyaquap-dev",
Passwd: "33n5y+4dm1n",
},
}
for _, d := range data {
cl, err := d.Connect()
assert.Nil(t, err, "Unexpected error when connecting to database")
assert.NotNil(t, cl, "Unexpected nil client when connecting to databse")
t.Log(d.URi())
err = MongoPingTest(d)
assert.Nil(t, err, "Unexpected error when ping testing the database")
}
}
8 changes: 6 additions & 2 deletions socket_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build exclude

package utilities

import (
Expand All @@ -21,8 +23,10 @@ func init() {
log.SetLevel(log.TraceLevel) // default is info level, if verbose then trace
}

/*handler: new connections are handled here, this will read the connection and print the message received
lets assume we receive json messages on this*/
/*
handler: new connections are handled here, this will read the connection and print the message received
lets assume we receive json messages on this
*/
func handler(c net.Conn) {
log.Printf("Client connected [%s]", c.RemoteAddr().Network())
buff := make([]byte, 512)
Expand Down

0 comments on commit 1957b98

Please sign in to comment.