diff --git a/docs/api.yaml b/docs/api.yaml new file mode 100644 index 00000000..64f2b33b --- /dev/null +++ b/docs/api.yaml @@ -0,0 +1,260 @@ +swagger: '2.0' +info: + title: '' + version: '' +basePath: / +paths: + '/v1/{project}/kie/kv': + get: + summary: list key values by labels and key + operationId: List + parameters: + - name: project + in: path + required: true + type: string + - name: label + in: query + description: 'label pairs,for example &label=service:order&label=version:1.0.0' + type: string + - name: wait + in: query + description: 'wait until any kv changed. for example wait=5s, server will not response until 5 seconds during that time window, if any kv changed, server will return 200 and kv list, otherwise return 304 and empty body' + type: string + consumes: + - '*/*' + produces: + - application/json + - text/yaml + responses: + '200': + description: '' + schema: + $ref: '#/definitions/KVResponse' + headers: + X-RateLimit-Limit: + type: integer + description: Request limit per hour. + '304': + description: empty body + delete: + summary: 'delete key by kvID and labelID. Want better performance, give labelID' + operationId: Delete + parameters: + - name: project + in: path + required: true + type: string + - name: kvID + in: query + required: true + type: string + - name: labelID + in: query + type: string + consumes: + - '*/*' + produces: + - '*/*' + responses: + '204': + description: Delete success + '400': + description: 'Failed,check url' + '500': + description: Server error + '/v1/{project}/kie/kv/{key}': + get: + summary: get key values by key and labels + operationId: GetByKey + parameters: + - name: project + in: path + required: true + type: string + - name: key + in: path + required: true + type: string + - name: label + in: query + description: 'label pairs,for example &label=service:order&label=version:1.0.0' + type: string + consumes: + - '*/*' + produces: + - application/json + - text/yaml + responses: + '200': + description: get key value success + schema: + type: array + items: + $ref: '#/definitions/KVResponse' + '304': + description: empty body + put: + summary: create or update key value + operationId: Put + parameters: + - name: project + in: path + required: true + type: string + - name: key + in: path + required: true + type: string + - name: body + in: body + required: true + schema: + $ref: '#/definitions/v1.KVBody' + consumes: + - application/json + - text/yaml + produces: + - application/json + - text/yaml + responses: + '200': + description: '' + schema: + $ref: '#/definitions/v1.KVBody' + '/v1/{project}/kie/revision/{label_id}': + get: + summary: get all revisions by label id + operationId: GetRevisions + parameters: + - name: project + in: path + required: true + type: string + - name: label_id + in: path + required: true + type: string + - name: key + in: query + description: only return history about a specific key + type: string + consumes: + - application/json + - text/yaml + produces: + - application/json + - text/yaml + responses: + '200': + description: 'true' + schema: + type: array + items: + $ref: '#/definitions/LabelHistoryResponse' + '/v1/{project}/kie/summary': + get: + summary: 'search key values by labels combination, it returns multiple labels group' + operationId: Search + parameters: + - name: project + in: path + required: true + type: string + - name: q + in: query + description: 'the combination format is {label_key}:{label_value}+{label_key}:{label_value} for example: /v1/test/kie/kv?q=app:mall&q=app:mall+service:cart, that will query key values from 2 kinds of labels' + type: string + consumes: + - '*/*' + produces: + - application/json + - text/yaml + responses: + '200': + description: get key value success + schema: + type: array + items: + $ref: '#/definitions/KVResponse' +definitions: + KVDoc: + type: object + properties: + _id: + type: string + check: + type: string + domain: + type: string + key: + type: string + label_id: + type: string + labels: + type: object + additionalProperties: + type: string + project: + type: string + revision: + type: integer + format: int32 + value: + type: string + value_type: + type: string + KVResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/definitions/KVDoc' + label: + $ref: '#/definitions/LabelDocResponse' + num: + type: integer + format: int32 + size: + type: integer + format: int32 + total: + type: integer + format: int32 + LabelDocResponse: + type: object + properties: + label_id: + type: string + labels: + type: object + additionalProperties: + type: string + LabelHistoryResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/definitions/KVDoc' + label_id: + type: string + labels: + type: object + additionalProperties: + type: string + revision: + type: integer + format: int32 + v1.KVBody: + type: object + properties: + labels: + type: object + additionalProperties: + type: string + value: + type: string + valueType: + type: string diff --git a/go.sum b/go.sum index 255818c9..7880f675 100644 --- a/go.sum +++ b/go.sum @@ -199,6 +199,8 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/parse v0.0.0-20180914084749-c4fd10affab1 h1:pLtjGOQfSDzI174jIfMFO7mPEPqaF30skLd2j2Jh99s= +github.com/modern-go/parse v0.0.0-20180914084749-c4fd10affab1/go.mod h1:Kti0/XV668vfZFqMe804NNTNcttRa57gzBJ79alE9E8= github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= diff --git a/server/service/mongo/session/session.go b/server/service/mongo/session/session.go index 199a8bff..246e1641 100644 --- a/server/service/mongo/session/session.go +++ b/server/service/mongo/session/session.go @@ -65,8 +65,10 @@ var ( ErrViewCreation = errors.New("can not create view") ErrViewUpdate = errors.New("can not update view") + ErrViewDelete = errors.New("can not delete view") ErrViewNotExist = errors.New("view not exists") ErrViewFinding = errors.New("view search error") + ErrGetPipeline = errors.New("can not get criteria") ) var client *mongo.Client @@ -152,3 +154,35 @@ func CreateView(ctx context.Context, view, source string, pipeline mongo.Pipelin } return nil } + +//DropView deletes view +func DropView(ctx context.Context, view string) error { + err := GetDB().Collection(view).Drop(ctx) + if err != nil { + openlogging.Error(err.Error()) + return err + } + return nil +} + +//GetColInfo get collection info +func GetColInfo(ctx context.Context, name string) (*CollectionInfo, error) { + cur, err := GetDB().ListCollections(ctx, bson.M{"name": name, "type": "view"}) + if err != nil { + openlogging.Error(err.Error()) + return nil, ErrGetPipeline + } + defer cur.Close(ctx) + for cur.Next(ctx) { + openlogging.Debug(cur.Current.String()) + c := &CollectionInfo{} + err := cur.Decode(c) + if err != nil { + openlogging.Error(err.Error()) + return nil, ErrGetPipeline + } + return c, nil + break + } + return nil, ErrGetPipeline +} diff --git a/server/service/mongo/session/session_test.go b/server/service/mongo/session/session_test.go new file mode 100644 index 00000000..e0f2e032 --- /dev/null +++ b/server/service/mongo/session/session_test.go @@ -0,0 +1,29 @@ +package session_test + +import ( + "context" + "github.com/apache/servicecomb-kie/server/config" + "github.com/apache/servicecomb-kie/server/service/mongo/session" + "github.com/stretchr/testify/assert" + "go.mongodb.org/mongo-driver/bson" + "testing" +) + +func TestGetColInfo(t *testing.T) { + var err error + config.Configurations = &config.Config{DB: config.DB{URI: "mongodb://kie:123@127.0.0.1:27017/kie"}} + err = session.Init() + assert.NoError(t, err) + err = session.CreateView(context.Background(), "test_view", session.CollectionKV, []bson.D{ + {{ + "$match", + bson.D{{"domain", "default"}, {"project", "default"}}, + }}, + }) + assert.NoError(t, err) + c, err := session.GetColInfo(context.Background(), "test_view") + assert.NoError(t, err) + assert.Equal(t, "default", c.Options.Pipeline[0]["$match"]["domain"]) + err = session.DropView(context.Background(), "test_view") + assert.NoError(t, err) +} diff --git a/server/service/mongo/session/struct.go b/server/service/mongo/session/struct.go new file mode 100644 index 00000000..44a5c624 --- /dev/null +++ b/server/service/mongo/session/struct.go @@ -0,0 +1,11 @@ +package session + +//CollectionInfo is struct +type CollectionInfo struct { + Options Options `json:"options"` +} + +//Options is struct +type Options struct { + Pipeline []map[string]map[string]string `json:"pipeline"` +} diff --git a/server/service/mongo/view/view_service.go b/server/service/mongo/view/view_service.go index 98c9f9b7..9b706fba 100644 --- a/server/service/mongo/view/view_service.go +++ b/server/service/mongo/view/view_service.go @@ -41,8 +41,10 @@ func (s *Service) Create(ctx context.Context, viewDoc *model.ViewDoc, options .. return nil, session.ErrMissingDomain } var pipeline mongo.Pipeline = []bson.D{ - {{"$match", bson.D{{"domain", viewDoc.Domain}}}}, - {{"$match", bson.D{{"project", viewDoc.Project}}}}, + {{ + "$match", + bson.D{{"domain", viewDoc.Domain}, {"project", viewDoc.Project}}, + }}, } opts := service.FindOptions{} for _, o := range options { diff --git a/server/service/mongo/view/view_service_test.go b/server/service/mongo/view/view_service_test.go index 58d59377..1f1f19ed 100644 --- a/server/service/mongo/view/view_service_test.go +++ b/server/service/mongo/view/view_service_test.go @@ -19,6 +19,7 @@ package view_test import ( "context" + "encoding/json" "github.com/apache/servicecomb-kie/pkg/model" "github.com/apache/servicecomb-kie/server/config" "github.com/apache/servicecomb-kie/server/service" @@ -26,6 +27,8 @@ import ( "github.com/apache/servicecomb-kie/server/service/mongo/session" "github.com/apache/servicecomb-kie/server/service/mongo/view" "github.com/stretchr/testify/assert" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" "testing" ) @@ -111,3 +114,16 @@ func TestGet(t *testing.T) { }) } + +func TestService_List(t *testing.T) { + var pipeline mongo.Pipeline = []bson.D{ + {{ + "$match", + bson.D{{"domain", "default"}, {"project", "default"}}, + }}, + } + + s, err := json.Marshal(pipeline) + assert.NoError(t, err) + t.Log(string(s)) +} diff --git a/server/service/service.go b/server/service/service.go index a26e697a..8d063310 100644 --- a/server/service/service.go +++ b/server/service/service.go @@ -69,7 +69,8 @@ type View interface { Create(ctx context.Context, viewDoc *model.ViewDoc, options ...FindOption) error Update(ctx context.Context, viewDoc *model.ViewDoc) error //TODO - //List(ctx context.Context, domain, project string, options ...FindOption) ([]*model.ViewDoc, error) + List(ctx context.Context, domain, project string, options ...FindOption) ([]*model.ViewDoc, error) + GetCriteria(ctx context.Context, viewName, domain, project string) (map[string]map[string]string, error) GetContent(ctx context.Context, id, domain, project string, options ...FindOption) ([]*model.KVResponse, error) }