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 2019/08/02 06:38:26 UTC

[servicecomb-kie] branch master updated: add GetHistoryByLabelID interface with unit test, Register history's UrlPatterns to chassis (#23)

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-kie.git


The following commit(s) were added to refs/heads/master by this push:
     new e84506f  add GetHistoryByLabelID interface with unit test, Register history's UrlPatterns to chassis (#23)
e84506f is described below

commit e84506f5d913898123d57e7fc47b0f298d026511
Author: Qi Liu <30...@users.noreply.github.com>
AuthorDate: Fri Aug 2 14:38:22 2019 +0800

    add GetHistoryByLabelID interface with unit test, Register history's UrlPatterns to chassis (#23)
    
    * add getHistoryByLabelID interface with unit test
    
    1. add getHistoryByLabelID interface along with unit test.
    2. new interface fit new dao structure.
    
    * remove fake handler, modify history model
    
    * remove comment in history unit test
---
 cmd/kieserver/main.go                       |  6 +-
 go.mod                                      |  9 ++-
 pkg/model/kv.go                             |  8 +++
 pkg/model/mongodb_doc.go                    |  6 +-
 server/resource/v1/doc_struct.go            |  5 ++
 server/resource/v1/history_resource.go      | 64 +++++++++++++++++++
 server/resource/v1/history_resource_test.go | 91 ++++++++++++++++++++++++++
 server/resource/v1/kv_resource.go           |  5 +-
 server/resource/v1/kv_resource_test.go      | 54 ++++++++++++----
 server/service/history/dao.go               | 32 ++++++++++
 server/service/history/service.go           | 13 +++-
 swagger/servicecomb-kie.yaml                | 99 +++++++++++++++--------------
 12 files changed, 321 insertions(+), 71 deletions(-)

diff --git a/cmd/kieserver/main.go b/cmd/kieserver/main.go
index 1c95c27..b861289 100644
--- a/cmd/kieserver/main.go
+++ b/cmd/kieserver/main.go
@@ -18,12 +18,13 @@
 package main
 
 import (
-	"github.com/apache/servicecomb-kie/server/db"
 	"os"
 
+	"github.com/apache/servicecomb-kie/server/db"
+
 	"github.com/apache/servicecomb-kie/server/config"
 	_ "github.com/apache/servicecomb-kie/server/handler"
-	"github.com/apache/servicecomb-kie/server/resource/v1"
+	v1 "github.com/apache/servicecomb-kie/server/resource/v1"
 	"github.com/go-chassis/go-chassis"
 	"github.com/go-mesh/openlogging"
 	"github.com/urfave/cli"
@@ -72,6 +73,7 @@ func main() {
 		openlogging.Fatal(err.Error())
 	}
 	chassis.RegisterSchema("rest", &v1.KVResource{})
+	chassis.RegisterSchema("rest", &v1.HistoryResource{})
 	if err := chassis.Init(); err != nil {
 		openlogging.Fatal(err.Error())
 	}
diff --git a/go.mod b/go.mod
index b76a7cd..db325ae 100644
--- a/go.mod
+++ b/go.mod
@@ -3,16 +3,19 @@ module github.com/apache/servicecomb-kie
 require (
 	github.com/emicklei/go-restful v2.8.0+incompatible
 	github.com/go-chassis/foundation v0.0.0-20190621030543-c3b63f787f4c
-	github.com/go-chassis/go-archaius v0.19.0
-	github.com/go-chassis/go-chassis v1.5.1
+	github.com/go-chassis/go-archaius v0.20.0
+	github.com/go-chassis/go-chassis v1.6.2-0.20190730080139-fcfd929304bc
 	github.com/go-chassis/paas-lager v1.0.2-0.20190328010332-cf506050ddb2
 	github.com/go-mesh/openlogging v1.0.1-0.20181205082104-3d418c478b2d
+	github.com/golang/snappy v0.0.1 // indirect
+	github.com/google/go-cmp v0.3.0 // indirect
 	github.com/onsi/ginkgo v1.8.0
 	github.com/onsi/gomega v1.5.0
 	github.com/stretchr/testify v1.3.0
+	github.com/tidwall/pretty v1.0.0 // indirect
 	github.com/urfave/cli v1.20.0
 	github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c // indirect
 	github.com/xdg/stringprep v1.0.0 // indirect
-	go.mongodb.org/mongo-driver v1.0.3
+	go.mongodb.org/mongo-driver v1.0.0
 	gopkg.in/yaml.v2 v2.2.1
 )
diff --git a/pkg/model/kv.go b/pkg/model/kv.go
index 2635f6e..968574c 100644
--- a/pkg/model/kv.go
+++ b/pkg/model/kv.go
@@ -28,3 +28,11 @@ type LabelDocResponse struct {
 	LabelID string            `json:"label_id,omitempty"`
 	Labels  map[string]string `json:"labels,omitempty"`
 }
+
+//LabelHistoryResponse is label history revision struct
+type LabelHistoryResponse struct {
+	LabelID  string            `json:"label_id,omitempty"  bson:"label_id,omitempty"`
+	Labels   map[string]string `json:"labels,omitempty"`
+	KVs      []*KVDoc          `json:"data,omitempty"`
+	Revision int               `json:"revision"`
+}
diff --git a/pkg/model/mongodb_doc.go b/pkg/model/mongodb_doc.go
index ce32c5d..07397ff 100644
--- a/pkg/model/mongodb_doc.go
+++ b/pkg/model/mongodb_doc.go
@@ -45,8 +45,8 @@ type KVDoc struct {
 type LabelRevisionDoc struct {
 	ID       primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
 	LabelID  string             `json:"label_id,omitempty"  bson:"label_id,omitempty"`
-	Labels   map[string]string  `json:"labels,omitempty"` //redundant
-	Domain   string             `json:"domain,omitempty"` //redundant
-	KVs      []*KVDoc           `json:"data,omitempty"`   // save states of this revision
+	Labels   map[string]string  `json:"labels,omitempty"`
+	Domain   string             `json:"-"`
+	KVs      []*KVDoc           `json:"data,omitempty"`
 	Revision int                `json:"revision"`
 }
diff --git a/server/resource/v1/doc_struct.go b/server/resource/v1/doc_struct.go
index 5b79d17..371ed63 100644
--- a/server/resource/v1/doc_struct.go
+++ b/server/resource/v1/doc_struct.go
@@ -44,6 +44,11 @@ var (
 		Name:      "key",
 		ParamType: goRestful.PathParameterKind,
 	}
+	DocPathLabelID = &restful.Parameters{
+		DataType:  "string",
+		Name:      "label_id",
+		ParamType: goRestful.PathParameterKind,
+	}
 	kvIDParameters = &restful.Parameters{
 		DataType:  "string",
 		Name:      "kvID",
diff --git a/server/resource/v1/history_resource.go b/server/resource/v1/history_resource.go
index 0bca053..2a2fc3c 100644
--- a/server/resource/v1/history_resource.go
+++ b/server/resource/v1/history_resource.go
@@ -17,6 +17,70 @@
 
 package v1
 
+import (
+	"net/http"
+
+	"github.com/apache/servicecomb-kie/pkg/common"
+	"github.com/apache/servicecomb-kie/pkg/model"
+	"github.com/apache/servicecomb-kie/server/db"
+	rvsvc "github.com/apache/servicecomb-kie/server/service/history"
+	goRestful "github.com/emicklei/go-restful"
+	"github.com/go-chassis/go-chassis/server/restful"
+	"github.com/go-mesh/openlogging"
+)
+
 //HistoryResource TODO
 type HistoryResource struct {
 }
+
+//GetRevisionsByLabelID search key only by label
+func (r *HistoryResource) GetRevisionsByLabelID(context *restful.Context) {
+	var err error
+	labelID := context.ReadPathParameter("label_id")
+	if labelID == "" {
+		openlogging.Debug("label id is null")
+		WriteErrResponse(context, http.StatusForbidden, "label_id must not be empty", common.ContentTypeText)
+		return
+	}
+	revisions, err := rvsvc.GetHistoryByLabelID(context.Ctx, labelID)
+	if err != nil {
+		if err == db.ErrRevisionNotExist {
+			WriteErrResponse(context, http.StatusNotFound, err.Error(), common.ContentTypeText)
+			return
+		}
+		WriteErrResponse(context, http.StatusInternalServerError, err.Error(), common.ContentTypeText)
+		return
+	}
+	if len(revisions) == 0 {
+		WriteErrResponse(context, http.StatusNotFound, "no revisions found", common.ContentTypeText)
+		return
+	}
+	err = context.WriteHeaderAndJSON(http.StatusOK, revisions, goRestful.MIME_JSON)
+	if err != nil {
+		openlogging.Error(err.Error())
+	}
+}
+
+//URLPatterns defined config operations
+func (r *HistoryResource) URLPatterns() []restful.Route {
+	return []restful.Route{
+		{
+			Method:           http.MethodGet,
+			Path:             "/v1/revision/{label_id}",
+			ResourceFuncName: "GetRevisionsByLabelID",
+			FuncDesc:         "get all revisions by label id",
+			Parameters: []*restful.Parameters{
+				DocPathLabelID,
+			},
+			Returns: []*restful.Returns{
+				{
+					Code:    http.StatusOK,
+					Message: "true",
+					Model:   []model.LabelHistoryResponse{},
+				},
+			},
+			Consumes: []string{goRestful.MIME_JSON},
+			Produces: []string{goRestful.MIME_JSON},
+		},
+	}
+}
diff --git a/server/resource/v1/history_resource_test.go b/server/resource/v1/history_resource_test.go
new file mode 100644
index 0000000..aacdf54
--- /dev/null
+++ b/server/resource/v1/history_resource_test.go
@@ -0,0 +1,91 @@
+/*
+ * 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 v1_test
+
+import (
+	"context"
+	"encoding/json"
+	"io/ioutil"
+
+	"github.com/go-chassis/go-chassis/core/common"
+	"github.com/go-chassis/go-chassis/core/handler"
+
+	"fmt"
+	"net/http"
+	"net/http/httptest"
+
+	"github.com/apache/servicecomb-kie/pkg/model"
+	"github.com/apache/servicecomb-kie/server/db"
+	kvsvc "github.com/apache/servicecomb-kie/server/service/kv"
+
+	"github.com/apache/servicecomb-kie/server/config"
+	v1 "github.com/apache/servicecomb-kie/server/resource/v1"
+	"github.com/go-chassis/go-chassis/server/restful/restfultest"
+
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+)
+
+var _ = Describe("v1 history resource", func() {
+
+	config.Configurations = &config.Config{
+		DB: config.DB{},
+	}
+
+	Describe("get history revisions", func() {
+		config.Configurations.DB.URI = "mongodb://kie:123@127.0.0.1:27017"
+		err := db.Init()
+		It("should not return err", func() {
+			Expect(err).Should(BeNil())
+		})
+		Context("valid param", func() {
+			kv := &model.KVDoc{
+				Key:   "test",
+				Value: "revisions",
+				Labels: map[string]string{
+					"test": "revisions",
+				},
+			}
+			kv, _ = kvsvc.CreateOrUpdate(context.Background(), "default", kv)
+			path := fmt.Sprintf("/v1/revision/%s", kv.LabelID)
+			r, _ := http.NewRequest("GET", path, nil)
+			revision := &v1.HistoryResource{}
+			chain, _ := handler.GetChain(common.Provider, "")
+			c, err := restfultest.New(revision, chain)
+			It("should not return err or nil", func() {
+				Expect(err).Should(BeNil())
+			})
+			resp := httptest.NewRecorder()
+			c.ServeHTTP(resp, r)
+
+			body, err := ioutil.ReadAll(resp.Body)
+			It("should not return err", func() {
+				Expect(err).Should(BeNil())
+			})
+			data := []*model.LabelRevisionDoc{}
+			err = json.Unmarshal(body, &data)
+			It("should not return err", func() {
+				Expect(err).Should(BeNil())
+			})
+
+			It("should return all revisions with the same label ID", func() {
+				Expect(len(data) > 0).Should(Equal(true))
+				Expect((data[0]).LabelID).Should(Equal(kv.LabelID))
+			})
+		})
+	})
+})
diff --git a/server/resource/v1/kv_resource.go b/server/resource/v1/kv_resource.go
index 45f276b..49ed48a 100644
--- a/server/resource/v1/kv_resource.go
+++ b/server/resource/v1/kv_resource.go
@@ -20,14 +20,15 @@ package v1
 
 import (
 	"encoding/json"
+	"net/http"
+
 	"github.com/apache/servicecomb-kie/pkg/common"
 	"github.com/apache/servicecomb-kie/pkg/model"
 	"github.com/apache/servicecomb-kie/server/db"
-	"github.com/apache/servicecomb-kie/server/service/kv"
+	kvsvc "github.com/apache/servicecomb-kie/server/service/kv"
 	goRestful "github.com/emicklei/go-restful"
 	"github.com/go-chassis/go-chassis/server/restful"
 	"github.com/go-mesh/openlogging"
-	"net/http"
 )
 
 //KVResource has API about kv operations
diff --git a/server/resource/v1/kv_resource_test.go b/server/resource/v1/kv_resource_test.go
index 586c25c..bba7d12 100644
--- a/server/resource/v1/kv_resource_test.go
+++ b/server/resource/v1/kv_resource_test.go
@@ -18,17 +18,23 @@
 package v1_test
 
 import (
+	"bytes"
+	"encoding/json"
+	"io/ioutil"
+	"net/http"
+	"net/http/httptest"
+
+	"github.com/go-chassis/go-chassis/core/common"
+	"github.com/go-chassis/go-chassis/core/handler"
+	"github.com/go-chassis/go-chassis/server/restful/restfultest"
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
 
-	"bytes"
-	"context"
-	"encoding/json"
 	"github.com/apache/servicecomb-kie/pkg/model"
 	"github.com/apache/servicecomb-kie/server/config"
-	"github.com/apache/servicecomb-kie/server/resource/v1"
-	"github.com/go-chassis/go-chassis/server/restful/restfultest"
-	"net/http"
+	"github.com/apache/servicecomb-kie/server/db"
+	noop "github.com/apache/servicecomb-kie/server/handler"
+	v1 "github.com/apache/servicecomb-kie/server/resource/v1"
 )
 
 var _ = Describe("v1 kv resource", func() {
@@ -36,23 +42,47 @@ var _ = Describe("v1 kv resource", func() {
 	config.Configurations = &config.Config{
 		DB: config.DB{},
 	}
-	config.Configurations.DB.URI = "mongodb://kie:123@127.0.0.1:27017"
+
 	Describe("put kv", func() {
+		config.Configurations.DB.URI = "mongodb://kie:123@127.0.0.1:27017"
+		err := db.Init()
+		It("should not return err", func() {
+			Expect(err).Should(BeNil())
+		})
 		Context("valid param", func() {
 			kv := &model.KVDoc{
+				Key:    "timeout",
 				Value:  "1s",
 				Labels: map[string]string{"service": "tester"},
 			}
 			j, _ := json.Marshal(kv)
 			r, _ := http.NewRequest("PUT", "/v1/kv/timeout", bytes.NewBuffer(j))
-			rctx := restfultest.NewRestfulContext(context.Background(), r)
-			rctx.ReadRestfulRequest().SetAttribute("domain", "default")
+			noopH := &noop.NoopAuthHandler{}
+			chain, _ := handler.CreateChain(common.Provider, "testchain1", noopH.Name())
+			r.Header.Set("Content-Type", "application/json")
 			kvr := &v1.KVResource{}
-			kvr.Put(rctx)
-			It("should be 500 ", func() {
-				Expect(rctx.Resp.StatusCode()).Should(Equal(http.StatusInternalServerError))
+			c, err := restfultest.New(kvr, chain)
+			It("should not return error", func() {
+				Expect(err).Should(BeNil())
+			})
+			resp := httptest.NewRecorder()
+			c.ServeHTTP(resp, r)
+
+			body, err := ioutil.ReadAll(resp.Body)
+			It("should not return err", func() {
+				Expect(err).Should(BeNil())
+			})
+
+			data := &model.KVDoc{}
+			err = json.Unmarshal(body, data)
+			It("should not return err", func() {
+				Expect(err).Should(BeNil())
 			})
 
+			It("should return created or updated kv", func() {
+				Expect(data.Value).Should(Equal(kv.Value))
+				Expect(data.Labels).Should(Equal(kv.Labels))
+			})
 		})
 	})
 })
diff --git a/server/service/history/dao.go b/server/service/history/dao.go
index d6a1aba..a373970 100644
--- a/server/service/history/dao.go
+++ b/server/service/history/dao.go
@@ -20,11 +20,13 @@ package history
 import (
 	"context"
 	"fmt"
+
 	"github.com/apache/servicecomb-kie/pkg/model"
 	"github.com/apache/servicecomb-kie/server/db"
 	"github.com/go-mesh/openlogging"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/primitive"
+	"go.mongodb.org/mongo-driver/mongo/options"
 )
 
 //AddHistory increment labels revision and save current label stats to history, then update current revision to db
@@ -63,3 +65,33 @@ func AddHistory(ctx context.Context,
 	openlogging.Debug(fmt.Sprintf("update revision to %d", labelRevision.Revision))
 	return labelRevision.Revision, nil
 }
+
+func getHistoryByLabelID(ctx context.Context, filter bson.M) ([]*model.LabelRevisionDoc, error) {
+	c, err := db.GetClient()
+	if err != nil {
+		return nil, err
+	}
+	collection := c.Database(db.Name).Collection(db.CollectionLabelRevision)
+	cur, err := collection.Find(ctx, filter, options.Find().SetSort(map[string]interface{}{
+		"revisions": -1,
+	}))
+	if err != nil {
+		return nil, err
+	}
+	rvs := []*model.LabelRevisionDoc{}
+	var exist bool
+	for cur.Next(ctx) {
+		var elem model.LabelRevisionDoc
+		err := cur.Decode(&elem)
+		if err != nil {
+			openlogging.Error("decode to LabelRevisionDoc error: " + err.Error())
+			return nil, err
+		}
+		exist = true
+		rvs = append(rvs, &elem)
+	}
+	if !exist {
+		return nil, db.ErrRevisionNotExist
+	}
+	return rvs, nil
+}
diff --git a/server/service/history/service.go b/server/service/history/service.go
index 1c38bfa..1de7695 100644
--- a/server/service/history/service.go
+++ b/server/service/history/service.go
@@ -20,16 +20,19 @@ package history
 import (
 	"context"
 	"fmt"
+
 	"github.com/apache/servicecomb-kie/pkg/model"
 	"github.com/apache/servicecomb-kie/server/db"
 	"github.com/apache/servicecomb-kie/server/service/label"
 	"github.com/go-mesh/openlogging"
+	"go.mongodb.org/mongo-driver/bson"
 )
 
 //GetAndAddHistory get latest labels revision and call AddHistory
 func GetAndAddHistory(ctx context.Context,
 	labelID string, labels map[string]string, kvs []*model.KVDoc, domain string) (int, error) {
-	ctx, _ = context.WithTimeout(ctx, db.Timeout)
+	ctx, cancel := context.WithTimeout(ctx, db.Timeout)
+	defer cancel()
 	r, err := label.GetLatestLabel(ctx, labelID)
 	if err != nil {
 		if err == db.ErrRevisionNotExist {
@@ -53,3 +56,11 @@ func GetAndAddHistory(ctx context.Context,
 	}
 	return r.Revision, nil
 }
+
+//GetHistoryByLabelID get all history by label id
+func GetHistoryByLabelID(ctx context.Context, labelID string) ([]*model.LabelRevisionDoc, error) {
+	ctx, cancel := context.WithTimeout(ctx, db.Timeout)
+	defer cancel()
+	filter := bson.M{"label_id": labelID}
+	return getHistoryByLabelID(ctx, filter)
+}
diff --git a/swagger/servicecomb-kie.yaml b/swagger/servicecomb-kie.yaml
index 4e7685b..4b786d6 100644
--- a/swagger/servicecomb-kie.yaml
+++ b/swagger/servicecomb-kie.yaml
@@ -9,88 +9,91 @@ paths:
       summary: search key values by labels combination
       operationId: SearchByLabels
       parameters:
-      - name: q
-        in: query
-        description: 'the combination format is {label_key}:{label_value}+{label_key}:{label_value}
-          for example: /v1/kv?q=app:mall&q=app:mall+service:cart that will query key
-          values from 2 kinds of labels'
-        type: string
+        - name: q
+          in: query
+          description:
+            "the combination format is {label_key}:{label_value}+{label_key}:{label_value}
+            for example: /v1/kv?q=app:mall&q=app:mall+service:cart that will query key
+            values from 2 kinds of labels"
+          type: string
       consumes:
-      - application/json
+        - application/json
       produces:
-      - application/json
+        - application/json
       responses:
         "200":
           description: get key value success
           schema:
             type: array
             items:
-              $ref: '#/definitions/KVResponse'
+              $ref: "#/definitions/KVResponse"
   /v1/kv/{key}:
     get:
       summary: get key values by key and labels
       operationId: GetByKey
       parameters:
-      - name: key
-        in: path
-        required: true
-        type: string
-      - name: X-Depth
-        in: header
-        description: integer, default is 1, if you set match policy, you can set,depth
-          to decide label number
-        type: string
-      - name: body
-        in: body
-        required: true
-        schema:
-          $ref: '#/definitions/*v1.KVBody'
+        - name: key
+          in: path
+          required: true
+          type: string
+        - name: X-Depth
+          in: header
+          description:
+            integer, default is 1, if you set match policy, you can set,depth
+            to decide label number
+          type: string
+        - name: body
+          in: body
+          required: true
+          schema:
+            $ref: "#/definitions/*v1.KVBody"
       consumes:
-      - application/json
+        - application/json
       produces:
-      - application/json
+        - application/json
       responses:
         "200":
           description: get key value success
           schema:
             type: array
             items:
-              $ref: '#/definitions/KVResponse'
+              $ref: "#/definitions/KVResponse"
     put:
       summary: create or update key value
       operationId: Put
       parameters:
-      - name: key
-        in: path
-        required: true
-        type: string
-      - name: X-Realm
-        in: header
-        description: set kv to heterogeneous config server, not implement yet
-        type: string
-      - name: body
-        in: body
-        required: true
-        schema:
-          $ref: '#/definitions/v1.KVBody'
+        - name: key
+          in: path
+          required: true
+          type: string
+        - name: X-Realm
+          in: header
+          description: set kv to heterogeneous config server, not implement yet
+          type: string
+        - name: body
+          in: body
+          required: true
+          schema:
+            $ref: "#/definitions/v1.KVBody"
       consumes:
-      - application/json
+        - application/json
       produces:
-      - application/json
+        - application/json
       responses:
         "200":
           description: "true"
   /v1/kv/{kvID}:
     delete:
-      summary: Delete key by kvID and labelID,If the labelID is nil, query the collection
+      summary:
+        Delete key by kvID and labelID,If the labelID is nil, query the collection
         kv to get it.It means if only get kvID, it can also delete normally.But if
         you want better performance, you need to pass the labelID
       operationId: Delete
       parameters:
-      - name: key
-        in: path
-        required: true
-        type: string
+        - name: key
+          in: path
+          required: true
+          type: string
       responses:
         "204":
           description: Delete success
@@ -132,9 +135,9 @@ definitions:
       data:
         type: array
         items:
-          $ref: '#/definitions/KVDoc'
+          $ref: "#/definitions/KVDoc"
       label:
-        $ref: '#/definitions/LabelDocResponse'
+        $ref: "#/definitions/LabelDocResponse"
   LabelDocResponse:
     type: object
     properties: