From b0ddfd2d76e3d3fca043419215bb3da2b2b6c59b Mon Sep 17 00:00:00 2001 From: Divya Darshana Date: Tue, 31 Dec 2024 10:27:19 +0530 Subject: [PATCH 01/13] replacing uri in logs with host for mongo --- pkg/gofr/datasource/mongo/mongo.go | 8 ++++---- pkg/gofr/datasource/mongo/mongo_test.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/gofr/datasource/mongo/mongo.go b/pkg/gofr/datasource/mongo/mongo.go index cd74193f6..2562cba4d 100644 --- a/pkg/gofr/datasource/mongo/mongo.go +++ b/pkg/gofr/datasource/mongo/mongo.go @@ -83,7 +83,7 @@ func (c *Client) UseTracer(tracer any) { // Connect establishes a connection to MongoDB and registers metrics using the provided configuration when the client was Created. func (c *Client) Connect() { - c.logger.Debugf("connecting to MongoDB at %v to database %v", c.config.URI, c.config.Database) + c.logger.Debugf("connecting to MongoDB at %v to database %v", c.config.Host, c.config.Database) uri := c.config.URI @@ -108,18 +108,18 @@ func (c *Client) Connect() { } if err = m.Ping(ctx, nil); err != nil { - c.logger.Errorf("could not connect to mongoDB at %v due to err: %v", c.config.URI, err) + c.logger.Errorf("could not connect to mongoDB at %v due to err: %v", c.config.Host, err) return } - c.logger.Logf("connected to mongoDB successfully at %v to database %v", c.config.URI, c.config.Database) + c.logger.Logf("connected to mongoDB successfully at %v to database %v", c.config.Host, c.config.Database) mongoBuckets := []float64{.05, .075, .1, .125, .15, .2, .3, .5, .75, 1, 2, 3, 4, 5, 7.5, 10} c.metrics.NewHistogram("app_mongo_stats", "Response time of MONGO queries in milliseconds.", mongoBuckets...) c.Database = m.Database(c.config.Database) - c.logger.Logf("connected to MongoDB at %v to database %v", uri, c.Database) + c.logger.Logf("connected to MongoDB at %v to database %v", c.config.Host, c.Database) } // InsertOne inserts a single document into the specified collection. diff --git a/pkg/gofr/datasource/mongo/mongo_test.go b/pkg/gofr/datasource/mongo/mongo_test.go index e42c63e73..647e430ba 100644 --- a/pkg/gofr/datasource/mongo/mongo_test.go +++ b/pkg/gofr/datasource/mongo/mongo_test.go @@ -46,7 +46,7 @@ func Test_NewMongoClientError(t *testing.T) { logger.EXPECT().Debugf("connecting to MongoDB at %v to database %v", "mongo", "test") logger.EXPECT().Errorf("error while connecting to MongoDB, err:%v", gomock.Any()) - client := New(Config{URI: "mongo", Database: "test"}) + client := New(Config{Host: "mongo", Database: "test"}) client.UseLogger(logger) client.UseMetrics(metrics) client.Connect() From c268d37c9e1d2effa1611a7a10d55bc6179e0dbe Mon Sep 17 00:00:00 2001 From: Divya Darshana Date: Tue, 31 Dec 2024 10:57:51 +0530 Subject: [PATCH 02/13] adding check to extract host from uri --- pkg/gofr/datasource/mongo/mongo.go | 29 +++++++++++++++-- pkg/gofr/datasource/mongo/mongo_test.go | 41 +++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/pkg/gofr/datasource/mongo/mongo.go b/pkg/gofr/datasource/mongo/mongo.go index 2562cba4d..5fc1d14c3 100644 --- a/pkg/gofr/datasource/mongo/mongo.go +++ b/pkg/gofr/datasource/mongo/mongo.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "regexp" "time" "go.opentelemetry.io/otel/attribute" @@ -83,6 +84,7 @@ func (c *Client) UseTracer(tracer any) { // Connect establishes a connection to MongoDB and registers metrics using the provided configuration when the client was Created. func (c *Client) Connect() { + var host string c.logger.Debugf("connecting to MongoDB at %v to database %v", c.config.Host, c.config.Database) uri := c.config.URI @@ -90,6 +92,14 @@ func (c *Client) Connect() { if uri == "" { uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/%s?authSource=admin", c.config.User, c.config.Password, c.config.Host, c.config.Port, c.config.Database) + + host = c.config.Host + } else { + host = getDBHost(uri) + + if host == "" { + c.logger.Debug("failed to parse URI: incorrect format provided") + } } timeout := c.config.ConnectionTimeout @@ -108,18 +118,31 @@ func (c *Client) Connect() { } if err = m.Ping(ctx, nil); err != nil { - c.logger.Errorf("could not connect to mongoDB at %v due to err: %v", c.config.Host, err) + c.logger.Errorf("could not connect to mongoDB at %v due to err: %v", host, err) return } - c.logger.Logf("connected to mongoDB successfully at %v to database %v", c.config.Host, c.config.Database) + c.logger.Logf("connected to mongoDB successfully at %v to database %v", host, c.config.Database) mongoBuckets := []float64{.05, .075, .1, .125, .15, .2, .3, .5, .75, 1, 2, 3, 4, 5, 7.5, 10} c.metrics.NewHistogram("app_mongo_stats", "Response time of MONGO queries in milliseconds.", mongoBuckets...) c.Database = m.Database(c.config.Database) - c.logger.Logf("connected to MongoDB at %v to database %v", c.config.Host, c.Database) + c.logger.Logf("connected to MongoDB at %v to database %v", host, c.Database) +} + +func getDBHost(uri string) (host string) { + // Define a regular expression to extract the host + re := regexp.MustCompile(`mongodb://.*?:.*?@(.*?):\d+/.*`) + + matches := re.FindStringSubmatch(uri) + + if len(matches) > 1 { + host = matches[1] + } + + return } // InsertOne inserts a single document into the specified collection. diff --git a/pkg/gofr/datasource/mongo/mongo_test.go b/pkg/gofr/datasource/mongo/mongo_test.go index 647e430ba..412c912ec 100644 --- a/pkg/gofr/datasource/mongo/mongo_test.go +++ b/pkg/gofr/datasource/mongo/mongo_test.go @@ -36,6 +36,47 @@ func Test_NewMongoClient(t *testing.T) { assert.NotNil(t, client) } +func TestGetDBHost(t *testing.T) { + tests := []struct { + name string + uri string + expected string + }{ + { + name: "Valid URI with host and port", + uri: "mongodb://username:password@hostname:27017/database?authSource=admin", + expected: "hostname", + }, + { + name: "Valid URI with IP address as host", + uri: "mongodb://username:password@192.168.1.1:27017/database?authSource=admin", + expected: "192.168.1.1", + }, + { + name: "Invalid URI with no host", + uri: "mongodb://username:password@:27017/database?authSource=admin", + expected: "", + }, + { + name: "Empty URI", + uri: "", + expected: "", + }, + { + name: "Malformed URI", + uri: "mongodb:/username:password@hostname:27017/database?authSource=admin", + expected: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := getDBHost(tt.uri) + assert.Equal(t, tt.expected, result, "Test case: %s", tt.name) + }) + } +} + func Test_NewMongoClientError(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() From 244272b70c86fabddf0d22edaf78113119f2ca00 Mon Sep 17 00:00:00 2001 From: Divya Darshana Date: Tue, 31 Dec 2024 10:59:51 +0530 Subject: [PATCH 03/13] minor fix --- pkg/gofr/datasource/mongo/mongo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/gofr/datasource/mongo/mongo.go b/pkg/gofr/datasource/mongo/mongo.go index 5fc1d14c3..ed1b28738 100644 --- a/pkg/gofr/datasource/mongo/mongo.go +++ b/pkg/gofr/datasource/mongo/mongo.go @@ -133,7 +133,7 @@ func (c *Client) Connect() { } func getDBHost(uri string) (host string) { - // Define a regular expression to extract the host + // regular expression to extract the host re := regexp.MustCompile(`mongodb://.*?:.*?@(.*?):\d+/.*`) matches := re.FindStringSubmatch(uri) From f2dcb4ae90e7153053f62f6620c4994502260d44 Mon Sep 17 00:00:00 2001 From: Divya Darshana Date: Tue, 31 Dec 2024 11:11:08 +0530 Subject: [PATCH 04/13] fixing linters --- pkg/gofr/datasource/mongo/mongo.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/gofr/datasource/mongo/mongo.go b/pkg/gofr/datasource/mongo/mongo.go index ed1b28738..62ae73224 100644 --- a/pkg/gofr/datasource/mongo/mongo.go +++ b/pkg/gofr/datasource/mongo/mongo.go @@ -85,6 +85,7 @@ func (c *Client) UseTracer(tracer any) { // Connect establishes a connection to MongoDB and registers metrics using the provided configuration when the client was Created. func (c *Client) Connect() { var host string + c.logger.Debugf("connecting to MongoDB at %v to database %v", c.config.Host, c.config.Database) uri := c.config.URI @@ -142,7 +143,7 @@ func getDBHost(uri string) (host string) { host = matches[1] } - return + return host } // InsertOne inserts a single document into the specified collection. From 3dd2edfba92bc861d19c372bdbac4e426bcaaf56 Mon Sep 17 00:00:00 2001 From: Divya Darshana Date: Thu, 2 Jan 2025 10:46:37 +0530 Subject: [PATCH 05/13] review suggestions --- pkg/gofr/datasource/mongo/mongo.go | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/pkg/gofr/datasource/mongo/mongo.go b/pkg/gofr/datasource/mongo/mongo.go index 62ae73224..ab0e109a9 100644 --- a/pkg/gofr/datasource/mongo/mongo.go +++ b/pkg/gofr/datasource/mongo/mongo.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "regexp" + "net/url" "time" "go.opentelemetry.io/otel/attribute" @@ -134,16 +134,12 @@ func (c *Client) Connect() { } func getDBHost(uri string) (host string) { - // regular expression to extract the host - re := regexp.MustCompile(`mongodb://.*?:.*?@(.*?):\d+/.*`) - - matches := re.FindStringSubmatch(uri) - - if len(matches) > 1 { - host = matches[1] + parsedURL, err := url.Parse(uri) + if err != nil { + return "" } - return host + return parsedURL.Hostname() } // InsertOne inserts a single document into the specified collection. From 917bcab4df8f49075bdb95f400e2933ae1128334 Mon Sep 17 00:00:00 2001 From: Divya Darshana Date: Fri, 3 Jan 2025 14:52:19 +0530 Subject: [PATCH 06/13] review suggestions --- pkg/gofr/datasource/mongo/mongo.go | 67 ++++++++---- pkg/gofr/datasource/mongo/mongo_test.go | 138 ++++++++++++++++++++---- 2 files changed, 165 insertions(+), 40 deletions(-) diff --git a/pkg/gofr/datasource/mongo/mongo.go b/pkg/gofr/datasource/mongo/mongo.go index ab0e109a9..b098e1a10 100644 --- a/pkg/gofr/datasource/mongo/mongo.go +++ b/pkg/gofr/datasource/mongo/mongo.go @@ -40,7 +40,12 @@ type Config struct { const defaultTimeout = 5 * time.Second -var errStatusDown = errors.New("status down") +var ( + errStatusDown = errors.New("status down") + errMissingField = errors.New("missing required field in config") + errIncorrectURI = errors.New("incorrect URI for mongo") + errParseHost = errors.New("failed to parse host from MongoDB URI") +) /* Developer Note: We could have accepted logger and metrics as part of the factory function `New`, but when mongo driver is @@ -84,25 +89,14 @@ func (c *Client) UseTracer(tracer any) { // Connect establishes a connection to MongoDB and registers metrics using the provided configuration when the client was Created. func (c *Client) Connect() { - var host string + uri, host, err := generateMongoURI(c.config) + if err != nil { + c.logger.Errorf("error generating mongo URI: %v", err) + return + } c.logger.Debugf("connecting to MongoDB at %v to database %v", c.config.Host, c.config.Database) - uri := c.config.URI - - if uri == "" { - uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/%s?authSource=admin", - c.config.User, c.config.Password, c.config.Host, c.config.Port, c.config.Database) - - host = c.config.Host - } else { - host = getDBHost(uri) - - if host == "" { - c.logger.Debug("failed to parse URI: incorrect format provided") - } - } - timeout := c.config.ConnectionTimeout if timeout == 0 { timeout = defaultTimeout @@ -133,13 +127,46 @@ func (c *Client) Connect() { c.logger.Logf("connected to MongoDB at %v to database %v", host, c.Database) } -func getDBHost(uri string) (host string) { +func generateMongoURI(config *Config) (uri, host string, err error) { + if config.URI != "" { + host, err = getDBHost(config.URI) + if err != nil || host == "" { + return "", "", err + } + + return config.URI, host, nil + } + + switch { + case config.Host == "": + return "", "", fmt.Errorf("%w: host is empty", errMissingField) + case config.Port == 0: + return "", "", fmt.Errorf("%w: port is empty", errMissingField) + case config.Database == "": + return "", "", fmt.Errorf("%w: database is empty", errMissingField) + } + + uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/%s?authSource=admin", + config.User, config.Password, config.Host, config.Port, config.Database) + + return uri, config.Host, nil +} + +func getDBHost(uri string) (host string, err error) { parsedURL, err := url.Parse(uri) if err != nil { - return "" + return "", err + } + + if parsedURL.Scheme != "mongodb" { + return "", errIncorrectURI + } + + if parsedURL.Hostname() == "" { + return "", errParseHost } - return parsedURL.Hostname() + return parsedURL.Hostname(), nil } // InsertOne inserts a single document into the specified collection. diff --git a/pkg/gofr/datasource/mongo/mongo_test.go b/pkg/gofr/datasource/mongo/mongo_test.go index 412c912ec..6b1bc6587 100644 --- a/pkg/gofr/datasource/mongo/mongo_test.go +++ b/pkg/gofr/datasource/mongo/mongo_test.go @@ -36,43 +36,141 @@ func Test_NewMongoClient(t *testing.T) { assert.NotNil(t, client) } +func TestGenerateMongoURI(t *testing.T) { + tests := []struct { + name string + config Config + expectedURI string + expectedHost string + expectedError string + }{ + { + name: "Valid Config", + config: Config{ + User: "admin", + Password: "password", + Host: "localhost", + Port: 27017, + Database: "mydb", + }, + expectedURI: "mongodb://admin:password@localhost:27017/mydb?authSource=admin", + expectedHost: "localhost", + expectedError: "", + }, + { + name: "Predefined URI", + config: Config{ + URI: "mongodb://admin:password@localhost:27017/mydb?authSource=admin", + }, + expectedURI: "mongodb://admin:password@localhost:27017/mydb?authSource=admin", + expectedHost: "localhost", + expectedError: "", + }, + { + name: "Empty Host", + config: Config{ + User: "admin", + Password: "password", + Port: 27017, + Database: "mydb", + }, + expectedURI: "", + expectedHost: "", + expectedError: "missing required field in config: host is empty", + }, + { + name: "Invalid Port", + config: Config{ + User: "admin", + Password: "password", + Host: "localhost", + Database: "mydb", + }, + expectedURI: "", + expectedHost: "", + expectedError: "missing required field in config: port is empty", + }, + { + name: "Empty Database", + config: Config{ + User: "admin", + Password: "password", + Host: "localhost", + Port: 27017, + }, + expectedURI: "", + expectedHost: "", + expectedError: "missing required field in config: database is empty", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + client := Client{config: &test.config} + uri, host, err := generateMongoURI(client.config) + + assert.Equal(t, test.expectedURI, uri, "Unexpected URI") + assert.Equal(t, test.expectedHost, host, "Unexpected Host") + + if test.expectedError != "" { + assert.EqualError(t, err, test.expectedError, "Unexpected error message") + } else { + assert.NoError(t, err, "Expected no error but got one") + } + }) + } +} + func TestGetDBHost(t *testing.T) { tests := []struct { - name string - uri string - expected string + name string + uri string + expected string + expectedErr string }{ { - name: "Valid URI with host and port", - uri: "mongodb://username:password@hostname:27017/database?authSource=admin", - expected: "hostname", + name: "Valid URI with host and port", + uri: "mongodb://username:password@hostname:27017/database?authSource=admin", + expected: "hostname", + expectedErr: "", }, { - name: "Valid URI with IP address as host", - uri: "mongodb://username:password@192.168.1.1:27017/database?authSource=admin", - expected: "192.168.1.1", + name: "Valid URI with IP address as host", + uri: "mongodb://username:password@192.168.1.1:27017/database?authSource=admin", + expected: "192.168.1.1", + expectedErr: "", }, { - name: "Invalid URI with no host", - uri: "mongodb://username:password@:27017/database?authSource=admin", - expected: "", + name: "Invalid URI with no host", + uri: "mongodb://username:password@:27017/database?authSource=admin", + expected: "", + expectedErr: "failed to parse host from MongoDB URI", }, { - name: "Empty URI", - uri: "", - expected: "", + name: "Empty URI", + uri: "", + expected: "", + expectedErr: "incorrect URI for mongo", }, { - name: "Malformed URI", - uri: "mongodb:/username:password@hostname:27017/database?authSource=admin", - expected: "", + name: "Malformed URI", + uri: "mongodb:/username:password@hostname:27017/database?authSource=admin", + expected: "", + expectedErr: "failed to parse host from MongoDB URI", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - result := getDBHost(tt.uri) - assert.Equal(t, tt.expected, result, "Test case: %s", tt.name) + host, err := getDBHost(tt.uri) + + assert.Equal(t, tt.expected, host, "Test case: %s", tt.name) + + if tt.expectedErr == "" { + assert.NoError(t, err, "Test case: %s", tt.name) + } else { + assert.EqualError(t, err, tt.expectedErr, "Test case: %s", tt.name) + } }) } } From 6ef1b5013cebe1a75455b75f68de150dc15bd3e3 Mon Sep 17 00:00:00 2001 From: Divya Darshana Date: Fri, 3 Jan 2025 14:58:45 +0530 Subject: [PATCH 07/13] fixing tests --- pkg/gofr/datasource/mongo/mongo_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/gofr/datasource/mongo/mongo_test.go b/pkg/gofr/datasource/mongo/mongo_test.go index 6b1bc6587..36e963a8f 100644 --- a/pkg/gofr/datasource/mongo/mongo_test.go +++ b/pkg/gofr/datasource/mongo/mongo_test.go @@ -182,8 +182,7 @@ func Test_NewMongoClientError(t *testing.T) { metrics := NewMockMetrics(ctrl) logger := NewMockLogger(ctrl) - logger.EXPECT().Debugf("connecting to MongoDB at %v to database %v", "mongo", "test") - logger.EXPECT().Errorf("error while connecting to MongoDB, err:%v", gomock.Any()) + logger.EXPECT().Errorf("error generating mongo URI: %v", gomock.Any()) client := New(Config{Host: "mongo", Database: "test"}) client.UseLogger(logger) From cff1ec5a2400438b688b8fb8a5a5dd17d8025eef Mon Sep 17 00:00:00 2001 From: Divya Darshana Date: Mon, 6 Jan 2025 13:07:19 +0530 Subject: [PATCH 08/13] implementing review suggestions --- pkg/gofr/datasource/mongo/mongo.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/pkg/gofr/datasource/mongo/mongo.go b/pkg/gofr/datasource/mongo/mongo.go index b098e1a10..1e07456e0 100644 --- a/pkg/gofr/datasource/mongo/mongo.go +++ b/pkg/gofr/datasource/mongo/mongo.go @@ -130,7 +130,7 @@ func (c *Client) Connect() { func generateMongoURI(config *Config) (uri, host string, err error) { if config.URI != "" { host, err = getDBHost(config.URI) - if err != nil || host == "" { + if err != nil { return "", "", err } @@ -146,10 +146,21 @@ func generateMongoURI(config *Config) (uri, host string, err error) { return "", "", fmt.Errorf("%w: database is empty", errMissingField) } - uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/%s?authSource=admin", - config.User, config.Password, config.Host, config.Port, config.Database) + u := &url.URL{ + Scheme: "mongodb", + Host: fmt.Sprintf("%s:%d", config.Host, config.Port), + Path: "/" + url.PathEscape(config.Database), + } + + if config.User != "" && config.Password != "" { + u.User = url.UserPassword(url.QueryEscape(config.User), url.QueryEscape(config.Password)) + } + + q := u.Query() + q.Set("authSource", "admin") + u.RawQuery = q.Encode() - return uri, config.Host, nil + return u.String(), u.Hostname(), nil } func getDBHost(uri string) (host string, err error) { From c8877d47ee48a31bb54adcc9d720dfc3cd84611f Mon Sep 17 00:00:00 2001 From: Divya Darshana Date: Tue, 7 Jan 2025 11:02:08 +0530 Subject: [PATCH 09/13] minor fix - review suggestion --- pkg/gofr/datasource/mongo/mongo.go | 10 +++++----- pkg/gofr/datasource/mongo/mongo_test.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/gofr/datasource/mongo/mongo.go b/pkg/gofr/datasource/mongo/mongo.go index 1e07456e0..801d85fc4 100644 --- a/pkg/gofr/datasource/mongo/mongo.go +++ b/pkg/gofr/datasource/mongo/mongo.go @@ -43,7 +43,7 @@ const defaultTimeout = 5 * time.Second var ( errStatusDown = errors.New("status down") errMissingField = errors.New("missing required field in config") - errIncorrectURI = errors.New("incorrect URI for mongo") + errIncorrectURI = errors.New("incorrect URI for MongoDB") errParseHost = errors.New("failed to parse host from MongoDB URI") ) @@ -91,7 +91,7 @@ func (c *Client) UseTracer(tracer any) { func (c *Client) Connect() { uri, host, err := generateMongoURI(c.config) if err != nil { - c.logger.Errorf("error generating mongo URI: %v", err) + c.logger.Errorf("error generating MongoDB URI: %v", err) return } @@ -113,14 +113,14 @@ func (c *Client) Connect() { } if err = m.Ping(ctx, nil); err != nil { - c.logger.Errorf("could not connect to mongoDB at %v due to err: %v", host, err) + c.logger.Errorf("could not connect to MongoDB at %v due to err: %v", host, err) return } - c.logger.Logf("connected to mongoDB successfully at %v to database %v", host, c.config.Database) + c.logger.Logf("connected to MongoDB successfully at %v to database %v", host, c.config.Database) mongoBuckets := []float64{.05, .075, .1, .125, .15, .2, .3, .5, .75, 1, 2, 3, 4, 5, 7.5, 10} - c.metrics.NewHistogram("app_mongo_stats", "Response time of MONGO queries in milliseconds.", mongoBuckets...) + c.metrics.NewHistogram("app_mongo_stats", "Response time of MongoDB queries in milliseconds.", mongoBuckets...) c.Database = m.Database(c.config.Database) diff --git a/pkg/gofr/datasource/mongo/mongo_test.go b/pkg/gofr/datasource/mongo/mongo_test.go index 36e963a8f..f1ebfa268 100644 --- a/pkg/gofr/datasource/mongo/mongo_test.go +++ b/pkg/gofr/datasource/mongo/mongo_test.go @@ -150,7 +150,7 @@ func TestGetDBHost(t *testing.T) { name: "Empty URI", uri: "", expected: "", - expectedErr: "incorrect URI for mongo", + expectedErr: "incorrect URI for MongoDB", }, { name: "Malformed URI", @@ -182,7 +182,7 @@ func Test_NewMongoClientError(t *testing.T) { metrics := NewMockMetrics(ctrl) logger := NewMockLogger(ctrl) - logger.EXPECT().Errorf("error generating mongo URI: %v", gomock.Any()) + logger.EXPECT().Errorf("error generating MongoDB URI: %v", gomock.Any()) client := New(Config{Host: "mongo", Database: "test"}) client.UseLogger(logger) From 23bb6e5cca05227592991d5ae149f1d484d036fe Mon Sep 17 00:00:00 2001 From: Raramuri Date: Tue, 7 Jan 2025 22:28:45 +0530 Subject: [PATCH 10/13] minor review fix --- pkg/gofr/datasource/mongo/mongo.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/gofr/datasource/mongo/mongo.go b/pkg/gofr/datasource/mongo/mongo.go index 801d85fc4..5a0d89dca 100644 --- a/pkg/gofr/datasource/mongo/mongo.go +++ b/pkg/gofr/datasource/mongo/mongo.go @@ -4,7 +4,9 @@ import ( "context" "errors" "fmt" + "net" "net/url" + "strconv" "time" "go.opentelemetry.io/otel/attribute" @@ -148,7 +150,7 @@ func generateMongoURI(config *Config) (uri, host string, err error) { u := &url.URL{ Scheme: "mongodb", - Host: fmt.Sprintf("%s:%d", config.Host, config.Port), + Host: net.JoinHostPort(config.Host, strconv.Itoa(int(config.Port))), Path: "/" + url.PathEscape(config.Database), } From 6ad8948f7e6c64883db6530a3071b9cd42ab18f9 Mon Sep 17 00:00:00 2001 From: Raramuri Date: Wed, 8 Jan 2025 10:54:33 +0530 Subject: [PATCH 11/13] linter fix --- pkg/gofr/datasource/mongo/mongo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/gofr/datasource/mongo/mongo.go b/pkg/gofr/datasource/mongo/mongo.go index 5a0d89dca..cd6ddda88 100644 --- a/pkg/gofr/datasource/mongo/mongo.go +++ b/pkg/gofr/datasource/mongo/mongo.go @@ -150,7 +150,7 @@ func generateMongoURI(config *Config) (uri, host string, err error) { u := &url.URL{ Scheme: "mongodb", - Host: net.JoinHostPort(config.Host, strconv.Itoa(int(config.Port))), + Host: net.JoinHostPort(config.Host, strconv.Itoa(config.Port)), Path: "/" + url.PathEscape(config.Database), } From c200644dc06d40249c0db685748bbf0b42c021ef Mon Sep 17 00:00:00 2001 From: Divya Darshana Date: Wed, 8 Jan 2025 12:12:57 +0530 Subject: [PATCH 12/13] review suggestions --- pkg/gofr/datasource/mongo/mongo.go | 2 +- pkg/gofr/datasource/mongo/mongo_test.go | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/pkg/gofr/datasource/mongo/mongo.go b/pkg/gofr/datasource/mongo/mongo.go index cd6ddda88..bfdf6fba4 100644 --- a/pkg/gofr/datasource/mongo/mongo.go +++ b/pkg/gofr/datasource/mongo/mongo.go @@ -166,7 +166,7 @@ func generateMongoURI(config *Config) (uri, host string, err error) { } func getDBHost(uri string) (host string, err error) { - parsedURL, err := url.Parse(uri) + parsedURL, err := url.ParseRequestURI(uri) if err != nil { return "", err } diff --git a/pkg/gofr/datasource/mongo/mongo_test.go b/pkg/gofr/datasource/mongo/mongo_test.go index f1ebfa268..85195783e 100644 --- a/pkg/gofr/datasource/mongo/mongo_test.go +++ b/pkg/gofr/datasource/mongo/mongo_test.go @@ -48,12 +48,23 @@ func TestGenerateMongoURI(t *testing.T) { name: "Valid Config", config: Config{ User: "admin", - Password: "password", + Password: "p@##word:", Host: "localhost", Port: 27017, Database: "mydb", }, - expectedURI: "mongodb://admin:password@localhost:27017/mydb?authSource=admin", + expectedURI: "mongodb://admin:p%2540%2523%2523word%253A@localhost:27017/mydb?authSource=admin", + expectedHost: "localhost", + expectedError: "", + }, + { + name: "Valid Config without authentication", + config: Config{ + Host: "localhost", + Port: 27017, + Database: "mydb", + }, + expectedURI: "mongodb://localhost:27017/mydb?authSource=admin", expectedHost: "localhost", expectedError: "", }, @@ -150,7 +161,7 @@ func TestGetDBHost(t *testing.T) { name: "Empty URI", uri: "", expected: "", - expectedErr: "incorrect URI for MongoDB", + expectedErr: "parse \"\": empty url", }, { name: "Malformed URI", From f21a9a452df0efc12d0fa60913a467b35100e009 Mon Sep 17 00:00:00 2001 From: Divya Darshana Date: Wed, 8 Jan 2025 12:22:27 +0530 Subject: [PATCH 13/13] updating go mod to fix security vulnerability issue --- pkg/gofr/datasource/mongo/go.mod | 23 +++++++++------- pkg/gofr/datasource/mongo/go.sum | 47 +++++++++++++++++++------------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/pkg/gofr/datasource/mongo/go.mod b/pkg/gofr/datasource/mongo/go.mod index a77c4b281..4f3e93db3 100644 --- a/pkg/gofr/datasource/mongo/go.mod +++ b/pkg/gofr/datasource/mongo/go.mod @@ -1,13 +1,15 @@ module gofr.dev/pkg/gofr/datasource/mongo -go 1.22 +go 1.22.0 + +toolchain go1.23.4 require ( - github.com/stretchr/testify v1.9.0 - go.mongodb.org/mongo-driver v1.15.1 - go.opentelemetry.io/otel v1.30.0 - go.opentelemetry.io/otel/trace v1.30.0 - go.uber.org/mock v0.4.0 + github.com/stretchr/testify v1.10.0 + go.mongodb.org/mongo-driver v1.17.2 + go.opentelemetry.io/otel v1.33.0 + go.opentelemetry.io/otel/trace v1.33.0 + go.uber.org/mock v0.5.0 ) require ( @@ -15,15 +17,16 @@ require ( github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/montanaflynn/stats v0.7.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect - github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76 // indirect - go.opentelemetry.io/otel/metric v1.30.0 // indirect - golang.org/x/crypto v0.31.0 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/otel/metric v1.33.0 // indirect + golang.org/x/crypto v0.32.0 // indirect golang.org/x/sync v0.10.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/pkg/gofr/datasource/mongo/go.sum b/pkg/gofr/datasource/mongo/go.sum index 8514ae623..2491cb773 100644 --- a/pkg/gofr/datasource/mongo/go.sum +++ b/pkg/gofr/datasource/mongo/go.sum @@ -9,37 +9,45 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76 h1:tBiBTKHnIjovYoLX/TPkcf+OjqqKGQrPtGT3Foz+Pgo= -github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76/go.mod h1:SQliXeA7Dhkt//vS29v3zpbEwoa+zb2Cn5xj5uO4K5U= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/mongo-driver v1.15.1 h1:l+RvoUOoMXFmADTLfYDm7On9dRm7p4T80/lEQM+r7HU= -go.mongodb.org/mongo-driver v1.15.1/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793SqyhzM= +go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= +go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= +go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= +go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= +go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= +go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -65,7 +73,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=