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 2020/12/01 02:17:42 UTC

[servicecomb-service-center] branch master updated: [SCD-2133] governance northbound Interface / abstract access layer (#766)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 4376fc5  [SCD-2133] governance northbound Interface / abstract access layer (#766)
4376fc5 is described below

commit 4376fc5affcf89cc60a961ad6d8da17bbb4b4a37
Author: GuoYL <53...@users.noreply.github.com>
AuthorDate: Tue Dec 1 10:17:33 2020 +0800

    [SCD-2133] governance northbound Interface / abstract access layer (#766)
    
    * [SCD-2133] governance northbound Interface / abstract access layer
    
    * [SCD-2133] add validate
    
    * [SCD-2133] fix ci failed
    
    * [SCD-2133] fix ci failed
    
    * [SCD-2133] modify as comment
    
    * [SCD-2133] modify as comment
---
 docs/openapi/v1-gov.yaml                      | 277 ++++++++++++++++++++++++++
 etc/conf/app.yaml                             |   7 +
 examples/governance/limiter.json              |  12 +-
 examples/governance/loadbalancer.json         |   7 -
 examples/governance/marker.json               |  13 +-
 examples/governance/retry.json                |  18 ++
 go.mod                                        |   7 +-
 go.sum                                        |  38 +++-
 pkg/gov/governance.go                         |  20 +-
 pkg/gov/governance_test.go                    |  11 +-
 server/bootstrap/bootstrap.go                 |   3 +
 server/config/config.go                       |   2 +-
 server/config/types.go                        |   2 +-
 server/resource/v1/gov_resource.go            |  83 +++++++-
 server/resource/v1/gov_resource_test.go       |  11 +-
 server/service/gov/config_distributor.go      |  42 +++-
 server/service/gov/config_distributor_test.go |   6 +-
 server/service/gov/kie/kie_distributor.go     | 206 +++++++++++++++++++
 server/service/gov/kie/validate.go            | 116 +++++++++++
 server/service/gov/mock/mock.go               |  24 ++-
 20 files changed, 848 insertions(+), 57 deletions(-)

diff --git a/docs/openapi/v1-gov.yaml b/docs/openapi/v1-gov.yaml
new file mode 100644
index 0000000..674c20d
--- /dev/null
+++ b/docs/openapi/v1-gov.yaml
@@ -0,0 +1,277 @@
+# 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.
+
+swagger: '2.0'
+info:
+  title: Service Center API
+  version: "4.0.0"
+# the domain of the service
+host: 127.0.0.1:30100
+# array of all schemes that your API supports
+schemes:
+  - http
+  - https
+# will be prefixed to all paths
+produces:
+  - application/json
+paths:
+  /v1/{project}/gov/{kind}:
+    get:
+      description: |
+        查询所有的policy/match-group集合。
+      parameters:
+        - name: x-domain-name
+          in: header
+          type: string
+          default: default
+        - name: project
+          in: path
+          required: true
+          type: string
+        - name: kind
+          in: path
+          required: true
+          type: string
+        - name: app
+          in: query
+          required: false
+          type: string
+        - name: env
+          in: query
+          required: false
+          type: string
+      tags:
+        - base
+      responses:
+        200:
+          description: 版本信息结构体
+          schema:
+            $ref: '#/definitions/GovItemList'
+        400:
+          description: 错误的请求
+          schema:
+            $ref: '#/definitions/Error'
+        500:
+          description: 内部错误
+          schema:
+            $ref: '#/definitions/Error'
+    post:
+      description: |
+        添加一个policy/match-group。
+      parameters:
+        - name: x-domain-name
+          in: header
+          type: string
+          default: default
+        - name: project
+          in: path
+          required: true
+          type: string
+        - name: kind
+          in: path
+          required: true
+          type: string
+        - name: GovItem
+          in: body
+          description: "治理规则"
+          required: true
+          schema:
+            $ref: '#/definitions/GovItem'
+      tags:
+        - base
+      responses:
+        200:
+          description: 治理项结构体
+          schema:
+            $ref: '#/definitions/GovItem'
+        400:
+          description: 错误的请求
+          schema:
+            $ref: '#/definitions/Error'
+        500:
+          description: 内部错误
+          schema:
+            $ref: '#/definitions/Error'
+  /v1/{project}/gov/{kind}/{id}:
+    get:
+      description: |
+        查询指定的policy。
+      parameters:
+        - name: x-domain-name
+          in: header
+          type: string
+          default: default
+        - name: project
+          in: path
+          required: true
+          type: string
+        - name: kind
+          in: path
+          required: true
+          type: string
+        - name: id
+          in: path
+          required: true
+          type: string
+        - name: app
+          in: query
+          required: false
+          type: string
+        - name: env
+          in: query
+          required: false
+          type: string
+      tags:
+        - base
+      responses:
+        200:
+          description: 版本信息结构体
+          schema:
+            $ref: '#/definitions/GovItem'
+        400:
+          description: 错误的请求
+          schema:
+            $ref: '#/definitions/Error'
+        500:
+          description: 内部错误
+          schema:
+            $ref: '#/definitions/Error'
+    put:
+      description: |
+        修改指定的policy。
+      parameters:
+        - name: x-domain-name
+          in: header
+          type: string
+          default: default
+        - name: project
+          in: path
+          required: true
+          type: string
+        - name: kind
+          in: path
+          required: true
+          type: string
+        - name: id
+          in: path
+          required: true
+          type: string
+        - name: GovItem
+          in: body
+          description: "治理规则"
+          required: true
+          schema:
+            $ref: '#/definitions/GovItem'
+      tags:
+        - base
+      responses:
+        200:
+          description: 治理项结构体
+          schema:
+            $ref: '#/definitions/GovItem'
+        400:
+          description: 错误的请求
+          schema:
+            $ref: '#/definitions/Error'
+        500:
+          description: 内部错误
+          schema:
+            $ref: '#/definitions/Error'
+    delete:
+      description: |
+        删除指定的policy。
+      parameters:
+        - name: x-domain-name
+          in: header
+          type: string
+          default: default
+        - name: project
+          in: path
+          required: true
+          type: string
+        - name: kind
+          in: path
+          required: true
+          type: string
+        - name: id
+          in: path
+          required: true
+          type: string
+        - name: GovItem
+          in: body
+          description: "治理规则"
+          required: true
+          schema:
+            $ref: '#/definitions/GovItem'
+      tags:
+        - base
+      responses:
+        200:
+          description: 治理项结构体
+          schema:
+            $ref: '#/definitions/GovItem'
+        400:
+          description: 错误的请求
+          schema:
+            $ref: '#/definitions/Error'
+        500:
+          description: 内部错误
+          schema:
+            $ref: '#/definitions/Error'
+
+definitions:
+  GovItemList:
+    type: object
+    properties:
+      total:
+        type: integer
+        format: int32
+      data:
+        type: array
+        items:
+          $ref: '#/definitions/GovItem'
+  GovItem:
+    type: object
+    properties:
+      name:
+        type: string
+      id:
+        type: string
+      status:
+        type: string
+      creatTime:
+        type: integer
+      updateTime:
+        type: integer
+      selector:
+        $ref: '#/definitions/Selector'
+      spec:
+        type: object
+  Selector:
+    type: object
+    properties:
+      app:
+        type: string
+      environment:
+        type: string
+  Error:
+    type: object
+    properties:
+      errorCode:
+        type: string
+      errorMessage:
+        type: string
+      detail:
+        type: string
diff --git a/etc/conf/app.yaml b/etc/conf/app.yaml
index 49e4209..99731bc 100644
--- a/etc/conf/app.yaml
+++ b/etc/conf/app.yaml
@@ -28,6 +28,12 @@ server:
   pprof:
     mode: 0
 
+gov:
+  plugins:
+    - name: kie
+      type: kie
+      endpoint: http://127.0.0.1:30110
+
 log:
   level: DEBUG
   file:
@@ -123,5 +129,6 @@ tracing:
 quota:
   kind:
 
+
 syncer:
   enabled: false
diff --git a/examples/governance/limiter.json b/examples/governance/limiter.json
index e4ae6b0..8a20818 100644
--- a/examples/governance/limiter.json
+++ b/examples/governance/limiter.json
@@ -1,7 +1,17 @@
 {
   "name": "limitTraffic2adminAPI",
+  "id": "xxx",
+  "status": "enabled",
+  "createTime": "123",
+  "updateTime": "123",
+  "selector" : {
+    "app": "xx",
+    "environment": "xx"
+  },
   "spec": {
-    "match": "traffic2adminAPI",
+    "rules": {
+      "match": "traffic2adminAPI"
+    },
     "rate": 100,
     "burst": 10
   }
diff --git a/examples/governance/loadbalancer.json b/examples/governance/loadbalancer.json
deleted file mode 100644
index 17e4f68..0000000
--- a/examples/governance/loadbalancer.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "name": "adminAPIRetry",
-  "spec": {
-    "match": "traffic2adminAPI",
-    "retryNext": 3
-  }
-}
\ No newline at end of file
diff --git a/examples/governance/marker.json b/examples/governance/marker.json
index 0d09672..780a800 100644
--- a/examples/governance/marker.json
+++ b/examples/governance/marker.json
@@ -1,8 +1,18 @@
 {
-  "name": "traffic2adminAPI",
+  "name": "demo-mark",
+  "id": "xxx",
+  "status": "enabled",
+  "createTime": "123",
+  "updateTime": "123",
+  "selector": {
+    "app": "xx",
+    "environment": "xx"
+  },
   "spec": {
+    "services": "ser1:1.0,ser2:2.0,ser3",
     "matches": [
       {
+        "name": "match1",
         "headers": {
           "X-User": {
             "regex": "ja.*"
@@ -17,6 +27,7 @@
         ]
       },
       {
+        "name": "match2",
         "apiPath": {
           "exact": "/health"
         },
diff --git a/examples/governance/retry.json b/examples/governance/retry.json
new file mode 100644
index 0000000..03aee5b
--- /dev/null
+++ b/examples/governance/retry.json
@@ -0,0 +1,18 @@
+{
+  "name": "adminAPIRetry",
+  "id": "xxx",
+  "status": "enabled",
+  "createTime": "123",
+  "updateTime": "123",
+  "selector": {
+    "app": "xx",
+    "environment": "xx"
+  },
+  "spec": {
+    "rules": {
+      "match": "traffic2adminAPI"
+    },
+    "maxAttempts": 3,
+    "onSame": false
+  }
+}
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 0aae634..7fe1212 100644
--- a/go.mod
+++ b/go.mod
@@ -3,6 +3,7 @@ module github.com/apache/servicecomb-service-center
 replace google.golang.org/grpc => google.golang.org/grpc v1.19.0
 
 require (
+	bou.ke/monkey v1.0.2
 	github.com/NYTimes/gziphandler v1.0.2-0.20180820182813-253f1acb9d9f
 	github.com/Shopify/sarama v1.27.2 // indirect
 	github.com/apache/thrift v0.0.0-20180125231006-3d556248a8b9 // indirect
@@ -15,11 +16,12 @@ require (
 	github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea // v4
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/dustin/go-humanize v1.0.0 // indirect
+	github.com/ghodss/yaml v1.0.0
 	github.com/go-chassis/cari v0.0.0-20201124050026-32fbf4d53439
 	github.com/go-chassis/foundation v0.2.0
 	github.com/go-chassis/go-archaius v1.3.6-0.20201130023516-387922b408d0
 	github.com/go-chassis/go-chassis/v2 v2.0.5-0.20201125123124-2d38733810fd
-	github.com/go-chassis/openlog v1.1.2
+	github.com/go-chassis/kie-client v0.0.0-20201127085925-8ad6f8fdd9fc
 	github.com/gogo/protobuf v1.3.1
 	github.com/golang/protobuf v1.4.2
 	github.com/gorilla/websocket v1.4.0
@@ -30,6 +32,7 @@ require (
 	github.com/iancoleman/strcase v0.1.2
 	github.com/jonboulle/clockwork v0.2.2 // indirect
 	github.com/karlseguin/ccache v2.0.3-0.20170217060820-3ba9789cfd2c+incompatible
+	github.com/karlseguin/expect v1.0.7 // indirect
 	github.com/labstack/echo v3.2.2-0.20180316170059-a5d81b8d4a62+incompatible
 	github.com/labstack/echo/v4 v4.1.17
 	github.com/mattn/go-runewidth v0.0.9 // indirect
@@ -54,12 +57,14 @@ require (
 	github.com/urfave/cli v1.22.4
 	github.com/widuu/gojson v0.0.0-20170212122013-7da9d2cd949b
 	github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
+	go.etcd.io/bbolt v1.3.5 // indirect
 	go.mongodb.org/mongo-driver v1.4.2
 	go.uber.org/multierr v1.6.0 // indirect
 	go.uber.org/zap v1.10.0
 	golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
 	golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
 	google.golang.org/grpc v1.33.1
+	gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect
 	gopkg.in/yaml.v2 v2.3.0
 	k8s.io/api v0.17.0
 	k8s.io/apimachinery v0.17.0
diff --git a/go.sum b/go.sum
index 8657ff2..8971d66 100644
--- a/go.sum
+++ b/go.sum
@@ -11,6 +11,7 @@ github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxB
 github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
 github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
 github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
@@ -22,6 +23,7 @@ github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdko
 github.com/Shonminh/apollo-client v0.4.0/go.mod h1:Jk6K99uIGxQm7Uyy1gCQTvM/kc1YLp4Qo9/jtGkEXvI=
 github.com/Shopify/sarama v1.27.2 h1:1EyY1dsxNDUQEv0O/4TsjosHI2CgB1uo9H/v56xzTxc=
 github.com/Shopify/sarama v1.27.2/go.mod h1:g5s5osgELxgM+Md9Qni9rzo7Rbt+vvFQI4bt/Mc93II=
+github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@@ -79,20 +81,22 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb
 github.com/emicklei/go-restful v2.12.0+incompatible h1:SIvoTSbsMEwuM3dzFirLwKc4BH6VXP5CNf+G1FfJVr4=
 github.com/emicklei/go-restful v2.12.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
+github.com/frankban/quicktest v1.10.2 h1:19ARM85nVi4xH7xPXuc5eM/udya5ieh7b/Sv+d844Tk=
 github.com/frankban/quicktest v1.10.2/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
 github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
 github.com/go-chassis/cari v0.0.0-20201113135522-88c21500ca3f h1:0ZnGRRUfJWL3zZej/yi4d38WeyXpSPw+01QHADe4l0Q=
 github.com/go-chassis/cari v0.0.0-20201113135522-88c21500ca3f/go.mod h1:8YrlRCUm70ou6KctjVRdKaqF7zWtllgbOtaMWI8tYEw=
-github.com/go-chassis/cari v0.0.0-20201124042558-14041cbb3e6b h1:+2cVxg45mBCD6x7lAQdwROsR9ydKb0G6U7PqHVheZrA=
-github.com/go-chassis/cari v0.0.0-20201124042558-14041cbb3e6b/go.mod h1:jsYzEzPrsmFemVwLj/nhv/+4toFIvqVZRiSWFmkJ4Ms=
 github.com/go-chassis/cari v0.0.0-20201124050026-32fbf4d53439 h1:lcibK+pZYz3sBv7rNOZmjyv3Oeh/ut0yovUR1bXmvNA=
 github.com/go-chassis/cari v0.0.0-20201124050026-32fbf4d53439/go.mod h1:jsYzEzPrsmFemVwLj/nhv/+4toFIvqVZRiSWFmkJ4Ms=
 github.com/go-chassis/foundation v0.1.1-0.20200825060850-b16bf420f7b3 h1:c+bwT0qLY69jSU8TmzuNcb9UL/QFAiU96kjuX5TMiQc=
@@ -101,17 +105,15 @@ github.com/go-chassis/foundation v0.2.0 h1:QzvITxnd1PUys3XR/x31C0YbwwvWsTXQWDEGf
 github.com/go-chassis/foundation v0.2.0/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
 github.com/go-chassis/go-archaius v1.3.6-0.20201103103813-43dd1680ebfb h1:+6mPi1HDASveJ72gWkH0rmq5hNz/rTZhrIgRXjFnSRE=
 github.com/go-chassis/go-archaius v1.3.6-0.20201103103813-43dd1680ebfb/go.mod h1:K9gt8DIj582EQfKQdZV+jWBKNeevwaM+2cdLQgpOlZM=
-github.com/go-chassis/go-archaius v1.3.6-0.20201125122128-5b60384e5d26 h1:LgClOK+rj2OjHZ2PdyRbxVG52gNqWGeqTvIHetv74qQ=
-github.com/go-chassis/go-archaius v1.3.6-0.20201125122128-5b60384e5d26/go.mod h1:plAORQ44oN/6Jxm7+eOQDj7L5jUR6ye17Kg1dtSr2cU=
 github.com/go-chassis/go-archaius v1.3.6-0.20201130023516-387922b408d0 h1:J56y/mYdCk966I8/HqAhyczf8t4DOlZirbQFO+8t/6g=
 github.com/go-chassis/go-archaius v1.3.6-0.20201130023516-387922b408d0/go.mod h1:EVt1gIkrv0laNP1yWxFVmWmOk8YIaw2BaRZx62Q1LHI=
-github.com/go-chassis/go-chassis/v2 v2.0.5-0.20201114043352-d6ab1f0a882d h1:mWjcGCOGlVPHNsrsAJa2aivI0bYVDlM1vA4g9AyY9i0=
-github.com/go-chassis/go-chassis/v2 v2.0.5-0.20201114043352-d6ab1f0a882d/go.mod h1:DHA83QKVmuOtdkaWCP5yCDOh+GIRH+YpX3uZ2BlGMWw=
 github.com/go-chassis/go-chassis/v2 v2.0.5-0.20201125123124-2d38733810fd h1:TkCeUatUsrCNU0yUKpnZyQfswbdQ4quIAgCrmEhD2vQ=
 github.com/go-chassis/go-chassis/v2 v2.0.5-0.20201125123124-2d38733810fd/go.mod h1:DHA83QKVmuOtdkaWCP5yCDOh+GIRH+YpX3uZ2BlGMWw=
 github.com/go-chassis/go-restful-swagger20 v1.0.3-0.20200310030431-17d80f34264f h1:5QmmNpVcGqIc6tuKNe5EAI4PA8Yn2EL9Oee7YdcJ4PE=
 github.com/go-chassis/go-restful-swagger20 v1.0.3-0.20200310030431-17d80f34264f/go.mod h1:eW62fYuzlNFDvIacB6AV8bhUDCTy4myfTCv0bT9Gbb0=
 github.com/go-chassis/kie-client v0.0.0-20201125103729-ea0126f9110d/go.mod h1:RvwNShUU5AvpTLPX3J/klcf/5MYtsmGOSKO9k820s1I=
+github.com/go-chassis/kie-client v0.0.0-20201127085925-8ad6f8fdd9fc h1:pQPCyzNaA4RnS1U1G0+AEjeVlKplsmgXdvl5Xdi+mbk=
+github.com/go-chassis/kie-client v0.0.0-20201127085925-8ad6f8fdd9fc/go.mod h1:RvwNShUU5AvpTLPX3J/klcf/5MYtsmGOSKO9k820s1I=
 github.com/go-chassis/openlog v1.1.1/go.mod h1:ZZOS68OvrFIKEJbuBa4YnYzmxyVx3lmcMfMKb+Hx/yQ=
 github.com/go-chassis/openlog v1.1.2 h1:LgGfwwOhpU8c6URV6ADpaRBPVY7Ph1C28jCQ6zzQawQ=
 github.com/go-chassis/openlog v1.1.2/go.mod h1:+eYCADVxWyJkwsFMUBrMxyQlNqW+UUsCxvR2LrYZUaA=
@@ -161,7 +163,9 @@ github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09Vjb
 github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
 github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
 github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8=
 github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -199,6 +203,7 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
 github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
 github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
 github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
@@ -247,6 +252,7 @@ github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem
 github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
 github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
 github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
 github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
 github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
@@ -257,10 +263,13 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
 github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
 github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 github.com/karlseguin/ccache v2.0.3-0.20170217060820-3ba9789cfd2c+incompatible h1:Yvcw4N+1TaDTNkIuHn3gn8D1KP7Wxn4LP5GngDPWcPQ=
 github.com/karlseguin/ccache v2.0.3-0.20170217060820-3ba9789cfd2c+incompatible/go.mod h1:CM9tNPzT6EdRh14+jiW8mEF9mkNZuuE51qmgGYUB93w=
+github.com/karlseguin/expect v1.0.7 h1:OF4mqjblc450v8nKARBS5Q0AweBNR0A+O3VjjpxwBrg=
+github.com/karlseguin/expect v1.0.7/go.mod h1:lXdI8iGiQhmzpnnmU/EGA60vqKs8NbRNFnhhrJGoD5g=
 github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
 github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
@@ -275,9 +284,11 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
 github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/labstack/echo v3.2.2-0.20180316170059-a5d81b8d4a62+incompatible h1:myCOvigjM7zY/vWklhLPEw9HaOSrPXNtNGsZ3w6RHWs=
 github.com/labstack/echo v3.2.2-0.20180316170059-a5d81b8d4a62+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
@@ -320,6 +331,7 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
 github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
 github.com/natefinch/lumberjack v0.0.0-20170531160350-a96e63847dc3 h1:BDvcX7oM8ZWOS08LQXaW8ucGblfoSG4srpoW6pKhvqs=
 github.com/natefinch/lumberjack v0.0.0-20170531160350-a96e63847dc3/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
 github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
@@ -342,6 +354,7 @@ github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsq
 github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 github.com/openzipkin/zipkin-go-opentracing v0.3.3-0.20180123190626-6bb822a7f15f h1:nn2nWXhr9DIrC4IxlTiwow9G6Zq6jVWdckXhIzYtJOM=
 github.com/openzipkin/zipkin-go-opentracing v0.3.3-0.20180123190626-6bb822a7f15f/go.mod h1:js2AbwmHW0YD9DwIw2JhQWmbfFi/UnWyYwdVhqbCDOE=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
@@ -389,7 +402,9 @@ github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
 github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -404,6 +419,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -411,6 +427,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966 h1:j6JEOq5QWFker+d7mFQYOhjTZonQ7YkLTHm56dbn+yM=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -424,6 +441,8 @@ github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52
 github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
 github.com/widuu/gojson v0.0.0-20170212122013-7da9d2cd949b h1:ieRJ8K7QAPWWltEOv7rzMruuPd7gbeAqTaBFhUECIy0=
 github.com/widuu/gojson v0.0.0-20170212122013-7da9d2cd949b/go.mod h1:9W1pyetRkwXqjR9tjOSrSuhGHBK0EqXoQSwWbhBHHwA=
+github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ=
+github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM=
 github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
 github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
 github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
@@ -431,6 +450,8 @@ github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
 github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
+go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
 go.mongodb.org/mongo-driver v1.4.2 h1:WlnEglfTg/PfPq4WXs2Vkl/5ICC6hoG8+r+LraPmGk4=
 go.mongodb.org/mongo-driver v1.4.2/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@@ -524,6 +545,7 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -583,7 +605,10 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
 gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk=
+gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
@@ -594,6 +619,7 @@ gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hr
 gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
 gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM=
 gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
+gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI=
 gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
 gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg=
 gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
diff --git a/pkg/gov/governance.go b/pkg/gov/governance.go
index bbe0276..d2eb4a0 100644
--- a/pkg/gov/governance.go
+++ b/pkg/gov/governance.go
@@ -22,15 +22,25 @@ package gov
 //Name is the policy name, for example: "rate-limit-payment-api"
 //MD is metadata.
 type GovernancePolicy struct {
-	Name string            `json:"name,omitempty"`
-	MD   map[string]string `json:"metadata,omitempty"`
+	Name       string   `json:"name,omitempty"`
+	ID         string   `json:"id,omitempty"`
+	Status     string   `json:"status,omitempty"`
+	CreatTime  int64    `json:"creatTime,omitempty"`
+	UpdateTime int64    `json:"updateTime,omitempty"`
+	Selector   Selector `json:"selector,omitempty"`
 }
 
-//LoadBalancer define policy and fault tolerant policy
-type LoadBalancer struct {
+//Policy define policy and fault tolerant policy
+type Policy struct {
 	*GovernancePolicy
-	Spec *LBSpec `json:"spec,omitempty"`
+	Spec interface{} `json:"spec,omitempty"`
 }
+
+type Selector struct {
+	App         string `json:"app,omitempty"`
+	Environment string `json:"environment,omitempty"`
+}
+
 type LBSpec struct {
 	MarkerName string         `json:"match"`
 	RetrySame  int            `json:"retrySame,omitempty"`
diff --git a/pkg/gov/governance_test.go b/pkg/gov/governance_test.go
index ada1e1d..fbc9d3a 100644
--- a/pkg/gov/governance_test.go
+++ b/pkg/gov/governance_test.go
@@ -25,7 +25,7 @@ import (
 )
 
 func TestNewInstance3(t *testing.T) {
-	b, _ := json.MarshalIndent(&gov.LoadBalancer{
+	b, _ := json.MarshalIndent(&gov.Policy{
 		GovernancePolicy: &gov.GovernancePolicy{
 			Name: "Traffic2adminAPI",
 		},
@@ -46,11 +46,10 @@ func TestNewInstance(t *testing.T) {
 	b, _ := json.MarshalIndent(&gov.TrafficMarker{
 		GovernancePolicy: &gov.GovernancePolicy{
 			Name: "traffic2adminAPI",
-			MD: map[string]string{
-				"service":     "payment",
-				"version":     "1.0.0",
-				"app":         "default",
-				"environment": "development",
+			ID:   "",
+			Selector: gov.Selector{
+				App:         "default",
+				Environment: "development",
 			},
 		},
 		Spec: &gov.MatchSpec{
diff --git a/server/bootstrap/bootstrap.go b/server/bootstrap/bootstrap.go
index 731d114..87a4a52 100644
--- a/server/bootstrap/bootstrap.go
+++ b/server/bootstrap/bootstrap.go
@@ -62,6 +62,9 @@ import (
 	//module 'syncer'
 	_ "github.com/apache/servicecomb-service-center/server/rest/syncer"
 
+	//governance
+	_ "github.com/apache/servicecomb-service-center/server/service/gov/kie"
+
 	//metrics
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/server/broker"
diff --git a/server/config/config.go b/server/config/config.go
index 94d5f25..91545ad 100644
--- a/server/config/config.go
+++ b/server/config/config.go
@@ -50,7 +50,7 @@ var Configurations = &Config{}
 var ServerInfo = NewServerInformation()
 
 //GetGov return governance configs
-func GetGov() Gov {
+func GetGov() *Gov {
 	return Configurations.Gov
 }
 
diff --git a/server/config/types.go b/server/config/types.go
index 4c74827..3ca396e 100644
--- a/server/config/types.go
+++ b/server/config/types.go
@@ -19,7 +19,7 @@ package config
 
 //Config is yaml file struct
 type Config struct {
-	Gov    Gov                `yaml:"gov"`
+	Gov    *Gov               `yaml:"gov"`
 	Server *ServerInformation `yaml:"server"`
 }
 type Gov struct {
diff --git a/server/resource/v1/gov_resource.go b/server/resource/v1/gov_resource.go
index 76513d9..16694e0 100644
--- a/server/resource/v1/gov_resource.go
+++ b/server/resource/v1/gov_resource.go
@@ -31,16 +31,25 @@ import (
 type Governance struct {
 }
 
+const (
+	AppKey         = "app"
+	EnvironmentKey = "environment"
+	KindKey        = ":kind"
+	ProjectKey     = ":project"
+	IDKey          = ":id"
+)
+
 //Create gov config
 func (t *Governance) Create(w http.ResponseWriter, req *http.Request) {
-	kind := req.URL.Query().Get(":kind")
+	kind := req.URL.Query().Get(KindKey)
+	project := req.URL.Query().Get(ProjectKey)
 	body, err := ioutil.ReadAll(req.Body)
 	if err != nil {
 		log.Error("read body err", err)
 		controller.WriteError(w, discovery.ErrInternal, err.Error())
 		return
 	}
-	err = gov.Create(kind, body)
+	err = gov.Create(kind, project, body)
 	if err != nil {
 		log.Error("create gov err", err)
 		controller.WriteError(w, discovery.ErrInternal, err.Error())
@@ -51,26 +60,84 @@ func (t *Governance) Create(w http.ResponseWriter, req *http.Request) {
 
 //Put gov config
 func (t *Governance) Put(w http.ResponseWriter, req *http.Request) {
-
+	kind := req.URL.Query().Get(KindKey)
+	id := req.URL.Query().Get(IDKey)
+	project := req.URL.Query().Get(ProjectKey)
+	body, err := ioutil.ReadAll(req.Body)
+	if err != nil {
+		log.Error("read body err", err)
+		controller.WriteError(w, discovery.ErrInternal, err.Error())
+		return
+	}
+	err = gov.Update(id, kind, project, body)
+	if err != nil {
+		log.Error("create gov err", err)
+		controller.WriteError(w, discovery.ErrInternal, err.Error())
+		return
+	}
+	w.WriteHeader(http.StatusOK)
 }
 
 //List return all gov config
 func (t *Governance) List(w http.ResponseWriter, req *http.Request) {
+	kind := req.URL.Query().Get(KindKey)
+	project := req.URL.Query().Get(ProjectKey)
+	app := req.URL.Query().Get(AppKey)
+	environment := req.URL.Query().Get(EnvironmentKey)
+	body, err := gov.List(kind, project, app, environment)
+	if err != nil {
+		log.Error("create gov err", err)
+		controller.WriteError(w, discovery.ErrInternal, err.Error())
+		return
+	}
+	_, err = w.Write(body)
+	if err != nil {
+		log.Error("", err)
+	}
+	w.WriteHeader(http.StatusOK)
+	w.Header().Set(rest.HeaderContentType, rest.ContentTypeJSON)
+}
 
+//Get gov config
+func (t *Governance) Get(w http.ResponseWriter, req *http.Request) {
+	id := req.URL.Query().Get(IDKey)
+	project := req.URL.Query().Get(ProjectKey)
+	body, err := gov.Get(id, project)
+	if err != nil {
+		log.Error("create gov err", err)
+		controller.WriteError(w, discovery.ErrInternal, err.Error())
+		return
+	}
+	_, err = w.Write(body)
+	if err != nil {
+		log.Error("", err)
+	}
+	w.WriteHeader(http.StatusOK)
+	w.Header().Set(rest.HeaderContentType, rest.ContentTypeJSON)
 }
 
 //Delete delete gov config
 func (t *Governance) Delete(w http.ResponseWriter, req *http.Request) {
-
+	id := req.URL.Query().Get(IDKey)
+	project := req.URL.Query().Get(ProjectKey)
+	err := gov.Delete(id, project)
+	if err != nil {
+		log.Error("create gov err", err)
+		controller.WriteError(w, discovery.ErrInternal, err.Error())
+		return
+	}
+	w.WriteHeader(http.StatusOK)
 }
+
 func (t *Governance) URLPatterns() []rest.Route {
 	return []rest.Route{
 		//servicecomb.marker.{name}
 		//servicecomb.rateLimiter.{name}
 		//....
-		{Method: http.MethodPost, Path: "/v1/:project/gov/:kind", Func: t.Create},
-		{Method: http.MethodGet, Path: "/v1/:project/gov/:kind", Func: t.List},
-		{Method: http.MethodPut, Path: "/v1/:project/gov/:kind/:name", Func: t.Put},
-		{Method: http.MethodDelete, Path: "/v1/:project/gov/:kind/:name", Func: t.Delete},
+		{Method: http.MethodPost, Path: "/v1/:project/gov/" + KindKey, Func: t.Create},
+		{Method: http.MethodGet, Path: "/v1/:project/gov/" + KindKey, Func: t.List},
+		{Method: http.MethodGet, Path: "/v1/:project/gov/" + KindKey + "/" + IDKey, Func: t.Get},
+		{Method: http.MethodPut, Path: "/v1/:project/gov/" + KindKey + "/" + IDKey, Func: t.Put},
+		{Method: http.MethodDelete, Path: "/v1/:project/gov/" + KindKey + "/" + IDKey, Func: t.Delete},
 	}
 }
diff --git a/server/resource/v1/gov_resource_test.go b/server/resource/v1/gov_resource_test.go
index 192cf9f..832c17a 100644
--- a/server/resource/v1/gov_resource_test.go
+++ b/server/resource/v1/gov_resource_test.go
@@ -10,6 +10,7 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/gov"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/rest"
+	"github.com/apache/servicecomb-service-center/server/config"
 	"github.com/apache/servicecomb-service-center/server/resource/v1"
 	svc "github.com/apache/servicecomb-service-center/server/service/gov"
 	"github.com/go-chassis/go-archaius"
@@ -19,6 +20,14 @@ import (
 )
 
 func init() {
+	config.Configurations.Gov = &config.Gov{
+		DistOptions: []config.DistributorOptions{
+			{
+				Name: "mock",
+				Type: "mock",
+			},
+		},
+	}
 	err := svc.Init()
 	if err != nil {
 		log.Fatal("", err)
@@ -32,7 +41,7 @@ func TestAuthResource_Login(t *testing.T) {
 	rest.RegisterServant(&v1.Governance{})
 
 	t.Run("create policy", func(t *testing.T) {
-		b, _ := json.Marshal(&gov.LoadBalancer{
+		b, _ := json.Marshal(&gov.Policy{
 			GovernancePolicy: &gov.GovernancePolicy{Name: "test"},
 			Spec: &gov.LBSpec{
 				Bo: &gov.BackOffPolicy{InitialInterval: 1}}})
diff --git a/server/service/gov/config_distributor.go b/server/service/gov/config_distributor.go
index 66580c4..c1c4224 100644
--- a/server/service/gov/config_distributor.go
+++ b/server/service/gov/config_distributor.go
@@ -38,10 +38,11 @@ var distributorPlugins = map[string]NewDistributors{}
 //or service mesh system like istio, linkerd.
 //ConfigDistributor will convert standard servicecomb gov config to concrete spec, that data plane can recognize.
 type ConfigDistributor interface {
-	Create(kind string, spec []byte) error
-	Update(kind string, spec []byte) error
-	Delete(name, kind string) error
-	List(kind string) ([]byte, error)
+	Create(kind, project string, spec []byte) error
+	Update(id, kind, project string, spec []byte) error
+	Delete(id, project string) error
+	List(kind, project, app, env string) ([]byte, error)
+	Get(id, project string) ([]byte, error)
 	Type() string
 	Name() string
 }
@@ -72,13 +73,42 @@ func Init() error {
 	}
 	return nil
 }
-func Create(kind string, spec []byte) error {
+
+func Create(kind, project string, spec []byte) error {
 	var err error
 	for _, cd := range distributors {
-		err = cd.Create(kind, spec)
+		err = cd.Create(kind, project, spec)
 		if err != nil {
 			return err
 		}
 	}
 	return nil
 }
+
+func List(kind, project, app, env string) ([]byte, error) {
+	for _, cd := range distributors {
+		return cd.List(kind, project, app, env)
+	}
+	return nil, nil
+}
+
+func Get(id, project string) ([]byte, error) {
+	for _, cd := range distributors {
+		return cd.Get(id, project)
+	}
+	return nil, nil
+}
+
+func Delete(id, project string) error {
+	for _, cd := range distributors {
+		return cd.Delete(id, project)
+	}
+	return nil
+}
+
+func Update(id, kind, project string, spec []byte) error {
+	for _, cd := range distributors {
+		return cd.Update(id, kind, project, spec)
+	}
+	return nil
+}
diff --git a/server/service/gov/config_distributor_test.go b/server/service/gov/config_distributor_test.go
index f61775b..fbb0d73 100644
--- a/server/service/gov/config_distributor_test.go
+++ b/server/service/gov/config_distributor_test.go
@@ -30,7 +30,7 @@ import (
 
 func TestCreate(t *testing.T) {
 	config.Configurations = &config.Config{
-		Gov: config.Gov{
+		Gov: &config.Gov{
 			DistOptions: []config.DistributorOptions{
 				{
 					Name: "mockServer",
@@ -41,12 +41,12 @@ func TestCreate(t *testing.T) {
 	}
 	err := svc.Init()
 	assert.NoError(t, err)
-	b, _ := json.MarshalIndent(&gov.LoadBalancer{
+	b, _ := json.MarshalIndent(&gov.Policy{
 		GovernancePolicy: &gov.GovernancePolicy{
 			Name: "Traffic2adminAPI",
 		},
 		Spec: &gov.LBSpec{RetryNext: 3, MarkerName: "traffic2adminAPI"},
 	}, "", "  ")
-	err = svc.Create("lb", b)
+	err = svc.Create("lb", "default", b)
 	assert.NoError(t, err)
 }
diff --git a/server/service/gov/kie/kie_distributor.go b/server/service/gov/kie/kie_distributor.go
new file mode 100644
index 0000000..df43e31
--- /dev/null
+++ b/server/service/gov/kie/kie_distributor.go
@@ -0,0 +1,206 @@
+package kie
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"fmt"
+	"log"
+	"strings"
+
+	"github.com/apache/servicecomb-service-center/pkg/gov"
+	"github.com/apache/servicecomb-service-center/server/config"
+	svc "github.com/apache/servicecomb-service-center/server/service/gov"
+	"github.com/ghodss/yaml"
+	"github.com/go-chassis/kie-client"
+)
+
+type Distributor struct {
+	lbPolicies map[string]*gov.Policy
+	name       string
+	client     *kie.Client
+}
+
+const (
+	PREFIX         = "servicecomb."
+	EnableStatus   = "enabled"
+	ValueType      = "text"
+	AppKey         = "app"
+	EnvironmentKey = "environment"
+)
+
+var rule = Validator{}
+
+func (d *Distributor) Create(kind, project string, spec []byte) error {
+	p := &gov.Policy{}
+	err := json.Unmarshal(spec, p)
+	if err != nil {
+		return err
+	}
+	log.Println(fmt.Sprintf("create %v", &p))
+	key := toSnake(kind) + "." + p.Name
+	err = rule.Validate(kind, p.Spec)
+	if err != nil {
+		return err
+	}
+	yamlByte, err := yaml.Marshal(p.Spec)
+	if err != nil {
+		return err
+	}
+	kv := kie.KVRequest{
+		Key:       PREFIX + key,
+		Value:     string(yamlByte),
+		Status:    EnableStatus,
+		ValueType: ValueType,
+		Labels:    map[string]string{AppKey: p.Selector.App, EnvironmentKey: p.Selector.Environment},
+	}
+	_, err = d.client.Create(context.TODO(), kv, kie.WithProject(project))
+	if err != nil {
+		log.Fatal("kie create failed", err)
+		return err
+	}
+	d.lbPolicies[p.GovernancePolicy.Name] = p
+	return nil
+}
+
+func (d *Distributor) Update(id, kind, project string, spec []byte) error {
+	p := &gov.Policy{}
+	err := json.Unmarshal(spec, p)
+	if err != nil {
+		return err
+	}
+	log.Println(fmt.Sprintf("update %v", &p))
+	err = rule.Validate(kind, p.Spec)
+	if err != nil {
+		return err
+	}
+	yamlByte, err := yaml.Marshal(p.Spec)
+	if err != nil {
+		return err
+	}
+	kv := kie.KVRequest{
+		ID:     id,
+		Value:  string(yamlByte),
+		Status: p.Status,
+	}
+	_, err = d.client.Put(context.TODO(), kv, kie.WithProject(project))
+	if err != nil {
+		log.Fatal("kie update failed", err)
+		return err
+	}
+	d.lbPolicies[p.GovernancePolicy.Name] = p
+	return nil
+}
+
+func (d *Distributor) Delete(id, project string) error {
+	err := d.client.Delete(context.TODO(), id, kie.WithProject(project))
+	if err != nil {
+		log.Fatal("kie delete failed", err)
+		return err
+	}
+	return nil
+}
+
+func (d *Distributor) List(kind, project, app, env string) ([]byte, error) {
+	list, _, err := d.client.List(context.TODO(),
+		kie.WithKey("beginWith("+PREFIX+toSnake(kind)+")"),
+		kie.WithLabels(map[string]string{AppKey: app, EnvironmentKey: env}),
+		kie.WithRevision(0),
+		kie.WithGetProject(project))
+	if err != nil {
+		return nil, err
+	}
+	r := make([]*gov.Policy, 0, list.Total)
+	for _, item := range list.Data {
+		goc := &gov.Policy{
+			GovernancePolicy: &gov.GovernancePolicy{},
+		}
+		spec := make(map[string]interface{})
+		specJSON, _ := yaml.YAMLToJSON([]byte(item.Value))
+		err = json.Unmarshal(specJSON, &spec)
+		if err != nil {
+			log.Fatal("kie list failed", err)
+			return nil, err
+		}
+		goc.ID = item.ID
+		goc.Status = item.Status
+		goc.Name = item.Key
+		goc.Spec = spec
+		goc.Selector.App = item.Labels[AppKey]
+		goc.Selector.Environment = item.Labels[EnvironmentKey]
+		goc.CreatTime = item.CreatTime
+		goc.UpdateTime = item.UpdateTime
+		r = append(r, goc)
+	}
+	b, _ := json.MarshalIndent(r, "", "  ")
+	return b, nil
+}
+
+func (d *Distributor) Get(id, project string) ([]byte, error) {
+	kv, err := d.client.Get(context.TODO(), id, kie.WithGetProject(project))
+	if err != nil {
+		log.Fatal("kie get failed", err)
+		return nil, err
+	}
+	goc := &gov.Policy{
+		GovernancePolicy: &gov.GovernancePolicy{},
+	}
+	goc.ID = kv.ID
+	goc.Status = kv.Status
+	goc.Name = kv.Key
+	goc.Spec = kv
+	goc.Selector.App = kv.Labels[AppKey]
+	goc.Selector.Environment = kv.Labels[EnvironmentKey]
+	goc.CreatTime = kv.CreatTime
+	goc.UpdateTime = kv.UpdateTime
+	b, _ := json.MarshalIndent(goc, "", "  ")
+	return b, nil
+}
+
+func (d *Distributor) Type() string {
+	return svc.ConfigDistributorKie
+}
+func (d *Distributor) Name() string {
+	return d.name
+}
+
+func initClient(endpoint string) *kie.Client {
+	client, err := kie.NewClient(
+		kie.Config{Endpoint: endpoint,
+			DefaultLabels: map[string]string{},
+		})
+	if err != nil {
+		log.Fatalf("init kie client failed, err: %s", err)
+	}
+	return client
+}
+
+func new(opts config.DistributorOptions) (svc.ConfigDistributor, error) {
+	return &Distributor{name: opts.Name, lbPolicies: map[string]*gov.Policy{}, client: initClient(opts.Endpoint)}, nil
+}
+
+func toSnake(name string) string {
+	if name == "" {
+		return ""
+	}
+	temp := strings.Split(name, "-")
+	var buffer bytes.Buffer
+	for num, v := range temp {
+		vv := []rune(v)
+		if num == 0 {
+			buffer.WriteString(string(vv))
+			continue
+		}
+		if len(vv) > 0 {
+			if vv[0] >= 'a' && vv[0] <= 'z' { //首字母大写
+				vv[0] -= 32
+			}
+			buffer.WriteString(string(vv))
+		}
+	}
+	return buffer.String()
+}
+
+func init() {
+	svc.InstallDistributor(svc.ConfigDistributorKie, new)
+}
diff --git a/server/service/gov/kie/validate.go b/server/service/gov/kie/validate.go
new file mode 100644
index 0000000..5ab7275
--- /dev/null
+++ b/server/service/gov/kie/validate.go
@@ -0,0 +1,116 @@
+package kie
+
+import (
+	"fmt"
+)
+
+type Validator struct {
+}
+
+var methodSet map[string]bool
+
+func (d *Validator) Validate(kind string, spec interface{}) error {
+	switch kind {
+	case "match-group":
+		return matchValidate(spec)
+	case "retry":
+		return retryValidate(spec)
+	case "rateLimiting":
+		return rateLimitingValidate(spec)
+	case "circuitBreaker":
+	case "bulkhead":
+	case "loadbalancer":
+		return nil
+	default:
+		return fmt.Errorf("not support kind yet")
+	}
+	return nil
+}
+
+func matchValidate(val interface{}) error {
+	spec, ok := val.(map[string]interface{})
+	if !ok {
+		return fmt.Errorf("illegal item : %v", val)
+	}
+	matches, ok := spec["matches"].([]interface{})
+	if !ok {
+		return fmt.Errorf("illegal item : %v", spec)
+	}
+	for _, match := range matches {
+		match, ok := match.(map[string]interface{})
+		if !ok {
+			return fmt.Errorf("illegal item : %v", match)
+		}
+		if match["name"] == nil {
+			return fmt.Errorf("match's name can not be null : %v", match)
+		}
+		if match["apiPath"] == nil && match["headers"] == nil && match["methods"] == nil {
+			return fmt.Errorf("match must have a match item [apiPath/headers/methods] %v", match)
+		}
+		//apiPath & headers do not check
+		if match["methods"] != nil {
+			methods, ok := match["methods"].([]string)
+			if !ok {
+				return fmt.Errorf("illegal item : %v", match)
+			}
+			for _, method := range methods {
+				if !methodSet[method] {
+					return fmt.Errorf("method must be one of the GET/POST/PUT/DELETE: %v", match)
+				}
+			}
+		}
+	}
+	return nil
+}
+
+func retryValidate(val interface{}) error {
+	err := policyValidate(val)
+	if err != nil {
+		return err
+	}
+	// item check
+	spec := val.(map[string]interface{})
+	maxAttempts, ok := spec["maxAttempts"].(int)
+	if !ok {
+		return fmt.Errorf("illegal item : %v", spec)
+	}
+	if maxAttempts >= 0 {
+		return fmt.Errorf("maxAttempts must be a positive num : %v", spec)
+	}
+	_, ok = spec["onSame"].(bool)
+	if !ok {
+		return fmt.Errorf("illegal item : %v", spec)
+	}
+	return nil
+}
+
+func rateLimitingValidate(val interface{}) error {
+	err := policyValidate(val)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func policyValidate(val interface{}) error {
+	spec, ok := val.(map[string]interface{})
+	if !ok {
+		return fmt.Errorf("illegal item : %v", val)
+	}
+	rules, ok := spec["rules"].(map[string]string)
+	if !ok {
+		return fmt.Errorf("illegal item : %v", spec)
+	}
+	if "" == rules["match"] {
+		return fmt.Errorf("policy's match can not be nil: %v", spec)
+	}
+	return nil
+}
+
+func init() {
+	methodSet = make(map[string]bool)
+	methodSet["GET"] = true
+	methodSet["POST"] = true
+	methodSet["DELETE"] = true
+	methodSet["PUT"] = true
+}
diff --git a/server/service/gov/mock/mock.go b/server/service/gov/mock/mock.go
index b8ded33..cc6359c 100644
--- a/server/service/gov/mock/mock.go
+++ b/server/service/gov/mock/mock.go
@@ -28,36 +28,40 @@ import (
 )
 
 type Distributor struct {
-	lbPolicies map[string]*gov.LoadBalancer
+	lbPolicies map[string]*gov.Policy
 	name       string
 }
 
-func (d *Distributor) Create(kind string, spec []byte) error {
-	p := &gov.LoadBalancer{}
+func (d *Distributor) Create(kind, project string, spec []byte) error {
+	p := &gov.Policy{}
 	err := json.Unmarshal(spec, p)
 	log.Println(fmt.Sprintf("create %v", &p))
 	d.lbPolicies[p.GovernancePolicy.Name] = p
 	return err
 }
-func (d *Distributor) Update(kind string, spec []byte) error {
-	p := &gov.LoadBalancer{}
+func (d *Distributor) Update(id, kind, project string, spec []byte) error {
+	p := &gov.Policy{}
 	err := json.Unmarshal(spec, p)
 	log.Println("update ", p)
 	d.lbPolicies[p.GovernancePolicy.Name] = p
 	return err
 }
-func (d *Distributor) Delete(name, kind string) error {
-	delete(d.lbPolicies, name)
+func (d *Distributor) Delete(id, project string) error {
+	delete(d.lbPolicies, id)
 	return nil
 }
-func (d *Distributor) List(kind string) ([]byte, error) {
-	r := make([]*gov.LoadBalancer, len(d.lbPolicies))
+func (d *Distributor) List(kind, project, app, env string) ([]byte, error) {
+	r := make([]*gov.Policy, 0, len(d.lbPolicies))
 	for _, g := range d.lbPolicies {
 		r = append(r, g)
 	}
 	b, _ := json.MarshalIndent(r, "", "  ")
 	return b, nil
 }
+
+func (d *Distributor) Get(id, project string) ([]byte, error) {
+	return nil, nil
+}
 func (d *Distributor) Type() string {
 	return svc.ConfigDistributorMock
 }
@@ -65,7 +69,7 @@ func (d *Distributor) Name() string {
 	return d.name
 }
 func new(opts config.DistributorOptions) (svc.ConfigDistributor, error) {
-	return &Distributor{name: opts.Name, lbPolicies: map[string]*gov.LoadBalancer{}}, nil
+	return &Distributor{name: opts.Name, lbPolicies: map[string]*gov.Policy{}}, nil
 }
 func init() {
 	svc.InstallDistributor(svc.ConfigDistributorMock, new)