You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by as...@apache.org on 2019/06/27 11:53:36 UTC
[servicecomb-kie] 25/29: SCB-1312 clear go lint (#12)
This is an automated email from the ASF dual-hosted git repository.
asifdxtreme pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-kie.git
commit 6e9a59f0495e7938e330ad225891745f5ddef024
Author: Shawn <xi...@gmail.com>
AuthorDate: Tue Jun 18 20:51:39 2019 +0800
SCB-1312 clear go lint (#12)
---
.travis.yml | 12 +--
build/build_server.sh | 9 +-
client/client.go | 9 +-
client/options.go | 3 +
cmd/{kie/cmd.go => kieserver/main.go} | 25 +++++-
cmd/main.go | 48 -----------
pkg/common/common.go | 7 +-
pkg/model/kv.go | 7 ++
pkg/model/mongodb_doc.go | 9 +-
scripts/start.sh | 2 +-
scripts/travis/start_deps.sh | 4 +-
server/config/config.go | 2 +
server/config/struct.go | 3 +
server/dao/kie_api.go | 148 ++++++++++++++-------------------
server/dao/kv.go | 47 ++++++++---
server/dao/label.go | 2 +
server/dao/label_history.go | 2 +
server/dao/options.go | 4 +-
server/dao/tool.go | 40 ++++++++-
server/handler/noop_auth_handler.go | 2 +
server/resource/v1/common.go | 14 +++-
server/resource/v1/doc_struct.go | 29 +++++++
server/resource/v1/history_resource.go | 1 +
server/resource/v1/kv_resource.go | 66 +++++----------
24 files changed, 276 insertions(+), 219 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 6e4794f..a5361b4 100755
--- a/.travis.yml
+++ b/.travis.yml
@@ -51,14 +51,10 @@ jobs:
- bash scripts/travis/goCycloChecker.sh
- stage: Unit Test
script:
+ - GO111MODULE=on go mod download
+ - GO111MODULE=on go mod vendor
- bash scripts/travis/start_deps.sh
+ - cd $HOME/gopath/src/github.com/apache/servicecomb-kie
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
- - GO111MODULE=on go mod download
- - GO111MODULE=on go mod vendor
- - bash scripts/travis/unit_test.sh && $HOME/gopath/bin/goveralls -coverprofile=coverage.txt -service=travis-ci
-
- - stage: Build
- script:
- - cd build
- - ./build_server.sh
+ - bash scripts/travis/unit_test.sh
diff --git a/build/build_server.sh b/build/build_server.sh
index 2ffe85b..099f64c 100755
--- a/build/build_server.sh
+++ b/build/build_server.sh
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
+set -x
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
@@ -46,8 +47,7 @@ echo "build from ${GIT_COMMIT}"
echo "building..."
-go build -o ${release_dir}/kie github.com/apache/servicecomb-kie/cmd/kie
-
+go build -o ${release_dir}/kie github.com/apache/servicecomb-kie/cmd/kieserver
writeConfig(){
echo "write template config..."
@@ -95,5 +95,6 @@ tar zcf ${pkg_name} conf kie
echo "building docker..."
cp ${PROJECT_DIR}/scripts/start.sh ./
-
-sudo docker build -t servicecomb/kie:${version} -f ${PROJECT_DIR}/build/docker/server/Dockerfile .
\ No newline at end of file
+cp ${PROJECT_DIR}/build/docker/server/Dockerfile ./
+sudo docker version
+sudo docker build -t servicecomb/kie:${version} .
\ No newline at end of file
diff --git a/client/client.go b/client/client.go
index 3bcf161..f9df929 100644
--- a/client/client.go
+++ b/client/client.go
@@ -33,25 +33,32 @@ import (
"net/url"
)
+//const
const (
APIPathKV = "v1/kv"
)
+//client errors
var (
ErrKeyNotExist = errors.New("can not find value")
)
+//Client is the servicecomb kie rest client.
+//it is concurrency safe
type Client struct {
opts Config
cipher security.Cipher
c *httpclient.URLClient
}
+
+//Config is the config of client
type Config struct {
Endpoint string
DefaultLabels map[string]string
VerifyPeer bool //TODO make it works, now just keep it false
}
+//New create a client
func New(config Config) (*Client, error) {
u, err := url.Parse(config.Endpoint)
if err != nil {
@@ -73,7 +80,7 @@ func New(config Config) (*Client, error) {
}, nil
}
-//GetValue get value of a key
+//Get get value of a key
func (c *Client) Get(ctx context.Context, key string, opts ...GetOption) ([]*model.KVDoc, error) {
options := GetOptions{}
for _, o := range opts {
diff --git a/client/options.go b/client/options.go
index 21f820b..e56b76e 100644
--- a/client/options.go
+++ b/client/options.go
@@ -17,7 +17,10 @@
package client
+//GetOption is the functional option of client func
type GetOption func(*GetOptions)
+
+//GetOptions is the options of client func
type GetOptions struct {
Labels map[string]string
MatchMode string
diff --git a/cmd/kie/cmd.go b/cmd/kieserver/main.go
similarity index 71%
rename from cmd/kie/cmd.go
rename to cmd/kieserver/main.go
index 4ddad70..f77434f 100644
--- a/cmd/kie/cmd.go
+++ b/cmd/kieserver/main.go
@@ -15,11 +15,16 @@
* limitations under the License.
*/
-package kie
+package main
import (
"os"
+ "github.com/apache/servicecomb-kie/server/config"
+ _ "github.com/apache/servicecomb-kie/server/handler"
+ "github.com/apache/servicecomb-kie/server/resource/v1"
+ "github.com/go-chassis/go-chassis"
+ "github.com/go-mesh/openlogging"
"github.com/urfave/cli"
)
@@ -61,3 +66,21 @@ func Init() error {
Configs = &ConfigFromCmd{}
return parseConfigFromCmd(os.Args)
}
+func main() {
+ if err := Init(); err != nil {
+ openlogging.Fatal(err.Error())
+ }
+ chassis.RegisterSchema("rest", &v1.KVResource{})
+ if err := chassis.Init(); err != nil {
+ openlogging.Error(err.Error())
+ os.Exit(1)
+ }
+ if err := config.Init(Configs.ConfigFile); err != nil {
+ openlogging.Error(err.Error())
+ os.Exit(1)
+ }
+ if err := chassis.Run(); err != nil {
+ openlogging.Error("service exit: " + err.Error())
+ os.Exit(1)
+ }
+}
diff --git a/cmd/main.go b/cmd/main.go
deleted file mode 100644
index 4ce2316..0000000
--- a/cmd/main.go
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package main
-
-import (
- "github.com/apache/servicecomb-kie/cmd/kie"
- _ "github.com/apache/servicecomb-kie/server/handler"
-
- "github.com/apache/servicecomb-kie/server/config"
- "github.com/apache/servicecomb-kie/server/resource/v1"
- "github.com/go-chassis/go-chassis"
- "github.com/go-mesh/openlogging"
- "os"
-)
-
-func main() {
- if err := kie.Init(); err != nil {
- openlogging.Fatal(err.Error())
- }
- chassis.RegisterSchema("rest", &v1.KVResource{})
- if err := chassis.Init(); err != nil {
- openlogging.Error(err.Error())
- os.Exit(1)
- }
- if err := config.Init(kie.Configs.ConfigFile); err != nil {
- openlogging.Error(err.Error())
- os.Exit(1)
- }
- if err := chassis.Run(); err != nil {
- openlogging.Error("service exit: " + err.Error())
- os.Exit(1)
- }
-}
diff --git a/pkg/common/common.go b/pkg/common/common.go
index 345086a..e39dca6 100644
--- a/pkg/common/common.go
+++ b/pkg/common/common.go
@@ -17,12 +17,15 @@
package common
+//match mode
const (
MatchGreedy = "greedy"
MatchExact = "exact"
)
+//http headers
const (
- HeaderMatch = "X-Match"
- HeaderDepth = "X-Depth"
+ HeaderMatch = "X-Match"
+ HeaderDepth = "X-Depth"
+ HeaderTenant = "X-Domain-Name"
)
diff --git a/pkg/model/kv.go b/pkg/model/kv.go
index 73d33e3..2635f6e 100644
--- a/pkg/model/kv.go
+++ b/pkg/model/kv.go
@@ -17,7 +17,14 @@
package model
+//KVResponse represents the key value list
type KVResponse struct {
LabelDoc *LabelDocResponse `json:"label"`
Data []*KVDoc `json:"data"`
}
+
+//LabelDocResponse is label struct
+type LabelDocResponse struct {
+ LabelID string `json:"label_id,omitempty"`
+ Labels map[string]string `json:"labels,omitempty"`
+}
diff --git a/pkg/model/mongodb_doc.go b/pkg/model/mongodb_doc.go
index 71a9483..ce32c5d 100644
--- a/pkg/model/mongodb_doc.go
+++ b/pkg/model/mongodb_doc.go
@@ -19,16 +19,15 @@ package model
import "go.mongodb.org/mongo-driver/bson/primitive"
-type LabelDocResponse struct {
- LabelID string `json:"label_id,omitempty"`
- Labels map[string]string `json:"labels,omitempty"`
-}
+//LabelDoc is database struct to store labels
type LabelDoc struct {
ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
Revision int `json:"revision,omitempty"`
Domain string `json:"domain,omitempty"` //tenant info
}
+
+//KVDoc is database struct to store kv
type KVDoc struct {
ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
LabelID string `json:"label_id,omitempty" bson:"label_id,omitempty"`
@@ -41,6 +40,8 @@ type KVDoc struct {
Domain string `json:"domain,omitempty"` //redundant
Revision int `json:"revision,omitempty" bson:"-"`
}
+
+//LabelRevisionDoc is database struct to store label history stats
type LabelRevisionDoc struct {
ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
LabelID string `json:"label_id,omitempty" bson:"label_id,omitempty"`
diff --git a/scripts/start.sh b/scripts/start.sh
index 682634c..9abf470 100755
--- a/scripts/start.sh
+++ b/scripts/start.sh
@@ -45,7 +45,7 @@ logger_level: ${LOG_LEVEL}
logger_file: log/chassis.log
-log_format_text: true
+log_format_text: false
rollingPolicy: size
diff --git a/scripts/travis/start_deps.sh b/scripts/travis/start_deps.sh
index b4587ef..d2236f6 100755
--- a/scripts/travis/start_deps.sh
+++ b/scripts/travis/start_deps.sh
@@ -15,4 +15,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-docker-compose up -f $GOPATH/src/github.com/apache/servicecomb-kie/deployments/docker/docker-compose.yaml
\ No newline at end of file
+cd build
+bash build_server.sh
+sudo docker-compose -f $GOPATH/src/github.com/apache/servicecomb-kie/deployments/docker/docker-compose.yaml up -d
\ No newline at end of file
diff --git a/server/config/config.go b/server/config/config.go
index 7e03731..76571de 100644
--- a/server/config/config.go
+++ b/server/config/config.go
@@ -26,6 +26,7 @@ import (
var configurations *Config
+//Init initiate config files
func Init(file string) error {
if err := archaius.AddFile(file, archaius.WithFileHandler(filesource.UseFileNameAsKeyContentAsValue)); err != nil {
return err
@@ -39,6 +40,7 @@ func Init(file string) error {
return nil
}
+//GetDB return db configs
func GetDB() DB {
return configurations.DB
}
diff --git a/server/config/struct.go b/server/config/struct.go
index cbfb644..0e2cd55 100644
--- a/server/config/struct.go
+++ b/server/config/struct.go
@@ -17,9 +17,12 @@
package config
+//Config is yaml file struct
type Config struct {
DB DB `yaml:"db"`
}
+
+//DB is yaml file struct to set mongodb config
type DB struct {
URI string `yaml:"uri"`
PoolSize int `yaml:"poolSize"`
diff --git a/server/dao/kie_api.go b/server/dao/kie_api.go
index 323d8e7..a5cca3d 100644
--- a/server/dao/kie_api.go
+++ b/server/dao/kie_api.go
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+//Package dao is the data access layer
package dao
import (
@@ -32,6 +33,7 @@ import (
var client *mongo.Client
+//const for dao
const (
DB = "kie"
CollectionLabel = "label"
@@ -41,11 +43,17 @@ const (
DefaultValueType = "text"
)
+//MongodbService operate data in mongodb
type MongodbService struct {
c *mongo.Client
timeout time.Duration
}
+//CreateOrUpdate will create or update a key value record
+//it first check label exists or not, and create labels if labels is first posted.
+//if label exists, then get its latest revision, and update current revision,
+//save the current label and its all key values to history collection
+//then check key exists or not, then create or update it
func (s *MongodbService) CreateOrUpdate(ctx context.Context, domain string, kv *model.KVDoc) (*model.KVDoc, error) {
if domain == "" {
return nil, ErrMissingDomain
@@ -176,9 +184,8 @@ func (s *MongodbService) FindKVByLabelID(ctx context.Context, domain, labelID, k
filter := bson.M{"label_id": labelID, "domain": domain}
if key != "" {
return s.findOneKey(ctx, filter, key)
- } else {
- return s.findKeys(ctx, filter, true)
}
+ return s.findKeys(ctx, filter, true)
}
@@ -193,107 +200,74 @@ func (s *MongodbService) FindKV(ctx context.Context, domain string, options ...F
if domain == "" {
return nil, ErrMissingDomain
}
- collection := s.c.Database(DB).Collection(CollectionKV)
- ctx, _ = context.WithTimeout(ctx, DefaultTimeout)
- filter := bson.M{"domain": domain}
- if opts.Key != "" {
- filter["key"] = opts.Key
- }
- for k, v := range opts.Labels {
- filter["labels."+k] = v
- }
- cur, err := collection.Find(ctx, filter)
+ cur, err := s.findKV(ctx, domain, opts)
if err != nil {
- if err.Error() == context.DeadlineExceeded.Error() {
- return nil, ErrAction("find", filter, fmt.Errorf("can not reach mongodb in %s", s.timeout))
- }
return nil, err
}
defer cur.Close(ctx)
- if cur.Err() != nil {
- return nil, err
- }
+
kvResp := make([]*model.KVResponse, 0)
if opts.ExactLabels {
- openlogging.Debug(fmt.Sprintf("find one [%s] with lables [%s] in [%s]", opts.Key, opts.Labels, domain))
- curKV := &model.KVDoc{} //reuse this pointer to reduce GC, only clear label
-
- //check label length to get the exact match
- for cur.Next(ctx) { //although complexity is O(n), but there won't be so much labels for one key
- curKV.Labels = nil
- err := cur.Decode(curKV)
- if err != nil {
- openlogging.Error("decode error: " + err.Error())
- return nil, err
- }
- if len(curKV.Labels) == len(opts.Labels) {
- openlogging.Debug("hit exact labels")
- labelGroup := &model.KVResponse{
- LabelDoc: &model.LabelDocResponse{
- Labels: opts.Labels,
- LabelID: curKV.LabelID,
- },
- Data: make([]*model.KVDoc, 0),
- }
- clearKV(curKV)
- labelGroup.Data = append(labelGroup.Data, curKV)
- kvResp = append(kvResp, labelGroup)
- return kvResp, nil
- }
+ openlogging.Debug("find one key", openlogging.WithTags(
+ map[string]interface{}{
+ "key": opts.Key,
+ "label": opts.Labels,
+ "domain": domain,
+ },
+ ))
+ return cursorToOneKV(ctx, cur, opts.Labels)
+ }
+ if opts.Depth == 0 {
+ opts.Depth = 1
+ }
+ for cur.Next(ctx) {
+ curKV := &model.KVDoc{}
+ if err := cur.Decode(curKV); err != nil {
+ openlogging.Error("decode to KVs error: " + err.Error())
+ return nil, err
}
- return nil, ErrKeyNotExists
- } else {
- if opts.Depth == 0 {
- opts.Depth = 1
+ if (len(curKV.Labels) - len(opts.Labels)) > opts.Depth {
+ //because it is query by labels, so result can not be minus
+ //so many labels,then continue
+ openlogging.Debug("so deep, skip this key")
+ continue
}
- for cur.Next(ctx) {
- curKV := &model.KVDoc{}
-
- if err := cur.Decode(curKV); err != nil {
- openlogging.Error("decode to KVs error: " + err.Error())
- return nil, err
- }
- if (len(curKV.Labels) - len(opts.Labels)) > opts.Depth {
- //because it is query by labels, so result can not be minus
- //so many labels,then continue
- openlogging.Debug("so deep, skip this key")
- continue
- }
- openlogging.Info(fmt.Sprintf("%v", curKV))
- var groupExist bool
- var labelGroup *model.KVResponse
- for _, labelGroup = range kvResp {
- if reflect.DeepEqual(labelGroup.LabelDoc.Labels, curKV.Labels) {
- groupExist = true
- clearKV(curKV)
- labelGroup.Data = append(labelGroup.Data, curKV)
- break
- }
-
- }
- if !groupExist {
- labelGroup = &model.KVResponse{
- LabelDoc: &model.LabelDocResponse{
- Labels: curKV.Labels,
- LabelID: curKV.LabelID,
- },
- Data: []*model.KVDoc{curKV},
- }
+ openlogging.Info(fmt.Sprintf("%v", curKV))
+ var groupExist bool
+ var labelGroup *model.KVResponse
+ for _, labelGroup = range kvResp {
+ if reflect.DeepEqual(labelGroup.LabelDoc.Labels, curKV.Labels) {
+ groupExist = true
clearKV(curKV)
- openlogging.Debug("add new label group")
- kvResp = append(kvResp, labelGroup)
+ labelGroup.Data = append(labelGroup.Data, curKV)
+ break
}
}
- if len(kvResp) == 0 {
- return nil, ErrKeyNotExists
+ if !groupExist {
+ labelGroup = &model.KVResponse{
+ LabelDoc: &model.LabelDocResponse{
+ Labels: curKV.Labels,
+ LabelID: curKV.LabelID,
+ },
+ Data: []*model.KVDoc{curKV},
+ }
+ clearKV(curKV)
+ openlogging.Debug("add new label group")
+ kvResp = append(kvResp, labelGroup)
}
- return kvResp, nil
+
+ }
+ if len(kvResp) == 0 {
+ return nil, ErrKeyNotExists
}
+ return kvResp, nil
}
+
+//DeleteByID delete a key value by collection ID
func (s *MongodbService) DeleteByID(id string) error {
collection := s.c.Database(DB).Collection(CollectionKV)
hex, err := primitive.ObjectIDFromHex(id)
@@ -312,6 +286,8 @@ func (s *MongodbService) DeleteByID(id string) error {
return nil
}
+//Delete remove a list of key values for a tenant
+//domain=tenant
func (s *MongodbService) Delete(ids []string, domain string) error {
if len(ids) == 0 {
openlogging.Warn("delete error,ids is blank")
@@ -351,6 +327,8 @@ func (s *MongodbService) Delete(ids []string, domain string) error {
}
return nil
}
+
+//NewMongoService create a new mongo db service
func NewMongoService(opts Options) (*MongodbService, error) {
if opts.Timeout == 0 {
opts.Timeout = DefaultTimeout
diff --git a/server/dao/kv.go b/server/dao/kv.go
index c48774b..41aba48 100644
--- a/server/dao/kv.go
+++ b/server/dao/kv.go
@@ -15,13 +15,14 @@
* limitations under the License.
*/
-//package dao is a persis layer of kie
+//Package dao is a persis layer of kie
package dao
import (
"context"
"crypto/tls"
"errors"
+ "fmt"
"github.com/apache/servicecomb-kie/pkg/model"
"github.com/apache/servicecomb-kie/server/config"
"github.com/go-mesh/openlogging"
@@ -31,6 +32,7 @@ import (
"time"
)
+//db errors
var (
ErrMissingDomain = errors.New("domain info missing, illegal access")
ErrKeyNotExists = errors.New("key with labels does not exits")
@@ -40,6 +42,7 @@ var (
ErrRevisionNotExist = errors.New("label revision not exist")
)
+//Options mongodb options
type Options struct {
URI string
PoolSize int
@@ -48,6 +51,8 @@ type Options struct {
Timeout time.Duration
}
+//NewKVService create a kv service
+//TODO, multiple config server
func NewKVService() (*MongodbService, error) {
opts := Options{
URI: config.GetDB().URI,
@@ -55,7 +60,7 @@ func NewKVService() (*MongodbService, error) {
SSL: config.GetDB().SSL,
}
if opts.SSL {
-
+ //TODO tls config
}
return NewMongoService(opts)
}
@@ -90,16 +95,36 @@ func (s *MongodbService) KVExist(ctx context.Context, domain, key string, option
return primitive.NilObjectID, err
}
return kvs[0].ID, nil
- } else {
- kvs, err := s.FindKV(ctx, domain, WithExactLabels(), WithLabels(opts.Labels), WithKey(key))
- if err != nil {
- return primitive.NilObjectID, err
- }
- if len(kvs) != 1 {
- return primitive.NilObjectID, ErrTooMany
- }
+ }
+ kvs, err := s.FindKV(ctx, domain, WithExactLabels(), WithLabels(opts.Labels), WithKey(key))
+ if err != nil {
+ return primitive.NilObjectID, err
+ }
+ if len(kvs) != 1 {
+ return primitive.NilObjectID, ErrTooMany
+ }
- return kvs[0].Data[0].ID, nil
+ return kvs[0].Data[0].ID, nil
+
+}
+
+func (s *MongodbService) findKV(ctx context.Context, domain string, opts FindOptions) (*mongo.Cursor, error) {
+ collection := s.c.Database(DB).Collection(CollectionKV)
+ ctx, _ = context.WithTimeout(ctx, DefaultTimeout)
+ filter := bson.M{"domain": domain}
+ if opts.Key != "" {
+ filter["key"] = opts.Key
+ }
+ for k, v := range opts.Labels {
+ filter["labels."+k] = v
}
+ cur, err := collection.Find(ctx, filter)
+ if err != nil {
+ if err.Error() == context.DeadlineExceeded.Error() {
+ return nil, ErrAction("find", filter, fmt.Errorf("can not reach mongodb in %s", s.timeout))
+ }
+ return nil, err
+ }
+ return cur, err
}
diff --git a/server/dao/label.go b/server/dao/label.go
index 3fddd2f..742c3dc 100644
--- a/server/dao/label.go
+++ b/server/dao/label.go
@@ -58,6 +58,8 @@ func (s *MongodbService) findOneLabels(ctx context.Context, filter bson.M) (*mod
}
return l, nil
}
+
+//LabelsExist check label exists or not and return label ID
func (s *MongodbService) LabelsExist(ctx context.Context, domain string, labels map[string]string) (primitive.ObjectID, error) {
l, err := s.FindLabels(ctx, domain, labels)
if err != nil {
diff --git a/server/dao/label_history.go b/server/dao/label_history.go
index fb8164f..a3809d6 100644
--- a/server/dao/label_history.go
+++ b/server/dao/label_history.go
@@ -56,6 +56,8 @@ func (s *MongodbService) getLatestLabel(ctx context.Context, labelID string) (*m
}
return h, nil
}
+
+//AddHistory get latest labels revision and plus 1 and save current label stats to history, then update current revision to db
func (s *MongodbService) AddHistory(ctx context.Context, labelID string, labels map[string]string, domain string) (int, error) {
r, err := s.getLatestLabel(ctx, labelID)
if err != nil {
diff --git a/server/dao/options.go b/server/dao/options.go
index 7e33798..fbbe031 100644
--- a/server/dao/options.go
+++ b/server/dao/options.go
@@ -17,6 +17,7 @@
package dao
+//FindOptions is option to find key value
type FindOptions struct {
ExactLabels bool
Depth int
@@ -26,6 +27,7 @@ type FindOptions struct {
ClearLabel bool
}
+//FindOption is functional option to find key value
type FindOption func(*FindOptions)
//WithExactLabels tell model service to return only one kv matches the labels
@@ -49,7 +51,7 @@ func WithLabels(labels map[string]string) FindOption {
}
}
-//WithLabels find kv by labelID
+//WithLabelID find kv by labelID
func WithLabelID(label string) FindOption {
return func(o *FindOptions) {
o.LabelID = label
diff --git a/server/dao/tool.go b/server/dao/tool.go
index b3d5ea4..08ff602 100644
--- a/server/dao/tool.go
+++ b/server/dao/tool.go
@@ -17,7 +17,12 @@
package dao
-import "github.com/apache/servicecomb-kie/pkg/model"
+import (
+ "context"
+ "github.com/apache/servicecomb-kie/pkg/model"
+ "github.com/go-mesh/openlogging"
+ "go.mongodb.org/mongo-driver/mongo"
+)
//clearKV clean attr which don't need to return to client side
func clearKV(kv *model.KVDoc) {
@@ -25,3 +30,36 @@ func clearKV(kv *model.KVDoc) {
kv.Labels = nil
kv.LabelID = ""
}
+
+func cursorToOneKV(ctx context.Context, cur *mongo.Cursor, labels map[string]string) ([]*model.KVResponse, error) {
+ kvResp := make([]*model.KVResponse, 0)
+ curKV := &model.KVDoc{} //reuse this pointer to reduce GC, only clear label
+ //check label length to get the exact match
+ for cur.Next(ctx) { //although complexity is O(n), but there won't be so much labels for one key
+ if cur.Err() != nil {
+ return nil, cur.Err()
+ }
+ curKV.Labels = nil
+ err := cur.Decode(curKV)
+ if err != nil {
+ openlogging.Error("decode error: " + err.Error())
+ return nil, err
+ }
+ if len(curKV.Labels) == len(labels) {
+ openlogging.Debug("hit exact labels")
+ labelGroup := &model.KVResponse{
+ LabelDoc: &model.LabelDocResponse{
+ Labels: labels,
+ LabelID: curKV.LabelID,
+ },
+ Data: make([]*model.KVDoc, 0),
+ }
+ clearKV(curKV)
+ labelGroup.Data = append(labelGroup.Data, curKV)
+ kvResp = append(kvResp, labelGroup)
+ return kvResp, nil
+ }
+
+ }
+ return nil, ErrKeyNotExists
+}
diff --git a/server/handler/noop_auth_handler.go b/server/handler/noop_auth_handler.go
index b2c4a20..b4a3833 100644
--- a/server/handler/noop_auth_handler.go
+++ b/server/handler/noop_auth_handler.go
@@ -26,6 +26,7 @@ import (
//developer can extend authenticate and authorization by set new handler in chassis.yaml
type NoopAuthHandler struct{}
+//Handle set local attribute to http request
func (bk *NoopAuthHandler) Handle(chain *handler.Chain, inv *invocation.Invocation, cb invocation.ResponseCallBack) {
inv.SetMetadata("domain", "default")
chain.Next(inv, cb)
@@ -35,6 +36,7 @@ func newDomainResolver() handler.Handler {
return &NoopAuthHandler{}
}
+//Name is handler name
func (bk *NoopAuthHandler) Name() string {
return "auth-handler"
}
diff --git a/server/resource/v1/common.go b/server/resource/v1/common.go
index eca9fef..48baa22 100644
--- a/server/resource/v1/common.go
+++ b/server/resource/v1/common.go
@@ -27,11 +27,8 @@ import (
"strconv"
)
+//const of server
const (
- HeaderTenant = "X-Domain-Name"
-
- FindExact = "exact"
- FindMany = "greedy"
MsgDomainMustNotBeEmpty = "domain must not be empty"
MsgIllegalFindPolicy = "value of header " + common.HeaderMatch + " can be greedy or exact"
MsgIllegalLabels = "label's value can not be empty, " +
@@ -40,9 +37,12 @@ const (
ErrIDMustNotEmpty = "must supply id if you want to remove key"
)
+//ReadDomain get domain info from attribute
func ReadDomain(context *restful.Context) interface{} {
return context.ReadRestfulRequest().Attribute("domain")
}
+
+//ReadFindDepth get find depth
func ReadFindDepth(context *restful.Context) (int, error) {
d := context.ReadRestfulRequest().HeaderParameter(common.HeaderDepth)
if d == "" {
@@ -54,6 +54,8 @@ func ReadFindDepth(context *restful.Context) (int, error) {
}
return depth, nil
}
+
+//ReadMatchPolicy get match policy
func ReadMatchPolicy(context *restful.Context) string {
policy := context.ReadRestfulRequest().HeaderParameter(common.HeaderMatch)
if policy == "" {
@@ -62,16 +64,20 @@ func ReadMatchPolicy(context *restful.Context) string {
}
return policy
}
+
+//WriteErrResponse write error message to client
func WriteErrResponse(context *restful.Context, status int, msg string) {
context.WriteHeader(status)
b, _ := json.MarshalIndent(&ErrorMsg{Msg: msg}, "", " ")
context.Write(b)
}
+//ErrLog record error
func ErrLog(action string, kv *model.KVDoc, err error) {
openlogging.Error(fmt.Sprintf("[%s] [%v] err:%s", action, kv, err.Error()))
}
+//InfoLog record info
func InfoLog(action string, kv *model.KVDoc) {
openlogging.Info(
fmt.Sprintf("[%s] [%s:%s] in [%s] success", action, kv.Key, kv.Value, kv.Domain))
diff --git a/server/resource/v1/doc_struct.go b/server/resource/v1/doc_struct.go
index a0402ae..37f7432 100644
--- a/server/resource/v1/doc_struct.go
+++ b/server/resource/v1/doc_struct.go
@@ -17,12 +17,41 @@
package v1
+import (
+ "github.com/apache/servicecomb-kie/pkg/common"
+ goRestful "github.com/emicklei/go-restful"
+ "github.com/go-chassis/go-chassis/server/restful"
+)
+
+//swagger doc elements
+var (
+ DocHeaderDepth = &restful.Parameters{
+ DataType: "string",
+ Name: common.HeaderDepth,
+ ParamType: goRestful.HeaderParameterKind,
+ Desc: "integer, default is 1, if you set match policy, you can set,depth to decide label number",
+ }
+ DocPathKey = &restful.Parameters{
+ DataType: "string",
+ Name: "key",
+ ParamType: goRestful.PathParameterKind,
+ }
+ DocHeaderMath = &restful.Parameters{
+ DataType: "string",
+ Name: common.HeaderMatch,
+ ParamType: goRestful.HeaderParameterKind,
+ Desc: "greedy or exact",
+ }
+)
+
+//KVBody is open api doc
type KVBody struct {
Labels map[string]string `json:"labels"`
ValueType string `json:"valueType"`
Value string `json:"value"`
}
+//ErrorMsg is open api doc
type ErrorMsg struct {
Msg string `json:"msg"`
}
diff --git a/server/resource/v1/history_resource.go b/server/resource/v1/history_resource.go
index 3952a19..0bca053 100644
--- a/server/resource/v1/history_resource.go
+++ b/server/resource/v1/history_resource.go
@@ -17,5 +17,6 @@
package v1
+//HistoryResource TODO
type HistoryResource struct {
}
diff --git a/server/resource/v1/kv_resource.go b/server/resource/v1/kv_resource.go
index 7832f23..a1f94b6 100644
--- a/server/resource/v1/kv_resource.go
+++ b/server/resource/v1/kv_resource.go
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-//v1 package hold http rest v1 API
+//Package v1 hold http rest v1 API
package v1
import (
@@ -31,9 +31,11 @@ import (
"strings"
)
+//KVResource has API about kv operations
type KVResource struct {
}
+//Put create or update kv
func (r *KVResource) Put(context *restful.Context) {
var err error
key := context.ReadPathParameter("key")
@@ -64,6 +66,8 @@ func (r *KVResource) Put(context *restful.Context) {
context.WriteHeaderAndJSON(http.StatusOK, kv, goRestful.MIME_JSON)
}
+
+//FindWithKey search key by label and key
func (r *KVResource) FindWithKey(context *restful.Context) {
var err error
key := context.ReadPathParameter("key")
@@ -121,6 +125,8 @@ func (r *KVResource) FindWithKey(context *restful.Context) {
}
}
+
+//FindByLabels search key only by label
func (r *KVResource) FindByLabels(context *restful.Context) {
var err error
values := context.ReadRequest().URL.Query()
@@ -169,6 +175,8 @@ func (r *KVResource) FindByLabels(context *restful.Context) {
}
}
+
+//Delete deletes key by ids
func (r *KVResource) Delete(context *restful.Context) {
domain := ReadDomain(context)
if domain == nil {
@@ -203,16 +211,7 @@ func (r *KVResource) URLPatterns() []restful.Route {
ResourceFuncName: "Put",
FuncDesc: "create or update key value",
Parameters: []*restful.Parameters{
- {
- DataType: "string",
- Name: "key",
- ParamType: goRestful.PathParameterKind,
- }, {
- DataType: "string",
- Name: HeaderTenant,
- ParamType: goRestful.HeaderParameterKind,
- Desc: "set kv to other tenant",
- }, {
+ DocPathKey, {
DataType: "string",
Name: "X-Realm",
ParamType: goRestful.HeaderParameterKind,
@@ -234,20 +233,7 @@ func (r *KVResource) URLPatterns() []restful.Route {
ResourceFuncName: "FindWithKey",
FuncDesc: "get key values by key and labels",
Parameters: []*restful.Parameters{
- {
- DataType: "string",
- Name: "key",
- ParamType: goRestful.PathParameterKind,
- }, {
- DataType: "string",
- Name: HeaderTenant,
- ParamType: goRestful.HeaderParameterKind,
- }, {
- DataType: "string",
- Name: common.HeaderMatch,
- ParamType: goRestful.HeaderParameterKind,
- Desc: "greedy or exact",
- },
+ DocPathKey, DocHeaderMath, DocHeaderDepth,
},
Returns: []*restful.Returns{
{
@@ -265,16 +251,7 @@ func (r *KVResource) URLPatterns() []restful.Route {
ResourceFuncName: "FindByLabels",
FuncDesc: "find key values only by labels",
Parameters: []*restful.Parameters{
- {
- DataType: "string",
- Name: HeaderTenant,
- ParamType: goRestful.HeaderParameterKind,
- }, {
- DataType: "string",
- Name: common.HeaderMatch,
- ParamType: goRestful.HeaderParameterKind,
- Desc: "greedy or exact",
- },
+ DocHeaderMath, DocHeaderDepth,
},
Returns: []*restful.Returns{
{
@@ -290,18 +267,13 @@ func (r *KVResource) URLPatterns() []restful.Route {
Path: "/v1/kv/{ids}",
ResourceFuncName: "Delete",
FuncDesc: "delete key by id,separated by ','",
- Parameters: []*restful.Parameters{
- {
- DataType: "string",
- Name: HeaderTenant,
- ParamType: goRestful.HeaderParameterKind,
- }, {
- DataType: "string",
- Name: "ids",
- ParamType: goRestful.PathParameterKind,
- Desc: "The id strings to be removed are separated by ',',If the actual number of deletions " +
- "and the number of parameters are not equal, no error will be returned and only warn log will be printed.",
- },
+ Parameters: []*restful.Parameters{{
+ DataType: "string",
+ Name: "ids",
+ ParamType: goRestful.PathParameterKind,
+ Desc: "The id strings to be removed are separated by ',',If the actual number of deletions " +
+ "and the number of parameters are not equal, no error will be returned and only warn log will be printed.",
+ },
},
Returns: []*restful.Returns{
{