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

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


The following commit(s) were added to refs/heads/master by this push:
     new 6e9a59f  SCB-1312 clear go lint (#12)
6e9a59f is described below

commit 6e9a59f0495e7938e330ad225891745f5ddef024
Author: Shawn <xiaoliang.t...@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{
                                {

Reply via email to