You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2022/08/08 08:55:08 UTC

[servicecomb-service-center] branch master updated: refactor policy validator (#1323)

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

littlecui 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 b69e249f refactor policy validator (#1323)
b69e249f is described below

commit b69e249f68e62f9d560c0c4a4568759e5801b688
Author: Shawn <xi...@gmail.com>
AuthorDate: Mon Aug 8 16:55:03 2022 +0800

    refactor policy validator (#1323)
---
 datasource/mongo/ms_test.go                        |  1 -
 .../request/register_intance_json.sh               |  3 +-
 go.sum                                             | 10 +++
 server/bootstrap/bootstrap.go                      |  3 +-
 server/ext/policy/buitin.go                        | 51 +++++++++++++++
 server/resource/gov/gov_resource.go                | 25 ++++----
 server/resource/gov/gov_resource_test.go           | 30 ++++++---
 server/server.go                                   |  4 +-
 server/service/{gov => grc}/config_distributor.go  |  2 +-
 .../{gov => grc}/config_distributor_test.go        | 27 ++++----
 server/service/{gov => grc}/kie/kie_distributor.go | 75 ++++++++--------------
 server/service/{gov => grc}/mock/mock.go           |  8 +--
 server/service/{gov => grc}/policy.go              | 31 +++++----
 server/service/{gov => grc}/policy_test.go         | 12 ++--
 server/service/{gov/kie => grc}/validate.go        | 33 ++++++----
 15 files changed, 191 insertions(+), 124 deletions(-)

diff --git a/datasource/mongo/ms_test.go b/datasource/mongo/ms_test.go
index ae6f99a7..ada39f57 100644
--- a/datasource/mongo/ms_test.go
+++ b/datasource/mongo/ms_test.go
@@ -138,4 +138,3 @@ func TestSyncMicroService(t *testing.T) {
 		})
 	})
 }
-
diff --git a/examples/service_center/request/register_intance_json.sh b/examples/service_center/request/register_intance_json.sh
index da799f61..a21aaf79 100644
--- a/examples/service_center/request/register_intance_json.sh
+++ b/examples/service_center/request/register_intance_json.sh
@@ -27,8 +27,9 @@ Postman-Token: bf33f47f-acfe-76fe-8c53-d1f79a46b246
 	"instance": 
 	{
 	    "endpoints": [
-			"ase://127.0.0.1:99841"
+			"grpc://127.0.0.1:99841"
 		],
+		"virtualAddress": "xxx.xxx.xxx.local:8080"
 		"hostName":"ase",
 		"status":"UP",
 		"environment":"production",
diff --git a/go.sum b/go.sum
index 3165904f..6590fc44 100644
--- a/go.sum
+++ b/go.sum
@@ -264,6 +264,7 @@ github.com/go-chassis/cari v0.0.0-20201210041921-7b6fbef2df11/go.mod h1:MgtsEI0A
 github.com/go-chassis/cari v0.4.0/go.mod h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SKa4Avrd8=
 github.com/go-chassis/cari v0.5.0/go.mod h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SKa4Avrd8=
 github.com/go-chassis/cari v0.5.1-0.20210823023004-74041d1363c4/go.mod h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SKa4Avrd8=
+github.com/go-chassis/cari v0.5.1-0.20220216075429-46c79de3311f/go.mod h1:tKTzguHTGohMCgkcWNZWtA4TwfcsJrIXpfYxsQtb7uw=
 github.com/go-chassis/cari v0.6.0 h1:cwBchwt9L8JOyO6QkzXFAsseMJ10zVSiVK8eDLD0HkA=
 github.com/go-chassis/cari v0.6.0/go.mod h1:mSDRCOQXGmlD69A6NG0hsv0UP1xbVPtL6HCGI6X1tqs=
 github.com/go-chassis/foundation v0.2.2-0.20201210043510-9f6d3de40234/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
@@ -272,16 +273,20 @@ github.com/go-chassis/foundation v0.3.0/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27
 github.com/go-chassis/foundation v0.4.0 h1:z0xETnSxF+vRXWjoIhOdzt6rywjZ4sB++utEl4YgWEY=
 github.com/go-chassis/foundation v0.4.0/go.mod h1:6NsIUaHghTFRGfCBcZN011zl196F6OR5QvD9N+P4oWU=
 github.com/go-chassis/go-archaius v1.5.1/go.mod h1:QPwvvtBxvwiC48rmydoAqxopqOr93RCQ6syWsIkXPXQ=
+github.com/go-chassis/go-archaius v1.5.2-0.20210301074935-e4694f6b077b/go.mod h1:qjfG7opNF/QTzj7SyVIn/eIawaPhl7xeGgg8kxzFsDw=
 github.com/go-chassis/go-archaius v1.5.6 h1:MF/yE9Mj51slccW6EmZInjFCmyfuhltRz9eu5Na4i88=
 github.com/go-chassis/go-archaius v1.5.6/go.mod h1:WsqeDyZsCR2qGdWEAEpywS1taxCUHRF4hPSHVMfnAkc=
 github.com/go-chassis/go-chassis-extension/protocol/grpc v0.0.0-20220208081606-003611df45da h1:DoPFX1Fy3MLEb1RvgchInKspm8DkxQhrvZ5kOcjeZAs=
 github.com/go-chassis/go-chassis-extension/protocol/grpc v0.0.0-20220208081606-003611df45da/go.mod h1:btid7R4NKuET4BCUkR74CL5EP0hk3J0jXSByjzwd9JM=
 github.com/go-chassis/go-chassis/v2 v2.3.0/go.mod h1:iyJ2DWSkqfnCmad/0Il9nXWHaob7RcwPGlIDRNxccH0=
+github.com/go-chassis/go-chassis/v2 v2.3.1-0.20211217084436-360a6a6a0ef3/go.mod h1:oMnRaz2P+OPTtEfh2HEuiF9YzdYHQrNVPXdnbKzKO9w=
 github.com/go-chassis/go-chassis/v2 v2.4.0 h1:BMmOS2zM/E8KDUoCNpSqalhFsW9fRjwh2Pz5wk1EGC8=
 github.com/go-chassis/go-chassis/v2 v2.4.0/go.mod h1:oMnRaz2P+OPTtEfh2HEuiF9YzdYHQrNVPXdnbKzKO9w=
 github.com/go-chassis/go-restful-swagger20 v1.0.3 h1:kWfeLwMwJZVkXP1zNyFpkmR41UZ55UTcOptTteXhvEs=
 github.com/go-chassis/go-restful-swagger20 v1.0.3/go.mod h1:eW62fYuzlNFDvIacB6AV8bhUDCTy4myfTCv0bT9Gbb0=
 github.com/go-chassis/kie-client v0.0.0-20201210060018-938c7680a9ab/go.mod h1:UTdbtyN5ge/v9DmQzdVRxQP7z51Q4z6hyl+W6ZpUHFM=
+github.com/go-chassis/kie-client v0.1.0/go.mod h1:UTdbtyN5ge/v9DmQzdVRxQP7z51Q4z6hyl+W6ZpUHFM=
+github.com/go-chassis/kie-client v0.1.1-0.20210926011742-97eed4281056/go.mod h1:N4SrGTb+e9ZiuOOU9vC/AohqsDtCkY2amNAPcvpEem0=
 github.com/go-chassis/kie-client v0.2.0 h1:9/BXLu8HaH9b7WLIrtizfhtbBaQEZlsbsk9c8z+mhgc=
 github.com/go-chassis/kie-client v0.2.0/go.mod h1:JCyQeOZcr3ti79tc8tix0VzkC2YpB5j7PRbsOmQGcKQ=
 github.com/go-chassis/openlog v1.1.2/go.mod h1:+eYCADVxWyJkwsFMUBrMxyQlNqW+UUsCxvR2LrYZUaA=
@@ -620,6 +625,7 @@ github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kN
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
 github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
@@ -932,6 +938,8 @@ go.etcd.io/etcd/raft/v3 v3.5.4/go.mod h1:SCuunjYvZFC0fBX0vxMSPjuZmpcSk+XaAcMrD6D
 go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
 go.etcd.io/etcd/server/v3 v3.5.4 h1:CMAZd0g8Bn5NRhynW6pKhc4FRg41/0QYy3d7aNm9874=
 go.etcd.io/etcd/server/v3 v3.5.4/go.mod h1:S5/YTU15KxymM5l3T6b09sNOHPXqGYIZStpuuGbb65c=
+go.mongodb.org/mongo-driver v1.4.2/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
+go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
 go.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI=
 go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw=
 go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
@@ -992,6 +1000,7 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -1001,6 +1010,7 @@ golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 h1:71vQrMauZZhcTVK6KdYM+rklehEEwb3E+ZhaE5jrPrE=
diff --git a/server/bootstrap/bootstrap.go b/server/bootstrap/bootstrap.go
index 46cb5b9d..b9aeccc5 100644
--- a/server/bootstrap/bootstrap.go
+++ b/server/bootstrap/bootstrap.go
@@ -60,7 +60,8 @@ import (
 	_ "github.com/apache/servicecomb-service-center/server/rest/admin"
 
 	//governance
-	_ "github.com/apache/servicecomb-service-center/server/service/gov/kie"
+	_ "github.com/apache/servicecomb-service-center/server/ext/policy"
+	_ "github.com/apache/servicecomb-service-center/server/service/grc/kie"
 
 	//metrics
 	_ "github.com/apache/servicecomb-service-center/server/rest/metrics"
diff --git a/server/ext/policy/buitin.go b/server/ext/policy/buitin.go
new file mode 100644
index 00000000..ddae6924
--- /dev/null
+++ b/server/ext/policy/buitin.go
@@ -0,0 +1,51 @@
+package policy
+
+import (
+	"github.com/apache/servicecomb-service-center/server/service/grc"
+	"k8s.io/kube-openapi/pkg/validation/spec"
+)
+
+func init() {
+	grc.RegisterPolicySchema("loadbalancer", &spec.Schema{
+		SchemaProps: spec.SchemaProps{
+			Type:     []string{"object"},
+			Required: []string{"rule"},
+			Properties: map[string]spec.Schema{
+				"rule": {
+					SchemaProps: spec.SchemaProps{Type: []string{"string"}}},
+			},
+		}})
+	grc.RegisterPolicySchema("circuitBreaker", &spec.Schema{
+		SchemaProps: spec.SchemaProps{
+			Type: []string{"object"},
+			Properties: map[string]spec.Schema{
+				"minimumNumberOfCalls": {
+					SchemaProps: spec.SchemaProps{Type: []string{"integer"}}},
+			},
+		}})
+	grc.RegisterPolicySchema("instanceIsolation", &spec.Schema{
+		SchemaProps: spec.SchemaProps{
+			Type: []string{"object"},
+			Properties: map[string]spec.Schema{
+				"minimumNumberOfCalls": {
+					SchemaProps: spec.SchemaProps{Type: []string{"integer"}}},
+			},
+		}})
+	grc.RegisterPolicySchema("faultInjection", &spec.Schema{
+		SchemaProps: spec.SchemaProps{
+			Type: []string{"object"},
+			Properties: map[string]spec.Schema{
+				"percentage": {
+					SchemaProps: spec.SchemaProps{Type: []string{"integer"}}},
+			},
+		}})
+	grc.RegisterPolicySchema("bulkhead", &spec.Schema{
+		SchemaProps: spec.SchemaProps{
+			Type: []string{"object"},
+			Properties: map[string]spec.Schema{
+				"maxConcurrentCalls": {
+					SchemaProps: spec.SchemaProps{Type: []string{"integer"}}},
+			},
+		}})
+
+}
diff --git a/server/resource/gov/gov_resource.go b/server/resource/gov/gov_resource.go
index 9a77b32a..ee7cfd49 100644
--- a/server/resource/gov/gov_resource.go
+++ b/server/resource/gov/gov_resource.go
@@ -26,8 +26,7 @@ import (
 	model "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/service/gov"
-	"github.com/apache/servicecomb-service-center/server/service/gov/kie"
+	"github.com/apache/servicecomb-service-center/server/service/grc"
 	"github.com/go-chassis/cari/discovery"
 )
 
@@ -63,15 +62,15 @@ func (t *Governance) Create(w http.ResponseWriter, r *http.Request) {
 		rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
 		return
 	}
-	err = gov.ValidateSpec(kind, p.Spec)
+	err = grc.ValidatePolicySpec(kind, p.Spec)
 	if err != nil {
-		log.Error("validate policy err", err)
+		log.Error(fmt.Sprintf("validate policy [%s] err", kind), err)
 		rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
 		return
 	}
-	id, err := gov.Create(r.Context(), kind, project, p)
+	id, err := grc.Create(r.Context(), kind, project, p)
 	if err != nil {
-		if _, ok := err.(*kie.ErrIllegalItem); ok {
+		if _, ok := err.(*grc.ErrIllegalItem); ok {
 			log.Error("", err)
 			rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
 			return
@@ -101,16 +100,16 @@ func (t *Governance) Put(w http.ResponseWriter, r *http.Request) {
 		rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
 		return
 	}
-	err = gov.ValidateSpec(kind, p.Spec)
+	err = grc.ValidatePolicySpec(kind, p.Spec)
 	if err != nil {
 		log.Error("validate policy err", err)
 		rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
 		return
 	}
 	log.Info(fmt.Sprintf("update %v", &p))
-	err = gov.Update(r.Context(), kind, id, project, p)
+	err = grc.Update(r.Context(), kind, id, project, p)
 	if err != nil {
-		if _, ok := err.(*kie.ErrIllegalItem); ok {
+		if _, ok := err.(*grc.ErrIllegalItem); ok {
 			log.Error("", err)
 			rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
 			return
@@ -131,9 +130,9 @@ func (t *Governance) ListOrDisPlay(w http.ResponseWriter, r *http.Request) {
 	var body []byte
 	var err error
 	if kind == DisplayKey {
-		body, err = gov.Display(r.Context(), project, app, environment)
+		body, err = grc.Display(r.Context(), project, app, environment)
 	} else {
-		body, err = gov.List(r.Context(), kind, project, app, environment)
+		body, err = grc.List(r.Context(), kind, project, app, environment)
 	}
 	if err != nil {
 		processError(w, err, "list gov err")
@@ -148,7 +147,7 @@ func (t *Governance) Get(w http.ResponseWriter, r *http.Request) {
 	kind := query.Get(KindKey)
 	id := query.Get(IDKey)
 	project := query.Get(ProjectKey)
-	body, err := gov.Get(r.Context(), kind, id, project)
+	body, err := grc.Get(r.Context(), kind, id, project)
 	if err != nil {
 		processError(w, err, "get gov err")
 		return
@@ -162,7 +161,7 @@ func (t *Governance) Delete(w http.ResponseWriter, r *http.Request) {
 	kind := query.Get(KindKey)
 	id := query.Get(IDKey)
 	project := query.Get(ProjectKey)
-	err := gov.Delete(r.Context(), kind, id, project)
+	err := grc.Delete(r.Context(), kind, id, project)
 	if err != nil {
 		processError(w, err, "delete gov err")
 		return
diff --git a/server/resource/gov/gov_resource_test.go b/server/resource/gov/gov_resource_test.go
index d41fa690..aab89cd3 100644
--- a/server/resource/gov/gov_resource_test.go
+++ b/server/resource/gov/gov_resource_test.go
@@ -24,16 +24,20 @@ import (
 	"net/http/httptest"
 	"testing"
 
+	_ "github.com/apache/servicecomb-service-center/test"
+
 	"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"
 	v1 "github.com/apache/servicecomb-service-center/server/resource/gov"
-	svc "github.com/apache/servicecomb-service-center/server/service/gov"
+	grcsvc "github.com/apache/servicecomb-service-center/server/service/grc"
 	"github.com/go-chassis/go-archaius"
 	"github.com/stretchr/testify/assert"
 
-	_ "github.com/apache/servicecomb-service-center/server/service/gov/mock"
+	_ "github.com/apache/servicecomb-service-center/server/service/grc/mock"
+
+	_ "github.com/apache/servicecomb-service-center/server/ext/policy"
 )
 
 func init() {
@@ -44,7 +48,7 @@ func init() {
 			},
 		},
 	}
-	err := svc.Init()
+	err := grcsvc.Init()
 	if err != nil {
 		log.Fatal("", err)
 	}
@@ -53,19 +57,27 @@ func TestGovernance_Create(t *testing.T) {
 	err := archaius.Init(archaius.WithMemorySource(), archaius.WithENVSource())
 	assert.NoError(t, err)
 
-	svc.Init()
+	grcsvc.Init()
 	rest.RegisterServant(&v1.Governance{})
 
-	t.Run("create policy", func(t *testing.T) {
+	t.Run("create load balancing, should success", func(t *testing.T) {
 		b, _ := json.Marshal(&gov.Policy{
 			GovernancePolicy: &gov.GovernancePolicy{Name: "test"},
 			Spec: map[string]interface{}{
-				"backoff": &gov.BackOffPolicy{InitialInterval: 1}}})
-
-		r, _ := http.NewRequest(http.MethodPost, "/v1/default/gov/loadBalancer", bytes.NewBuffer(b))
+				"rule": "rr",
+			}})
+		r, _ := http.NewRequest(http.MethodPost, "/v1/default/gov/loadbalancer", bytes.NewBuffer(b))
 		w := httptest.NewRecorder()
 		rest.GetRouter().ServeHTTP(w, r)
 		assert.Equal(t, http.StatusOK, w.Code)
 	})
-
+	t.Run("create load balancing without rule, should failed", func(t *testing.T) {
+		b, _ := json.Marshal(&gov.Policy{
+			GovernancePolicy: &gov.GovernancePolicy{Name: "test"},
+			Spec:             map[string]interface{}{}})
+		r, _ := http.NewRequest(http.MethodPost, "/v1/default/gov/loadbalancer", bytes.NewBuffer(b))
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusBadRequest, w.Code)
+	})
 }
diff --git a/server/server.go b/server/server.go
index ca3933d4..fbef2fe2 100644
--- a/server/server.go
+++ b/server/server.go
@@ -32,7 +32,7 @@ import (
 	"github.com/apache/servicecomb-service-center/server/config"
 	"github.com/apache/servicecomb-service-center/server/event"
 	"github.com/apache/servicecomb-service-center/server/plugin/security/tlsconf"
-	"github.com/apache/servicecomb-service-center/server/service/gov"
+	"github.com/apache/servicecomb-service-center/server/service/grc"
 	"github.com/apache/servicecomb-service-center/server/service/rbac"
 	"github.com/go-chassis/foundation/gopool"
 )
@@ -163,7 +163,7 @@ func (s *ServiceCenterServer) startServices() {
 	// load server plugins
 	plugin.LoadPlugins()
 	rbac.Init()
-	if err := gov.Init(); err != nil {
+	if err := grc.Init(); err != nil {
 		log.Fatal("init gov failed", err)
 	}
 	// check version
diff --git a/server/service/gov/config_distributor.go b/server/service/grc/config_distributor.go
similarity index 99%
rename from server/service/gov/config_distributor.go
rename to server/service/grc/config_distributor.go
index 08a25022..4a87d906 100644
--- a/server/service/gov/config_distributor.go
+++ b/server/service/grc/config_distributor.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package gov
+package grc
 
 import (
 	"context"
diff --git a/server/service/gov/config_distributor_test.go b/server/service/grc/config_distributor_test.go
similarity index 81%
rename from server/service/gov/config_distributor_test.go
rename to server/service/grc/config_distributor_test.go
index 9ed9b643..857e58c1 100644
--- a/server/service/gov/config_distributor_test.go
+++ b/server/service/grc/config_distributor_test.go
@@ -15,18 +15,19 @@
  * limitations under the License.
  */
 
-package gov_test
+package grc_test
 
 import (
 	"context"
 	"encoding/json"
 	"testing"
 
+	"github.com/stretchr/testify/assert"
+
 	"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/apache/servicecomb-service-center/server/service/gov/mock"
-	"github.com/stretchr/testify/assert"
+	grcsvc "github.com/apache/servicecomb-service-center/server/service/grc"
+	_ "github.com/apache/servicecomb-service-center/server/service/grc/mock"
 )
 
 const Project = "default"
@@ -47,14 +48,14 @@ func init() {
 			},
 		},
 	}
-	err := svc.Init()
+	err := grcsvc.Init()
 	if err != nil {
 		panic(err)
 	}
 }
 
 func TestCreate(t *testing.T) {
-	res, err := svc.Create(context.TODO(), MockKind, Project, &gov.Policy{
+	res, err := grcsvc.Create(context.TODO(), MockKind, Project, &gov.Policy{
 		GovernancePolicy: &gov.GovernancePolicy{
 			Name: "Traffic2adminAPI",
 			Selector: gov.Selector{
@@ -70,7 +71,7 @@ func TestCreate(t *testing.T) {
 }
 
 func TestUpdate(t *testing.T) {
-	err := svc.Update(context.TODO(), MockKind, id, Project, &gov.Policy{
+	err := grcsvc.Update(context.TODO(), MockKind, id, Project, &gov.Policy{
 		GovernancePolicy: &gov.GovernancePolicy{
 			Name: "Traffic2adminAPI",
 			Selector: gov.Selector{
@@ -84,7 +85,7 @@ func TestUpdate(t *testing.T) {
 }
 
 func TestDisplay(t *testing.T) {
-	res, err := svc.Create(context.TODO(), MatchGroup, Project, &gov.Policy{
+	res, err := grcsvc.Create(context.TODO(), MatchGroup, Project, &gov.Policy{
 		GovernancePolicy: &gov.GovernancePolicy{
 			Name: "Traffic2adminAPI",
 			Selector: gov.Selector{
@@ -96,7 +97,7 @@ func TestDisplay(t *testing.T) {
 	id = string(res)
 	assert.NoError(t, err)
 	policies := &[]*gov.DisplayData{}
-	res, err = svc.Display(context.TODO(), Project, MockApp, MockEnv)
+	res, err = grcsvc.Display(context.TODO(), Project, MockApp, MockEnv)
 	assert.NoError(t, err)
 	err = json.Unmarshal(res, policies)
 	assert.NoError(t, err)
@@ -105,7 +106,7 @@ func TestDisplay(t *testing.T) {
 
 func TestList(t *testing.T) {
 	policies := &[]*gov.Policy{}
-	res, err := svc.List(context.TODO(), MockKind, Project, MockApp, MockEnv)
+	res, err := grcsvc.List(context.TODO(), MockKind, Project, MockApp, MockEnv)
 	assert.NoError(t, err)
 	err = json.Unmarshal(res, policies)
 	assert.NoError(t, err)
@@ -114,7 +115,7 @@ func TestList(t *testing.T) {
 
 func TestGet(t *testing.T) {
 	policy := &gov.Policy{}
-	res, err := svc.Get(context.TODO(), MockKind, id, Project)
+	res, err := grcsvc.Get(context.TODO(), MockKind, id, Project)
 	assert.NoError(t, err)
 	err = json.Unmarshal(res, policy)
 	assert.NoError(t, err)
@@ -122,8 +123,8 @@ func TestGet(t *testing.T) {
 }
 
 func TestDelete(t *testing.T) {
-	err := svc.Delete(context.TODO(), MockKind, id, Project)
+	err := grcsvc.Delete(context.TODO(), MockKind, id, Project)
 	assert.NoError(t, err)
-	res, _ := svc.Get(context.TODO(), MockKind, id, Project)
+	res, _ := grcsvc.Get(context.TODO(), MockKind, id, Project)
 	assert.Nil(t, res)
 }
diff --git a/server/service/gov/kie/kie_distributor.go b/server/service/grc/kie/kie_distributor.go
similarity index 86%
rename from server/service/gov/kie/kie_distributor.go
rename to server/service/grc/kie/kie_distributor.go
index 40899952..c0be5fbd 100644
--- a/server/service/gov/kie/kie_distributor.go
+++ b/server/service/grc/kie/kie_distributor.go
@@ -26,14 +26,15 @@ import (
 	"strings"
 	"time"
 
+	"github.com/ghodss/yaml"
+	"github.com/go-chassis/foundation/httpclient"
+	"github.com/go-chassis/kie-client"
+
 	"github.com/apache/servicecomb-service-center/pkg/gov"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/server/config"
-	svc "github.com/apache/servicecomb-service-center/server/service/gov"
+	grcsvc "github.com/apache/servicecomb-service-center/server/service/grc"
 	rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
-	"github.com/ghodss/yaml"
-	"github.com/go-chassis/foundation/httpclient"
-	"github.com/go-chassis/kie-client"
 )
 
 type Distributor struct {
@@ -41,21 +42,6 @@ type Distributor struct {
 	client *kie.Client
 }
 
-const (
-	KeyPrefix       = "servicecomb."
-	KindMatchGroup  = "match-group"
-	GroupNamePrefix = "scene-"
-	StatusEnabled   = "enabled"
-	TypeText        = "text"
-	KeyApp          = "app"
-	KeyEnvironment  = "environment"
-	EnvAll          = "all"
-	Alias           = "alias"
-	Method          = "method"
-	Matches         = "matches"
-	Rules           = "rules"
-)
-
 var PolicyNames = []string{
 	"retry",
 	"rateLimiting",
@@ -66,21 +52,14 @@ var PolicyNames = []string{
 	"loadbalancer",
 }
 
-var rule = Validator{}
-
 func (d *Distributor) Create(ctx context.Context, kind, project string, p *gov.Policy) ([]byte, error) {
-	if kind == KindMatchGroup {
+	if kind == grcsvc.KindMatchGroup {
 		err := d.generateID(ctx, project, p)
 		if err != nil {
 			return nil, err
 		}
 	}
-
-	err := rule.Validate(kind, p.Spec)
-	if err != nil {
-		return nil, err
-	}
-	if kind == KindMatchGroup {
+	if kind == grcsvc.KindMatchGroup {
 		setAliasIfEmpty(p.Spec, p.Name)
 	}
 	yamlByte, err := yaml.Marshal(p.Spec)
@@ -90,8 +69,8 @@ func (d *Distributor) Create(ctx context.Context, kind, project string, p *gov.P
 	kv := kie.KVRequest{
 		Key:       toGovKeyPrefix(kind) + p.Name,
 		Value:     string(yamlByte),
-		Status:    StatusEnabled,
-		ValueType: TypeText,
+		Status:    grcsvc.StatusEnabled,
+		ValueType: grcsvc.TypeText,
 		Labels:    p.Selector,
 	}
 	res, err := d.client.Create(ctx, kv, kie.WithProject(project))
@@ -103,11 +82,7 @@ func (d *Distributor) Create(ctx context.Context, kind, project string, p *gov.P
 }
 
 func (d *Distributor) Update(ctx context.Context, kind, id, project string, p *gov.Policy) error {
-	err := rule.Validate(kind, p.Spec)
-	if err != nil {
-		return err
-	}
-	if kind == KindMatchGroup {
+	if kind == grcsvc.KindMatchGroup {
 		setAliasIfEmpty(p.Spec, p.Name)
 	}
 	yamlByte, err := yaml.Marshal(p.Spec)
@@ -128,7 +103,7 @@ func (d *Distributor) Update(ctx context.Context, kind, id, project string, p *g
 }
 
 func (d *Distributor) Delete(ctx context.Context, kind, id, project string) error {
-	if kind == KindMatchGroup {
+	if kind == grcsvc.KindMatchGroup {
 		// should remove all policies of this group
 		return d.DeleteMatchGroup(ctx, id, project)
 	}
@@ -142,14 +117,14 @@ func (d *Distributor) Delete(ctx context.Context, kind, id, project string) erro
 }
 
 func (d *Distributor) DeleteMatchGroup(ctx context.Context, id string, project string) error {
-	policy, err := d.getPolicy(ctx, KindMatchGroup, id, project)
+	policy, err := d.getPolicy(ctx, grcsvc.KindMatchGroup, id, project)
 	if err != nil {
 		log.Error("kie get failed", err)
 		return err
 	}
 
 	ops := []kie.GetOption{
-		kie.WithKey("wildcard(" + KeyPrefix + "*." + policy.Name + ")"),
+		kie.WithKey("wildcard(" + grcsvc.KeyPrefix + "*." + policy.Name + ")"),
 		kie.WithLabels(policy.Selector),
 		kie.WithRevision(0),
 		kie.WithGetProject(project),
@@ -176,7 +151,7 @@ func (d *Distributor) DeleteMatchGroup(ctx context.Context, id string, project s
 }
 
 func (d *Distributor) Display(ctx context.Context, project, app, env string) ([]byte, error) {
-	list, _, err := d.listDataByKind(ctx, KindMatchGroup, project, app, env)
+	list, _, err := d.listDataByKind(ctx, grcsvc.KindMatchGroup, project, app, env)
 	if err != nil {
 		return nil, err
 	}
@@ -197,7 +172,7 @@ func (d *Distributor) Display(ctx context.Context, project, app, env string) ([]
 	}
 	r := make([]*gov.DisplayData, 0, list.Total)
 	for _, item := range list.Data {
-		match, err := d.transform(item, KindMatchGroup)
+		match, err := d.transform(item, grcsvc.KindMatchGroup)
 		if err != nil {
 			log.Warn(fmt.Sprintf("transform config failed: key is [%s], value is [%s]", item.Key, item.Value))
 			continue
@@ -270,7 +245,7 @@ func (d *Distributor) getPolicy(ctx context.Context, kind string, id string, pro
 }
 
 func (d *Distributor) Type() string {
-	return svc.ConfigDistributorKie
+	return grcsvc.ConfigDistributorKie
 }
 func (d *Distributor) Name() string {
 	return d.name
@@ -290,7 +265,7 @@ func initClient(endpoint string) *kie.Client {
 	return client
 }
 
-func new(opts config.DistributorOptions) (svc.ConfigDistributor, error) {
+func new(opts config.DistributorOptions) (grcsvc.ConfigDistributor, error) {
 	return &Distributor{name: opts.Name, client: initClient(opts.Endpoint)}, nil
 }
 
@@ -323,11 +298,11 @@ func (d *Distributor) listDataByKind(ctx context.Context, kind, project, app, en
 		kie.WithGetProject(project),
 	}
 	labels := map[string]string{}
-	if env != EnvAll {
-		labels[KeyEnvironment] = env
+	if env != grcsvc.EnvAll {
+		labels[grcsvc.KeyEnvironment] = env
 	}
 	if app != "" {
-		labels[KeyApp] = app
+		labels[grcsvc.KeyApp] = app
 	}
 	if len(labels) > 0 {
 		ops = append(ops, kie.WithLabels(labels))
@@ -344,8 +319,8 @@ func (d *Distributor) generateID(ctx context.Context, project string, p *gov.Pol
 	if p.Name != "" {
 		return nil
 	}
-	kind := KindMatchGroup
-	list, _, err := d.listDataByKind(ctx, kind, project, p.Selector[KeyApp], p.Selector[KeyEnvironment])
+	kind := grcsvc.KindMatchGroup
+	list, _, err := d.listDataByKind(ctx, kind, project, p.Selector[grcsvc.KeyApp], p.Selector[grcsvc.KeyEnvironment])
 	if err != nil {
 		return err
 	}
@@ -376,7 +351,7 @@ func getID() string {
 	for i := 0; i < 4; i++ {
 		result = append(result, b[r.Intn(len(b))])
 	}
-	return GroupNamePrefix + string(result)
+	return grcsvc.GroupNamePrefix + string(result)
 }
 
 func (d *Distributor) transform(kv *kie.KVDoc, kind string) (*gov.Policy, error) {
@@ -404,9 +379,9 @@ func (d *Distributor) transform(kv *kie.KVDoc, kind string) (*gov.Policy, error)
 }
 
 func toGovKeyPrefix(kind string) string {
-	return KeyPrefix + toSnake(kind) + "."
+	return grcsvc.KeyPrefix + toSnake(kind) + "."
 }
 
 func init() {
-	svc.InstallDistributor(svc.ConfigDistributorKie, new)
+	grcsvc.InstallDistributor(grcsvc.ConfigDistributorKie, new)
 }
diff --git a/server/service/gov/mock/mock.go b/server/service/grc/mock/mock.go
similarity index 93%
rename from server/service/gov/mock/mock.go
rename to server/service/grc/mock/mock.go
index 7ec32eda..0636c34d 100644
--- a/server/service/gov/mock/mock.go
+++ b/server/service/grc/mock/mock.go
@@ -27,7 +27,7 @@ import (
 
 	"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"
+	grcsvc "github.com/apache/servicecomb-service-center/server/service/grc"
 )
 
 type Distributor struct {
@@ -126,14 +126,14 @@ func (d *Distributor) Get(ctx context.Context, kind, id, project string) ([]byte
 }
 
 func (d *Distributor) Type() string {
-	return svc.ConfigDistributorMock
+	return grcsvc.ConfigDistributorMock
 }
 func (d *Distributor) Name() string {
 	return d.name
 }
-func new(opts config.DistributorOptions) (svc.ConfigDistributor, error) {
+func new(opts config.DistributorOptions) (grcsvc.ConfigDistributor, error) {
 	return &Distributor{name: opts.Name, lbPolicies: map[string]*gov.Policy{}}, nil
 }
 func init() {
-	svc.InstallDistributor(svc.ConfigDistributorMock, new)
+	grcsvc.InstallDistributor(grcsvc.ConfigDistributorMock, new)
 }
diff --git a/server/service/gov/policy.go b/server/service/grc/policy.go
similarity index 61%
rename from server/service/gov/policy.go
rename to server/service/grc/policy.go
index c9dbfec9..03791b0b 100644
--- a/server/service/gov/policy.go
+++ b/server/service/grc/policy.go
@@ -15,7 +15,8 @@
  * limitations under the License.
  */
 
-package gov
+//Package grc include API of governance(grc is the abbreviation of governance)
+package grc
 
 import (
 	"errors"
@@ -32,21 +33,29 @@ import (
 
 type ValueType string
 
-//policies saves kind and policy schemas
-var policies = make(map[string]*spec.Schema)
+//policySchemas saves policy kind and schema
+var policySchemas = make(map[string]*spec.Schema)
 
-//RegisterPolicy register a contract of one kind of policy
+//RegisterPolicySchema register a contract of one kind of policy
 //this API is not thread safe, only use it during sc init
-func RegisterPolicy(kind string, schema *spec.Schema) {
-	policies[kind] = schema
+func RegisterPolicySchema(kind string, schema *spec.Schema) {
+	policySchemas[kind] = schema
+	log.Info("register policy schema: " + kind)
 }
 
-//ValidateSpec validates spec attributes
-func ValidateSpec(kind string, spec interface{}) error {
-	schema, ok := policies[kind]
+// ValidatePolicySpec validates spec attributes
+// it first us legacy mechanism Validate 3 kinds of policy.
+// then it use new mechanism to validate all of other policy
+func ValidatePolicySpec(kind string, spec interface{}) error {
+	// TODO this legacy API should be removed. after 3 kinds of policy schema is registered by "RegisterPolicySchema"
+	err := Validate(kind, spec)
+	if err != nil {
+		return err
+	}
+	schema, ok := policySchemas[kind]
 	if !ok {
-		log.Warn(fmt.Sprintf("can not recognize %s", kind))
-		return nil
+		log.Warn(fmt.Sprintf("can not recognize policy %s", kind))
+		return &ErrIllegalItem{"not support kind yet", kind}
 	}
 	validator := validate.NewSchemaValidator(schema, nil, "", strfmt.Default)
 	errs := validator.Validate(spec).Errors
diff --git a/server/service/gov/policy_test.go b/server/service/grc/policy_test.go
similarity index 87%
rename from server/service/gov/policy_test.go
rename to server/service/grc/policy_test.go
index 46ddd98b..610a1513 100644
--- a/server/service/gov/policy_test.go
+++ b/server/service/grc/policy_test.go
@@ -15,14 +15,14 @@
  * limitations under the License.
  */
 
-package gov_test
+package grc_test
 
 import (
+	"github.com/apache/servicecomb-service-center/server/service/grc"
 	"testing"
 
 	"k8s.io/kube-openapi/pkg/validation/spec"
 
-	"github.com/apache/servicecomb-service-center/server/service/gov"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -45,9 +45,9 @@ func TestPolicySchema_Validate(t *testing.T) {
 						SchemaProps: spec.SchemaProps{Type: []string{"integer"}}},
 				},
 			}}
-		gov.RegisterPolicy("custom", schema)
+		grc.RegisterPolicySchema("custom", schema)
 		t.Run("given right content, should no error", func(t *testing.T) {
-			err := gov.ValidateSpec("custom", map[string]interface{}{
+			err := grc.ValidatePolicySpec("custom", map[string]interface{}{
 				"allow":   true,
 				"timeout": "5s",
 				"name":    "a",
@@ -58,7 +58,7 @@ func TestPolicySchema_Validate(t *testing.T) {
 			assert.NoError(t, err)
 		})
 		t.Run("given value with wrong type, should return error", func(t *testing.T) {
-			err := gov.ValidateSpec("custom", map[string]interface{}{
+			err := grc.ValidatePolicySpec("custom", map[string]interface{}{
 				"allow":   "str",
 				"timeout": "5s",
 				"name":    "a",
@@ -69,7 +69,7 @@ func TestPolicySchema_Validate(t *testing.T) {
 			assert.Error(t, err)
 		})
 		t.Run("do not give required value, should return error", func(t *testing.T) {
-			err := gov.ValidateSpec("custom", map[string]interface{}{
+			err := grc.ValidatePolicySpec("custom", map[string]interface{}{
 				"allow":   true,
 				"timeout": "5s",
 				"age":     10,
diff --git a/server/service/gov/kie/validate.go b/server/service/grc/validate.go
similarity index 82%
rename from server/service/gov/kie/validate.go
rename to server/service/grc/validate.go
index b487af65..f19c40df 100644
--- a/server/service/gov/kie/validate.go
+++ b/server/service/grc/validate.go
@@ -15,14 +15,26 @@
  * limitations under the License.
  */
 
-package kie
+package grc
 
 import (
 	"fmt"
 )
 
-type Validator struct {
-}
+const (
+	KeyPrefix       = "servicecomb."
+	KindMatchGroup  = "match-group"
+	GroupNamePrefix = "scene-"
+	StatusEnabled   = "enabled"
+	TypeText        = "text"
+	KeyApp          = "app"
+	KeyEnvironment  = "environment"
+	EnvAll          = "all"
+	Alias           = "alias"
+	Method          = "method"
+	Matches         = "matches"
+	Rules           = "rules"
+)
 
 type ErrIllegalItem struct {
 	err string
@@ -37,7 +49,11 @@ func (e *ErrIllegalItem) Error() string {
 	return fmt.Sprintf("illegal item : %v , msg: %s", e.val, e.err)
 }
 
-func (d *Validator) Validate(kind string, spec interface{}) error {
+// Validate is a legacy API, it is not extensible due to its bad design pattern
+// Please use grc.RegisterPolicySchema
+// it only response for validate 3 kinds of policy. if it is not this 3 kinds, it will not return error,
+// it return nil error, and let grc.ValidatePolicySpec to do the job
+func Validate(kind string, spec interface{}) error {
 	switch kind {
 	case "match-group":
 		return matchValidate(spec)
@@ -45,16 +61,9 @@ func (d *Validator) Validate(kind string, spec interface{}) error {
 		return retryValidate(spec)
 	case "rate-limiting":
 		return rateLimitingValidate(spec)
-	case "circuit-breaker":
-	case "instance-isolation":
-	case "fault-injection":
-	case "bulkhead":
-	case "loadbalancer":
-		return nil
 	default:
-		return &ErrIllegalItem{"not support kind yet", kind}
+		return nil
 	}
-	return nil
 }
 
 func matchValidate(val interface{}) error {