You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ti...@apache.org on 2021/02/10 02:13:33 UTC

[servicecomb-service-center] branch master updated: add ensure index and validate (#855)

This is an automated email from the ASF dual-hosted git repository.

tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-service-center.git


The following commit(s) were added to refs/heads/master by this push:
     new d55296e  add ensure index and validate (#855)
d55296e is described below

commit d55296e7a0770af8af63579ed1d2369f628a335b
Author: panqian <pq...@163.com>
AuthorDate: Wed Feb 10 10:13:25 2021 +0800

    add ensure index and validate (#855)
---
 datasource/mongo/client/errortypes.go |   3 +-
 datasource/mongo/client/mongo.go      |   4 +
 datasource/mongo/mongo.go             | 157 +++++++++++++++++++++++-----------
 datasource/mongo/util.go              |  14 +++
 4 files changed, 128 insertions(+), 50 deletions(-)

diff --git a/datasource/mongo/client/errortypes.go b/datasource/mongo/client/errortypes.go
index 3c86420..423401b 100644
--- a/datasource/mongo/client/errortypes.go
+++ b/datasource/mongo/client/errortypes.go
@@ -26,7 +26,8 @@ var (
 )
 
 const (
-	DuplicateKey = 11000
+	DuplicateKey      = 11000
+	CollectionsExists = 48
 )
 
 func IsDuplicateKey(err error) bool {
diff --git a/datasource/mongo/client/mongo.go b/datasource/mongo/client/mongo.go
index 8f23eee..b0739be 100644
--- a/datasource/mongo/client/mongo.go
+++ b/datasource/mongo/client/mongo.go
@@ -245,3 +245,7 @@ func (mc *MongoClient) DocDelete(ctx context.Context, table string, filter inter
 func (mc *MongoClient) DeleteOne(ctx context.Context, Table string, filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
 	return mc.db.Collection(Table).DeleteOne(ctx, filter, opts...)
 }
+
+func (mc *MongoClient) GetDB() *mongo.Database {
+	return mc.db
+}
diff --git a/datasource/mongo/mongo.go b/datasource/mongo/mongo.go
index 4ce4cdc..731704c 100644
--- a/datasource/mongo/mongo.go
+++ b/datasource/mongo/mongo.go
@@ -29,7 +29,6 @@ import (
 	"github.com/go-chassis/go-chassis/v2/storage"
 	"go.mongodb.org/mongo-driver/mongo"
 	"go.mongodb.org/mongo-driver/mongo/options"
-	"go.mongodb.org/mongo-driver/x/bsonx"
 )
 
 func init() {
@@ -69,11 +68,9 @@ func (ds *DataSource) initialize() error {
 	if err != nil {
 		return err
 	}
-	err = ds.createIndexes()
-	if err != nil {
-		return err
-	}
-	// init mongo cache
+	// create db index and validator
+	EnsureDB()
+	// init cache
 	ds.initStore()
 	return nil
 }
@@ -100,64 +97,126 @@ func (ds *DataSource) initClient() error {
 	}
 }
 
-//{Key: StringBuilder([]string{ColumnService, ColumnAlias}), Value: bsonx.Int32(1)}
-func (ds *DataSource) createIndexes() (err error) {
-	err = client.GetMongoClient().CreateIndexes(context.TODO(), CollectionService, []mongo.IndexModel{{
-		Keys:    bsonx.Doc{{Key: StringBuilder([]string{ColumnService, ColumnServiceID}), Value: bsonx.Int32(1)}},
-		Options: options.Index().SetUnique(true),
-	}, {
-		Keys: bsonx.Doc{{Key: StringBuilder([]string{ColumnService, ColumnAppID}), Value: bsonx.Int32(1)},
-			{Key: StringBuilder([]string{ColumnService, ColumnServiceName}), Value: bsonx.Int32(1)},
-			{Key: StringBuilder([]string{ColumnService, ColumnEnv}), Value: bsonx.Int32(1)},
-			{Key: StringBuilder([]string{ColumnService, ColumnVersion}), Value: bsonx.Int32(1)},
-			{Key: ColumnDomain, Value: bsonx.Int32(1)},
-			{Key: ColumnProject, Value: bsonx.Int32(1)},
-		},
-		Options: options.Index().SetUnique(true),
-	}})
+func EnsureDB() {
+	EnsureService()
+	EnsureInstance()
+	EnsureRule()
+	EnsureSchema()
+	EnsureDep()
+}
+
+func EnsureService() {
+	err := client.GetMongoClient().GetDB().CreateCollection(context.Background(), CollectionService, options.CreateCollection().SetValidator(nil))
+	wrapCreateCollectionError(err)
+
+	serviceIDIndex := BuildIndexDoc(
+		StringBuilder([]string{ColumnService, ColumnServiceID}))
+	serviceIDIndex.Options = options.Index().SetUnique(true)
+
+	serviceIndex := BuildIndexDoc(
+		StringBuilder([]string{ColumnService, ColumnAppID}),
+		StringBuilder([]string{ColumnService, ColumnServiceName}),
+		StringBuilder([]string{ColumnService, ColumnEnv}),
+		StringBuilder([]string{ColumnService, ColumnVersion}),
+		ColumnDomain,
+		ColumnProject)
+	serviceIndex.Options = options.Index().SetUnique(true)
+
+	var serviceIndexs []mongo.IndexModel
+	serviceIndexs = append(serviceIndexs, serviceIDIndex, serviceIndex)
+
+	err = client.GetMongoClient().CreateIndexes(context.Background(), CollectionService, serviceIndexs)
 	if err != nil {
+		log.Fatal("failed to create service collection indexs", err)
 		return
 	}
-	err = client.GetMongoClient().CreateIndexes(context.TODO(), CollectionInstance, []mongo.IndexModel{{
-		Keys:    bsonx.Doc{{Key: StringBuilder([]string{ColumnInstance, ColumnInstanceID}), Value: bsonx.Int32(1)}},
-		Options: options.Index().SetUnique(true),
-	}, {
-		Keys: bsonx.Doc{{Key: StringBuilder([]string{ColumnInstanceID, ColumnServiceID}), Value: bsonx.Int32(1)}},
-	}, {
-		Keys:    bsonx.Doc{{Key: ColumnRefreshTime, Value: bsonx.Int32(1)}},
-		Options: options.Index().SetExpireAfterSeconds(60),
-	}})
+}
+
+func EnsureInstance() {
+	err := client.GetMongoClient().GetDB().CreateCollection(context.Background(), CollectionInstance, options.CreateCollection().SetValidator(nil))
+	wrapCreateCollectionError(err)
+
+	instanceIndex := BuildIndexDoc(ColumnRefreshTime)
+	instanceIndex.Options = options.Index().SetExpireAfterSeconds(60)
+
+	instanceServiceIndex := BuildIndexDoc(StringBuilder([]string{ColumnInstanceID, ColumnServiceID}))
+
+	var instanceIndexs []mongo.IndexModel
+	instanceIndexs = append(instanceIndexs, instanceIndex, instanceServiceIndex)
+
+	err = client.GetMongoClient().CreateIndexes(context.Background(), CollectionInstance, instanceIndexs)
 	if err != nil {
+		log.Fatal("failed to create instance collection indexs", err)
 		return
 	}
-	err = client.GetMongoClient().CreateIndexes(context.TODO(), CollectionSchema, []mongo.IndexModel{{
-		Keys: bsonx.Doc{
-			{Key: ColumnDomain, Value: bsonx.Int32(1)},
-			{Key: ColumnProject, Value: bsonx.Int32(1)},
-			{Key: ColumnServiceID, Value: bsonx.Int32(1)}},
-	}})
+}
+
+func EnsureSchema() {
+	err := client.GetMongoClient().GetDB().CreateCollection(context.Background(), CollectionSchema, options.CreateCollection().SetValidator(nil))
+	wrapCreateCollectionError(err)
+
+	schemaServiceIndex := BuildIndexDoc(
+		ColumnDomain,
+		ColumnProject,
+		ColumnServiceID)
+
+	var schemaIndexs []mongo.IndexModel
+	schemaIndexs = append(schemaIndexs, schemaServiceIndex)
+
+	err = client.GetMongoClient().CreateIndexes(context.Background(), CollectionSchema, schemaIndexs)
 	if err != nil {
+		log.Fatal("failed to create schema collection indexs", err)
 		return
 	}
-	err = client.GetMongoClient().CreateIndexes(context.TODO(), CollectionRule, []mongo.IndexModel{{
-		Keys: bsonx.Doc{
-			{Key: ColumnDomain, Value: bsonx.Int32(1)},
-			{Key: ColumnProject, Value: bsonx.Int32(1)},
-			{Key: ColumnServiceID, Value: bsonx.Int32(1)}},
-	}})
+}
+
+func EnsureRule() {
+	err := client.GetMongoClient().GetDB().CreateCollection(context.Background(), CollectionRule, options.CreateCollection().SetValidator(nil))
+	wrapCreateCollectionError(err)
+
+	ruleServiceIndex := BuildIndexDoc(
+		ColumnDomain,
+		ColumnProject,
+		ColumnServiceID)
+
+	var ruleIndexs []mongo.IndexModel
+	ruleIndexs = append(ruleIndexs, ruleServiceIndex)
+
+	err = client.GetMongoClient().CreateIndexes(context.Background(), CollectionRule, ruleIndexs)
 	if err != nil {
+		log.Fatal("failed to create rule collection indexs", err)
 		return
 	}
-	err = client.GetMongoClient().CreateIndexes(context.TODO(), CollectionDep, []mongo.IndexModel{{
-		Keys: bsonx.Doc{
-			{Key: ColumnDomain, Value: bsonx.Int32(1)},
-			{Key: ColumnProject, Value: bsonx.Int32(1)},
-			{Key: ColumnServiceKey, Value: bsonx.Int32(1)}},
-	}})
+}
+
+func EnsureDep() {
+	err := client.GetMongoClient().GetDB().CreateCollection(context.Background(), CollectionDep, options.CreateCollection().SetValidator(nil))
+	wrapCreateCollectionError(err)
+
+	depServiceIndex := BuildIndexDoc(
+		ColumnDomain,
+		ColumnProject,
+		ColumnServiceKey)
+
+	var depIndexs []mongo.IndexModel
+	depIndexs = append(depIndexs, depServiceIndex)
+
+	err = client.GetMongoClient().CreateIndexes(context.Background(), CollectionDep, depIndexs)
 	if err != nil {
+		log.Fatal("failed to create dep collection indexs", err)
 		return
 	}
-	return
+}
+
+func wrapCreateCollectionError(err error) {
+	if err != nil {
+		// commandError can be returned by any operation
+		cmdErr, ok := err.(mongo.CommandError)
+		if ok && cmdErr.Code == client.CollectionsExists {
+			return
+		}
+		log.Fatal("failed to create collection with validation", err)
+	}
 }
 
 func (ds *DataSource) initStore() {
diff --git a/datasource/mongo/util.go b/datasource/mongo/util.go
index 8e07918..f5654ed 100644
--- a/datasource/mongo/util.go
+++ b/datasource/mongo/util.go
@@ -21,6 +21,9 @@ import (
 	"context"
 	"strings"
 
+	"go.mongodb.org/mongo-driver/mongo"
+	"go.mongodb.org/mongo-driver/x/bsonx"
+
 	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/pkg/gopool"
 	"github.com/apache/servicecomb-service-center/pkg/util"
@@ -42,6 +45,17 @@ func (s InstanceSlice) Less(i, j int) bool {
 	return s[i].InstanceId < s[j].InstanceId
 }
 
+func BuildIndexDoc(keys ...string) mongo.IndexModel {
+	keysDoc := bsonx.Doc{}
+	for _, key := range keys {
+		keysDoc = keysDoc.Append(key, bsonx.Int32(1))
+	}
+	index := mongo.IndexModel{
+		Keys: keysDoc,
+	}
+	return index
+}
+
 func StringBuilder(data []string) string {
 	var str strings.Builder
 	for index, value := range data {