Skip to content

Commit 18e6f4e

Browse files
author
Andrei Skomorkhov
authored
Merge pull request #50 from OlgaMinyaeva/master
Mongo v.4 storage implementaton
2 parents b27f8fa + d1efe16 commit 18e6f4e

File tree

374 files changed

+75438
-30
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

374 files changed

+75438
-30
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ after_success:
1010
- bash <(curl -s https://codecov.io/bash)
1111
services:
1212
- mysql
13+
- mongodb
1314

1415
env:
15-
- TEST_MYSQL_CONNECTION="root:@(127.0.0.1:3306)/%dbname%?tx_isolation=SERIALIZABLE&parseTime=true"
16+
- TEST_MYSQL_CONNECTION="root:@(127.0.0.1:3306)/%dbname%?tx_isolation=SERIALIZABLE&parseTime=true";TEST_MONGO_CONNECTION="mongodb://localhost:27017"

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,18 @@ Configurations are stored in json files. Example:
6060
| logger.level | `debug`, `info`, `warning`, `error` | Logging level. |
6161

6262
### DB - Configuration of storage.
63-
| Option | Possible values | Description |
64-
| ----------------- | --------------- | ------------------------------------------ |
65-
| db.implementation | `mysql`, `local` | Select your favorite db, or local storage. |
66-
| db.connection | see next table | DSN for your db. |
63+
| Option | Possible values | Description |
64+
| ----------------- | ------------------------ | ------------------------------------------ |
65+
| db.implementation | `mysql`, `local`, `mongo`| Select your favorite db, or local storage. |
66+
| db.connection | see next table | DSN for your db. |
6767

6868
>Note: Note: Local (in-memory) storage does not support common session storage between grid-instances.
6969
7070
| DB implementation | DSN format |
7171
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
7272
| mysql | [spec](https://github.com/go-sql-driver/mysql#dsn-data-source-name), example `db_user:db_pass@(db_host:3306)/db_name?parseTime=true` (parseTime=true - required option) |
7373
| local | omit this property, because every instance have its own in-memory storage |
74+
| mongo | NOTE! Mongo db supports only persistent node strateg and version from 4.0, example `mongodb://localhost:27017`
7475

7576
### Statsd - Configuration of metrics(optional).
7677
| Option | Possible values | Description |

config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ type Logger struct {
5353
type DB struct {
5454
Implementation string `json:"implementation"`
5555
Connection string `json:"connection"`
56+
DbName string `json:"db_name"`
5657
}
5758

5859
// Statsd - Settings of metrics sender.

handlers/createSession.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func (h *CreateSession) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
7474
func (h *CreateSession) tryCreateSession(r *http.Request, capabilities *capabilities.Capabilities) (*proxy.ResponseWriter, error) {
7575
select {
7676
case <-r.Context().Done():
77-
err := errors.New("Request cancelled by client, " + r.Context().Err().Error())
77+
err := errors.New("Request canceled by client, " + r.Context().Err().Error())
7878
return nil, err
7979
default:
8080
}

invoke.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package main
33
import (
44
_ "github.com/go-sql-driver/mysql"
55

6+
"github.com/qa-dev/jsonwire-grid/storage/mongo"
7+
68
"github.com/qa-dev/jsonwire-grid/config"
79

810
"errors"
@@ -32,6 +34,13 @@ func invokeStorageFactory(config config.Config) (factory StorageFactoryInterface
3234
factory = new(mysql.Factory)
3335
case "local":
3436
factory = new(local.Factory)
37+
case "mongo":
38+
for _, s := range config.Grid.StrategyList {
39+
if s.Type != string(pool.NodeTypePersistent) {
40+
err = errors.New("Invalid config: Mongo db supports only persistent node strategy ")
41+
}
42+
}
43+
factory = new(mongo.Factory)
3544
default:
3645
err = errors.New("Invalid config, unknown param [db.implementation=" + config.DB.Implementation + "]")
3746
}

pool/node.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ type Node struct {
2222
// The value may depend on the strategy:
2323
// - for constant nodes ip: port
2424
// - for temporary pod.name
25-
Key string `json:"key"`
26-
Type NodeType `json:"type"`
27-
Address string `json:"address"`
28-
Status NodeStatus `json:"status"`
29-
SessionID string `json:"session_id"`
30-
Updated int64 `json:"updated"`
31-
Registered int64 `json:"registered"`
32-
CapabilitiesList []capabilities.Capabilities `json:"capabilities_list"`
25+
Key string `json:"key" bson:"key"`
26+
Type NodeType `json:"type" bson:"type"`
27+
Address string `json:"address" bson:"address"`
28+
Status NodeStatus `json:"status" bson:"status"`
29+
SessionID string `json:"session_id" bson:"session_id"`
30+
Updated int64 `json:"updated" bson:"updated"`
31+
Registered int64 `json:"registered" bson:"registered"`
32+
CapabilitiesList []capabilities.Capabilities `json:"capabilities_list" bson:"capabilities_list"`
3333
}
3434

3535
func (n *Node) String() string {

pool/strategy/kubernetes/strategy.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ func (s *Strategy) Reserve(desiredCaps capabilities.Capabilities) (pool.Node, er
4848
}
4949
node.Address = nodeAddress
5050
return *node, nil
51-
5251
}
5352

5453
func (s *Strategy) CleanUp(node pool.Node) error {

pool/strategy/persistent/strategy.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ func (s *Strategy) registerCapabilities(nodeList []pool.Node) {
112112
for _, node := range nodeList {
113113
for _, availableCaps := range node.CapabilitiesList {
114114
s.capsComparator.Register(availableCaps)
115-
116115
}
117116
}
118117
}

storage/mongo/factory.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package mongo
2+
3+
import (
4+
"context"
5+
"errors"
6+
"strconv"
7+
"strings"
8+
9+
"go.mongodb.org/mongo-driver/bson"
10+
"go.mongodb.org/mongo-driver/mongo"
11+
"go.mongodb.org/mongo-driver/mongo/options"
12+
"go.mongodb.org/mongo-driver/x/bsonx"
13+
14+
"github.com/qa-dev/jsonwire-grid/config"
15+
"github.com/qa-dev/jsonwire-grid/pool"
16+
)
17+
18+
type Factory struct {
19+
}
20+
21+
func (f *Factory) Create(cfg config.Config) (pool.StorageInterface, error) {
22+
ctx := context.Background()
23+
client, err := mongo.Connect(ctx, options.Client().ApplyURI(cfg.DB.Connection))
24+
if err != nil {
25+
panic("Database connection error: " + err.Error())
26+
}
27+
28+
err = client.Ping(ctx, nil)
29+
if err != nil {
30+
err = errors.New("Database connection not established: " + err.Error())
31+
return nil, err
32+
}
33+
34+
db := client.Database(cfg.DB.DbName)
35+
err = checkServerVersion(ctx, client)
36+
if err != nil {
37+
err = errors.New("version check error: " + err.Error())
38+
return nil, err
39+
}
40+
41+
s := NewMongoStorage(db)
42+
mod := mongo.IndexModel{
43+
Keys: bson.M{
44+
"key": 1,
45+
"address": 1,
46+
},
47+
Options: options.Index().SetUnique(true).SetName("key_address_unique"),
48+
}
49+
50+
_, err = s.collection.Indexes().CreateOne(ctx, mod)
51+
if err != nil {
52+
err = errors.New("Create index error: " + err.Error())
53+
return nil, err
54+
}
55+
56+
return s, nil
57+
}
58+
59+
func checkServerVersion(ctx context.Context, client *mongo.Client) error {
60+
serverStatus, err := client.Database("admin").RunCommand(
61+
ctx,
62+
bsonx.Doc{bsonx.Elem{Key: "serverStatus", Value: bsonx.Int32(1)}},
63+
).DecodeBytes()
64+
if err != nil {
65+
return err
66+
}
67+
68+
version, err := serverStatus.LookupErr("version")
69+
if err != nil {
70+
return err
71+
}
72+
73+
majorVersion, _ := strconv.Atoi(strings.Split(version.StringValue(), ".")[0])
74+
if majorVersion < 4 {
75+
return errors.New("mongodb version not supported: " + version.StringValue())
76+
}
77+
return nil
78+
}

storage/mongo/factory_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package mongo
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
9+
"github.com/qa-dev/jsonwire-grid/config"
10+
)
11+
12+
func TestFactory_Create_Positive(t *testing.T) {
13+
f := Factory{}
14+
storage, err := f.Create(config.Config{
15+
DB: config.DB{
16+
Connection: os.Getenv(dbConnectionStringEnvVariable),
17+
DbName: "grid",
18+
},
19+
})
20+
assert.NoError(t, err)
21+
assert.NotNil(t, storage)
22+
}

0 commit comments

Comments
 (0)