You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@servicecomb.apache.org by GitBox <gi...@apache.org> on 2017/12/26 07:55:35 UTC

[GitHub] asifdxtreme closed pull request #224: SCB-127 The consumer micro-service can discovery SC instances.

asifdxtreme closed pull request #224: SCB-127 The consumer micro-service can discovery SC instances.
URL: https://github.com/apache/incubator-servicecomb-service-center/pull/224
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/integration/microservices_test.go b/integration/microservices_test.go
index a5f16572..95445809 100644
--- a/integration/microservices_test.go
+++ b/integration/microservices_test.go
@@ -30,6 +30,7 @@ import (
 	"strconv"
 	"strings"
 	"testing"
+	"time"
 )
 
 var serviceName = ""
@@ -409,6 +410,8 @@ var _ = Describe("MicroService Api Test", func() {
 					// Validate the dependency creation
 					Expect(resp.StatusCode).To(Equal(http.StatusOK))
 
+					<-time.After(time.Second)
+
 					//Get Provider by ConsumerID
 					url := strings.Replace(GETCONPRODEPENDENCY, ":consumerId", consumerServiceID, 1)
 					req, _ = http.NewRequest(GET, SCURL+url, nil)
diff --git a/pkg/etcdsync/mutex.go b/pkg/etcdsync/mutex.go
index 5a722ca7..0ef019f6 100644
--- a/pkg/etcdsync/mutex.go
+++ b/pkg/etcdsync/mutex.go
@@ -36,7 +36,7 @@ const (
 )
 
 // A Mutex is a mutual exclusion lock which is distributed across a cluster.
-type LockerFactory struct {
+type DLockFactory struct {
 	key    string
 	ctx    context.Context
 	ttl    int64
@@ -44,13 +44,13 @@ type LockerFactory struct {
 	logger io.Writer
 }
 
-type Locker struct {
-	builder *LockerFactory
+type DLock struct {
+	builder *DLockFactory
 	id      string
 }
 
 var (
-	globalMap map[string]*LockerFactory
+	globalMap map[string]*DLockFactory
 	globalMux sync.Mutex
 	IsDebug   bool
 	hostname  string
@@ -58,7 +58,7 @@ var (
 )
 
 func init() {
-	globalMap = make(map[string]*LockerFactory)
+	globalMap = make(map[string]*DLockFactory)
 	IsDebug = false
 
 	var err error
@@ -72,7 +72,7 @@ func init() {
 // New creates a Mutex with the given key which must be the same
 // across the cluster nodes.
 // machines are the ectd cluster addresses
-func New(key string, ttl int64) *LockerFactory {
+func NewLockFactory(key string, ttl int64) *DLockFactory {
 	if len(key) == 0 {
 		return nil
 	}
@@ -80,7 +80,7 @@ func New(key string, ttl int64) *LockerFactory {
 		ttl = defaultTTL
 	}
 
-	return &LockerFactory{
+	return &DLockFactory{
 		key:   key,
 		ctx:   context.Background(),
 		ttl:   ttl,
@@ -90,21 +90,27 @@ func New(key string, ttl int64) *LockerFactory {
 
 // Lock locks m.
 // If the lock is already in use, the calling goroutine
-// blocks until the mutex is available.
-func (m *LockerFactory) Lock() (l *Locker, err error) {
+// blocks until the mutex is available. Flag wait is false,
+// this function is non-block when lock exist.
+func (m *DLockFactory) NewDLock(wait bool) (l *DLock, err error) {
 	if !IsDebug {
 		m.mutex.Lock()
 	}
-	l = &Locker{
+	l = &DLock{
 		builder: m,
 		id:      fmt.Sprintf("%v-%v-%v", hostname, pid, time.Now().Format("20060102-15:04:05.999999999")),
 	}
 	for try := 1; try <= defaultTry; try++ {
-		err = l.Lock()
+		err = l.Lock(wait)
 		if err == nil {
 			return l, nil
 		}
 
+		if !wait {
+			l, err = nil, nil
+			break
+		}
+
 		if try <= defaultTry {
 			util.Logger().Warnf(err, "Try to lock key %s again, id=%s", m.key, l.id)
 		} else {
@@ -117,11 +123,11 @@ func (m *LockerFactory) Lock() (l *Locker, err error) {
 	return l, err
 }
 
-func (m *Locker) ID() string {
+func (m *DLock) ID() string {
 	return m.id
 }
 
-func (m *Locker) Lock() error {
+func (m *DLock) Lock(wait bool) error {
 	opts := []registry.PluginOpOption{
 		registry.WithStrKey(m.builder.key),
 		registry.WithStrValue(m.id)}
@@ -142,6 +148,11 @@ func (m *Locker) Lock() error {
 			util.Logger().Infof("Create Lock OK, key=%s, id=%s", m.builder.key, m.id)
 			return nil
 		}
+
+		if !wait {
+			return fmt.Errorf("Key %s is locked by id=%s", m.builder.key, m.id)
+		}
+
 		util.Logger().Warnf(err, "Key %s is locked, waiting for other node releases it, id=%s", m.builder.key, m.id)
 
 		ctx, cancel := context.WithTimeout(m.builder.ctx, defaultTTL*time.Second)
@@ -177,7 +188,7 @@ func (m *Locker) Lock() error {
 // A locked Mutex is not associated with a particular goroutine.
 // It is allowed for one goroutine to lock a Mutex and then
 // arrange for another goroutine to unlock it.
-func (m *Locker) Unlock() (err error) {
+func (m *DLock) Unlock() (err error) {
 	opts := []registry.PluginOpOption{
 		registry.DEL,
 		registry.WithStrKey(m.builder.key)}
@@ -206,13 +217,13 @@ func (m *Locker) Unlock() (err error) {
 	return err
 }
 
-func Lock(key string) (*Locker, error) {
+func Lock(key string, wait bool) (*DLock, error) {
 	globalMux.Lock()
 	lc, ok := globalMap[key]
 	if !ok {
-		lc = New(fmt.Sprintf("%s%s", ROOT_PATH, key), -1)
+		lc = NewLockFactory(fmt.Sprintf("%s%s", ROOT_PATH, key), -1)
 		globalMap[key] = lc
 	}
 	globalMux.Unlock()
-	return lc.Lock()
+	return lc.NewDLock(wait)
 }
diff --git a/pkg/etcdsync/mutex_test.go b/pkg/etcdsync/mutex_test.go
index d8da8916..23a333b5 100644
--- a/pkg/etcdsync/mutex_test.go
+++ b/pkg/etcdsync/mutex_test.go
@@ -26,21 +26,21 @@ import (
 var _ = Describe("Mutex", func() {
 	Context("normal", func() {
 		It("TestLockTimeout", func() {
-			m1 := New("key1", 10)
-			m2 := New("key1", 2)
-			m1.Lock()
+			m1 := NewLockFactory("key1", 10)
+			m2 := NewLockFactory("key1", 2)
+			m1.NewDLock(true)
 			fmt.Println("UT===================m1 locked")
 			ch := make(chan bool)
 			go func() {
-				l, _ := m2.Lock()
+				l, _ := m2.NewDLock(true)
 				fmt.Println("UT===================m2 locked")
 				l.Unlock()
 				ch <- true
 			}()
 			<-ch
 			fmt.Println("lock m1 timeout")
-			m3 := New("key1", 2)
-			l, _ := m3.Lock()
+			m3 := NewLockFactory("key1", 2)
+			l, _ := m3.NewDLock(true)
 			fmt.Println("UT===================m3 locked")
 			l.Unlock()
 
diff --git a/pkg/util/goroutines.go b/pkg/util/goroutines.go
index 5a3d3f89..a021f52c 100644
--- a/pkg/util/goroutines.go
+++ b/pkg/util/goroutines.go
@@ -77,6 +77,7 @@ func GoInit() {
 
 func GoCloseAndWait() {
 	defaultGo.Close(true)
+	Logger().Debugf("all goroutines quit normally")
 }
 
 func NewGo(stopCh chan struct{}) *GoRoutine {
diff --git a/pkg/util/util.go b/pkg/util/util.go
index 2f2ac8c7..eea2da33 100644
--- a/pkg/util/util.go
+++ b/pkg/util/util.go
@@ -149,6 +149,14 @@ func ParseDomainProject(ctx context.Context) string {
 	return ParseDomain(ctx) + "/" + ParseProject(ctx)
 }
 
+func ParseTargetDomainProject(ctx context.Context) string {
+	domain := ParseTargetDomain(ctx)
+	if len(domain) == 0 {
+		return ParseDomainProject(ctx)
+	}
+	return domain + "/" + ParseTargetProject(ctx)
+}
+
 func ParseDomain(ctx context.Context) string {
 	v, ok := FromContext(ctx, "domain").(string)
 	if !ok {
@@ -157,6 +165,14 @@ func ParseDomain(ctx context.Context) string {
 	return v
 }
 
+func ParseTargetDomain(ctx context.Context) string {
+	v, ok := FromContext(ctx, "target-domain").(string)
+	if !ok {
+		return ""
+	}
+	return v
+}
+
 func ParseProject(ctx context.Context) string {
 	v, ok := FromContext(ctx, "project").(string)
 	if !ok {
@@ -165,6 +181,14 @@ func ParseProject(ctx context.Context) string {
 	return v
 }
 
+func ParseTargetProject(ctx context.Context) string {
+	v, ok := FromContext(ctx, "target-project").(string)
+	if !ok {
+		return ""
+	}
+	return v
+}
+
 func GetIPFromContext(ctx context.Context) string {
 	v, ok := FromContext(ctx, "x-remote-ip").(string)
 	if !ok {
diff --git a/server/core/backend/store/cacher.go b/server/core/backend/store/cacher.go
index d698e234..b1ab8677 100644
--- a/server/core/backend/store/cacher.go
+++ b/server/core/backend/store/cacher.go
@@ -430,7 +430,7 @@ func (c *KvCacher) onEvents(evts []*Event) {
 
 		switch evt.Type {
 		case proto.EVT_CREATE, proto.EVT_UPDATE:
-			util.Logger().Debugf("sync %s event and notify watcher, cache key %s, %+v", evt.Type, key, kv)
+			util.Logger().Debugf("sync %s event and notify watcher, cache %v", evt.Type, kv)
 
 			t := evt.Type
 			if !ok && evt.Type != proto.EVT_CREATE {
@@ -458,7 +458,7 @@ func (c *KvCacher) onEvents(evts []*Event) {
 				continue
 			}
 
-			util.Logger().Debugf("sync %s event and notify watcher, remove key %s, %+v", evt.Type, key, kv)
+			util.Logger().Debugf("sync %s event and notify watcher, remove cache %v", evt.Type, kv)
 			delete(store, key)
 			kvEvts[idx] = &KvEvent{
 				Revision: evt.Revision,
diff --git a/server/core/backend/store/event.go b/server/core/backend/store/event.go
index 91c6f898..9991f3d9 100644
--- a/server/core/backend/store/event.go
+++ b/server/core/backend/store/event.go
@@ -71,6 +71,7 @@ func EventProxy(t StoreType) *KvEventProxy {
 	return evtProxies[t]
 }
 
+// the event handler/func must be good performance, or will block the event bus.
 func AddEventHandleFunc(t StoreType, f KvEventFunc) {
 	EventProxy(t).AddHandleFunc(f)
 }
diff --git a/server/core/backend/store/indexer.go b/server/core/backend/store/indexer.go
index 3cfc1f8a..65349bdf 100644
--- a/server/core/backend/store/indexer.go
+++ b/server/core/backend/store/indexer.go
@@ -157,7 +157,7 @@ func (i *Indexer) searchPrefixKeyWithCache(ctx context.Context, op registry.Plug
 		kvs[idx] = c.(*mvccpb.KeyValue)
 		idx++
 	}
-	util.LogNilOrWarnf(t, "too long to copy data[%d] from cache with prefix %s", idx, prefix)
+	util.LogNilOrWarnf(t, "too long to copy data[%d] from cache[%d] with prefix %s", idx, len(i.prefixIndex), prefix)
 
 	resp.Kvs = kvs[:idx]
 	return resp, nil
@@ -196,6 +196,7 @@ func (i *Indexer) buildIndex() {
 				if !ok {
 					return
 				}
+				t := time.Now()
 				key := util.BytesToStringWithNoCopy(evt.KV.Key)
 				prefix := key[:strings.LastIndex(key[:len(key)-1], "/")+1]
 
@@ -208,6 +209,8 @@ func (i *Indexer) buildIndex() {
 				}
 				i.prefixLock.Unlock()
 
+				util.LogNilOrWarnf(t, "too long to rebuild(action: %s) index[%d], key is %s",
+					evt.Action, key, len(i.prefixIndex))
 			}
 		}
 		util.Logger().Debugf("build %s index goroutine is stopped", i.cacheType)
@@ -235,10 +238,10 @@ func (i *Indexer) getPrefixKey(arr *[]string, prefix string) (count int) {
 			}
 			break
 		}
-		count += n
+		/*count += n
 		if arr != nil {
 			*arr = append(*arr, *childs...)
-		}
+		}*/
 	}
 	return count
 }
@@ -268,11 +271,18 @@ func (i *Indexer) deletePrefixKey(prefix, key string) {
 	if !ok {
 		return
 	}
-
+	// remove child
 	for k := range i.prefixIndex[key] {
 		i.deletePrefixKey(key, k)
 	}
+
 	delete(m, key)
+
+	// remove parent which has no child
+	if len(m) == 0 {
+		delete(i.prefixIndex, prefix)
+		i.deletePrefixKey(prefix[:strings.LastIndex(prefix[:len(prefix)-1], "/")+1], prefix)
+	}
 }
 
 func (i *Indexer) Run() {
diff --git a/server/core/backend/store/opt.go b/server/core/backend/store/opt.go
index 6aa3bbd3..252f2449 100644
--- a/server/core/backend/store/opt.go
+++ b/server/core/backend/store/opt.go
@@ -24,7 +24,7 @@ import (
 const (
 	DEFAULT_MAX_NO_EVENT_INTERVAL     = 1 // TODO it should be set to 1 for prevent etcd data is lost accidentally.
 	DEFAULT_LISTWATCH_TIMEOUT         = 30 * time.Second
-	DEFAULT_SELF_PRESERVATION_PERCENT = 0.85
+	DEFAULT_SELF_PRESERVATION_PERCENT = 0.8
 )
 
 type KvCacherCfg struct {
diff --git a/server/core/backend/store/store.go b/server/core/backend/store/store.go
index 5311d60f..d2f89e79 100644
--- a/server/core/backend/store/store.go
+++ b/server/core/backend/store/store.go
@@ -38,6 +38,7 @@ const (
 	RULE_INDEX
 	DEPENDENCY
 	DEPENDENCY_RULE
+	DEPENDENCY_QUEUE
 	SCHEMA // big data should not be stored in memory.
 	SCHEMA_SUMMARY
 	INSTANCE
@@ -49,39 +50,41 @@ const (
 const TIME_FORMAT = "15:04:05.000"
 
 var TypeNames = []string{
-	SERVICE:         "SERVICE",
-	INSTANCE:        "INSTANCE",
-	DOMAIN:          "DOMAIN",
-	SCHEMA:          "SCHEMA",
-	SCHEMA_SUMMARY:  "SCHEMA_SUMMARY",
-	RULE:            "RULE",
-	LEASE:           "LEASE",
-	SERVICE_INDEX:   "SERVICE_INDEX",
-	SERVICE_ALIAS:   "SERVICE_ALIAS",
-	SERVICE_TAG:     "SERVICE_TAG",
-	RULE_INDEX:      "RULE_INDEX",
-	DEPENDENCY:      "DEPENDENCY",
-	DEPENDENCY_RULE: "DEPENDENCY_RULE",
-	PROJECT:         "PROJECT",
-	ENDPOINTS:       "ENDPOINTS",
+	SERVICE:          "SERVICE",
+	INSTANCE:         "INSTANCE",
+	DOMAIN:           "DOMAIN",
+	SCHEMA:           "SCHEMA",
+	SCHEMA_SUMMARY:   "SCHEMA_SUMMARY",
+	RULE:             "RULE",
+	LEASE:            "LEASE",
+	SERVICE_INDEX:    "SERVICE_INDEX",
+	SERVICE_ALIAS:    "SERVICE_ALIAS",
+	SERVICE_TAG:      "SERVICE_TAG",
+	RULE_INDEX:       "RULE_INDEX",
+	DEPENDENCY:       "DEPENDENCY",
+	DEPENDENCY_RULE:  "DEPENDENCY_RULE",
+	DEPENDENCY_QUEUE: "DEPENDENCY_QUEUE",
+	PROJECT:          "PROJECT",
+	ENDPOINTS:        "ENDPOINTS",
 }
 
 var TypeRoots = map[StoreType]string{
-	SERVICE:         apt.GetServiceRootKey(""),
-	INSTANCE:        apt.GetInstanceRootKey(""),
-	DOMAIN:          apt.GetDomainRootKey() + "/",
-	SCHEMA:          apt.GetServiceSchemaRootKey(""),
-	SCHEMA_SUMMARY:  apt.GetServiceSchemaSummaryRootKey(""),
-	RULE:            apt.GetServiceRuleRootKey(""),
-	LEASE:           apt.GetInstanceLeaseRootKey(""),
-	SERVICE_INDEX:   apt.GetServiceIndexRootKey(""),
-	SERVICE_ALIAS:   apt.GetServiceAliasRootKey(""),
-	SERVICE_TAG:     apt.GetServiceTagRootKey(""),
-	RULE_INDEX:      apt.GetServiceRuleIndexRootKey(""),
-	DEPENDENCY:      apt.GetServiceDependencyRootKey(""),
-	DEPENDENCY_RULE: apt.GetServiceDependencyRuleRootKey(""),
-	PROJECT:         apt.GetProjectRootKey(""),
-	ENDPOINTS:       apt.GetEndpointsRootKey(""),
+	SERVICE:          apt.GetServiceRootKey(""),
+	INSTANCE:         apt.GetInstanceRootKey(""),
+	DOMAIN:           apt.GetDomainRootKey() + "/",
+	SCHEMA:           apt.GetServiceSchemaRootKey(""),
+	SCHEMA_SUMMARY:   apt.GetServiceSchemaSummaryRootKey(""),
+	RULE:             apt.GetServiceRuleRootKey(""),
+	LEASE:            apt.GetInstanceLeaseRootKey(""),
+	SERVICE_INDEX:    apt.GetServiceIndexRootKey(""),
+	SERVICE_ALIAS:    apt.GetServiceAliasRootKey(""),
+	SERVICE_TAG:      apt.GetServiceTagRootKey(""),
+	RULE_INDEX:       apt.GetServiceRuleIndexRootKey(""),
+	DEPENDENCY:       apt.GetServiceDependencyRootKey(""),
+	DEPENDENCY_RULE:  apt.GetServiceDependencyRuleRootKey(""),
+	DEPENDENCY_QUEUE: apt.GetServiceDependencyQueueRootKey(""),
+	PROJECT:          apt.GetProjectRootKey(""),
+	ENDPOINTS:        apt.GetEndpointsRootKey(""),
 }
 
 var store = &KvStore{}
@@ -276,6 +279,10 @@ func (s *KvStore) DependencyRule() *Indexer {
 	return s.indexers[DEPENDENCY_RULE]
 }
 
+func (s *KvStore) DependencyQueue() *Indexer {
+	return s.indexers[DEPENDENCY_QUEUE]
+}
+
 func (s *KvStore) Domain() *Indexer {
 	return s.indexers[DOMAIN]
 }
diff --git a/server/core/key_generator.go b/server/core/key_generator.go
index 959dbc30..73775e89 100644
--- a/server/core/key_generator.go
+++ b/server/core/key_generator.go
@@ -40,6 +40,7 @@ const (
 	REGISTRY_LEASE_KEY          = "leases"
 	REGISTRY_DEPENDENCY_KEY     = "deps"
 	REGISTRY_DEPS_RULE_KEY      = "dep-rules"
+	REGISTRY_DEPS_QUEUE_KEY     = "dep-queue"
 	REGISTRY_METRICS_KEY        = "metrics"
 	ENDPOINTS_ROOT_KEY          = "eps"
 )
@@ -300,6 +301,15 @@ func GetServiceDependencyRuleRootKey(domainProject string) string {
 	}, "/")
 }
 
+func GetServiceDependencyQueueRootKey(domainProject string) string {
+	return util.StringJoin([]string{
+		GetRootKey(),
+		REGISTRY_SERVICE_KEY,
+		REGISTRY_DEPS_QUEUE_KEY,
+		domainProject,
+	}, "/")
+}
+
 func GenerateConsumerDependencyKey(domainProject string, consumerId string, providerId string) string {
 	return GenerateServiceDependencyKey("c", domainProject, consumerId, providerId)
 }
@@ -317,6 +327,14 @@ func GenerateProviderDependencyKey(domainProject string, providerId string, cons
 	return GenerateServiceDependencyKey("p", domainProject, providerId, consumerId)
 }
 
+func GenerateConsumerDependencyQueueKey(domainProject, consumerId, uuid string) string {
+	return util.StringJoin([]string{
+		GetServiceDependencyQueueRootKey(domainProject),
+		consumerId,
+		uuid,
+	}, "/")
+}
+
 func GetServiceDependencyRootKey(domainProject string) string {
 	return util.StringJoin([]string{
 		GetRootKey(),
diff --git a/server/core/microservice.go b/server/core/microservice.go
index 7536cc86..d42ec00c 100644
--- a/server/core/microservice.go
+++ b/server/core/microservice.go
@@ -80,11 +80,18 @@ func IsDefaultDomainProject(domainProject string) bool {
 	return domainProject == util.StringJoin([]string{REGISTRY_DOMAIN, REGISTRY_PROJECT}, "/")
 }
 
-func IsSCKey(key *pb.MicroServiceKey) bool {
+func IsShared(key *pb.MicroServiceKey) bool {
 	if !IsDefaultDomainProject(key.Tenant) {
 		return false
 	}
-	return key.AppId == Service.AppId && key.ServiceName == Service.ServiceName
+	return key.AppId == Service.AppId
+}
+
+func IsSCKey(key *pb.MicroServiceKey) bool {
+	if !IsShared(key) {
+		return false
+	}
+	return key.ServiceName == Service.ServiceName
 }
 
 func IsSCInstance(ctx context.Context) bool {
@@ -93,6 +100,7 @@ func IsSCInstance(ctx context.Context) bool {
 	}
 	return false
 }
+
 func GetExistenceRequest() *pb.GetExistenceRequest {
 	return &pb.GetExistenceRequest{
 		Type:        pb.EXISTENCE_MS,
diff --git a/server/core/proto/services.go b/server/core/proto/services.go
index e9eeadd5..23ba8b44 100644
--- a/server/core/proto/services.go
+++ b/server/core/proto/services.go
@@ -221,7 +221,7 @@ func GetInfoFromSvcIndexKV(kv *mvccpb.KeyValue) (key *MicroServiceKey, data []by
 func GetInfoFromSchemaSummaryKV(kv *mvccpb.KeyValue) (schemaId string, data []byte) {
 	keys, data := KvToResponse(kv)
 	l := len(keys)
-	if l < 2 {
+	if l < 1 {
 		return
 	}
 
@@ -231,25 +231,31 @@ func GetInfoFromSchemaSummaryKV(kv *mvccpb.KeyValue) (schemaId string, data []by
 func GetInfoFromSchemaKV(kv *mvccpb.KeyValue) (schemaId string, data []byte) {
 	keys, data := KvToResponse(kv)
 	l := len(keys)
-	if l < 2 {
+	if l < 1 {
 		return
 	}
 
 	return keys[l-1], data
 }
 
-func DependenciesToKeys(in []*DependencyKey, domainProject string) []*MicroServiceKey {
-	rst := []*MicroServiceKey{}
+func GetInfoFromDependencyQueueKV(kv *mvccpb.KeyValue) (consumerId, domainProject string, data []byte) {
+	keys, data := KvToResponse(kv)
+	l := len(keys)
+	if l < 4 {
+		return
+	}
+	consumerId = keys[l-2]
+	domainProject = fmt.Sprintf("%s/%s", keys[l-4], keys[l-3])
+	return
+}
+
+func DependenciesToKeys(in []*MicroServiceKey, domainProject string) []*MicroServiceKey {
 	for _, value := range in {
-		rst = append(rst, &MicroServiceKey{
-			Tenant:      domainProject,
-			Environment: value.Environment,
-			AppId:       value.AppId,
-			ServiceName: value.ServiceName,
-			Version:     value.Version,
-		})
+		if len(value.Tenant) == 0 {
+			value.Tenant = domainProject
+		}
 	}
-	return rst
+	return in
 }
 
 func MicroServiceToKey(domainProject string, in *MicroService) *MicroServiceKey {
@@ -258,6 +264,7 @@ func MicroServiceToKey(domainProject string, in *MicroService) *MicroServiceKey
 		Environment: in.Environment,
 		AppId:       in.AppId,
 		ServiceName: in.ServiceName,
+		Alias:       in.Alias,
 		Version:     in.Version,
 	}
 }
diff --git a/server/core/proto/services.pb.go b/server/core/proto/services.pb.go
index 63099d0d..f490822d 100644
--- a/server/core/proto/services.pb.go
+++ b/server/core/proto/services.pb.go
@@ -89,7 +89,6 @@ It has these top-level messages:
 	AddDependenciesRequest
 	AddDependenciesResponse
 	CreateDependenciesRequest
-	DependencyKey
 	ConsumerDependency
 	CreateDependenciesResponse
 	GetDependenciesRequest
@@ -529,7 +528,7 @@ type MicroService struct {
 	Status       string             `protobuf:"bytes,8,opt,name=status" json:"status,omitempty"`
 	Properties   map[string]string  `protobuf:"bytes,9,rep,name=properties" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
 	Timestamp    string             `protobuf:"bytes,11,opt,name=timestamp" json:"timestamp,omitempty"`
-	Providers    []*DependencyKey   `protobuf:"bytes,12,rep,name=providers" json:"providers,omitempty"`
+	Providers    []*MicroServiceKey `protobuf:"bytes,12,rep,name=providers" json:"providers,omitempty"`
 	Alias        string             `protobuf:"bytes,13,opt,name=alias" json:"alias,omitempty"`
 	LBStrategy   map[string]string  `protobuf:"bytes,14,rep,name=LBStrategy" json:"LBStrategy,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
 	ModTimestamp string             `protobuf:"bytes,15,opt,name=modTimestamp" json:"modTimestamp,omitempty"`
@@ -620,7 +619,7 @@ func (m *MicroService) GetTimestamp() string {
 	return ""
 }
 
-func (m *MicroService) GetProviders() []*DependencyKey {
+func (m *MicroService) GetProviders() []*MicroServiceKey {
 	if m != nil {
 		return m.Providers
 	}
@@ -2413,70 +2412,38 @@ func (m *CreateDependenciesRequest) GetDependencies() []*ConsumerDependency {
 	return nil
 }
 
-type DependencyKey struct {
-	AppId       string `protobuf:"bytes,1,opt,name=appId" json:"appId,omitempty"`
-	ServiceName string `protobuf:"bytes,2,opt,name=serviceName" json:"serviceName,omitempty"`
-	Version     string `protobuf:"bytes,3,opt,name=version" json:"version,omitempty"`
-	Environment string `protobuf:"bytes,4,opt,name=environment" json:"environment,omitempty"`
-}
-
-func (m *DependencyKey) Reset()                    { *m = DependencyKey{} }
-func (m *DependencyKey) String() string            { return proto1.CompactTextString(m) }
-func (*DependencyKey) ProtoMessage()               {}
-func (*DependencyKey) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{81} }
-
-func (m *DependencyKey) GetAppId() string {
-	if m != nil {
-		return m.AppId
-	}
-	return ""
-}
-
-func (m *DependencyKey) GetServiceName() string {
-	if m != nil {
-		return m.ServiceName
-	}
-	return ""
-}
-
-func (m *DependencyKey) GetVersion() string {
-	if m != nil {
-		return m.Version
-	}
-	return ""
-}
-
-func (m *DependencyKey) GetEnvironment() string {
-	if m != nil {
-		return m.Environment
-	}
-	return ""
-}
-
 type ConsumerDependency struct {
-	Consumer  *DependencyKey   `protobuf:"bytes,1,opt,name=consumer" json:"consumer,omitempty"`
-	Providers []*DependencyKey `protobuf:"bytes,2,rep,name=providers" json:"providers,omitempty"`
+	Consumer  *MicroServiceKey   `protobuf:"bytes,1,opt,name=consumer" json:"consumer,omitempty"`
+	Providers []*MicroServiceKey `protobuf:"bytes,2,rep,name=providers" json:"providers,omitempty"`
+	Override  bool               `protobuf:"varint,3,opt,name=override" json:"override,omitempty"`
 }
 
 func (m *ConsumerDependency) Reset()                    { *m = ConsumerDependency{} }
 func (m *ConsumerDependency) String() string            { return proto1.CompactTextString(m) }
 func (*ConsumerDependency) ProtoMessage()               {}
-func (*ConsumerDependency) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{82} }
+func (*ConsumerDependency) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{81} }
 
-func (m *ConsumerDependency) GetConsumer() *DependencyKey {
+func (m *ConsumerDependency) GetConsumer() *MicroServiceKey {
 	if m != nil {
 		return m.Consumer
 	}
 	return nil
 }
 
-func (m *ConsumerDependency) GetProviders() []*DependencyKey {
+func (m *ConsumerDependency) GetProviders() []*MicroServiceKey {
 	if m != nil {
 		return m.Providers
 	}
 	return nil
 }
 
+func (m *ConsumerDependency) GetOverride() bool {
+	if m != nil {
+		return m.Override
+	}
+	return false
+}
+
 type CreateDependenciesResponse struct {
 	Response *Response `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"`
 }
@@ -2484,7 +2451,7 @@ type CreateDependenciesResponse struct {
 func (m *CreateDependenciesResponse) Reset()                    { *m = CreateDependenciesResponse{} }
 func (m *CreateDependenciesResponse) String() string            { return proto1.CompactTextString(m) }
 func (*CreateDependenciesResponse) ProtoMessage()               {}
-func (*CreateDependenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{83} }
+func (*CreateDependenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{82} }
 
 func (m *CreateDependenciesResponse) GetResponse() *Response {
 	if m != nil {
@@ -2500,7 +2467,7 @@ type GetDependenciesRequest struct {
 func (m *GetDependenciesRequest) Reset()                    { *m = GetDependenciesRequest{} }
 func (m *GetDependenciesRequest) String() string            { return proto1.CompactTextString(m) }
 func (*GetDependenciesRequest) ProtoMessage()               {}
-func (*GetDependenciesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{84} }
+func (*GetDependenciesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{83} }
 
 func (m *GetDependenciesRequest) GetServiceId() string {
 	if m != nil {
@@ -2517,7 +2484,7 @@ type GetConDependenciesResponse struct {
 func (m *GetConDependenciesResponse) Reset()                    { *m = GetConDependenciesResponse{} }
 func (m *GetConDependenciesResponse) String() string            { return proto1.CompactTextString(m) }
 func (*GetConDependenciesResponse) ProtoMessage()               {}
-func (*GetConDependenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{85} }
+func (*GetConDependenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{84} }
 
 func (m *GetConDependenciesResponse) GetResponse() *Response {
 	if m != nil {
@@ -2541,7 +2508,7 @@ type GetProDependenciesResponse struct {
 func (m *GetProDependenciesResponse) Reset()                    { *m = GetProDependenciesResponse{} }
 func (m *GetProDependenciesResponse) String() string            { return proto1.CompactTextString(m) }
 func (*GetProDependenciesResponse) ProtoMessage()               {}
-func (*GetProDependenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{86} }
+func (*GetProDependenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{85} }
 
 func (m *GetProDependenciesResponse) GetResponse() *Response {
 	if m != nil {
@@ -2573,7 +2540,7 @@ type ServiceDetail struct {
 func (m *ServiceDetail) Reset()                    { *m = ServiceDetail{} }
 func (m *ServiceDetail) String() string            { return proto1.CompactTextString(m) }
 func (*ServiceDetail) ProtoMessage()               {}
-func (*ServiceDetail) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{87} }
+func (*ServiceDetail) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{86} }
 
 func (m *ServiceDetail) GetMicroService() *MicroService {
 	if m != nil {
@@ -2647,7 +2614,7 @@ type GetServiceDetailResponse struct {
 func (m *GetServiceDetailResponse) Reset()                    { *m = GetServiceDetailResponse{} }
 func (m *GetServiceDetailResponse) String() string            { return proto1.CompactTextString(m) }
 func (*GetServiceDetailResponse) ProtoMessage()               {}
-func (*GetServiceDetailResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{88} }
+func (*GetServiceDetailResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{87} }
 
 func (m *GetServiceDetailResponse) GetResponse() *Response {
 	if m != nil {
@@ -2672,7 +2639,7 @@ type DelServicesRequest struct {
 func (m *DelServicesRequest) Reset()                    { *m = DelServicesRequest{} }
 func (m *DelServicesRequest) String() string            { return proto1.CompactTextString(m) }
 func (*DelServicesRequest) ProtoMessage()               {}
-func (*DelServicesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{89} }
+func (*DelServicesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{88} }
 
 func (m *DelServicesRequest) GetServiceIds() []string {
 	if m != nil {
@@ -2697,7 +2664,7 @@ type DelServicesRspInfo struct {
 func (m *DelServicesRspInfo) Reset()                    { *m = DelServicesRspInfo{} }
 func (m *DelServicesRspInfo) String() string            { return proto1.CompactTextString(m) }
 func (*DelServicesRspInfo) ProtoMessage()               {}
-func (*DelServicesRspInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{90} }
+func (*DelServicesRspInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{89} }
 
 func (m *DelServicesRspInfo) GetErrMessage() string {
 	if m != nil {
@@ -2722,7 +2689,7 @@ type DelServicesResponse struct {
 func (m *DelServicesResponse) Reset()                    { *m = DelServicesResponse{} }
 func (m *DelServicesResponse) String() string            { return proto1.CompactTextString(m) }
 func (*DelServicesResponse) ProtoMessage()               {}
-func (*DelServicesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{91} }
+func (*DelServicesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{90} }
 
 func (m *DelServicesResponse) GetResponse() *Response {
 	if m != nil {
@@ -2745,7 +2712,7 @@ type GetAppsRequest struct {
 func (m *GetAppsRequest) Reset()                    { *m = GetAppsRequest{} }
 func (m *GetAppsRequest) String() string            { return proto1.CompactTextString(m) }
 func (*GetAppsRequest) ProtoMessage()               {}
-func (*GetAppsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{92} }
+func (*GetAppsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{91} }
 
 func (m *GetAppsRequest) GetEnvironment() string {
 	if m != nil {
@@ -2762,7 +2729,7 @@ type GetAppsResponse struct {
 func (m *GetAppsResponse) Reset()                    { *m = GetAppsResponse{} }
 func (m *GetAppsResponse) String() string            { return proto1.CompactTextString(m) }
 func (*GetAppsResponse) ProtoMessage()               {}
-func (*GetAppsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{93} }
+func (*GetAppsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{92} }
 
 func (m *GetAppsResponse) GetResponse() *Response {
 	if m != nil {
@@ -2860,7 +2827,6 @@ func init() {
 	proto1.RegisterType((*AddDependenciesRequest)(nil), "com.huawei.paas.cse.serviceregistry.api.AddDependenciesRequest")
 	proto1.RegisterType((*AddDependenciesResponse)(nil), "com.huawei.paas.cse.serviceregistry.api.AddDependenciesResponse")
 	proto1.RegisterType((*CreateDependenciesRequest)(nil), "com.huawei.paas.cse.serviceregistry.api.CreateDependenciesRequest")
-	proto1.RegisterType((*DependencyKey)(nil), "com.huawei.paas.cse.serviceregistry.api.DependencyKey")
 	proto1.RegisterType((*ConsumerDependency)(nil), "com.huawei.paas.cse.serviceregistry.api.ConsumerDependency")
 	proto1.RegisterType((*CreateDependenciesResponse)(nil), "com.huawei.paas.cse.serviceregistry.api.CreateDependenciesResponse")
 	proto1.RegisterType((*GetDependenciesRequest)(nil), "com.huawei.paas.cse.serviceregistry.api.GetDependenciesRequest")
@@ -4228,219 +4194,218 @@ var _GovernServiceCtrl_serviceDesc = grpc.ServiceDesc{
 func init() { proto1.RegisterFile("services.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-	// 3422 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5c, 0xdb, 0x6f, 0x24, 0x47,
-	0xd5, 0x57, 0x8d, 0x67, 0x3c, 0x9e, 0xe3, 0xf5, 0xee, 0xba, 0xd6, 0x5e, 0xf7, 0x4e, 0xf2, 0xe5,
-	0x5b, 0xb5, 0x22, 0x7d, 0x79, 0x88, 0xfc, 0x25, 0x0e, 0x49, 0x96, 0xbd, 0x64, 0x63, 0x7b, 0x37,
-	0x5e, 0xef, 0x66, 0xb3, 0x9b, 0x1e, 0x27, 0x4b, 0x12, 0x20, 0x6a, 0xcf, 0x94, 0x67, 0x3a, 0x3b,
-	0xd3, 0x3d, 0xe9, 0xee, 0xf1, 0x66, 0x24, 0x24, 0x94, 0x90, 0x40, 0x20, 0x90, 0x10, 0x01, 0x4f,
-	0x79, 0x00, 0x01, 0x79, 0x04, 0x09, 0x84, 0x14, 0xa1, 0x88, 0x08, 0x81, 0x78, 0x41, 0x44, 0x3c,
-	0x21, 0x9e, 0xf8, 0x0f, 0x78, 0xe3, 0x0f, 0x00, 0xd5, 0xa5, 0xbb, 0xab, 0x2f, 0x9e, 0x9d, 0xea,
-	0x76, 0x27, 0xe2, 0xc9, 0x5d, 0xd5, 0xae, 0x53, 0xa7, 0xce, 0xad, 0x4e, 0xfd, 0xea, 0x4c, 0xc3,
-	0x51, 0x8f, 0xb8, 0xfb, 0x56, 0x9b, 0x78, 0xab, 0x43, 0xd7, 0xf1, 0x1d, 0xfc, 0x7f, 0x6d, 0x67,
-	0xb0, 0xda, 0x1b, 0x99, 0x77, 0x88, 0xb5, 0x3a, 0x34, 0x4d, 0x6f, 0xb5, 0xed, 0x91, 0x55, 0xf1,
-	0x3f, 0x2e, 0xe9, 0x5a, 0x9e, 0xef, 0x8e, 0x57, 0xcd, 0xa1, 0xa5, 0x7f, 0x1d, 0x96, 0xae, 0x3b,
-	0x1d, 0x6b, 0x6f, 0xdc, 0x6a, 0xf7, 0xc8, 0xc0, 0xf4, 0x0c, 0xf2, 0xea, 0x88, 0x78, 0x3e, 0xbe,
-	0x17, 0x1a, 0xe2, 0xdf, 0xb7, 0x3b, 0x1a, 0x3a, 0x8d, 0x1e, 0x68, 0x18, 0x51, 0x07, 0xde, 0x86,
-	0xba, 0xc7, 0xff, 0x5f, 0xab, 0x9c, 0x9e, 0x79, 0x60, 0x7e, 0xed, 0xff, 0x57, 0xa7, 0x9c, 0x70,
-	0x95, 0xcf, 0x63, 0x04, 0xe3, 0xf5, 0xe7, 0x61, 0x96, 0x77, 0xe1, 0x26, 0xcc, 0xf1, 0xce, 0x70,
-	0xc6, 0xb0, 0x8d, 0x35, 0xa8, 0x7b, 0xa3, 0xc1, 0xc0, 0x74, 0xc7, 0x5a, 0x85, 0xbd, 0x0a, 0x9a,
-	0xf8, 0x24, 0xcc, 0xf2, 0xff, 0xd2, 0x66, 0xd8, 0x0b, 0xd1, 0xd2, 0xf7, 0x60, 0x39, 0xb1, 0x30,
-	0x6f, 0xe8, 0xd8, 0x1e, 0xc1, 0xd7, 0x61, 0xce, 0x15, 0xcf, 0x6c, 0x9a, 0xf9, 0xb5, 0x87, 0xa7,
-	0x66, 0x3e, 0x20, 0x62, 0x84, 0x24, 0xf4, 0x57, 0xe1, 0xc4, 0x15, 0x62, 0xba, 0xfe, 0x2e, 0x31,
-	0xfd, 0x16, 0xf1, 0x03, 0xf9, 0xbd, 0x08, 0x0d, 0xcb, 0xf6, 0x7c, 0xd3, 0x6e, 0x13, 0x4f, 0x43,
-	0x4c, 0x46, 0xe7, 0xa7, 0x9e, 0x46, 0x26, 0x78, 0xb9, 0x4f, 0x06, 0xc4, 0xf6, 0x8d, 0x88, 0x9c,
-	0xde, 0x8a, 0x4f, 0x29, 0xfe, 0xe3, 0x2e, 0x2a, 0xbb, 0x0f, 0x20, 0xa0, 0xb0, 0xdd, 0x11, 0x42,
-	0x94, 0x7a, 0xf4, 0x8f, 0x11, 0x2c, 0xc5, 0x17, 0x52, 0x8a, 0xbc, 0xf0, 0x8e, 0x2c, 0x18, 0x6e,
-	0x3c, 0x8f, 0x4d, 0x4d, 0x6f, 0x5b, 0x8c, 0xbc, 0xb2, 0x6b, 0x78, 0x31, 0x91, 0x0c, 0x60, 0x21,
-	0xf6, 0xae, 0x98, 0x30, 0xe8, 0x7b, 0xe2, 0xba, 0xd7, 0x89, 0xe7, 0x99, 0x5d, 0x22, 0x0c, 0x4b,
-	0xea, 0xd1, 0x37, 0xa1, 0xd1, 0xf2, 0x5b, 0x9c, 0x1c, 0x5e, 0x82, 0x5a, 0xdb, 0x19, 0xd9, 0x3e,
-	0x9b, 0x66, 0xc6, 0xe0, 0x0d, 0x7c, 0x1a, 0xe6, 0x1d, 0xbb, 0x6f, 0xd9, 0x64, 0x93, 0xbd, 0xab,
-	0xb0, 0x77, 0x72, 0x97, 0xae, 0x03, 0xb4, 0xfc, 0x80, 0xeb, 0x6c, 0x2a, 0xfa, 0xff, 0x40, 0xad,
-	0xe5, 0xaf, 0x0f, 0x87, 0x07, 0xbc, 0xfe, 0x17, 0xa2, 0x34, 0x4c, 0xdf, 0xf2, 0x7c, 0xab, 0xed,
-	0xe1, 0x67, 0x60, 0x2e, 0x88, 0x03, 0x42, 0x55, 0x6b, 0xd3, 0xfb, 0x65, 0xb0, 0x1e, 0x23, 0xa4,
-	0x81, 0x9f, 0x8d, 0xeb, 0x8a, 0x12, 0x7c, 0x44, 0x81, 0x60, 0xb0, 0x36, 0x49, 0x51, 0x78, 0x03,
-	0xaa, 0xe6, 0x70, 0xe8, 0x31, 0x99, 0xce, 0xaf, 0xad, 0x2a, 0x50, 0x5b, 0x1f, 0x0e, 0x0d, 0x36,
-	0x56, 0x7f, 0x1b, 0xc1, 0xc9, 0x2d, 0x12, 0xf0, 0xeb, 0x6d, 0xdb, 0x7b, 0x4e, 0xe0, 0x76, 0x1a,
-	0xd4, 0x9d, 0xa1, 0x6f, 0x39, 0x36, 0x77, 0xba, 0x86, 0x11, 0x34, 0xa9, 0x00, 0xcd, 0xe1, 0x30,
-	0xd4, 0x36, 0x6f, 0x50, 0x2d, 0x89, 0xd9, 0x9e, 0x31, 0x07, 0x81, 0xa6, 0xe5, 0x2e, 0x6a, 0x48,
-	0x4c, 0xd6, 0x37, 0xec, 0xfe, 0x58, 0xab, 0x9e, 0x46, 0x0f, 0xcc, 0x19, 0x51, 0x87, 0xfe, 0xb3,
-	0x0a, 0xac, 0xa4, 0x58, 0x29, 0xc7, 0x71, 0x3a, 0xb0, 0x68, 0xf6, 0xfb, 0xc1, 0x4c, 0x97, 0x88,
-	0x6f, 0x5a, 0x7d, 0x65, 0x07, 0x12, 0xc3, 0xf9, 0x68, 0x23, 0x4d, 0x10, 0xb7, 0x00, 0xbc, 0xd0,
-	0xa0, 0x84, 0x96, 0x54, 0x74, 0x1e, 0x0c, 0x35, 0x24, 0x32, 0xfa, 0xa7, 0x08, 0x8e, 0x5d, 0xb7,
-	0xda, 0xae, 0x23, 0x26, 0xbb, 0x46, 0x58, 0xdc, 0xf6, 0x89, 0x6d, 0x0a, 0x8b, 0x6e, 0x18, 0xa2,
-	0x45, 0x35, 0x38, 0x74, 0x9d, 0x57, 0x48, 0xdb, 0x0f, 0x22, 0xbd, 0x68, 0x46, 0x1a, 0x9c, 0x99,
-	0xa0, 0xc1, 0x6a, 0x5a, 0x83, 0x1a, 0xd4, 0xf7, 0x89, 0xeb, 0x59, 0x8e, 0xad, 0xd5, 0x38, 0x45,
-	0xd1, 0xa4, 0x63, 0x89, 0xbd, 0x6f, 0xb9, 0x8e, 0x4d, 0x03, 0xa8, 0x36, 0xcb, 0xc7, 0x4a, 0x5d,
-	0x6c, 0xce, 0xbe, 0x65, 0x7a, 0x5a, 0x5d, 0xcc, 0x49, 0x1b, 0xfa, 0x9f, 0xeb, 0x70, 0x44, 0x5e,
-	0xcf, 0x5d, 0xa2, 0x4d, 0x5e, 0xd3, 0x93, 0x18, 0xaf, 0xa6, 0x18, 0xef, 0x10, 0xaf, 0xed, 0x5a,
-	0xcc, 0xb8, 0xc5, 0xb2, 0xe4, 0x2e, 0x3a, 0x67, 0x9f, 0xec, 0x93, 0xbe, 0x58, 0x14, 0x6f, 0xb0,
-	0x6d, 0x54, 0xec, 0xdb, 0x75, 0xee, 0x1e, 0xa2, 0x89, 0xaf, 0x42, 0x6d, 0x68, 0xfa, 0x3d, 0x4f,
-	0x03, 0x66, 0x51, 0x5f, 0x50, 0xb5, 0xa8, 0x9b, 0xa6, 0xdf, 0x33, 0x38, 0x09, 0xb6, 0x25, 0xfb,
-	0xa6, 0x3f, 0xf2, 0xb4, 0x39, 0xb1, 0x25, 0xb3, 0x16, 0x26, 0x00, 0x43, 0xd7, 0x19, 0x12, 0xd7,
-	0xb7, 0x88, 0xa7, 0x35, 0xd8, 0x44, 0x97, 0xa7, 0x9e, 0x48, 0x16, 0xf8, 0xea, 0xcd, 0x90, 0xce,
-	0x65, 0xdb, 0x77, 0xc7, 0x86, 0x44, 0x98, 0x2a, 0xc3, 0xb7, 0x06, 0xc4, 0xf3, 0xcd, 0xc1, 0x50,
-	0x9b, 0xe7, 0xca, 0x08, 0x3b, 0xe8, 0xfe, 0x33, 0x74, 0x9d, 0x7d, 0xab, 0x43, 0x5c, 0x4f, 0x3b,
-	0xa2, 0xe8, 0x3e, 0x97, 0xc8, 0x90, 0xd8, 0x1d, 0x62, 0xb7, 0xc7, 0xd7, 0xc8, 0xd8, 0x88, 0x08,
-	0x45, 0x76, 0xb2, 0x20, 0xd9, 0x09, 0x5d, 0xf0, 0xd3, 0x1b, 0x2d, 0xdf, 0x35, 0x7d, 0xd2, 0x1d,
-	0x6b, 0x47, 0x8b, 0x2c, 0x38, 0xa2, 0x23, 0x16, 0x1c, 0x75, 0x60, 0x1d, 0x8e, 0x0c, 0x9c, 0xce,
-	0x4e, 0xb8, 0xe6, 0x63, 0x8c, 0x87, 0x58, 0x5f, 0xd2, 0xd4, 0x8f, 0xa7, 0x4d, 0xfd, 0x3e, 0x00,
-	0x3e, 0x3d, 0x71, 0x37, 0xc6, 0xda, 0x22, 0xdf, 0xf3, 0xa2, 0x1e, 0xfc, 0x25, 0x68, 0xec, 0xb9,
-	0xe6, 0x80, 0xdc, 0x71, 0xdc, 0xdb, 0x1a, 0x66, 0x81, 0xe1, 0xec, 0xd4, 0x6b, 0x79, 0x8a, 0x8e,
-	0xbc, 0xe5, 0xb8, 0xb7, 0x85, 0xe2, 0xc6, 0x46, 0x44, 0xac, 0x79, 0x01, 0x8e, 0x25, 0xf4, 0x89,
-	0x8f, 0xc3, 0xcc, 0x6d, 0x32, 0x16, 0xae, 0x44, 0x1f, 0xa9, 0x84, 0xf7, 0xcd, 0xfe, 0x88, 0x04,
-	0x4e, 0xc4, 0x1a, 0x67, 0x2b, 0x67, 0x10, 0x1d, 0x9e, 0x90, 0x8e, 0xca, 0x70, 0x7d, 0x1d, 0x16,
-	0x53, 0xdc, 0x61, 0x0c, 0x55, 0x9b, 0x7a, 0x25, 0xa7, 0xc0, 0x9e, 0x65, 0x77, 0xac, 0xc4, 0xdc,
-	0x51, 0xff, 0x07, 0x82, 0xf9, 0x60, 0xf7, 0x1c, 0xf5, 0x09, 0x75, 0x00, 0x77, 0xd4, 0x8f, 0x62,
-	0x81, 0x68, 0xd1, 0x0c, 0x97, 0x3e, 0xed, 0x8c, 0x87, 0x01, 0x1f, 0x61, 0x9b, 0x5a, 0xad, 0xe9,
-	0xfb, 0xae, 0xb5, 0x3b, 0xf2, 0x83, 0x60, 0x10, 0x75, 0xb0, 0xa8, 0x68, 0xfa, 0x3e, 0x71, 0xc3,
-	0x50, 0x20, 0x9a, 0x53, 0x84, 0x82, 0x98, 0x3f, 0xcc, 0x26, 0xfd, 0x21, 0x69, 0x3c, 0xf5, 0xb4,
-	0xf1, 0xe8, 0xef, 0x22, 0x38, 0xb9, 0xde, 0xe9, 0xdc, 0x70, 0x9f, 0x1b, 0x76, 0x4c, 0x9f, 0xc8,
-	0x4b, 0x95, 0x97, 0x84, 0x26, 0x2d, 0xa9, 0x32, 0x61, 0x49, 0x33, 0x13, 0x97, 0x54, 0x4d, 0x2d,
-	0x49, 0xff, 0x24, 0x12, 0x38, 0x0d, 0x3c, 0x54, 0x5d, 0x34, 0xf4, 0x04, 0xea, 0xa2, 0xcf, 0xf8,
-	0xab, 0x30, 0x27, 0x82, 0xc2, 0x58, 0x6c, 0x93, 0x1b, 0x79, 0x82, 0x5a, 0x10, 0x6a, 0x84, 0xdf,
-	0x85, 0x34, 0x9b, 0xe7, 0x60, 0x21, 0xf6, 0x4a, 0xc9, 0xe8, 0xce, 0xc0, 0x5c, 0x98, 0x27, 0x60,
-	0xa8, 0xb6, 0x9d, 0x0e, 0x17, 0x5f, 0xcd, 0x60, 0xcf, 0x54, 0x38, 0x03, 0x91, 0x7d, 0x0a, 0x5b,
-	0x13, 0x4d, 0xfd, 0xef, 0x08, 0x4e, 0x6c, 0x11, 0xff, 0xf2, 0x6b, 0xd4, 0x2f, 0x69, 0x72, 0x25,
-	0x32, 0x1f, 0x0c, 0x55, 0x3f, 0x52, 0x02, 0x7b, 0x2e, 0x61, 0xe3, 0x89, 0x6d, 0x74, 0xb5, 0xe4,
-	0x46, 0x27, 0x9f, 0xe0, 0x66, 0x13, 0x27, 0xb8, 0x44, 0x00, 0xaa, 0xa7, 0x02, 0x90, 0xfe, 0x5b,
-	0x04, 0x4b, 0xf1, 0x95, 0x95, 0x93, 0x48, 0xc5, 0xd6, 0x50, 0x99, 0xb4, 0x86, 0x99, 0x83, 0x4f,
-	0xa1, 0xd5, 0xd8, 0x29, 0x54, 0xff, 0xd5, 0x0c, 0x2c, 0x6d, 0xba, 0x44, 0x72, 0x0e, 0xa1, 0x96,
-	0x1b, 0x50, 0x17, 0xb4, 0x05, 0xeb, 0x8f, 0xe6, 0x8a, 0xff, 0x46, 0x40, 0x05, 0x3f, 0x07, 0x35,
-	0xea, 0x60, 0xc1, 0xd9, 0xe9, 0xe2, 0xd4, 0xe4, 0xb2, 0x1d, 0xd8, 0xe0, 0xd4, 0xf0, 0x4b, 0x50,
-	0xf5, 0xcd, 0x2e, 0xcd, 0xf8, 0x28, 0xd5, 0xad, 0xa9, 0xa9, 0x66, 0x2d, 0x7a, 0x75, 0xc7, 0xec,
-	0x8a, 0x7d, 0x99, 0x11, 0xc5, 0x2f, 0xc9, 0xe7, 0x88, 0x2a, 0x9b, 0xe1, 0x42, 0x2e, 0x31, 0x64,
-	0x9c, 0x28, 0x9a, 0x8f, 0x43, 0x23, 0x9c, 0x4f, 0xc9, 0x07, 0xdf, 0x44, 0xb0, 0x9c, 0x60, 0xff,
-	0x73, 0x30, 0x38, 0xfd, 0x2a, 0x2c, 0x5d, 0x22, 0x7d, 0x92, 0xb2, 0x9c, 0xbb, 0xe6, 0x94, 0x7b,
-	0x8e, 0xdb, 0xe6, 0xcb, 0x9a, 0x33, 0x78, 0x43, 0xdf, 0x83, 0xe5, 0x04, 0xad, 0x72, 0x40, 0x8f,
-	0x87, 0x61, 0x31, 0x3a, 0xf5, 0x4c, 0xc5, 0xb0, 0xfe, 0x1b, 0x04, 0x58, 0x1e, 0x53, 0x8e, 0xa8,
-	0x25, 0x77, 0xab, 0x1c, 0x86, 0xbb, 0xe9, 0x4b, 0x32, 0xd7, 0x01, 0x3a, 0xa6, 0x7f, 0xc4, 0x83,
-	0x70, 0xd4, 0x5d, 0xce, 0x6a, 0x9e, 0x95, 0xce, 0xf3, 0xdc, 0xdd, 0x73, 0x2e, 0x27, 0x24, 0xa3,
-	0xff, 0x13, 0xc1, 0xa9, 0x58, 0x10, 0xa0, 0x7b, 0xd8, 0x94, 0xa8, 0x9f, 0x1b, 0xcb, 0xdf, 0x39,
-	0x43, 0xc6, 0xd4, 0x0c, 0x1d, 0x38, 0xeb, 0xa4, 0x64, 0xbe, 0x60, 0x6e, 0xa8, 0xdf, 0x86, 0x66,
-	0xd6, 0xbc, 0xe5, 0x78, 0xc5, 0x63, 0x32, 0x2c, 0x41, 0x83, 0xab, 0x37, 0xb5, 0x6b, 0xac, 0xa4,
-	0x06, 0x96, 0x63, 0x51, 0x57, 0xe3, 0xbb, 0x87, 0xf2, 0x31, 0x4f, 0xda, 0x32, 0xf4, 0x0f, 0x11,
-	0x68, 0xe9, 0xfd, 0x64, 0x2a, 0x4b, 0x8a, 0x12, 0xe4, 0x4a, 0x2c, 0x41, 0x6e, 0x41, 0x95, 0x3e,
-	0x09, 0xdc, 0xa1, 0xf0, 0xde, 0xc6, 0x88, 0xe9, 0xaf, 0x24, 0x2c, 0x9e, 0xb3, 0x59, 0x8e, 0x09,
-	0x7c, 0x8f, 0x67, 0xca, 0xca, 0x36, 0x50, 0xd2, 0xb6, 0xae, 0xbf, 0x81, 0x60, 0x25, 0xc5, 0x4f,
-	0x39, 0xa6, 0xa5, 0x41, 0xdd, 0x60, 0x5a, 0xe4, 0x6b, 0x68, 0x18, 0x41, 0x53, 0x6f, 0xc1, 0xa9,
-	0xf8, 0xae, 0x34, 0xbd, 0x58, 0x34, 0xa8, 0xbb, 0x71, 0xa2, 0xa2, 0x49, 0x3d, 0x3b, 0x8b, 0x68,
-	0x39, 0x6a, 0x7d, 0x14, 0x96, 0x23, 0x07, 0xa5, 0xd9, 0xc6, 0x74, 0x8e, 0xfd, 0xef, 0x18, 0x50,
-	0xc9, 0xc7, 0x95, 0x23, 0xfc, 0xaf, 0x88, 0xf4, 0x8d, 0x5b, 0xcf, 0xf6, 0xd4, 0xa4, 0xb2, 0xb9,
-	0x4b, 0x26, 0x70, 0xf9, 0x73, 0xac, 0x97, 0x61, 0x25, 0x66, 0x9b, 0x3b, 0x66, 0x77, 0x3a, 0xc5,
-	0x8b, 0x49, 0x2a, 0x19, 0x93, 0xcc, 0x48, 0x93, 0xe8, 0x56, 0x22, 0x06, 0xb1, 0x09, 0xca, 0x31,
-	0x82, 0xbf, 0x20, 0x58, 0x8e, 0x7c, 0x69, 0x6a, 0x2b, 0xc0, 0x5f, 0x8e, 0xe9, 0xe6, 0x8a, 0x8a,
-	0x67, 0xa7, 0xe7, 0x3a, 0x3c, 0xd5, 0x74, 0xe5, 0x48, 0x55, 0xa2, 0x6d, 0xea, 0x4f, 0x83, 0x16,
-	0xf3, 0xd4, 0xe9, 0x25, 0x87, 0xa1, 0x7a, 0x9b, 0x8c, 0x03, 0xd7, 0x67, 0xcf, 0x34, 0x9a, 0x67,
-	0x50, 0x2b, 0x87, 0xf3, 0x31, 0xcc, 0x5f, 0x21, 0x66, 0xdf, 0xef, 0x6d, 0xf6, 0x48, 0xfb, 0x36,
-	0x65, 0x67, 0x10, 0x1c, 0xd4, 0x1b, 0x06, 0x7b, 0x66, 0xc8, 0x83, 0xe3, 0x72, 0xac, 0xba, 0x66,
-	0xb0, 0x67, 0x7a, 0x84, 0xb4, 0x6c, 0x9f, 0xb8, 0xfb, 0x66, 0x9f, 0x19, 0x6b, 0xcd, 0x08, 0xdb,
-	0x54, 0x1f, 0x0c, 0x7b, 0x61, 0x07, 0xc8, 0x9a, 0xc1, 0x1b, 0x54, 0x6f, 0x23, 0xb7, 0x2f, 0x0e,
-	0xd4, 0xf4, 0x51, 0xff, 0x6b, 0x15, 0x96, 0xb2, 0x4e, 0x3e, 0x89, 0xab, 0x2b, 0x94, 0xba, 0xba,
-	0x9a, 0x7c, 0xba, 0xbd, 0x17, 0x1a, 0xc4, 0xee, 0x0c, 0x1d, 0xcb, 0xf6, 0xf9, 0x59, 0xaf, 0x61,
-	0x44, 0x1d, 0x94, 0xf1, 0x9e, 0xe3, 0xf9, 0x12, 0x90, 0x1e, 0xb6, 0x25, 0x50, 0xb7, 0x16, 0x03,
-	0x75, 0x07, 0xb1, 0xa4, 0x70, 0x96, 0xd9, 0xf8, 0xf5, 0x42, 0x87, 0xbb, 0x89, 0xe0, 0xee, 0xf3,
-	0x30, 0xdf, 0x8b, 0x54, 0xc2, 0x60, 0x04, 0x95, 0x34, 0x46, 0x52, 0xa7, 0x21, 0x13, 0x8a, 0x83,
-	0x64, 0x73, 0x49, 0x90, 0xec, 0x65, 0x38, 0xda, 0x31, 0x7d, 0x73, 0x93, 0x50, 0x35, 0x6e, 0xdb,
-	0x7b, 0x8e, 0xd6, 0x60, 0x13, 0x3f, 0x3e, 0x3d, 0x72, 0x1c, 0x1b, 0x6e, 0x24, 0xc8, 0xa5, 0x50,
-	0x38, 0x48, 0xa3, 0x70, 0x45, 0x53, 0xe1, 0x5d, 0x38, 0x1a, 0x67, 0x22, 0x13, 0xe4, 0xa4, 0x99,
-	0x19, 0xe9, 0x46, 0x18, 0xa7, 0x68, 0xe1, 0xfb, 0x61, 0xc1, 0xdc, 0x37, 0xad, 0xbe, 0xb9, 0xdb,
-	0x27, 0x2f, 0x3a, 0x76, 0x10, 0x85, 0xe3, 0x9d, 0xfa, 0x2d, 0x58, 0xc9, 0xd2, 0xe8, 0x35, 0x32,
-	0x2e, 0x66, 0xb7, 0xba, 0x0f, 0x2b, 0x86, 0x80, 0xa2, 0x43, 0x0c, 0x40, 0x84, 0x90, 0x17, 0xa8,
-	0xb7, 0xf1, 0x2e, 0xe1, 0xf3, 0x05, 0xb1, 0x85, 0x90, 0x9c, 0xfe, 0x6d, 0x04, 0x5a, 0x7a, 0xda,
-	0x72, 0x76, 0xf0, 0xbb, 0xdd, 0xcf, 0xbf, 0x00, 0xa7, 0x9e, 0xb3, 0xdd, 0x03, 0x64, 0x50, 0xec,
-	0xea, 0x9f, 0x1e, 0x92, 0x32, 0x48, 0x97, 0x13, 0x53, 0x6f, 0xc2, 0xf1, 0xb0, 0xcc, 0xe0, 0x70,
-	0xd8, 0xdf, 0x85, 0x45, 0x89, 0x62, 0x39, 0x5c, 0xff, 0x1a, 0xc1, 0xd2, 0x53, 0x96, 0xdd, 0x09,
-	0xa4, 0x13, 0x6e, 0x60, 0x0f, 0xc2, 0x62, 0xdb, 0xb1, 0xbd, 0xd1, 0x80, 0xb8, 0xad, 0xc4, 0x12,
-	0xd2, 0x2f, 0x72, 0x03, 0xb2, 0xa7, 0x61, 0x5e, 0x20, 0xb0, 0x34, 0xcd, 0x0d, 0x10, 0x71, 0xa9,
-	0x8b, 0xc1, 0xbf, 0x34, 0xc9, 0xa8, 0xf1, 0xad, 0x92, 0x3e, 0xeb, 0x7f, 0x44, 0xb0, 0x9c, 0x60,
-	0xba, 0x1c, 0xdb, 0x7d, 0x29, 0x5d, 0xd3, 0x71, 0x68, 0xf8, 0x9e, 0xfe, 0x11, 0x62, 0xc9, 0xf7,
-	0x0d, 0x9b, 0x24, 0xad, 0x5e, 0x4d, 0xf6, 0x0f, 0xc2, 0x62, 0x70, 0x5f, 0xd7, 0x4a, 0x04, 0x9a,
-	0xf4, 0x0b, 0xbc, 0x0a, 0x38, 0xe8, 0xdc, 0x8e, 0x8c, 0x8f, 0xab, 0x26, 0xe3, 0x4d, 0x28, 0xff,
-	0xaa, 0x24, 0xff, 0x3f, 0xf0, 0xf4, 0x3f, 0xc6, 0x79, 0x39, 0x0a, 0x90, 0x63, 0x60, 0xe5, 0x70,
-	0x63, 0xe0, 0x5b, 0x1c, 0xea, 0x2a, 0x68, 0xf8, 0x6a, 0xc2, 0xc7, 0x12, 0x18, 0x2d, 0x09, 0x73,
-	0x29, 0xce, 0xc7, 0x7f, 0xa1, 0x2d, 0x7b, 0x70, 0x0f, 0x3f, 0xad, 0x04, 0x2f, 0x5b, 0x2c, 0x89,
-	0x3a, 0x94, 0x38, 0x28, 0x65, 0x68, 0x33, 0x72, 0x86, 0xa6, 0x0f, 0xe0, 0xde, 0xec, 0x49, 0xcb,
-	0x09, 0x95, 0xef, 0x56, 0x02, 0xcc, 0x2d, 0x98, 0x4f, 0x01, 0x62, 0xbc, 0xdb, 0x1a, 0xbd, 0x58,
-	0xb6, 0xc9, 0x2f, 0x2b, 0x5a, 0x8a, 0x10, 0x64, 0x16, 0x5b, 0x65, 0x62, 0x90, 0xfd, 0xa4, 0xd2,
-	0x4b, 0x05, 0x21, 0xcf, 0xc3, 0xd2, 0x2d, 0xd3, 0x6f, 0xf7, 0x92, 0xc1, 0xf2, 0x7e, 0x58, 0xf0,
-	0x48, 0x7f, 0x2f, 0xe9, 0xab, 0xf1, 0x4e, 0xfd, 0xc3, 0x0a, 0x2c, 0x27, 0x86, 0x97, 0xe3, 0x66,
-	0x27, 0x61, 0xd6, 0x6c, 0xfb, 0x52, 0x9e, 0xc9, 0x5b, 0xf8, 0x2a, 0x17, 0x2c, 0x07, 0x00, 0xcf,
-	0xe4, 0x72, 0xbc, 0x6b, 0x64, 0xcc, 0x55, 0x22, 0x47, 0xc5, 0xea, 0xe1, 0x46, 0xc5, 0xa7, 0xe1,
-	0xf8, 0x16, 0xf1, 0x45, 0x2d, 0xeb, 0x54, 0x96, 0x2d, 0xdf, 0x2b, 0x56, 0xe2, 0xf7, 0x8a, 0x7a,
-	0x8b, 0x85, 0xd8, 0xf5, 0x7e, 0x5f, 0x85, 0xe0, 0x7d, 0x00, 0x77, 0x2c, 0xbf, 0xc7, 0x87, 0x88,
-	0x6b, 0x20, 0xa9, 0x47, 0xff, 0x09, 0xe2, 0x97, 0x34, 0x82, 0x64, 0x69, 0x6a, 0xf4, 0x22, 0x06,
-	0xc2, 0xea, 0x5b, 0x66, 0x6d, 0xec, 0xa9, 0x25, 0xee, 0x4b, 0xc5, 0x71, 0x21, 0xd6, 0xa9, 0xff,
-	0x92, 0xc7, 0x74, 0x69, 0xe1, 0xe5, 0x70, 0xb9, 0x25, 0x71, 0x99, 0xab, 0x5a, 0x39, 0x28, 0x2a,
-	0xbe, 0x01, 0x27, 0x04, 0xf8, 0x70, 0x48, 0x9a, 0x27, 0xe1, 0xe5, 0x5f, 0x99, 0x02, 0xd0, 0x5f,
-	0x47, 0x70, 0x42, 0xae, 0x86, 0x2e, 0xcc, 0xf8, 0x41, 0x65, 0xd7, 0x13, 0xae, 0xc8, 0x49, 0xbc,
-	0xd2, 0xbc, 0x3c, 0xcc, 0xe6, 0xe4, 0x7a, 0xa7, 0x13, 0x16, 0x6a, 0x59, 0x51, 0xc6, 0xf2, 0x32,
-	0x1c, 0xe9, 0x48, 0xdd, 0xa2, 0x2a, 0xfb, 0xdc, 0xf4, 0x57, 0xdd, 0x22, 0xab, 0x89, 0x8a, 0xc0,
-	0x8c, 0x18, 0x41, 0xbd, 0xc7, 0xb0, 0xf6, 0xf8, 0xd4, 0xe5, 0x2c, 0xf2, 0x6b, 0x70, 0x8a, 0xdf,
-	0x5c, 0x7f, 0x2e, 0xeb, 0xfc, 0x06, 0x82, 0x85, 0x58, 0x25, 0x5c, 0x74, 0xae, 0x41, 0x13, 0xce,
-	0x35, 0x95, 0x89, 0x85, 0x26, 0x33, 0x13, 0x4b, 0x33, 0xab, 0xe9, 0x72, 0x91, 0x4f, 0x10, 0xe0,
-	0x34, 0xab, 0xd8, 0x80, 0xb9, 0x20, 0xfd, 0x14, 0x92, 0xce, 0x5b, 0xde, 0x17, 0xd2, 0x89, 0xd7,
-	0x0c, 0x56, 0x0e, 0xa9, 0x66, 0x90, 0x1e, 0xbb, 0xb3, 0x94, 0x58, 0xe6, 0xdd, 0x64, 0x96, 0xb9,
-	0x4c, 0xbe, 0xc2, 0xf8, 0x3d, 0x82, 0xe6, 0x16, 0xf1, 0x37, 0x1d, 0xfb, 0x33, 0xe0, 0x12, 0xb7,
-	0xd2, 0x82, 0xce, 0x79, 0xe3, 0x2d, 0xc9, 0x59, 0x2c, 0xe1, 0xa6, 0xeb, 0x7c, 0x46, 0x4b, 0x08,
-	0xec, 0xa6, 0xe8, 0x12, 0x42, 0x3a, 0xfa, 0x4f, 0x67, 0x61, 0x21, 0x56, 0xba, 0x8d, 0x5f, 0x80,
-	0x23, 0x03, 0xe9, 0x9f, 0x8b, 0x15, 0x17, 0xc5, 0x48, 0x95, 0x7a, 0x02, 0xc2, 0xcf, 0xc2, 0xbc,
-	0xd8, 0x43, 0xec, 0x3d, 0x27, 0xc8, 0xe0, 0x95, 0xf7, 0x63, 0x99, 0x46, 0x74, 0xa7, 0x5d, 0x2d,
-	0x7c, 0xa7, 0x1d, 0x37, 0xc0, 0xda, 0xe1, 0x18, 0x60, 0xdc, 0x24, 0x66, 0x0f, 0xc7, 0x24, 0xf0,
-	0x8e, 0x38, 0x23, 0xd7, 0x19, 0xbd, 0x27, 0xf3, 0xfd, 0x02, 0x20, 0x55, 0xa9, 0xb5, 0x06, 0x4b,
-	0xb2, 0x2d, 0x3c, 0xcf, 0xa3, 0xb1, 0xa7, 0xcd, 0xb1, 0x93, 0x78, 0xe6, 0x3b, 0x7c, 0x1d, 0xea,
-	0xac, 0xd6, 0xbf, 0xed, 0x09, 0x54, 0x3c, 0xd7, 0xef, 0x05, 0x02, 0x1a, 0xf9, 0x2f, 0xb4, 0x3e,
-	0x46, 0xa0, 0x45, 0xf7, 0x99, 0xe2, 0x27, 0x0e, 0x25, 0x79, 0xf9, 0xcd, 0x64, 0x9d, 0x51, 0xde,
-	0x9f, 0x60, 0x84, 0x85, 0x46, 0x57, 0x01, 0x5f, 0x22, 0xfd, 0x44, 0xa1, 0x11, 0x4d, 0xf2, 0xc3,
-	0x58, 0x1c, 0xfc, 0xa4, 0x45, 0xea, 0x39, 0xa0, 0x0c, 0xcc, 0x88, 0xd3, 0xf2, 0x86, 0x0c, 0xee,
-	0x8f, 0xff, 0xa8, 0x09, 0x25, 0x7f, 0xd4, 0x74, 0x17, 0x04, 0xfe, 0x77, 0x88, 0xe5, 0xbe, 0x65,
-	0x97, 0x3c, 0xdd, 0x4a, 0x95, 0x3c, 0x9d, 0x53, 0xd8, 0x69, 0x93, 0x6b, 0x96, 0x0a, 0x9f, 0xd6,
-	0xe0, 0x28, 0x3d, 0x6a, 0x0c, 0x23, 0x24, 0x22, 0x91, 0x62, 0xa0, 0x74, 0x8a, 0xf1, 0x1a, 0x1c,
-	0x0b, 0xc7, 0x94, 0x77, 0x0c, 0xa6, 0xb9, 0x52, 0x70, 0xc7, 0x29, 0x5a, 0x6b, 0x7f, 0xbb, 0x27,
-	0x2c, 0x70, 0xde, 0xf4, 0xdd, 0x3e, 0x7e, 0x13, 0x41, 0x8d, 0xbc, 0x66, 0x79, 0x3e, 0x3e, 0xaf,
-	0x72, 0xb7, 0x9f, 0xac, 0x12, 0x6e, 0x5e, 0xc8, 0x39, 0x5a, 0xb0, 0xfb, 0x2d, 0x04, 0xb3, 0x6d,
-	0x96, 0xb3, 0xe0, 0x0b, 0x85, 0x4a, 0x44, 0x9b, 0x4f, 0xe4, 0x1d, 0x2e, 0x71, 0xd2, 0x61, 0x27,
-	0x27, 0x05, 0x4e, 0xb2, 0xea, 0x2c, 0x15, 0x38, 0xc9, 0x2e, 0xad, 0x7c, 0x1d, 0xc1, 0x6c, 0x97,
-	0xa1, 0xbc, 0xf8, 0x6c, 0x8e, 0xba, 0x8b, 0x80, 0x8d, 0x73, 0xb9, 0xc6, 0x0a, 0x1e, 0xde, 0x46,
-	0x30, 0xdf, 0x8d, 0xea, 0x11, 0x71, 0x1e, 0x62, 0x81, 0x5f, 0x34, 0xcf, 0xe7, 0x1b, 0x2c, 0x58,
-	0xf9, 0x00, 0xc1, 0xf1, 0x11, 0x83, 0xbb, 0x22, 0xcc, 0x0c, 0x6f, 0x14, 0xaf, 0x12, 0x6c, 0x6e,
-	0x16, 0xa2, 0x21, 0xb8, 0xfb, 0x2e, 0x82, 0xba, 0xd9, 0xe9, 0xb0, 0x2b, 0x93, 0x8b, 0x39, 0x2a,
-	0x31, 0xe4, 0xd2, 0xa5, 0xe6, 0x93, 0xf9, 0x09, 0x48, 0xec, 0x74, 0x89, 0xaf, 0xc8, 0x4e, 0x76,
-	0x91, 0xa1, 0x02, 0x3b, 0x07, 0x15, 0x1b, 0xfe, 0x00, 0x01, 0x70, 0xdd, 0x31, 0x8e, 0xd6, 0xf3,
-	0x49, 0x5c, 0x2a, 0x03, 0x6c, 0x6e, 0x14, 0x21, 0x21, 0xb8, 0xfa, 0x11, 0x02, 0xe0, 0xae, 0xce,
-	0xb8, 0xda, 0xc8, 0xe9, 0xaf, 0xb2, 0xa8, 0x36, 0x0b, 0xd1, 0x10, 0x7c, 0x7d, 0x87, 0xdb, 0x12,
-	0x4d, 0x56, 0xf0, 0x13, 0xc5, 0xaa, 0x7a, 0x9a, 0x17, 0x73, 0x8f, 0x97, 0x98, 0xe9, 0x12, 0x5f,
-	0x91, 0x99, 0xcc, 0xa2, 0xb6, 0xe6, 0xc5, 0x82, 0xe5, 0x63, 0xf8, 0xfb, 0x08, 0x1a, 0xdc, 0x8e,
-	0x76, 0xcc, 0x2e, 0x7e, 0x32, 0x9f, 0x0d, 0x44, 0xa5, 0x62, 0xcd, 0xf5, 0x02, 0x14, 0x24, 0xd3,
-	0xe6, 0x46, 0xc4, 0x44, 0xb4, 0x9e, 0xcf, 0x00, 0x64, 0x29, 0x6d, 0x14, 0x21, 0x21, 0xb8, 0xfa,
-	0x26, 0x82, 0x85, 0x6e, 0x80, 0xd1, 0xb2, 0x24, 0xed, 0x8b, 0x4a, 0xb2, 0x97, 0xc1, 0xbc, 0xe6,
-	0xd9, 0x3c, 0x43, 0x05, 0x23, 0xef, 0x21, 0x38, 0xde, 0x95, 0x90, 0x58, 0xc6, 0x8b, 0xd2, 0x46,
-	0x90, 0x44, 0xaf, 0xd5, 0x52, 0x8d, 0x34, 0x04, 0xfc, 0x0e, 0x82, 0x23, 0x1d, 0x09, 0x1a, 0x55,
-	0xe0, 0x26, 0x03, 0xa2, 0x6d, 0x5e, 0xc8, 0x39, 0x5a, 0xe2, 0x66, 0x20, 0xa1, 0x97, 0x0a, 0xdc,
-	0x64, 0xe0, 0xae, 0x0a, 0xdc, 0x64, 0x42, 0xa6, 0xef, 0x22, 0x58, 0x90, 0xb9, 0xf1, 0x70, 0x3e,
-	0x82, 0x9e, 0x7a, 0x0e, 0x94, 0xfd, 0x4d, 0x8d, 0x9f, 0x23, 0xf8, 0x5f, 0x33, 0x0e, 0x7d, 0x3e,
-	0xe5, 0xb8, 0xf2, 0xd1, 0xd5, 0x53, 0xdb, 0x6e, 0x33, 0x80, 0x2a, 0xb5, 0xed, 0x36, 0x13, 0xea,
-	0xf9, 0x05, 0x02, 0xbd, 0x9d, 0x82, 0xdc, 0x52, 0x9c, 0x6e, 0x28, 0xe6, 0xa6, 0x59, 0xcc, 0x6e,
-	0x16, 0xa2, 0x21, 0xf8, 0xfd, 0x31, 0x82, 0x95, 0x2e, 0x43, 0xae, 0x18, 0x92, 0x20, 0xff, 0x8f,
-	0x5a, 0xba, 0x50, 0x8c, 0xc3, 0x09, 0xe0, 0x99, 0xe0, 0x30, 0x85, 0xc3, 0x7e, 0xf6, 0x1c, 0x1e,
-	0x84, 0x50, 0xbe, 0x83, 0xe0, 0x68, 0x47, 0x0e, 0xc0, 0x2a, 0xd9, 0x71, 0xfa, 0x44, 0xde, 0x3c,
-	0x9f, 0x6f, 0x30, 0xe7, 0x66, 0xed, 0xd3, 0x79, 0x38, 0x91, 0x40, 0xc7, 0xd8, 0xf9, 0xee, 0x3d,
-	0x44, 0xcf, 0x95, 0xbc, 0x02, 0x4b, 0x61, 0xc3, 0x3c, 0xa0, 0x26, 0x4e, 0x61, 0xc3, 0x3c, 0xb0,
-	0xbc, 0x8d, 0x66, 0x5d, 0xa3, 0xb0, 0x2a, 0x4c, 0x25, 0x83, 0x3f, 0xa8, 0x4a, 0x4d, 0x25, 0x83,
-	0x3f, 0xb8, 0x1c, 0xed, 0x0d, 0x04, 0x8d, 0x5e, 0x50, 0xee, 0xa5, 0xb0, 0x5d, 0x26, 0x8b, 0xce,
-	0x14, 0xb6, 0xcb, 0x74, 0x75, 0xd9, 0x5b, 0x08, 0xaa, 0x7b, 0x96, 0xdd, 0x51, 0x88, 0xbb, 0x59,
-	0xd5, 0x63, 0x0a, 0x71, 0x37, 0xbb, 0x8e, 0x8b, 0x6e, 0x4b, 0x5d, 0xa9, 0x28, 0x46, 0x6d, 0xcb,
-	0x4e, 0xb1, 0x73, 0x21, 0xe7, 0x68, 0xc1, 0xcd, 0xfb, 0x08, 0x8e, 0x76, 0x63, 0xf5, 0x4e, 0x6a,
-	0xa9, 0x68, 0xba, 0xc4, 0x4b, 0x2d, 0x15, 0xcd, 0x2a, 0xb4, 0xfa, 0x00, 0xc1, 0x11, 0x9e, 0x8a,
-	0xf2, 0xaa, 0x17, 0x7c, 0x29, 0x67, 0xb5, 0x48, 0xac, 0x52, 0xa7, 0x79, 0xb9, 0x20, 0x15, 0xc1,
-	0xdd, 0x87, 0x08, 0xb4, 0x51, 0xaa, 0x36, 0x44, 0x1c, 0x9a, 0x37, 0x0f, 0xa1, 0xae, 0xa5, 0x79,
-	0xa9, 0x18, 0x91, 0x08, 0x5f, 0xa8, 0xdd, 0x31, 0xfd, 0x76, 0x4f, 0xc1, 0xe0, 0xb3, 0xaa, 0x50,
-	0x14, 0x0c, 0x3e, 0xb3, 0x0a, 0xe5, 0x21, 0xc4, 0x4c, 0xbe, 0x27, 0x7d, 0xa7, 0x0a, 0xe7, 0xfb,
-	0xac, 0x96, 0xba, 0xc9, 0x67, 0x7d, 0x1c, 0x6b, 0xed, 0x4f, 0x33, 0xb0, 0xb8, 0xe5, 0xec, 0x13,
-	0xd7, 0x96, 0xd1, 0xba, 0xf7, 0x79, 0x36, 0x1d, 0xbf, 0xb1, 0x29, 0x02, 0x0e, 0xad, 0xe7, 0x18,
-	0x9b, 0x00, 0xc0, 0x7f, 0x88, 0xe0, 0x58, 0x37, 0xfe, 0xa5, 0xa2, 0x5c, 0x90, 0x83, 0xfc, 0xb9,
-	0xa5, 0x5c, 0x90, 0x43, 0xfc, 0x23, 0x49, 0x6f, 0x72, 0xb6, 0xd6, 0x87, 0xc3, 0xbe, 0xd5, 0x36,
-	0xf9, 0xa7, 0x9a, 0x1e, 0x57, 0x3a, 0x39, 0x44, 0x88, 0x6e, 0xf3, 0x8c, 0xfa, 0x40, 0xce, 0xc6,
-	0xc6, 0x43, 0x30, 0xed, 0x17, 0xf3, 0x5e, 0xac, 0xb1, 0x2f, 0xec, 0xed, 0xce, 0xb2, 0x3f, 0x8f,
-	0xfc, 0x27, 0x00, 0x00, 0xff, 0xff, 0xc4, 0x56, 0xf4, 0x2b, 0x7a, 0x4f, 0x00, 0x00,
+	// 3405 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5c, 0xdb, 0x8f, 0x1c, 0xc5,
+	0xb9, 0x57, 0xcd, 0xce, 0xec, 0xec, 0x7c, 0x7b, 0xb1, 0xb7, 0xbc, 0xeb, 0x6d, 0x0f, 0x1c, 0x8e,
+	0xd5, 0x42, 0x3a, 0x3c, 0xa0, 0x3d, 0xb0, 0x1c, 0xc0, 0xc7, 0xd8, 0x98, 0xbd, 0x98, 0xf5, 0x1a,
+	0x8c, 0x4d, 0xcf, 0x62, 0x07, 0x48, 0x82, 0x7a, 0x67, 0x6a, 0x67, 0x1a, 0xcf, 0x74, 0x37, 0xdd,
+	0x3d, 0x6b, 0x46, 0x8a, 0x14, 0x81, 0x20, 0x21, 0x21, 0x81, 0xa0, 0x24, 0x4f, 0x3c, 0x24, 0x4a,
+	0xc2, 0x63, 0x22, 0x25, 0x8a, 0x84, 0x22, 0x94, 0x28, 0x4a, 0x94, 0x37, 0x50, 0x9e, 0xa2, 0x3c,
+	0x25, 0x7f, 0x41, 0xde, 0xf2, 0x07, 0x24, 0xaa, 0x4b, 0x77, 0x57, 0x5f, 0x76, 0xdd, 0x97, 0x6d,
+	0x50, 0x9e, 0xb6, 0xab, 0x7a, 0xea, 0xab, 0xaf, 0xbe, 0x5b, 0x7d, 0xf5, 0xab, 0x6f, 0x1b, 0x16,
+	0x5c, 0xe2, 0x1c, 0x18, 0x5d, 0xe2, 0xae, 0xda, 0x8e, 0xe5, 0x59, 0xf8, 0x7f, 0xba, 0xd6, 0x68,
+	0x75, 0x30, 0xd6, 0xef, 0x10, 0x63, 0xd5, 0xd6, 0x75, 0x77, 0xb5, 0xeb, 0x92, 0x55, 0xf1, 0x1b,
+	0x87, 0xf4, 0x0d, 0xd7, 0x73, 0x26, 0xab, 0xba, 0x6d, 0xa8, 0x5f, 0x87, 0xa5, 0x6b, 0x56, 0xcf,
+	0xd8, 0x9f, 0x74, 0xba, 0x03, 0x32, 0xd2, 0x5d, 0x8d, 0xbc, 0x36, 0x26, 0xae, 0x87, 0xef, 0x85,
+	0x96, 0xf8, 0xf9, 0x4e, 0x4f, 0x41, 0x67, 0xd1, 0x03, 0x2d, 0x2d, 0xec, 0xc0, 0x3b, 0xd0, 0x74,
+	0xf9, 0xef, 0x95, 0xda, 0xd9, 0xa9, 0x07, 0x66, 0xd7, 0xfe, 0x77, 0x35, 0xe3, 0x84, 0xab, 0x7c,
+	0x1e, 0xcd, 0x1f, 0xaf, 0xde, 0x84, 0x69, 0xde, 0x85, 0xdb, 0x30, 0xc3, 0x3b, 0x83, 0x19, 0x83,
+	0x36, 0x56, 0xa0, 0xe9, 0x8e, 0x47, 0x23, 0xdd, 0x99, 0x28, 0x35, 0xf6, 0xca, 0x6f, 0xe2, 0xd3,
+	0x30, 0xcd, 0x7f, 0xa5, 0x4c, 0xb1, 0x17, 0xa2, 0xa5, 0xee, 0xc3, 0x72, 0x6c, 0x61, 0xae, 0x6d,
+	0x99, 0x2e, 0xc1, 0xd7, 0x60, 0xc6, 0x11, 0xcf, 0x6c, 0x9a, 0xd9, 0xb5, 0x87, 0x33, 0x33, 0xef,
+	0x13, 0xd1, 0x02, 0x12, 0xea, 0x6b, 0x70, 0xea, 0x0a, 0xd1, 0x1d, 0x6f, 0x8f, 0xe8, 0x5e, 0x87,
+	0x78, 0xbe, 0xfc, 0x5e, 0x82, 0x96, 0x61, 0xba, 0x9e, 0x6e, 0x76, 0x89, 0xab, 0x20, 0x26, 0xa3,
+	0x0b, 0x99, 0xa7, 0x91, 0x09, 0x5e, 0x1e, 0x92, 0x11, 0x31, 0x3d, 0x2d, 0x24, 0xa7, 0x76, 0xa2,
+	0x53, 0x8a, 0x5f, 0xdc, 0x45, 0x65, 0xf7, 0x01, 0xf8, 0x14, 0x76, 0x7a, 0x42, 0x88, 0x52, 0x8f,
+	0xfa, 0x09, 0x82, 0xa5, 0xe8, 0x42, 0x2a, 0x91, 0x17, 0xde, 0x95, 0x05, 0xc3, 0x8d, 0xe7, 0xb1,
+	0xcc, 0xf4, 0x76, 0xc4, 0xc8, 0x2b, 0x7b, 0x9a, 0x1b, 0x11, 0xc9, 0x08, 0xe6, 0x23, 0xef, 0xca,
+	0x09, 0x83, 0xbe, 0x27, 0x8e, 0x73, 0x8d, 0xb8, 0xae, 0xde, 0x27, 0xc2, 0xb0, 0xa4, 0x1e, 0x75,
+	0x13, 0x5a, 0x1d, 0xaf, 0xc3, 0xc9, 0xe1, 0x25, 0x68, 0x74, 0xad, 0xb1, 0xe9, 0xb1, 0x69, 0xa6,
+	0x34, 0xde, 0xc0, 0x67, 0x61, 0xd6, 0x32, 0x87, 0x86, 0x49, 0x36, 0xd9, 0xbb, 0x1a, 0x7b, 0x27,
+	0x77, 0xa9, 0x2a, 0x40, 0xc7, 0xf3, 0xb9, 0x4e, 0xa7, 0xa2, 0xfe, 0x17, 0x34, 0x3a, 0xde, 0xba,
+	0x6d, 0x1f, 0xf2, 0xfa, 0x9f, 0x88, 0xd2, 0xd0, 0x3d, 0xc3, 0xf5, 0x8c, 0xae, 0x8b, 0x9f, 0x83,
+	0x19, 0x3f, 0x0e, 0x08, 0x55, 0xad, 0x65, 0xf7, 0x4b, 0x7f, 0x3d, 0x5a, 0x40, 0x03, 0x3f, 0x1f,
+	0xd5, 0x15, 0x25, 0xf8, 0x48, 0x0e, 0x82, 0xfe, 0xda, 0x24, 0x45, 0xe1, 0x0d, 0xa8, 0xeb, 0xb6,
+	0xed, 0x32, 0x99, 0xce, 0xae, 0xad, 0xe6, 0xa0, 0xb6, 0x6e, 0xdb, 0x1a, 0x1b, 0xab, 0xbe, 0x83,
+	0xe0, 0xf4, 0x36, 0xf1, 0xf9, 0x75, 0x77, 0xcc, 0x7d, 0xcb, 0x77, 0x3b, 0x05, 0x9a, 0x96, 0xed,
+	0x19, 0x96, 0xc9, 0x9d, 0xae, 0xa5, 0xf9, 0x4d, 0x2a, 0x40, 0xdd, 0xb6, 0x03, 0x6d, 0xf3, 0x06,
+	0xd5, 0x92, 0x98, 0xed, 0x39, 0x7d, 0xe4, 0x6b, 0x5a, 0xee, 0xa2, 0x86, 0xc4, 0x64, 0x7d, 0xdd,
+	0x1c, 0x4e, 0x94, 0xfa, 0x59, 0xf4, 0xc0, 0x8c, 0x16, 0x76, 0xa8, 0x3f, 0xad, 0xc1, 0x4a, 0x82,
+	0x95, 0x6a, 0x1c, 0xa7, 0x07, 0x8b, 0xfa, 0x70, 0xe8, 0xcf, 0xb4, 0x45, 0x3c, 0xdd, 0x18, 0xe6,
+	0x76, 0x20, 0x31, 0x9c, 0x8f, 0xd6, 0x92, 0x04, 0x71, 0x07, 0xc0, 0x0d, 0x0c, 0x4a, 0x68, 0x29,
+	0x8f, 0xce, 0xfd, 0xa1, 0x9a, 0x44, 0x46, 0xfd, 0x0c, 0xc1, 0x89, 0x6b, 0x46, 0xd7, 0xb1, 0xc4,
+	0x64, 0xcf, 0x10, 0x16, 0xb7, 0x3d, 0x62, 0xea, 0xc2, 0xa2, 0x5b, 0x9a, 0x68, 0x51, 0x0d, 0xda,
+	0x8e, 0xf5, 0x2a, 0xe9, 0x7a, 0x7e, 0xa4, 0x17, 0xcd, 0x50, 0x83, 0x53, 0x47, 0x68, 0xb0, 0x9e,
+	0xd4, 0xa0, 0x02, 0xcd, 0x03, 0xe2, 0xb8, 0x86, 0x65, 0x2a, 0x0d, 0x4e, 0x51, 0x34, 0xe9, 0x58,
+	0x62, 0x1e, 0x18, 0x8e, 0x65, 0xd2, 0x00, 0xaa, 0x4c, 0xf3, 0xb1, 0x52, 0x17, 0x9b, 0x73, 0x68,
+	0xe8, 0xae, 0xd2, 0x14, 0x73, 0xd2, 0x86, 0xfa, 0x69, 0x13, 0xe6, 0xe4, 0xf5, 0xdc, 0x25, 0xda,
+	0x14, 0x35, 0x3d, 0x89, 0xf1, 0x7a, 0x82, 0xf1, 0x1e, 0x71, 0xbb, 0x8e, 0xc1, 0x8c, 0x5b, 0x2c,
+	0x4b, 0xee, 0xa2, 0x73, 0x0e, 0xc9, 0x01, 0x19, 0x8a, 0x45, 0xf1, 0x06, 0xdb, 0x46, 0xc5, 0xbe,
+	0xdd, 0xe4, 0xee, 0x21, 0x9a, 0xf8, 0x2a, 0x34, 0x6c, 0xdd, 0x1b, 0xb8, 0x0a, 0x30, 0x8b, 0xfa,
+	0xbf, 0xbc, 0x16, 0x75, 0x43, 0xf7, 0x06, 0x1a, 0x27, 0xc1, 0xb6, 0x64, 0x4f, 0xf7, 0xc6, 0xae,
+	0x32, 0x23, 0xb6, 0x64, 0xd6, 0xc2, 0x04, 0xc0, 0x76, 0x2c, 0x9b, 0x38, 0x9e, 0x41, 0x5c, 0xa5,
+	0xc5, 0x26, 0xba, 0x9c, 0x79, 0x22, 0x59, 0xe0, 0xab, 0x37, 0x02, 0x3a, 0x97, 0x4d, 0xcf, 0x99,
+	0x68, 0x12, 0x61, 0xaa, 0x0c, 0xcf, 0x18, 0x11, 0xd7, 0xd3, 0x47, 0xb6, 0x32, 0xcb, 0x95, 0x11,
+	0x74, 0xe0, 0x9b, 0xd0, 0xb2, 0x1d, 0xeb, 0xc0, 0xe8, 0x11, 0xc7, 0x55, 0xe6, 0x18, 0x0f, 0xe7,
+	0x0a, 0xf1, 0xf0, 0x0c, 0x99, 0x68, 0x21, 0xa9, 0xd0, 0x52, 0xe6, 0x25, 0x4b, 0xa1, 0x4b, 0x7e,
+	0x76, 0xa3, 0xe3, 0x39, 0xba, 0x47, 0xfa, 0x13, 0x65, 0xa1, 0xcc, 0x92, 0x43, 0x3a, 0x62, 0xc9,
+	0x61, 0x07, 0x56, 0x61, 0x6e, 0x64, 0xf5, 0x76, 0x83, 0x55, 0x9f, 0x60, 0x3c, 0x44, 0xfa, 0xe2,
+	0xc6, 0x7e, 0x32, 0x69, 0xec, 0xf7, 0x01, 0xf0, 0xe9, 0x89, 0xb3, 0x31, 0x51, 0x16, 0xf9, 0xae,
+	0x17, 0xf6, 0xe0, 0x2f, 0x41, 0x6b, 0xdf, 0xd1, 0x47, 0xe4, 0x8e, 0xe5, 0xdc, 0x56, 0x30, 0x0b,
+	0x0d, 0xe7, 0x33, 0xaf, 0xe5, 0x69, 0x3a, 0xf2, 0x96, 0xe5, 0xdc, 0x16, 0xaa, 0x9b, 0x68, 0x21,
+	0xb1, 0xf6, 0x45, 0x38, 0x11, 0xd3, 0x28, 0x3e, 0x09, 0x53, 0xb7, 0xc9, 0x44, 0x38, 0x13, 0x7d,
+	0xa4, 0x12, 0x3e, 0xd0, 0x87, 0x63, 0xe2, 0xbb, 0x11, 0x6b, 0x9c, 0xaf, 0x9d, 0x43, 0x74, 0x78,
+	0x4c, 0x3a, 0x79, 0x86, 0xab, 0xeb, 0xb0, 0x98, 0xe0, 0x0e, 0x63, 0xa8, 0x9b, 0xd4, 0x2f, 0x39,
+	0x05, 0xf6, 0x2c, 0x3b, 0x64, 0x2d, 0xe2, 0x90, 0xea, 0xdf, 0x10, 0xcc, 0xfa, 0xfb, 0xe7, 0x78,
+	0x48, 0xa8, 0x0b, 0x38, 0xe3, 0x61, 0x18, 0x0d, 0x44, 0x8b, 0xe6, 0xb8, 0xf4, 0x69, 0x77, 0x62,
+	0xfb, 0x7c, 0x04, 0x6d, 0x6a, 0xb7, 0xba, 0xe7, 0x39, 0xc6, 0xde, 0xd8, 0xf3, 0xc3, 0x41, 0xd8,
+	0xc1, 0xe2, 0xa2, 0xee, 0x79, 0xc4, 0x09, 0x82, 0x81, 0x68, 0x66, 0x08, 0x06, 0x11, 0x8f, 0x98,
+	0x8e, 0x7b, 0x44, 0xdc, 0x78, 0x9a, 0x49, 0xe3, 0x51, 0xdf, 0x43, 0x70, 0x7a, 0xbd, 0xd7, 0xbb,
+	0xee, 0xbc, 0x60, 0xf7, 0x74, 0x8f, 0xc8, 0x4b, 0x95, 0x97, 0x84, 0x8e, 0x5a, 0x52, 0xed, 0x88,
+	0x25, 0x4d, 0x1d, 0xb9, 0xa4, 0x7a, 0x62, 0x49, 0xea, 0xef, 0x42, 0x81, 0xd3, 0xd0, 0x43, 0xd5,
+	0x45, 0x83, 0x8f, 0xaf, 0x2e, 0xfa, 0x8c, 0xbf, 0x0a, 0x33, 0x22, 0x2c, 0x4c, 0xc4, 0x46, 0xb9,
+	0x51, 0x24, 0xac, 0xf9, 0xc1, 0x46, 0xf8, 0x5d, 0x40, 0xb3, 0xfd, 0x04, 0xcc, 0x47, 0x5e, 0xe5,
+	0x32, 0xba, 0x73, 0x30, 0x13, 0x64, 0x0a, 0x18, 0xea, 0x5d, 0xab, 0xc7, 0xc5, 0xd7, 0xd0, 0xd8,
+	0x33, 0x15, 0xce, 0x48, 0xe4, 0x9f, 0xc2, 0xd6, 0x44, 0x53, 0xfd, 0x2b, 0x82, 0x53, 0xdb, 0xc4,
+	0xbb, 0xfc, 0x3a, 0xf5, 0x4b, 0x9a, 0x5e, 0x89, 0xdc, 0x07, 0x43, 0xdd, 0x0b, 0x95, 0xc0, 0x9e,
+	0x2b, 0xd8, 0x7a, 0x22, 0x5b, 0x5d, 0x23, 0xbe, 0xd5, 0xc9, 0x67, 0xb8, 0xe9, 0xd8, 0x19, 0x2e,
+	0x16, 0x80, 0x9a, 0x89, 0x00, 0xa4, 0xfe, 0x06, 0xc1, 0x52, 0x74, 0x65, 0xd5, 0xa4, 0x52, 0x91,
+	0x35, 0xd4, 0x8e, 0x5a, 0xc3, 0xd4, 0xe1, 0xe7, 0xd0, 0x7a, 0xe4, 0x1c, 0xaa, 0xfe, 0x72, 0x0a,
+	0x96, 0x36, 0x1d, 0x22, 0x39, 0x87, 0x50, 0xcb, 0x75, 0x68, 0x0a, 0xda, 0x82, 0xf5, 0x47, 0x0b,
+	0xc5, 0x7f, 0xcd, 0xa7, 0x82, 0x5f, 0x80, 0x06, 0x75, 0x30, 0xff, 0xf4, 0x74, 0x29, 0x33, 0xb9,
+	0x74, 0x07, 0xd6, 0x38, 0x35, 0xfc, 0x32, 0xd4, 0x3d, 0xbd, 0x4f, 0x73, 0x3e, 0x4a, 0x75, 0x3b,
+	0x33, 0xd5, 0xb4, 0x45, 0xaf, 0xee, 0xea, 0x7d, 0xb1, 0x33, 0x33, 0xa2, 0xf8, 0x65, 0xf9, 0x24,
+	0x51, 0x67, 0x33, 0x5c, 0x2c, 0x24, 0x86, 0x94, 0x33, 0x45, 0xfb, 0x71, 0x68, 0x05, 0xf3, 0xe5,
+	0xf2, 0xc1, 0xb7, 0x10, 0x2c, 0xc7, 0xd8, 0xff, 0x02, 0x0c, 0x4e, 0xbd, 0x0a, 0x4b, 0x5b, 0x64,
+	0x48, 0x12, 0x96, 0x73, 0xd7, 0xac, 0x72, 0xdf, 0x72, 0xba, 0x7c, 0x59, 0x33, 0x1a, 0x6f, 0xa8,
+	0xfb, 0xb0, 0x1c, 0xa3, 0x55, 0x0d, 0xec, 0xf1, 0x30, 0x2c, 0x86, 0xe7, 0x9e, 0x4c, 0x0c, 0xab,
+	0xbf, 0x46, 0x80, 0xe5, 0x31, 0xd5, 0x88, 0x5a, 0x72, 0xb7, 0xda, 0x71, 0xb8, 0x9b, 0xba, 0x24,
+	0x73, 0xed, 0xe3, 0x63, 0xea, 0xc7, 0x3c, 0x08, 0x87, 0xdd, 0xd5, 0xac, 0xe6, 0x79, 0xe9, 0x44,
+	0xcf, 0xdd, 0xbd, 0xe0, 0x72, 0x02, 0x32, 0xea, 0x3f, 0x10, 0x9c, 0x89, 0x04, 0x01, 0xba, 0x87,
+	0x65, 0xc4, 0xfd, 0x9c, 0x48, 0x06, 0xcf, 0x19, 0xd2, 0x32, 0x33, 0x74, 0xe8, 0xac, 0x47, 0xa5,
+	0xf3, 0x25, 0x73, 0x43, 0xf5, 0x36, 0xb4, 0xd3, 0xe6, 0xad, 0xc6, 0x2b, 0x1e, 0x93, 0x81, 0x09,
+	0x1a, 0x5c, 0xdd, 0xcc, 0xae, 0xb1, 0x92, 0x18, 0x58, 0x8d, 0x45, 0x5d, 0x8d, 0xee, 0x1e, 0xb9,
+	0x0f, 0x7a, 0xd2, 0x96, 0xa1, 0x7e, 0x84, 0x40, 0x49, 0xee, 0x27, 0x99, 0x2c, 0x29, 0x4c, 0x90,
+	0x6b, 0x91, 0x04, 0xb9, 0x03, 0x75, 0xfa, 0x24, 0x90, 0x87, 0xd2, 0x7b, 0x1b, 0x23, 0xa6, 0xbe,
+	0x1a, 0xb3, 0x78, 0xce, 0x66, 0x35, 0x26, 0xf0, 0x5d, 0x9e, 0x29, 0xe7, 0xb6, 0x81, 0x8a, 0xb6,
+	0x75, 0xf5, 0x4d, 0x04, 0x2b, 0x09, 0x7e, 0xaa, 0x31, 0x2d, 0x05, 0x9a, 0x1a, 0xd3, 0x22, 0x5f,
+	0x43, 0x4b, 0xf3, 0x9b, 0x6a, 0x07, 0xce, 0x44, 0x77, 0xa5, 0xec, 0x62, 0x51, 0xa0, 0xe9, 0x44,
+	0x89, 0x8a, 0x26, 0xf5, 0xec, 0x34, 0xa2, 0xd5, 0xa8, 0xf5, 0x51, 0x58, 0x0e, 0x1d, 0x94, 0x66,
+	0x1b, 0xd9, 0x1c, 0xfb, 0x5f, 0x11, 0xa8, 0x92, 0x8f, 0xab, 0x46, 0xf8, 0x5f, 0x11, 0xe9, 0x1b,
+	0xb7, 0x9e, 0x9d, 0xcc, 0xa4, 0xd2, 0xb9, 0x8b, 0x27, 0x70, 0xc5, 0x73, 0xac, 0x57, 0x60, 0x25,
+	0x62, 0x9b, 0xbb, 0x7a, 0x3f, 0x9b, 0xe2, 0xc5, 0x24, 0xb5, 0x94, 0x49, 0xa6, 0xa4, 0x49, 0x54,
+	0x23, 0x16, 0x83, 0xd8, 0x04, 0xd5, 0x18, 0xc1, 0xa7, 0x08, 0x96, 0x43, 0x5f, 0xca, 0x6c, 0x05,
+	0xf8, 0xcb, 0x11, 0xdd, 0x5c, 0xc9, 0xe3, 0xd9, 0xc9, 0xb9, 0x8e, 0x4f, 0x35, 0x7d, 0x39, 0x52,
+	0x55, 0x68, 0x9b, 0xea, 0xb3, 0xa0, 0x44, 0x3c, 0x35, 0xbb, 0xe4, 0x30, 0xd4, 0x6f, 0x93, 0x89,
+	0xef, 0xfa, 0xec, 0x99, 0x46, 0xf3, 0x14, 0x6a, 0xd5, 0x70, 0x3e, 0x81, 0xd9, 0x2b, 0x44, 0x1f,
+	0x7a, 0x83, 0xcd, 0x01, 0xe9, 0xde, 0xa6, 0xec, 0x8c, 0xfc, 0x83, 0x7a, 0x4b, 0x63, 0xcf, 0x0c,
+	0x79, 0xb0, 0x1c, 0x8e, 0x56, 0x37, 0x34, 0xf6, 0x4c, 0x8f, 0x90, 0x86, 0xe9, 0x11, 0xe7, 0x40,
+	0x1f, 0x32, 0x63, 0x6d, 0x68, 0x41, 0x9b, 0xea, 0x83, 0x61, 0x2f, 0xec, 0x00, 0xd9, 0xd0, 0x78,
+	0x83, 0xea, 0x6d, 0xec, 0x0c, 0xc5, 0x81, 0x9a, 0x3e, 0xaa, 0x7f, 0xae, 0xc3, 0x52, 0xda, 0xc9,
+	0x27, 0x76, 0x79, 0x85, 0x12, 0x97, 0x57, 0x47, 0x9f, 0x6e, 0xef, 0x85, 0x16, 0x31, 0x7b, 0xb6,
+	0x65, 0x98, 0x1e, 0x3f, 0xeb, 0xb5, 0xb4, 0xb0, 0x83, 0x32, 0x3e, 0xb0, 0x5c, 0x4f, 0x82, 0xd2,
+	0x83, 0xb6, 0x04, 0xeb, 0x36, 0x22, 0xb0, 0xee, 0x28, 0x92, 0x14, 0x4e, 0x33, 0x1b, 0xbf, 0x56,
+	0xea, 0x70, 0x77, 0x24, 0xbc, 0x7b, 0x13, 0x66, 0x07, 0xa1, 0x4a, 0x18, 0x8c, 0x90, 0x27, 0x8d,
+	0x91, 0xd4, 0xa9, 0xc9, 0x84, 0xa2, 0x20, 0xd9, 0x4c, 0x1c, 0x24, 0x7b, 0x05, 0x16, 0x7a, 0xba,
+	0xa7, 0x6f, 0x12, 0xaa, 0xc6, 0x1d, 0x73, 0xdf, 0x52, 0x5a, 0x6c, 0xe2, 0xc7, 0x33, 0x4f, 0xbc,
+	0x15, 0x19, 0xae, 0xc5, 0xc8, 0x25, 0x50, 0x38, 0x48, 0xa2, 0x70, 0x65, 0x53, 0xe1, 0x3d, 0x58,
+	0x88, 0x32, 0x91, 0x0a, 0x72, 0xd2, 0xcc, 0x8c, 0xf4, 0x43, 0x8c, 0x53, 0xb4, 0xf0, 0xfd, 0x30,
+	0xaf, 0x1f, 0xe8, 0xc6, 0x50, 0xdf, 0x1b, 0x92, 0x97, 0x2c, 0xd3, 0x8f, 0xc2, 0xd1, 0x4e, 0xf5,
+	0x16, 0xac, 0xa4, 0x69, 0xf4, 0x19, 0x32, 0x29, 0x67, 0xb7, 0xaa, 0x07, 0x2b, 0x9a, 0x80, 0xa2,
+	0x03, 0x0c, 0x40, 0x84, 0x90, 0x17, 0xa9, 0xb7, 0xf1, 0x2e, 0xe1, 0xf3, 0x25, 0xb1, 0x85, 0x80,
+	0x9c, 0xfa, 0x2d, 0x04, 0x4a, 0x72, 0xda, 0x6a, 0x76, 0xf0, 0xbb, 0xdd, 0xd0, 0xbf, 0x08, 0x67,
+	0x5e, 0x30, 0x9d, 0x43, 0x64, 0x50, 0xee, 0xf2, 0x9f, 0x1e, 0x92, 0x52, 0x48, 0x57, 0x13, 0x53,
+	0x6f, 0xc0, 0xc9, 0xa0, 0xd0, 0xe0, 0x78, 0xd8, 0xdf, 0x83, 0x45, 0x89, 0x62, 0x35, 0x5c, 0xff,
+	0x0a, 0xc1, 0xd2, 0xd3, 0x86, 0xd9, 0xf3, 0xa5, 0x13, 0x6c, 0x60, 0x0f, 0xc2, 0x62, 0xd7, 0x32,
+	0xdd, 0xf1, 0x88, 0x38, 0x9d, 0xd8, 0x12, 0x92, 0x2f, 0x0a, 0x03, 0xb2, 0x67, 0x61, 0x56, 0x20,
+	0xb0, 0x34, 0xcd, 0xf5, 0x11, 0x71, 0xa9, 0x8b, 0xc1, 0xbf, 0x34, 0xc9, 0x68, 0xf0, 0xad, 0x92,
+	0x3e, 0xab, 0x7f, 0x44, 0xb0, 0x1c, 0x63, 0xba, 0x1a, 0xdb, 0x7d, 0x39, 0x59, 0xd5, 0x71, 0x6c,
+	0xf8, 0x9e, 0xfa, 0x31, 0x62, 0xc9, 0xf7, 0x75, 0x93, 0xc4, 0xad, 0x3e, 0x9f, 0xec, 0x1f, 0x84,
+	0x45, 0xff, 0xbe, 0xae, 0x13, 0x0b, 0x34, 0xc9, 0x17, 0x78, 0x15, 0xb0, 0xdf, 0xb9, 0x13, 0x1a,
+	0x1f, 0x57, 0x4d, 0xca, 0x9b, 0x40, 0xfe, 0x75, 0x49, 0xfe, 0x7f, 0xe0, 0xe9, 0x7f, 0x84, 0xf3,
+	0x6a, 0x14, 0x20, 0xc7, 0xc0, 0xda, 0xf1, 0xc6, 0xc0, 0xb7, 0x39, 0xd4, 0x55, 0xd2, 0xf0, 0xf3,
+	0x09, 0x1f, 0x4b, 0x60, 0xb4, 0x24, 0xcc, 0xa5, 0x28, 0x1f, 0xff, 0x81, 0xb6, 0xec, 0xc2, 0x3d,
+	0xfc, 0xb4, 0xe2, 0xbf, 0xec, 0xb0, 0x24, 0xea, 0x58, 0xe2, 0xa0, 0x94, 0xa1, 0x4d, 0xc9, 0x19,
+	0x9a, 0x3a, 0x82, 0x7b, 0xd3, 0x27, 0xad, 0x26, 0x54, 0xbe, 0x57, 0xf3, 0x31, 0x37, 0x7f, 0xbe,
+	0x1c, 0x10, 0xe3, 0xdd, 0xd6, 0xe8, 0x46, 0xb2, 0x4d, 0x7e, 0x59, 0xd1, 0xc9, 0x09, 0x41, 0xa6,
+	0xb1, 0x55, 0x25, 0x06, 0x39, 0x8c, 0x2b, 0xbd, 0x52, 0x10, 0xf2, 0x02, 0x2c, 0xdd, 0xd2, 0xbd,
+	0xee, 0x20, 0x1e, 0x2c, 0xef, 0x87, 0x79, 0x97, 0x0c, 0xf7, 0xe3, 0xbe, 0x1a, 0xed, 0x54, 0x3f,
+	0xaa, 0xc1, 0x72, 0x6c, 0x78, 0x35, 0x6e, 0x76, 0x1a, 0xa6, 0xf5, 0xae, 0x27, 0xe5, 0x99, 0xbc,
+	0x85, 0xaf, 0x72, 0xc1, 0x72, 0x00, 0xb0, 0x78, 0x69, 0x06, 0x53, 0x89, 0x1c, 0x15, 0xeb, 0xc7,
+	0x1b, 0x15, 0x9f, 0x85, 0x93, 0xdb, 0xc4, 0x13, 0xd5, 0xac, 0x99, 0x2c, 0x5b, 0xbe, 0x57, 0xac,
+	0x45, 0xef, 0x15, 0xd5, 0x0e, 0x0b, 0xb1, 0xeb, 0xc3, 0x61, 0x1e, 0x82, 0xf7, 0x01, 0xdc, 0x31,
+	0xbc, 0x01, 0x1f, 0x22, 0xae, 0x81, 0xa4, 0x1e, 0xf5, 0xc7, 0x88, 0x5f, 0xd2, 0x08, 0x92, 0x95,
+	0xa9, 0xd1, 0x0d, 0x19, 0x08, 0xea, 0x6f, 0x99, 0xb5, 0xb1, 0xa7, 0x8e, 0xb8, 0x2f, 0x15, 0xc7,
+	0x85, 0x48, 0xa7, 0xfa, 0x0b, 0x1e, 0xd3, 0xa5, 0x85, 0x57, 0xc3, 0xe5, 0xb6, 0xc4, 0x65, 0xa1,
+	0x7a, 0x65, 0xbf, 0xac, 0xf8, 0x3a, 0x9c, 0x12, 0xe0, 0xc3, 0x31, 0x69, 0x9e, 0x04, 0x97, 0x7f,
+	0x55, 0x0a, 0x40, 0x7d, 0x03, 0xc1, 0x29, 0xb9, 0x1e, 0xba, 0x34, 0xe3, 0x87, 0x15, 0x5e, 0x1f,
+	0x71, 0x45, 0x4e, 0xa2, 0xb5, 0xe6, 0xd5, 0x61, 0x36, 0xa7, 0xd7, 0x7b, 0xbd, 0x2d, 0x62, 0x13,
+	0xb3, 0x47, 0xcc, 0xae, 0x11, 0x66, 0x2c, 0xaf, 0xc0, 0x5c, 0x4f, 0xea, 0x16, 0x75, 0xd9, 0x4f,
+	0x64, 0xbf, 0xea, 0x16, 0x59, 0x4d, 0x40, 0x7b, 0xa2, 0x45, 0x08, 0xaa, 0x03, 0x86, 0xb5, 0x47,
+	0xa7, 0xae, 0x66, 0x91, 0x5f, 0x83, 0x33, 0xfc, 0xe6, 0xfa, 0x0b, 0x59, 0xe7, 0xdf, 0x11, 0xe0,
+	0xe4, 0x8f, 0xf0, 0x2e, 0xcc, 0xf8, 0x89, 0x9f, 0x58, 0x63, 0xf1, 0xf8, 0x1d, 0x50, 0x8a, 0x56,
+	0xec, 0xd5, 0x8e, 0xaf, 0x62, 0xaf, 0x0d, 0x33, 0xd6, 0x01, 0x71, 0x1c, 0xa3, 0xc7, 0x4f, 0x5c,
+	0x33, 0x5a, 0xd0, 0xa6, 0x07, 0xe2, 0x34, 0xf1, 0x56, 0x79, 0x6b, 0x98, 0xa6, 0xc8, 0xa3, 0x2f,
+	0x17, 0x7e, 0x8f, 0xa0, 0xbd, 0x4d, 0xbc, 0x4d, 0xcb, 0xfc, 0x1c, 0xb8, 0xc4, 0x9d, 0xa4, 0x1a,
+	0x0a, 0xde, 0x45, 0x87, 0x74, 0xfc, 0x25, 0xdc, 0x70, 0xac, 0xcf, 0x69, 0x09, 0xbe, 0x55, 0x95,
+	0x5d, 0x42, 0x40, 0x47, 0xfd, 0xc9, 0x34, 0xcc, 0x47, 0xca, 0xaa, 0xf1, 0x8b, 0x30, 0x37, 0x92,
+	0x7e, 0x5c, 0xae, 0xec, 0x27, 0x42, 0xaa, 0xd2, 0xb3, 0x09, 0x7e, 0x1e, 0x66, 0x45, 0x74, 0x37,
+	0xf7, 0x2d, 0x3f, 0xb7, 0xce, 0xbd, 0x53, 0xca, 0x34, 0xc2, 0xdb, 0xe6, 0x7a, 0xe9, 0xdb, 0xe6,
+	0xa8, 0x01, 0x36, 0x8e, 0xc7, 0x00, 0xa3, 0x26, 0x31, 0x7d, 0x3c, 0x26, 0x81, 0x77, 0xc5, 0xe9,
+	0xb5, 0xc9, 0xe8, 0x3d, 0x55, 0xac, 0x3a, 0x3f, 0x51, 0x43, 0xb5, 0x06, 0x4b, 0xb2, 0x2d, 0xdc,
+	0xe4, 0xd8, 0x8f, 0xab, 0xcc, 0xb0, 0x33, 0x72, 0xea, 0x3b, 0x7c, 0x0d, 0x9a, 0xac, 0x0e, 0xbf,
+	0xeb, 0x0a, 0xbc, 0xba, 0x50, 0x2d, 0xbf, 0x4f, 0xa3, 0xf8, 0x55, 0xd3, 0x27, 0x08, 0x94, 0xf0,
+	0xa6, 0x51, 0xfc, 0xfb, 0x41, 0x45, 0x5e, 0x7e, 0x23, 0x5e, 0x01, 0x54, 0xf4, 0xdf, 0x23, 0x82,
+	0x12, 0xa0, 0xab, 0x80, 0xb7, 0xc8, 0x30, 0x56, 0x02, 0x44, 0xd3, 0xef, 0x20, 0x16, 0xfb, 0xff,
+	0x6e, 0x22, 0xf5, 0x1c, 0x52, 0xa0, 0xa5, 0x45, 0x69, 0xb9, 0x36, 0x03, 0xe2, 0xa3, 0xff, 0x70,
+	0x84, 0xe2, 0xff, 0x70, 0x74, 0x17, 0x6c, 0xfc, 0xb7, 0x88, 0x65, 0xa5, 0x55, 0x17, 0x23, 0xdd,
+	0x4a, 0x14, 0x23, 0x65, 0x4f, 0x29, 0x92, 0x6b, 0x96, 0x4a, 0x92, 0xd6, 0x60, 0x81, 0x1e, 0x02,
+	0xec, 0x10, 0x23, 0x88, 0xd5, 0x8a, 0xa2, 0x64, 0xad, 0xe8, 0xeb, 0x70, 0x22, 0x18, 0x53, 0xdd,
+	0x01, 0xd5, 0xb6, 0xc3, 0xc2, 0x03, 0xd1, 0x5a, 0xfb, 0xcb, 0x3d, 0x41, 0xe9, 0xf1, 0xa6, 0xe7,
+	0x0c, 0xf1, 0x5b, 0x08, 0x1a, 0xe4, 0x75, 0xc3, 0xf5, 0xf0, 0x85, 0x3c, 0xb7, 0xee, 0xf1, 0xfa,
+	0xdd, 0xf6, 0xc5, 0x82, 0xa3, 0x05, 0xbb, 0xdf, 0x44, 0x30, 0xdd, 0x65, 0x39, 0x0b, 0xbe, 0x58,
+	0xaa, 0x78, 0xb3, 0xfd, 0x64, 0xd1, 0xe1, 0x12, 0x27, 0x3d, 0x76, 0xa6, 0xc9, 0xc1, 0x49, 0x5a,
+	0x05, 0x64, 0x0e, 0x4e, 0xd2, 0x8b, 0x1e, 0xdf, 0x40, 0x30, 0xdd, 0x67, 0xf8, 0x2b, 0x3e, 0x5f,
+	0xa0, 0x22, 0xc2, 0x67, 0xe3, 0x89, 0x42, 0x63, 0x05, 0x0f, 0xef, 0x20, 0x98, 0xed, 0x87, 0x95,
+	0x82, 0xb8, 0x08, 0x31, 0xdf, 0x2f, 0xda, 0x17, 0x8a, 0x0d, 0x16, 0xac, 0x7c, 0x88, 0xe0, 0xe4,
+	0x98, 0x01, 0x51, 0x21, 0x9a, 0x85, 0x37, 0xca, 0xd7, 0xef, 0xb5, 0x37, 0x4b, 0xd1, 0x10, 0xdc,
+	0x7d, 0x07, 0x41, 0x53, 0xef, 0xf5, 0xd8, 0x65, 0xc6, 0xa5, 0x02, 0x35, 0x12, 0x72, 0x51, 0x51,
+	0xfb, 0xa9, 0xe2, 0x04, 0x24, 0x76, 0xfa, 0xc4, 0xcb, 0xc9, 0x4e, 0x7a, 0xf9, 0x5f, 0x0e, 0x76,
+	0x0e, 0x2b, 0x03, 0xfc, 0x3e, 0x02, 0xe0, 0xba, 0x63, 0x1c, 0xad, 0x17, 0x93, 0xb8, 0x54, 0xa0,
+	0xd7, 0xde, 0x28, 0x43, 0x42, 0x70, 0xf5, 0x43, 0x04, 0xc0, 0x5d, 0x9d, 0x71, 0xb5, 0x51, 0xd0,
+	0x5f, 0x65, 0x51, 0x6d, 0x96, 0xa2, 0x21, 0xf8, 0xfa, 0x36, 0xb7, 0x25, 0x9a, 0xac, 0xe0, 0x27,
+	0xcb, 0xd5, 0xdb, 0xb4, 0x2f, 0x15, 0x1e, 0x2f, 0x31, 0xd3, 0x27, 0x5e, 0x4e, 0x66, 0x52, 0xcb,
+	0xcd, 0xda, 0x97, 0x4a, 0x16, 0x76, 0xe1, 0xef, 0x21, 0x68, 0x71, 0x3b, 0xda, 0xd5, 0xfb, 0xf8,
+	0xa9, 0x62, 0x36, 0x10, 0x16, 0x71, 0xb5, 0xd7, 0x4b, 0x50, 0x90, 0x4c, 0x9b, 0x1b, 0x11, 0x13,
+	0xd1, 0x7a, 0x31, 0x03, 0x90, 0xa5, 0xb4, 0x51, 0x86, 0x84, 0xe0, 0xea, 0x1b, 0x08, 0xe6, 0xfb,
+	0x3e, 0x7a, 0xca, 0x92, 0xb4, 0xff, 0xcf, 0x25, 0x7b, 0x19, 0x66, 0x6b, 0x9f, 0x2f, 0x32, 0x54,
+	0x30, 0xf2, 0x3e, 0x82, 0x93, 0x7d, 0x09, 0x23, 0x65, 0xbc, 0xe4, 0xda, 0x08, 0xe2, 0xb8, 0x72,
+	0xbe, 0x54, 0x23, 0x09, 0xce, 0xbe, 0x8b, 0x60, 0xae, 0x27, 0x81, 0x96, 0x39, 0xb8, 0x49, 0x01,
+	0x4f, 0xdb, 0x17, 0x0b, 0x8e, 0x96, 0xb8, 0x19, 0x49, 0xb8, 0x62, 0x0e, 0x6e, 0x52, 0x10, 0xd1,
+	0x1c, 0xdc, 0xa4, 0x82, 0x99, 0xef, 0x21, 0x98, 0x97, 0xb9, 0x71, 0x71, 0x31, 0x82, 0x6e, 0xfe,
+	0x1c, 0x28, 0xfd, 0x7b, 0x17, 0x3f, 0x43, 0xf0, 0xdf, 0x7a, 0x14, 0x94, 0x7c, 0xda, 0x72, 0xe4,
+	0xa3, 0xab, 0x9b, 0x6f, 0xbb, 0x4d, 0x01, 0xaa, 0xf2, 0x6d, 0xb7, 0xa9, 0x50, 0xcf, 0xcf, 0x11,
+	0xa8, 0xdd, 0x04, 0xe4, 0x96, 0xe0, 0x74, 0x23, 0x67, 0x6e, 0x9a, 0xc6, 0xec, 0x66, 0x29, 0x1a,
+	0x82, 0xdf, 0x1f, 0x21, 0x58, 0xe9, 0x33, 0xe4, 0x8a, 0x21, 0x09, 0xf2, 0x6f, 0xf2, 0xa5, 0x0b,
+	0xe5, 0x38, 0x3c, 0x02, 0x3c, 0x13, 0x1c, 0x26, 0x70, 0xda, 0xcf, 0x9f, 0xc3, 0xc3, 0x10, 0xca,
+	0x77, 0x11, 0x2c, 0xf4, 0xe4, 0x00, 0x9c, 0x27, 0x3b, 0x4e, 0x9e, 0xc8, 0xdb, 0x17, 0x8a, 0x0d,
+	0xe6, 0xdc, 0xac, 0x7d, 0x36, 0x0b, 0xa7, 0x62, 0xe8, 0x18, 0x3b, 0xdf, 0xbd, 0x8f, 0xe8, 0xb9,
+	0x92, 0xd7, 0x46, 0xe5, 0xd8, 0x30, 0x0f, 0xa9, 0x56, 0xcb, 0xb1, 0x61, 0x1e, 0x5a, 0x78, 0x46,
+	0xb3, 0xae, 0x71, 0x50, 0xaf, 0x95, 0x27, 0x83, 0x3f, 0xac, 0x7e, 0x2c, 0x4f, 0x06, 0x7f, 0x78,
+	0xa1, 0xd8, 0x9b, 0x08, 0x5a, 0x03, 0xbf, 0x10, 0x2b, 0xc7, 0x76, 0x19, 0x2f, 0x07, 0xcb, 0xb1,
+	0x5d, 0x26, 0xeb, 0xbe, 0xde, 0x46, 0x50, 0xdf, 0x37, 0xcc, 0x5e, 0x8e, 0xb8, 0x9b, 0x56, 0xd7,
+	0x95, 0x23, 0xee, 0xa6, 0x57, 0x58, 0xd1, 0x6d, 0xa9, 0x2f, 0x95, 0xab, 0xe4, 0xdb, 0xb2, 0x13,
+	0xec, 0x5c, 0x2c, 0x38, 0x5a, 0x70, 0xf3, 0x01, 0x82, 0x85, 0x7e, 0xa4, 0x12, 0x29, 0x5f, 0x2a,
+	0x9a, 0x2c, 0xbe, 0xca, 0x97, 0x8a, 0xa6, 0x95, 0x40, 0x7d, 0x88, 0x60, 0x8e, 0xa7, 0xa2, 0xbc,
+	0x1e, 0x05, 0x6f, 0x15, 0xac, 0xe3, 0x88, 0xd4, 0xd0, 0xb4, 0x2f, 0x97, 0xa4, 0x22, 0xb8, 0xfb,
+	0x08, 0x81, 0x32, 0x4e, 0x54, 0x6d, 0x88, 0x43, 0xf3, 0xe6, 0x31, 0x54, 0x9c, 0xb4, 0xb7, 0xca,
+	0x11, 0x09, 0xf1, 0x85, 0xc6, 0x1d, 0xdd, 0xeb, 0x0e, 0x72, 0x18, 0x7c, 0x5a, 0x7d, 0x48, 0x0e,
+	0x83, 0x4f, 0xad, 0x0f, 0x79, 0x08, 0x31, 0x93, 0x1f, 0x48, 0xdf, 0x90, 0xc2, 0xc5, 0x3e, 0x79,
+	0x95, 0xdf, 0xe4, 0xd3, 0x3e, 0x5c, 0xb5, 0xf6, 0xa7, 0x29, 0x58, 0xdc, 0xb6, 0x0e, 0x88, 0x63,
+	0xca, 0x68, 0xdd, 0x07, 0x3c, 0x9b, 0x8e, 0xde, 0xd8, 0x94, 0x01, 0x87, 0xd6, 0x0b, 0x8c, 0x8d,
+	0x01, 0xe0, 0x3f, 0x40, 0x70, 0xa2, 0x1f, 0xfd, 0x8a, 0x50, 0x21, 0xc8, 0x41, 0xfe, 0x14, 0x52,
+	0x21, 0xc8, 0x21, 0xfa, 0x01, 0xa3, 0xb7, 0x38, 0x5b, 0xeb, 0xb6, 0x3d, 0x34, 0xba, 0x3a, 0xff,
+	0x8c, 0xd2, 0xe3, 0xb9, 0x4e, 0x0e, 0x21, 0xa2, 0xdb, 0x3e, 0x97, 0x7f, 0x20, 0x67, 0x63, 0xe3,
+	0x21, 0xc8, 0xfa, 0x35, 0xbb, 0x97, 0x1a, 0xec, 0xeb, 0x77, 0x7b, 0xd3, 0xec, 0xcf, 0x23, 0xff,
+	0x0e, 0x00, 0x00, 0xff, 0xff, 0x35, 0xc6, 0x35, 0x3f, 0x16, 0x4f, 0x00, 0x00,
 }
diff --git a/server/core/proto/services.proto b/server/core/proto/services.proto
index 330d08b2..64ac5e77 100644
--- a/server/core/proto/services.proto
+++ b/server/core/proto/services.proto
@@ -149,7 +149,7 @@ message MicroService {
     string status = 8; // UP|DOWN
     map<string, string> properties = 9;
     string timestamp = 11;
-    repeated DependencyKey providers = 12;
+    repeated MicroServiceKey providers = 12;
     string alias = 13;
     map<string, string> LBStrategy = 14;
     string modTimestamp = 15;
@@ -518,16 +518,10 @@ message CreateDependenciesRequest {
     repeated ConsumerDependency dependencies = 1;
 }
 
-message DependencyKey {
-    string appId = 1;
-    string serviceName = 2;
-    string version = 3;
-    string environment = 4;
-}
-
 message ConsumerDependency {
-    DependencyKey consumer = 1;
-    repeated DependencyKey providers = 2;
+    MicroServiceKey consumer = 1;
+    repeated MicroServiceKey providers = 2;
+    bool override = 3;
 }
 
 message CreateDependenciesResponse {
diff --git a/server/govern/service.go b/server/govern/service.go
index f3c08408..eea638f5 100644
--- a/server/govern/service.go
+++ b/server/govern/service.go
@@ -324,7 +324,7 @@ func getServiceDetailUtil(ctx context.Context, serviceDetailOpt ServiceDetailOpt
 			serviceDetail.SchemaInfos = schemas
 		case "dependencies":
 			service := serviceDetailOpt.service
-			dr := serviceUtil.NewDependencyRelation(ctx, domainProject, serviceId, service, serviceId, service)
+			dr := serviceUtil.NewDependencyRelation(ctx, domainProject, service, service)
 			consumers, err := dr.GetDependencyConsumers()
 			if err != nil {
 				util.Logger().Errorf(err, "Get service's all consumers for govern service failed.")
diff --git a/server/handler/context/context.go b/server/handler/context/context.go
index 7fd42faa..85e52b94 100644
--- a/server/handler/context/context.go
+++ b/server/handler/context/context.go
@@ -40,6 +40,8 @@ func (c *ContextHandler) Handle(i *chain.Invocation) {
 	case v3.IsMatch(r):
 		err = v3.Do(r)
 	case v4.IsMatch(r):
+		util.SetRequestContext(r, "target-domain", "default")
+		util.SetRequestContext(r, "target-project", "default")
 		err = v4.Do(r)
 	}
 
diff --git a/server/handler/context/v3.go b/server/handler/context/v3.go
index c2592656..d7826849 100644
--- a/server/handler/context/v3.go
+++ b/server/handler/context/v3.go
@@ -34,12 +34,13 @@ func (v *v3Context) IsMatch(r *http.Request) bool {
 func (v *v3Context) Do(r *http.Request) error {
 	ctx := r.Context()
 
-	if len(util.ParseDomain(ctx)) == 0 {
-		domain := r.Header.Get("X-Tenant-Name")
-		if len(domain) == 0 {
-			domain = r.Header.Get("X-Domain-Name")
-		}
+	domain := r.Header.Get("X-Tenant-Name")
+	if len(domain) == 0 {
+		domain = r.Header.Get("X-Domain-Name")
+	}
 
+	// self domain
+	if len(util.ParseDomain(ctx)) == 0 {
 		if len(domain) == 0 {
 			err := errors.New("Header does not contain domain.")
 			util.Logger().Errorf(err, "Invalid Request URI %s", r.RequestURI)
@@ -51,6 +52,12 @@ func (v *v3Context) Do(r *http.Request) error {
 	if len(util.ParseProject(ctx)) == 0 {
 		util.SetRequestContext(r, "project", core.REGISTRY_PROJECT)
 	}
-
+	// target domain
+	if len(util.ParseTargetDomain(ctx)) == 0 {
+		util.SetRequestContext(r, "target-domain", domain)
+	}
+	if len(util.ParseTargetProject(ctx)) == 0 {
+		util.SetRequestContext(r, "target-project", core.REGISTRY_PROJECT)
+	}
 	return nil
 }
diff --git a/server/handler/context/v4.go b/server/handler/context/v4.go
index 8d7531d6..0a22e301 100644
--- a/server/handler/context/v4.go
+++ b/server/handler/context/v4.go
@@ -34,25 +34,16 @@ func (v *v4Context) IsMatch(r *http.Request) bool {
 
 func (v *v4Context) Do(r *http.Request) error {
 	ctx := r.Context()
-	if len(util.ParseProject(ctx)) == 0 {
-		path, err := url.PathUnescape(r.RequestURI)
-		if err != nil {
-			util.Logger().Errorf(err, "Invalid Request URI %s", r.RequestURI)
-			return err
-		}
 
-		start := len("/v4/")
-		end := start + strings.Index(path[start:], "/")
-
-		project := strings.TrimSpace(path[start:end])
-		if len(project) == 0 {
-			project = core.REGISTRY_PROJECT
-		}
-		util.SetRequestContext(r, "project", project)
+	domain := r.Header.Get("X-Domain-Name")
+	path, err := url.PathUnescape(r.RequestURI)
+	if err != nil {
+		util.Logger().Errorf(err, "Invalid Request URI %s", r.RequestURI)
+		return err
 	}
 
+	// self domain
 	if len(util.ParseDomain(ctx)) == 0 {
-		domain := r.Header.Get("X-Domain-Name")
 		if len(domain) == 0 {
 			err := errors.New("Header does not contain domain.")
 			util.Logger().Errorf(err, "Invalid Request URI %s", r.RequestURI)
@@ -60,5 +51,26 @@ func (v *v4Context) Do(r *http.Request) error {
 		}
 		util.SetRequestContext(r, "domain", domain)
 	}
+	if len(util.ParseProject(ctx)) == 0 {
+		util.SetRequestContext(r, "project", v.parseProjectFromPath(path))
+	}
+	// target domain
+	if len(util.ParseTargetDomain(ctx)) == 0 {
+		util.SetRequestContext(r, "target-domain", domain)
+	}
+	if len(util.ParseTargetProject(ctx)) == 0 {
+		util.SetRequestContext(r, "target-project", v.parseProjectFromPath(path))
+	}
 	return nil
 }
+
+func (v *v4Context) parseProjectFromPath(path string) string {
+	start := len("/v4/")
+	end := start + strings.Index(path[start:], "/")
+
+	project := strings.TrimSpace(path[start:end])
+	if len(project) == 0 {
+		project = core.REGISTRY_PROJECT
+	}
+	return project
+}
diff --git a/server/infra/registry/registry.go b/server/infra/registry/registry.go
index 407f90f1..d331c8ee 100644
--- a/server/infra/registry/registry.go
+++ b/server/infra/registry/registry.go
@@ -165,6 +165,7 @@ type Registry interface {
 	// 3. response.Err()
 	// 4. time out to watch, but return nil
 	Watch(ctx context.Context, opts ...PluginOpOption) error
+	Compact(ctx context.Context, reserve int64) error
 	Close()
 }
 
@@ -290,15 +291,28 @@ func (op CompareOp) String() string {
 	)
 }
 
-func CmpVer(key []byte) CompareOp          { return CompareOp{Key: key, Type: CMP_VERSION} }
-func CmpCreateRev(key []byte) CompareOp    { return CompareOp{Key: key, Type: CMP_CREATE} }
-func CmpModRev(key []byte) CompareOp       { return CompareOp{Key: key, Type: CMP_MOD} }
-func CmpVal(key []byte) CompareOp          { return CompareOp{Key: key, Type: CMP_VALUE} }
-func CmpStrVer(key string) CompareOp       { return CmpVer(util.StringToBytesWithNoCopy(key)) }
-func CmpStrCreateRev(key string) CompareOp { return CmpCreateRev(util.StringToBytesWithNoCopy(key)) }
-func CmpStrModRev(key string) CompareOp    { return CmpModRev(util.StringToBytesWithNoCopy(key)) }
-func CmpStrVal(key string) CompareOp       { return CmpVal(util.StringToBytesWithNoCopy(key)) }
-func OpCmp(cmp CompareOp, result CompareResult, v interface{}) CompareOp {
+type CompareOperation func(op *CompareOp)
+
+func CmpVer(key []byte) CompareOperation {
+	return func(op *CompareOp) { op.Key = key; op.Type = CMP_VERSION }
+}
+func CmpCreateRev(key []byte) CompareOperation {
+	return func(op *CompareOp) { op.Key = key; op.Type = CMP_CREATE }
+}
+func CmpModRev(key []byte) CompareOperation {
+	return func(op *CompareOp) { op.Key = key; op.Type = CMP_MOD }
+}
+func CmpVal(key []byte) CompareOperation {
+	return func(op *CompareOp) { op.Key = key; op.Type = CMP_VALUE }
+}
+func CmpStrVer(key string) CompareOperation { return CmpVer(util.StringToBytesWithNoCopy(key)) }
+func CmpStrCreateRev(key string) CompareOperation {
+	return CmpCreateRev(util.StringToBytesWithNoCopy(key))
+}
+func CmpStrModRev(key string) CompareOperation { return CmpModRev(util.StringToBytesWithNoCopy(key)) }
+func CmpStrVal(key string) CompareOperation    { return CmpVal(util.StringToBytesWithNoCopy(key)) }
+func OpCmp(opt CompareOperation, result CompareResult, v interface{}) (cmp CompareOp) {
+	opt(&cmp)
 	cmp.Result = result
 	cmp.Value = v
 	return cmp
diff --git a/server/mux/mux.go b/server/mux/mux.go
index 4be7295d..85f816bd 100644
--- a/server/mux/mux.go
+++ b/server/mux/mux.go
@@ -33,9 +33,14 @@ func (m *MuxType) String() (s string) {
 }
 
 const (
-	GLOBAL_LOCK MuxType = "/global"
+	GLOBAL_LOCK    MuxType = "/cse-sr/lock/global"
+	DEP_QUEUE_LOCK MuxType = "/cse-sr/lock/dep-queue"
 )
 
-func Lock(t MuxType) (*etcdsync.Locker, error) {
-	return etcdsync.Lock(t.String())
+func Lock(t MuxType) (*etcdsync.DLock, error) {
+	return etcdsync.Lock(t.String(), true)
+}
+
+func Try(t MuxType) (*etcdsync.DLock, error) {
+	return etcdsync.Lock(t.String(), false)
 }
diff --git a/server/plugin/infra/registry/buildin/buildin.go b/server/plugin/infra/registry/buildin/buildin.go
index ab68c721..302dd563 100644
--- a/server/plugin/infra/registry/buildin/buildin.go
+++ b/server/plugin/infra/registry/buildin/buildin.go
@@ -69,6 +69,9 @@ func (ec *BuildinRegistry) LeaseRevoke(ctx context.Context, leaseID int64) error
 func (ec *BuildinRegistry) Watch(ctx context.Context, opts ...registry.PluginOpOption) error {
 	return noPluginErr
 }
+func (c *BuildinRegistry) Compact(ctx context.Context, reserve int64) error {
+	return noPluginErr
+}
 func (ec *BuildinRegistry) Close() {
 	ec.safeClose(ec.ready)
 }
diff --git a/server/plugin/infra/registry/embededetcd/embededetcd.go b/server/plugin/infra/registry/embededetcd/embededetcd.go
index fb488ffc..d5eb8769 100644
--- a/server/plugin/infra/registry/embededetcd/embededetcd.go
+++ b/server/plugin/infra/registry/embededetcd/embededetcd.go
@@ -223,24 +223,39 @@ func (s *EtcdEmbed) toCompares(cmps []registry.CompareOp) []*etcdserverpb.Compar
 	return etcdCmps
 }
 
-func (s *EtcdEmbed) CompactCluster(ctx context.Context) {
-}
-
-func (s *EtcdEmbed) Compact(ctx context.Context, revision int64) error {
+func (s *EtcdEmbed) Compact(ctx context.Context, reserve int64) error {
 	otCtx, cancel := registry.WithTimeout(ctx)
 	defer cancel()
-	revToCompact := max(0, revision-core.ServerInfo.Config.CompactIndexDelta)
-	util.Logger().Debug(fmt.Sprintf("Compacting %d", revToCompact))
-	resp, err := s.Server.Server.Compact(otCtx, &etcdserverpb.CompactionRequest{
+
+	curRev := s.getLeaderCurrentRevision(otCtx)
+	revToCompact := max(0, curRev-reserve)
+	if revToCompact <= 0 {
+		util.Logger().Infof("revision is %d, <=%d, no nead to compact", curRev, reserve)
+		return nil
+	}
+
+	util.Logger().Infof("Compacting... revision is %d(current: %d, reserve %d)", revToCompact, curRev, reserve)
+	_, err := s.Server.Server.Compact(otCtx, &etcdserverpb.CompactionRequest{
 		Revision: revToCompact,
+		Physical: true,
 	})
 	if err != nil {
+		util.Logger().Errorf(err, "Compact locally failed, revision is %d(current: %d, reserve %d)",
+			revToCompact, curRev, reserve)
 		return err
 	}
-	util.Logger().Info(fmt.Sprintf("Compacted %v", resp))
+	util.Logger().Infof("Compacted locally, revision is %d(current: %d, reserve %d)", revToCompact, curRev, reserve)
+
+	// TODO defragment
+	util.Logger().Infof("Defraged locally")
+
 	return nil
 }
 
+func (s *EtcdEmbed) getLeaderCurrentRevision(ctx context.Context) int64 {
+	return s.Server.Server.KV().Rev()
+}
+
 func (s *EtcdEmbed) PutNoOverride(ctx context.Context, opts ...registry.PluginOpOption) (bool, error) {
 	op := registry.OpPut(opts...)
 	resp, err := s.TxnWithCmp(ctx, []registry.PluginOp{op}, []registry.CompareOp{
diff --git a/server/plugin/infra/registry/etcd/etcd.go b/server/plugin/infra/registry/etcd/etcd.go
index 1ab43ac6..f6796fce 100644
--- a/server/plugin/infra/registry/etcd/etcd.go
+++ b/server/plugin/infra/registry/etcd/etcd.go
@@ -66,40 +66,62 @@ func (s *EtcdClient) Close() {
 	util.Logger().Debugf("etcd client stopped.")
 }
 
-func (c *EtcdClient) CompactCluster(ctx context.Context) {
-	for _, ep := range c.Client.Endpoints() {
-		otCtx, cancel := registry.WithTimeout(ctx)
-		defer cancel()
-		mapi := clientv3.NewMaintenance(c.Client)
-		resp, err := mapi.Status(otCtx, ep)
-		if err != nil {
-			util.Logger().Error(fmt.Sprintf("Compact error ,can not get status from %s", ep), err)
-			continue
-		}
-		curRev := resp.Header.Revision
-		util.Logger().Debug(fmt.Sprintf("Compacting.... endpoint: %s / IsLeader: %v\n / revision is %d", ep, resp.Header.MemberId == resp.Leader, curRev))
-		c.Compact(ctx, curRev)
-	}
-
-}
+func (c *EtcdClient) Compact(ctx context.Context, reserve int64) error {
+	eps := c.Client.Endpoints()
+	curRev := c.getLeaderCurrentRevision(ctx)
 
-func (c *EtcdClient) Compact(ctx context.Context, revision int64) error {
-	otCtx, cancel := registry.WithTimeout(ctx)
-	defer cancel()
-	revToCompact := max(0, revision-core.ServerInfo.Config.CompactIndexDelta)
+	revToCompact := max(0, curRev-reserve)
 	if revToCompact <= 0 {
-		util.Logger().Warnf(nil, "revToCompact is %d, <=0, no nead to compact.", revToCompact)
+		util.Logger().Infof("revision is %d, <=%d, no nead to compact %s", curRev, reserve, eps)
 		return nil
 	}
-	util.Logger().Debug(fmt.Sprintf("Compacting %d", revToCompact))
-	resp, err := c.Client.KV.Compact(otCtx, revToCompact)
+
+	otCtx, cancel := registry.WithTimeout(ctx)
+	defer cancel()
+
+	_, err := c.Client.Compact(otCtx, revToCompact, clientv3.WithCompactPhysical())
 	if err != nil {
+		util.Logger().Errorf(err, "Compact %s failed, revision is %d(current: %d, reserve %d)",
+			eps, revToCompact, curRev, reserve)
 		return err
 	}
-	util.Logger().Debugf(fmt.Sprintf("Compacted %v", resp))
+	util.Logger().Infof("Compacted %s, revision is %d(current: %d, reserve %d)", eps, revToCompact, curRev, reserve)
+
+	for _, ep := range eps {
+		_, err := c.Client.Defragment(otCtx, ep)
+		if err != nil {
+			util.Logger().Errorf(err, "Defrag %s failed", ep)
+			continue
+		}
+		util.Logger().Infof("Defraged %s", ep)
+	}
+
 	return nil
 }
 
+func (c *EtcdClient) getLeaderCurrentRevision(ctx context.Context) int64 {
+	eps := c.Client.Endpoints()
+	curRev := int64(0)
+	for _, ep := range eps {
+		otCtx, cancel := registry.WithTimeout(ctx)
+
+		resp, err := c.Client.Status(otCtx, ep)
+		if err != nil {
+			util.Logger().Error(fmt.Sprintf("Compact error ,can not get status from %s", ep), err)
+			cancel()
+			continue
+		}
+		curRev = resp.Header.Revision
+		if resp.Leader == resp.Header.MemberId {
+			util.Logger().Infof("Get leader endpoint: %s, revision is %d", ep, curRev)
+			break
+		}
+
+		cancel()
+	}
+	return curRev
+}
+
 func max(n1, n2 int64) int64 {
 	if n1 > n2 {
 		return n1
@@ -276,8 +298,12 @@ func (c *EtcdClient) paging(ctx context.Context, op registry.PluginOp) (*clientv
 		l := int64(len(recordResp.Kvs))
 		nextKey = clientv3.GetPrefixRangeEnd(util.BytesToStringWithNoCopy(recordResp.Kvs[l-1].Key))
 
-		if op.Offset >= 0 && (op.Offset < i*op.Limit || op.Offset >= (i+1)*op.Limit) {
-			continue
+		if op.Offset >= 0 {
+			if op.Offset < i*op.Limit {
+				continue
+			} else if op.Offset >= (i+1)*op.Limit {
+				break
+			}
 		}
 		etcdResp.Kvs = append(etcdResp.Kvs, recordResp.Kvs...)
 	}
@@ -290,14 +316,14 @@ func (c *EtcdClient) paging(ctx context.Context, op registry.PluginOp) (*clientv
 	// too slow
 	if op.SortOrder == registry.SORT_DESCEND {
 		t := time.Now()
-		for i := int64(0); i < recordCount; i++ {
-			last := recordCount - i - 1
+		for i, l := 0, len(etcdResp.Kvs); i < l; i++ {
+			last := l - i - 1
 			if last <= i {
 				break
 			}
 			etcdResp.Kvs[i], etcdResp.Kvs[last] = etcdResp.Kvs[last], etcdResp.Kvs[i]
 		}
-		util.LogNilOrWarnf(t, "sorted %d KeyValues(%s)", recordCount, key)
+		util.LogNilOrWarnf(t, "sorted descend %d KeyValues(%s)", recordCount, key)
 	}
 	return etcdResp, nil
 }
@@ -585,12 +611,12 @@ func NewRegistry() mgr.PluginInstance {
 	inv, _ := time.ParseDuration(core.ServerInfo.Config.AutoSyncInterval)
 	client, err := newClient(endpoints, inv)
 	if err != nil {
-		util.Logger().Errorf(err, "get etcd client %+v failed.", endpoints)
+		util.Logger().Errorf(err, "get etcd client %v failed.", endpoints)
 		inst.err <- err
 		return inst
 	}
 
-	util.Logger().Warnf(nil, "get etcd client %+v completed, auto sync endpoints interval is %s.",
+	util.Logger().Warnf(nil, "get etcd client %v completed, auto sync endpoints interval is %s.",
 		endpoints, core.ServerInfo.Config.AutoSyncInterval)
 	inst.Client = client
 	close(inst.ready)
diff --git a/server/server.go b/server/server.go
index cb6cb340..2f959229 100644
--- a/server/server.go
+++ b/server/server.go
@@ -28,6 +28,7 @@ import (
 	serviceUtil "github.com/apache/incubator-servicecomb-service-center/server/service/util"
 	"github.com/apache/incubator-servicecomb-service-center/version"
 	"github.com/astaxie/beego"
+	"golang.org/x/net/context"
 	"os"
 	"strings"
 	"time"
@@ -54,8 +55,6 @@ type ServiceCenterServer struct {
 func (s *ServiceCenterServer) Run() {
 	s.initialize()
 
-	s.waitForReady()
-
 	s.startNotifyService()
 
 	s.startApiServer()
@@ -63,9 +62,6 @@ func (s *ServiceCenterServer) Run() {
 	s.waitForQuit()
 }
 
-func (s *ServiceCenterServer) initialize() {
-}
-
 func (s *ServiceCenterServer) waitForQuit() {
 	var err error
 	select {
@@ -93,8 +89,10 @@ func (s *ServiceCenterServer) needUpgrade() bool {
 		fmt.Sprintf("%s+", version.Ver().Version))
 }
 
-func (s *ServiceCenterServer) waitForReady() {
+func (s *ServiceCenterServer) initialize() {
+	// check version
 	lock, err := mux.Lock(mux.GLOBAL_LOCK)
+	defer lock.Unlock()
 	if err != nil {
 		util.Logger().Errorf(err, "wait for server ready failed")
 		os.Exit(1)
@@ -102,10 +100,39 @@ func (s *ServiceCenterServer) waitForReady() {
 	if s.needUpgrade() {
 		core.UpgradeServerVersion()
 	}
-	lock.Unlock()
 
+	// cache mechanism
 	s.store.Run()
 	<-s.store.Ready()
+
+	// auto compact backend
+	s.autoCompactBackend()
+}
+
+func (s *ServiceCenterServer) autoCompactBackend() {
+	delta := core.ServerInfo.Config.CompactIndexDelta
+	if delta <= 0 {
+		return
+	}
+	util.Go(func(stopCh <-chan struct{}) {
+		util.Logger().Infof("start the automatic compact mechanism, compact once every 12h")
+		for {
+			select {
+			case <-stopCh:
+				return
+			case <-time.After(12 * time.Hour):
+				lock, err := mux.Try(mux.GLOBAL_LOCK)
+				if lock == nil {
+					util.Logger().Warnf(err, "can not compact backend by this service center instance now")
+					continue
+				}
+
+				backend.Registry().Compact(context.Background(), delta)
+
+				lock.Unlock()
+			}
+		}
+	})
 }
 
 func (s *ServiceCenterServer) startNotifyService() {
diff --git a/server/service/concurrent_test.go b/server/service/concurrent_test.go
index 8a10ab17..12b09ddb 100644
--- a/server/service/concurrent_test.go
+++ b/server/service/concurrent_test.go
@@ -39,7 +39,7 @@ func init() {
 	etcdsync.IsDebug = true
 }
 
-func TestServiceController_CreateDependenciesForMicroServices(t *testing.T) {
+func testServiceController_CreateDependenciesForMicroServices(t *testing.T) {
 	tryTimes := 3
 	testCount := 10
 	serviceResource, _ := service.AssembleResources()
@@ -65,12 +65,12 @@ func TestServiceController_CreateDependenciesForMicroServices(t *testing.T) {
 			_, err := serviceResource.CreateDependenciesForMicroServices(getContext(), &pb.CreateDependenciesRequest{
 				Dependencies: []*pb.ConsumerDependency{
 					{
-						Consumer: &pb.DependencyKey{
+						Consumer: &pb.MicroServiceKey{
 							AppId:       "test_deps",
 							ServiceName: serviceName,
 							Version:     "1.0.0",
 						},
-						Providers: []*pb.DependencyKey{
+						Providers: []*pb.MicroServiceKey{
 							{
 								AppId:       "test_deps",
 								ServiceName: "service0",
diff --git a/server/service/event/dependency_event_handler.go b/server/service/event/dependency_event_handler.go
new file mode 100644
index 00000000..fb367e2b
--- /dev/null
+++ b/server/service/event/dependency_event_handler.go
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package event
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/apache/incubator-servicecomb-service-center/pkg/util"
+	"github.com/apache/incubator-servicecomb-service-center/server/core"
+	"github.com/apache/incubator-servicecomb-service-center/server/core/backend"
+	"github.com/apache/incubator-servicecomb-service-center/server/core/backend/store"
+	pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
+	"github.com/apache/incubator-servicecomb-service-center/server/infra/registry"
+	"github.com/apache/incubator-servicecomb-service-center/server/mux"
+	serviceUtil "github.com/apache/incubator-servicecomb-service-center/server/service/util"
+	"github.com/coreos/etcd/mvcc/mvccpb"
+	"golang.org/x/net/context"
+	"time"
+)
+
+type DependencyEventHandler struct {
+	signals *util.UniQueue
+}
+
+func (h *DependencyEventHandler) Type() store.StoreType {
+	return store.DEPENDENCY_QUEUE
+}
+
+func (h *DependencyEventHandler) OnEvent(evt *store.KvEvent) {
+	action := evt.Action
+	if action != pb.EVT_CREATE && action != pb.EVT_UPDATE && action != pb.EVT_INIT {
+		return
+	}
+
+	h.signals.Put(context.Background(), struct{}{})
+}
+
+func (h *DependencyEventHandler) loop() {
+	util.Go(func(stopCh <-chan struct{}) {
+		waitDelayIndex := 0
+		waitDelay := []int{1, 1, 5, 10, 20, 30, 60}
+		retry := func() {
+			if waitDelayIndex >= len(waitDelay) {
+				waitDelayIndex = 0
+			}
+			<-time.After(time.Duration(waitDelay[waitDelayIndex]) * time.Second)
+			waitDelayIndex++
+
+			h.signals.Put(context.Background(), struct{}{})
+		}
+		for {
+			select {
+			case <-stopCh:
+				return
+			case <-h.signals.Chan():
+				lock, err := mux.Try(mux.DEP_QUEUE_LOCK)
+				if err != nil {
+					util.Logger().Errorf(err, "try to lock %s failed", mux.DEP_QUEUE_LOCK)
+					retry()
+					continue
+				}
+
+				if lock == nil {
+					continue
+				}
+
+				err = h.Handle()
+				lock.Unlock()
+				if err != nil {
+					util.Logger().Errorf(err, "handle dependency event failed")
+					retry()
+					continue
+				}
+			case <-time.After(10 * time.Second):
+				key := core.GetServiceDependencyQueueRootKey("")
+				resp, _ := store.Store().DependencyQueue().Search(context.Background(),
+					registry.WithStrKey(key),
+					registry.WithPrefix(),
+					registry.WithCountOnly(),
+					registry.WithCacheOnly())
+				if resp != nil && resp.Count > 0 {
+					util.Logger().Infof("wait for dependency event timed out(10s) and found %d items still in queue",
+						resp.Count)
+					h.signals.Put(context.Background(), struct{}{})
+				}
+			}
+		}
+	})
+}
+
+func (h *DependencyEventHandler) Handle() error {
+	key := core.GetServiceDependencyQueueRootKey("")
+	resp, err := store.Store().DependencyQueue().Search(context.Background(),
+		registry.WithStrKey(key),
+		registry.WithPrefix())
+	if err != nil {
+		return err
+	}
+
+	// maintain dependency rules.
+	l := len(resp.Kvs)
+	if l == 0 {
+		return nil
+	}
+
+	var (
+		r   *pb.ConsumerDependency = &pb.ConsumerDependency{}
+		ctx context.Context        = context.Background()
+	)
+
+	for _, kv := range resp.Kvs {
+		consumerId, domainProject, data := pb.GetInfoFromDependencyQueueKV(kv)
+
+		err := json.Unmarshal(data, r)
+		if err != nil {
+			util.Logger().Errorf(err, "maintain dependency failed, unmarshal failed, consumer %s dependency: %s",
+				consumerId, util.BytesToStringWithNoCopy(data))
+
+			if err = h.removeKV(ctx, kv); err != nil {
+				return err
+			}
+			continue
+		}
+
+		serviceUtil.SetDependencyDefaultValue(r)
+
+		consumerFlag := util.StringJoin([]string{r.Consumer.AppId, r.Consumer.ServiceName, r.Consumer.Version}, "/")
+		consumerInfo := pb.DependenciesToKeys([]*pb.MicroServiceKey{r.Consumer}, domainProject)[0]
+		providersInfo := pb.DependenciesToKeys(r.Providers, domainProject)
+
+		consumerId, err = serviceUtil.GetServiceId(ctx, consumerInfo)
+		if err != nil {
+			return fmt.Errorf("get consumer %s id failed, override: %t, %s", consumerFlag, r.Override, err.Error())
+		}
+		if len(consumerId) == 0 {
+			util.Logger().Errorf(nil, "maintain dependency failed, override: %t, consumer %s does not exist",
+				r.Override, consumerFlag)
+
+			if err = h.removeKV(ctx, kv); err != nil {
+				return err
+			}
+			continue
+		}
+
+		var dep serviceUtil.Dependency
+		dep.DomainProject = domainProject
+		dep.Consumer = consumerInfo
+		dep.ProvidersRule = providersInfo
+		dep.ConsumerId = consumerId
+		if r.Override {
+			err = serviceUtil.CreateDependencyRule(ctx, &dep)
+		} else {
+			err = serviceUtil.AddDependencyRule(ctx, &dep)
+		}
+
+		if err != nil {
+			return fmt.Errorf("override: %t, consumer is %s, %s", r.Override, consumerFlag, err.Error())
+		}
+
+		if err = h.removeKV(ctx, kv); err != nil {
+			return err
+		}
+
+		util.Logger().Infof("maintain dependency %v successfully, override: %t", r, r.Override)
+	}
+	return nil
+}
+
+func (h *DependencyEventHandler) removeKV(ctx context.Context, kv *mvccpb.KeyValue) error {
+	dresp, err := backend.Registry().TxnWithCmp(ctx, []registry.PluginOp{registry.OpDel(registry.WithKey(kv.Key))},
+		[]registry.CompareOp{registry.OpCmp(registry.CmpVer(kv.Key), registry.CMP_EQUAL, kv.Version)},
+		nil)
+	if err != nil {
+		return fmt.Errorf("can not remove the dependency %s request, %s", util.BytesToStringWithNoCopy(kv.Key), err.Error())
+	}
+	if !dresp.Succeeded {
+		util.Logger().Infof("the dependency %s request is changed", util.BytesToStringWithNoCopy(kv.Key))
+	}
+	return nil
+}
+
+func NewDependencyEventHandler() *DependencyEventHandler {
+	h := &DependencyEventHandler{
+		signals: util.NewUniQueue(),
+	}
+	h.loop()
+	return h
+}
diff --git a/server/service/event/event.go b/server/service/event/event.go
index ef4179ff..53fe882b 100644
--- a/server/service/event/event.go
+++ b/server/service/event/event.go
@@ -25,4 +25,5 @@ func init() {
 	store.AddEventHandler(NewInstanceEventHandler())
 	store.AddEventHandler(NewRuleEventHandler())
 	store.AddEventHandler(NewTagEventHandler())
+	store.AddEventHandler(NewDependencyEventHandler())
 }
diff --git a/server/service/event/instance_event_handler.go b/server/service/event/instance_event_handler.go
index 76f78aeb..4d44e7ca 100644
--- a/server/service/event/instance_event_handler.go
+++ b/server/service/event/instance_event_handler.go
@@ -84,7 +84,7 @@ func (h *InstanceEventHandler) OnEvent(evt *store.KvEvent) {
 	}
 
 	// ????consumer
-	consumerIds, _, err := serviceUtil.GetConsumerIds(context.Background(), domainProject, ms)
+	consumerIds, _, err := serviceUtil.GetConsumerIdsByProvider(context.Background(), domainProject, ms)
 	if err != nil {
 		util.Logger().Errorf(err, "query service %s consumers failed", providerId)
 		return
diff --git a/server/service/event/rule_event_handler.go b/server/service/event/rule_event_handler.go
index f25d4cf9..42c956cc 100644
--- a/server/service/event/rule_event_handler.go
+++ b/server/service/event/rule_event_handler.go
@@ -65,7 +65,7 @@ func (apt *RulesChangedAsyncTask) publish(ctx context.Context, domainProject, pr
 		provider = tmpProvider.(*pb.MicroService)
 	}
 
-	consumerIds, err := serviceUtil.GetConsumersInCache(ctx, domainProject, providerId, provider)
+	consumerIds, err := serviceUtil.GetConsumersInCache(ctx, domainProject, provider)
 	if err != nil {
 		util.Logger().Errorf(err, "get consumer services by provider %s failed", providerId)
 		return err
diff --git a/server/service/event/service_event_handler.go b/server/service/event/service_event_handler.go
index 08d6aeb9..2aa6f4d3 100644
--- a/server/service/event/service_event_handler.go
+++ b/server/service/event/service_event_handler.go
@@ -47,15 +47,12 @@ func (h *ServiceEventHandler) OnEvent(evt *store.KvEvent) {
 		return
 	}
 
-	switch action {
-	case pb.EVT_CREATE, pb.EVT_INIT:
-		newDomain := domainProject[:strings.Index(domainProject, "/")]
-		newProject := domainProject[strings.Index(domainProject, "/")+1:]
-		err := serviceUtil.NewDomainProject(context.Background(), newDomain, newProject)
-		if err != nil {
-			util.Logger().Errorf(err, "new domain(%s) or project(%s) failed", newDomain, newProject)
-			return
-		}
+	newDomain := domainProject[:strings.Index(domainProject, "/")]
+	newProject := domainProject[strings.Index(domainProject, "/")+1:]
+	err := serviceUtil.NewDomainProject(context.Background(), newDomain, newProject)
+	if err != nil {
+		util.Logger().Errorf(err, "new domain(%s) or project(%s) failed", newDomain, newProject)
+		return
 	}
 }
 
diff --git a/server/service/event/tag_event_handler.go b/server/service/event/tag_event_handler.go
index 104e5032..42ea494c 100644
--- a/server/service/event/tag_event_handler.go
+++ b/server/service/event/tag_event_handler.go
@@ -64,7 +64,7 @@ func (apt *TagsChangedAsyncTask) publish(ctx context.Context, domainProject, con
 		}
 		consumer = consumerTmp.(*pb.MicroService)
 	}
-	providerIds, err := serviceUtil.GetProvidersInCache(ctx, domainProject, consumerId, consumer)
+	providerIds, err := serviceUtil.GetProvidersInCache(ctx, domainProject, consumer)
 	if err != nil {
 		util.Logger().Errorf(err, "get provider services by consumer %s failed", consumerId)
 		return err
diff --git a/server/service/instances.go b/server/service/instances.go
index ad96a3c9..8edde82a 100644
--- a/server/service/instances.go
+++ b/server/service/instances.go
@@ -434,11 +434,11 @@ func (s *InstanceService) GetOneInstance(ctx context.Context, in *pb.GetOneInsta
 	}
 	conPro := util.StringJoin([]string{in.ConsumerServiceId, in.ProviderServiceId, in.ProviderInstanceId}, "/")
 
-	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
 
 	serviceId := in.ProviderServiceId
 	instanceId := in.ProviderInstanceId
-	instance, err := serviceUtil.GetInstance(ctx, domainProject, serviceId, instanceId)
+	instance, err := serviceUtil.GetInstance(ctx, targetDomainProject, serviceId, instanceId)
 	if err != nil {
 		util.Logger().Errorf(err, "get instance failed, %s(consumer/provider): get instance failed.", conPro)
 		return &pb.GetOneInstanceResponse{
@@ -463,9 +463,9 @@ func (s *InstanceService) getInstancePreCheck(ctx context.Context, in interface{
 	if err != nil {
 		return scerr.NewError(scerr.ErrInvalidParams, err.Error())
 	}
+	var targetDomainProject = util.ParseTargetDomainProject(ctx)
 	var providerServiceId, consumerServiceId string
 	var tags []string
-	domainProject := util.ParseDomainProject(ctx)
 
 	switch in.(type) {
 	case *pb.GetOneInstanceRequest:
@@ -478,13 +478,13 @@ func (s *InstanceService) getInstancePreCheck(ctx context.Context, in interface{
 		tags = in.(*pb.GetInstancesRequest).Tags
 	}
 
-	if !serviceUtil.ServiceExist(ctx, domainProject, providerServiceId) {
+	if !serviceUtil.ServiceExist(ctx, targetDomainProject, providerServiceId) {
 		return scerr.NewError(scerr.ErrServiceNotExists, "Provider serviceId is invalid")
 	}
 
 	// Tag??
 	if len(tags) > 0 {
-		tagsFromETCD, err := serviceUtil.GetTagsUtils(ctx, domainProject, providerServiceId)
+		tagsFromETCD, err := serviceUtil.GetTagsUtils(ctx, targetDomainProject, providerServiceId)
 		if err != nil {
 			return scerr.NewError(scerr.ErrInternal, fmt.Sprintf("An error occurred in query provider tags(%s)", err.Error()))
 		}
@@ -499,7 +499,7 @@ func (s *InstanceService) getInstancePreCheck(ctx context.Context, in interface{
 	}
 	// ????
 	// ?????
-	forbid := serviceUtil.Accessible(ctx, domainProject, consumerServiceId, providerServiceId)
+	forbid := serviceUtil.Accessible(ctx, consumerServiceId, providerServiceId)
 	if forbid != nil {
 		util.Logger().Errorf(forbid,
 			"consumer %s can't access provider %s", consumerServiceId, providerServiceId)
@@ -522,9 +522,9 @@ func (s *InstanceService) GetInstances(ctx context.Context, in *pb.GetInstancesR
 	}
 	conPro := util.StringJoin([]string{in.ConsumerServiceId, in.ProviderServiceId}, "/")
 
-	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
 
-	instances, err := serviceUtil.GetAllInstancesOfOneService(ctx, domainProject, in.ProviderServiceId)
+	instances, err := serviceUtil.GetAllInstancesOfOneService(ctx, targetDomainProject, in.ProviderServiceId)
 	if err != nil {
 		util.Logger().Errorf(err, "get instances failed, %s(consumer/provider): get instances from etcd failed.", conPro)
 		return &pb.GetInstancesResponse{
@@ -547,6 +547,7 @@ func (s *InstanceService) Find(ctx context.Context, in *pb.FindInstancesRequest)
 	}
 
 	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
 
 	findFlag := fmt.Sprintf("consumer %s --> provider %s/%s/%s", in.ConsumerServiceId, in.AppId, in.ServiceName, in.VersionRule)
 	service, err := serviceUtil.GetService(ctx, domainProject, in.ConsumerServiceId)
@@ -563,14 +564,21 @@ func (s *InstanceService) Find(ctx context.Context, in *pb.FindInstancesRequest)
 		}, nil
 	}
 
-	// ????
-	ids, err := serviceUtil.FindServiceIds(ctx, in.VersionRule, &pb.MicroServiceKey{
-		Tenant:      domainProject,
+	provider := &pb.MicroServiceKey{
+		Tenant:      targetDomainProject,
 		Environment: service.Environment,
 		AppId:       in.AppId,
 		ServiceName: in.ServiceName,
 		Alias:       in.ServiceName,
-	})
+	}
+
+	if apt.IsShared(provider) {
+		// it means the shared micro-services must be the same env with SC.
+		provider.Environment = apt.Service.Environment
+	}
+
+	// ????
+	ids, err := serviceUtil.FindServiceIds(ctx, in.VersionRule, provider)
 	if err != nil {
 		util.Logger().Errorf(err, "find instance failed, %s: get providers failed.", findFlag)
 		return &pb.FindInstancesResponse{
@@ -601,25 +609,20 @@ func (s *InstanceService) Find(ctx context.Context, in *pb.FindInstancesRequest)
 			instances = append(instances, resp.GetInstances()...)
 		}
 	}
-	consumer := pb.MicroServiceToKey(domainProject, service)
+
 	//??version???,servicename ????????????
-	providerService, _ := serviceUtil.GetService(ctx, domainProject, ids[0])
+	providerService, err := serviceUtil.GetService(ctx, targetDomainProject, ids[0])
 	if providerService == nil {
-		util.Logger().Errorf(nil, "find instance failed, %s: no provider matched.", findFlag)
+		util.Logger().Errorf(err, "find instance failed, %s: no provider matched.", findFlag)
 		return &pb.FindInstancesResponse{
 			Response: pb.CreateResponse(scerr.ErrServiceNotExists, "No provider matched."),
 		}, nil
 	}
-	provider := &pb.MicroServiceKey{
-		Tenant:      domainProject,
-		Environment: consumer.Environment,
-		AppId:       in.AppId,
-		ServiceName: providerService.ServiceName,
-		Version:     in.VersionRule,
-	}
 
-	err = serviceUtil.AddServiceVersionRule(ctx, domainProject, provider, consumer)
+	provider = pb.MicroServiceToKey(targetDomainProject, providerService)
+	provider.Version = in.VersionRule
 
+	err = serviceUtil.AddServiceVersionRule(ctx, domainProject, service, provider)
 	if err != nil {
 		util.Logger().Errorf(err, "find instance failed, %s: add service version rule failed.", findFlag)
 		return &pb.FindInstancesResponse{
@@ -806,7 +809,7 @@ func (s *InstanceService) WebSocketListAndWatch(ctx context.Context, in *pb.Watc
 		return
 	}
 	nf.DoWebSocketListAndWatch(ctx, in.SelfServiceId, func() ([]*pb.WatchInstanceResponse, int64) {
-		return serviceUtil.QueryAllProvidersIntances(ctx, in.SelfServiceId)
+		return serviceUtil.QueryAllProvidersInstances(ctx, in.SelfServiceId)
 	}, conn)
 }
 
diff --git a/server/service/microservices.go b/server/service/microservices.go
index 4308ccdb..98114719 100644
--- a/server/service/microservices.go
+++ b/server/service/microservices.go
@@ -223,7 +223,7 @@ func (s *MicroServiceService) DeleteServicePri(ctx context.Context, ServiceId st
 
 	// ???????????????????????? ???????????provider?????,??????????????????????
 	if !force {
-		dr := serviceUtil.NewProviderDependencyRelation(ctx, domainProject, ServiceId, service)
+		dr := serviceUtil.NewProviderDependencyRelation(ctx, domainProject, service)
 		services, err := dr.GetDependencyConsumerIds()
 		if err != nil {
 			util.Logger().Errorf(err, "delete microservice failed, serviceId is %s: inner err, get service dependency failed.", ServiceId)
@@ -260,7 +260,7 @@ func (s *MicroServiceService) DeleteServicePri(ctx context.Context, ServiceId st
 	}
 
 	//refresh msCache consumerCache, ensure that watch can notify consumers when no cache.
-	err = serviceUtil.RefreshDependencyCache(ctx, domainProject, ServiceId, service)
+	err = serviceUtil.RefreshDependencyCache(ctx, domainProject, service)
 	if err != nil {
 		util.Logger().Errorf(err, "%s microservice failed, serviceId is %s: inner err, refresh service dependency cache failed.", title, ServiceId)
 		return pb.CreateResponse(scerr.ErrInternal, "Refresh dependency cache failed."), err
@@ -275,7 +275,7 @@ func (s *MicroServiceService) DeleteServicePri(ctx context.Context, ServiceId st
 	}
 
 	//??????
-	lock, err := mux.Lock(mux.GLOBAL_LOCK)
+	lock, err := mux.Lock(mux.DEP_QUEUE_LOCK)
 	if err != nil {
 		util.Logger().Errorf(err, "%s microservice failed, serviceId is %s: inner err, create lock failed.", title, ServiceId)
 		return pb.CreateResponse(scerr.ErrUnavailableBackend, err.Error()), err
diff --git a/server/service/microservices_test.go b/server/service/microservices_test.go
index d9b04914..e4aa9f02 100644
--- a/server/service/microservices_test.go
+++ b/server/service/microservices_test.go
@@ -867,6 +867,8 @@ var _ = Describe("'Micro-service' service", func() {
 			})
 			Expect(err).To(BeNil())
 			Expect(respFind.Response.Code).To(Equal(pb.Response_SUCCESS))
+
+			Expect(deh.Handle()).To(BeNil())
 		})
 
 		Context("when request is invalid", func() {
diff --git a/server/service/service_dependency.go b/server/service/service_dependency.go
index 73d19b2c..4dd8c772 100644
--- a/server/service/service_dependency.go
+++ b/server/service/service_dependency.go
@@ -17,11 +17,14 @@
 package service
 
 import (
+	"encoding/json"
 	"github.com/apache/incubator-servicecomb-service-center/pkg/util"
+	"github.com/apache/incubator-servicecomb-service-center/pkg/uuid"
 	apt "github.com/apache/incubator-servicecomb-service-center/server/core"
+	"github.com/apache/incubator-servicecomb-service-center/server/core/backend"
 	pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
 	scerr "github.com/apache/incubator-servicecomb-service-center/server/error"
-	"github.com/apache/incubator-servicecomb-service-center/server/mux"
+	"github.com/apache/incubator-servicecomb-service-center/server/infra/registry"
 	serviceUtil "github.com/apache/incubator-servicecomb-service-center/server/service/util"
 	"golang.org/x/net/context"
 )
@@ -44,62 +47,62 @@ func (s *MicroServiceService) AddOrUpdateDependencies(ctx context.Context, depen
 	if len(dependencyInfos) == 0 {
 		return serviceUtil.BadParamsResponse("Invalid request body.").Response, nil
 	}
+	opts := make([]registry.PluginOp, 0, len(dependencyInfos))
 	domainProject := util.ParseDomainProject(ctx)
 	for _, dependencyInfo := range dependencyInfos {
 		if len(dependencyInfo.Providers) == 0 || dependencyInfo.Consumer == nil {
 			return serviceUtil.BadParamsResponse("Provider is invalid").Response, nil
 		}
 
-		util.Logger().Infof("start create dependency, data info %v", dependencyInfo)
-
 		serviceUtil.SetDependencyDefaultValue(dependencyInfo)
 
 		consumerFlag := util.StringJoin([]string{dependencyInfo.Consumer.AppId, dependencyInfo.Consumer.ServiceName, dependencyInfo.Consumer.Version}, "/")
-		consumerInfo := pb.DependenciesToKeys([]*pb.DependencyKey{dependencyInfo.Consumer}, domainProject)[0]
+		consumerInfo := pb.DependenciesToKeys([]*pb.MicroServiceKey{dependencyInfo.Consumer}, domainProject)[0]
 		providersInfo := pb.DependenciesToKeys(dependencyInfo.Providers, domainProject)
 
 		rsp := serviceUtil.ParamsChecker(consumerInfo, providersInfo)
 		if rsp != nil {
-			util.Logger().Errorf(nil, "create dependency failed, conusmer %s: invalid params.%s", consumerFlag, rsp.Response.Message)
+			util.Logger().Errorf(nil, "put request into dependency queue failed, override: %t, consumer is %s, %s",
+				override, consumerFlag, rsp.Response.Message)
 			return rsp.Response, nil
 		}
 
 		consumerId, err := serviceUtil.GetServiceId(ctx, consumerInfo)
-		util.Logger().Debugf("consumerId is %s", consumerId)
 		if err != nil {
-			util.Logger().Errorf(err, "create dependency failed, consumer %s: get consumer failed.", consumerFlag)
+			util.Logger().Errorf(err, "put request into dependency queue failed, override: %t, get consumer %s id failed",
+				override, consumerFlag)
 			return pb.CreateResponse(scerr.ErrInternal, err.Error()), err
 		}
 		if len(consumerId) == 0 {
-			util.Logger().Errorf(nil, "create dependency failed, consumer %s: consumer not exist.", consumerFlag)
+			util.Logger().Errorf(nil, "put request into dependency queue failed, override: %t, consumer %s does not exist.",
+				override, consumerFlag)
 			return pb.CreateResponse(scerr.ErrServiceNotExists, "Get consumer's serviceId is empty."), nil
 		}
 
-		//???????????????
-		lock, err := mux.Lock(mux.GLOBAL_LOCK)
+		dependencyInfo.Override = override
+		data, err := json.Marshal(dependencyInfo)
 		if err != nil {
-			util.Logger().Errorf(err, "create dependency failed, consumer %s: create lock failed.", consumerFlag)
+			util.Logger().Errorf(err, "put request into dependency queue failed, override: %t, marshal consumer %s dependency failed",
+				override, consumerFlag)
 			return pb.CreateResponse(scerr.ErrInternal, err.Error()), err
 		}
 
-		var dep serviceUtil.Dependency
-		dep.DomainProject = domainProject
-		dep.Consumer = consumerInfo
-		dep.ProvidersRule = providersInfo
-		dep.ConsumerId = consumerId
-		if override {
-			err = serviceUtil.CreateDependencyRule(ctx, &dep)
-		} else {
-			err = serviceUtil.AddDependencyRule(ctx, &dep)
+		id := "0"
+		if !override {
+			id = uuid.GenerateUuid()
 		}
-		lock.Unlock()
+		key := apt.GenerateConsumerDependencyQueueKey(domainProject, consumerId, id)
+		opts = append(opts, registry.OpPut(registry.WithStrKey(key), registry.WithValue(data)))
+	}
 
-		if err != nil {
-			util.Logger().Errorf(err, "create dependency rule failed: consumer %s", consumerFlag)
-			return pb.CreateResponse(scerr.ErrInternal, err.Error()), err
-		}
-		util.Logger().Infof("Create dependency success: consumer %s, %s  from remote %s", consumerFlag, consumerId, util.GetIPFromContext(ctx))
+	_, err := backend.Registry().Txn(ctx, opts)
+	if err != nil {
+		util.Logger().Errorf(err, "put request into dependency queue failed, override: %t, %v", override, dependencyInfos)
+		return pb.CreateResponse(scerr.ErrInternal, err.Error()), err
 	}
+
+	util.Logger().Infof("put request into dependency queue successfully, override: %t, %v, from remote %s",
+		override, dependencyInfos, util.GetIPFromContext(ctx))
 	return pb.CreateResponse(pb.Response_SUCCESS, "Create dependency successfully."), nil
 }
 
@@ -126,7 +129,7 @@ func (s *MicroServiceService) GetProviderDependencies(ctx context.Context, in *p
 		}, nil
 	}
 
-	dr := serviceUtil.NewProviderDependencyRelation(ctx, domainProject, providerServiceId, provider)
+	dr := serviceUtil.NewProviderDependencyRelation(ctx, domainProject, provider)
 	services, err := dr.GetDependencyConsumers()
 	if err != nil {
 		util.Logger().Errorf(err, "GetProviderDependencies failed.")
@@ -166,7 +169,7 @@ func (s *MicroServiceService) GetConsumerDependencies(ctx context.Context, in *p
 		}, nil
 	}
 
-	dr := serviceUtil.NewConsumerDependencyRelation(ctx, domainProject, consumerId, consumer)
+	dr := serviceUtil.NewConsumerDependencyRelation(ctx, domainProject, consumer)
 	services, err := dr.GetDependencyProviders()
 	if err != nil {
 		util.Logger().Errorf(err, "GetConsumerDependencies failed for get providers failed.")
diff --git a/server/service/service_dependency_test.go b/server/service/service_dependency_test.go
index d1370d63..115dc45f 100644
--- a/server/service/service_dependency_test.go
+++ b/server/service/service_dependency_test.go
@@ -18,10 +18,13 @@ package service_test
 
 import (
 	pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
+	"github.com/apache/incubator-servicecomb-service-center/server/service/event"
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
 )
 
+var deh event.DependencyEventHandler
+
 var _ = Describe("'Dependency' service", func() {
 	Describe("execute 'create' operartion", func() {
 		var (
@@ -90,12 +93,12 @@ var _ = Describe("'Dependency' service", func() {
 				Expect(err).To(BeNil())
 				Expect(respCreateDependency.Response.Code).ToNot(Equal(pb.Response_SUCCESS))
 
-				consumer := &pb.DependencyKey{
+				consumer := &pb.MicroServiceKey{
 					AppId:       "create_dep_group",
 					ServiceName: "create_dep_consumer",
 					Version:     "1.0.0",
 				}
-				providers := []*pb.DependencyKey{
+				providers := []*pb.MicroServiceKey{
 					{
 						AppId:       "create_dep_group",
 						ServiceName: "create_dep_provider",
@@ -107,7 +110,7 @@ var _ = Describe("'Dependency' service", func() {
 				respCreateDependency, err = serviceResource.CreateDependenciesForMicroServices(getContext(), &pb.CreateDependenciesRequest{
 					Dependencies: []*pb.ConsumerDependency{
 						{
-							Consumer: &pb.DependencyKey{
+							Consumer: &pb.MicroServiceKey{
 								AppId:       "noexistapp",
 								ServiceName: "noexistservice",
 								Version:     "1.0.0",
@@ -123,7 +126,7 @@ var _ = Describe("'Dependency' service", func() {
 				respCreateDependency, err = serviceResource.CreateDependenciesForMicroServices(getContext(), &pb.CreateDependenciesRequest{
 					Dependencies: []*pb.ConsumerDependency{
 						{
-							Consumer: &pb.DependencyKey{
+							Consumer: &pb.MicroServiceKey{
 								AppId:       "create_dep_group",
 								ServiceName: "create_dep_consumer",
 								Version:     "1.0.0+",
@@ -139,7 +142,7 @@ var _ = Describe("'Dependency' service", func() {
 				respCreateDependency, err = serviceResource.CreateDependenciesForMicroServices(getContext(), &pb.CreateDependenciesRequest{
 					Dependencies: []*pb.ConsumerDependency{
 						{
-							Consumer: &pb.DependencyKey{
+							Consumer: &pb.MicroServiceKey{
 								AppId:       "create_dep_group",
 								ServiceName: "*",
 								Version:     "1.0.0",
@@ -167,7 +170,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "*",
 									ServiceName: "service_name_provider",
@@ -185,7 +188,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "service_group_provider",
 									ServiceName: "-",
@@ -203,7 +206,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "service_group_provider",
 									ServiceName: "service_name_provider",
@@ -221,7 +224,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									Environment: pb.ENV_PROD,
 									AppId:       "service_group_provider",
@@ -248,7 +251,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "service_group_provider",
 									ServiceName: "service_name_provider",
@@ -272,7 +275,7 @@ var _ = Describe("'Dependency' service", func() {
 
 		Context("when request is valid", func() {
 			It("should be passed", func() {
-				consumer := &pb.DependencyKey{
+				consumer := &pb.MicroServiceKey{
 					ServiceName: "create_dep_consumer",
 					AppId:       "create_dep_group",
 					Version:     "1.0.0",
@@ -283,7 +286,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "create_dep_group",
 									ServiceName: "create_dep_provider",
@@ -301,7 +304,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "create_dep_group",
 									ServiceName: "create_dep_provider",
@@ -319,7 +322,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									ServiceName: "*",
 								},
@@ -335,7 +338,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "create_dep_group",
 									ServiceName: "create_dep_provider",
@@ -356,7 +359,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "create_dep_group",
 									ServiceName: "create_dep_provider",
@@ -374,7 +377,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "create_dep_group",
 									ServiceName: "create_dep_provider",
@@ -500,6 +503,8 @@ var _ = Describe("'Dependency' service", func() {
 				Expect(err).To(BeNil())
 				Expect(resp.Response.Code).To(Equal(pb.Response_SUCCESS))
 
+				Expect(deh.Handle()).To(BeNil())
+
 				By("get provider's deps")
 				respGetP, err := serviceResource.GetProviderDependencies(getContext(), &pb.GetDependenciesRequest{
 					ServiceId: providerId1,
@@ -526,6 +531,8 @@ var _ = Describe("'Dependency' service", func() {
 				Expect(err).To(BeNil())
 				Expect(resp.Response.Code).To(Equal(pb.Response_SUCCESS))
 
+				Expect(deh.Handle()).To(BeNil())
+
 				By("get provider again")
 				respGetP, err = serviceResource.GetProviderDependencies(getContext(), &pb.GetDependenciesRequest{
 					ServiceId: providerId1,
diff --git a/server/service/util/dependency.go b/server/service/util/dependency.go
index 5ad5cc41..3b1a118e 100644
--- a/server/service/util/dependency.go
+++ b/server/service/util/dependency.go
@@ -28,7 +28,6 @@ import (
 	pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
 	scerr "github.com/apache/incubator-servicecomb-service-center/server/error"
 	"github.com/apache/incubator-servicecomb-service-center/server/infra/registry"
-	"github.com/apache/incubator-servicecomb-service-center/server/mux"
 	"golang.org/x/net/context"
 	"strings"
 	"time"
@@ -50,73 +49,75 @@ func init() {
 	providerCache = cache.New(d, d)
 }
 
-func GetConsumersInCache(ctx context.Context, domainProject string, providerId string, provider *pb.MicroService) ([]string, error) {
+func GetConsumersInCache(ctx context.Context, domainProject string, provider *pb.MicroService) ([]string, error) {
 	// ????consumer
-	dr := NewProviderDependencyRelation(ctx, domainProject, providerId, provider)
+	dr := NewProviderDependencyRelation(ctx, domainProject, provider)
 	consumerIds, err := dr.GetDependencyConsumerIds()
 	if err != nil {
-		util.Logger().Errorf(err, "Get dependency consumerIds failed.%s", providerId)
+		util.Logger().Errorf(err, "Get dependency consumerIds failed.%s", provider.ServiceId)
 		return nil, err
 	}
 
 	if len(consumerIds) == 0 {
-		consumerIds, found := consumerCache.Get(providerId)
+		consumerIds, found := consumerCache.Get(provider.ServiceId)
 		if found && len(consumerIds.([]string)) > 0 {
 			return consumerIds.([]string), nil
 		}
-		util.Logger().Warnf(nil, "Can not find any consumer from local cache and backend. provider is %s", providerId)
+		util.Logger().Warnf(nil, "Can not find any consumer from local cache and backend. provider is %s",
+			provider.ServiceId)
 		return nil, nil
 	}
 
 	return consumerIds, nil
 }
 
-func GetProvidersInCache(ctx context.Context, domainProject string, consumerId string, consumer *pb.MicroService) ([]string, error) {
+func GetProvidersInCache(ctx context.Context, domainProject string, consumer *pb.MicroService) ([]string, error) {
 	// ????provider
-	dr := NewConsumerDependencyRelation(ctx, domainProject, consumerId, consumer)
+	dr := NewConsumerDependencyRelation(ctx, domainProject, consumer)
 	providerIds, err := dr.GetDependencyProviderIds()
 	if err != nil {
-		util.Logger().Errorf(err, "Get dependency providerIds failed.%s", consumerId)
+		util.Logger().Errorf(err, "Get dependency providerIds failed.%s", consumer.ServiceId)
 		return nil, err
 	}
 
 	if len(providerIds) == 0 {
-		providerIds, found := providerCache.Get(consumerId)
+		providerIds, found := providerCache.Get(consumer.ServiceId)
 		if found && len(providerIds.([]string)) > 0 {
 			return providerIds.([]string), nil
 		}
-		util.Logger().Warnf(nil, "Can not find any provider from local cache and backend. consumer is %s", consumerId)
+		util.Logger().Warnf(nil, "Can not find any provider from local cache and backend. consumer is %s",
+			consumer.ServiceId)
 		return nil, nil
 	}
 
 	return providerIds, nil
 }
 
-func RefreshDependencyCache(ctx context.Context, domainProject string, serviceId string, service *pb.MicroService) error {
-	dr := NewDependencyRelation(ctx, domainProject, serviceId, service, serviceId, service)
+func RefreshDependencyCache(ctx context.Context, domainProject string, service *pb.MicroService) error {
+	dr := NewDependencyRelation(ctx, domainProject, service, service)
 	consumerIds, err := dr.GetDependencyConsumerIds()
 	if err != nil {
-		util.Logger().Errorf(err, "%s,refresh dependency cache failed, get consumerIds failed.", serviceId)
+		util.Logger().Errorf(err, "%s,refresh dependency cache failed, get consumerIds failed.", service.ServiceId)
 		return err
 	}
 	providerIds, err := dr.GetDependencyProviderIds()
 	if err != nil {
-		util.Logger().Errorf(err, "%s,refresh dependency cache failed, get providerIds failed.", serviceId)
+		util.Logger().Errorf(err, "%s,refresh dependency cache failed, get providerIds failed.", service.ServiceId)
 		return err
 	}
-	MsCache().Set(serviceId, service, 5*time.Minute)
+	MsCache().Set(service.ServiceId, service, 5*time.Minute)
 	if len(consumerIds) > 0 {
-		util.Logger().Infof("refresh %s dependency cache: cached %d consumerId(s) for 5min.", serviceId, len(consumerIds))
-		consumerCache.Set(serviceId, consumerIds, 5*time.Minute)
+		util.Logger().Infof("refresh %s dependency cache: cached %d consumerId(s) for 5min.", service.ServiceId, len(consumerIds))
+		consumerCache.Set(service.ServiceId, consumerIds, 5*time.Minute)
 	}
 	if len(providerIds) > 0 {
-		util.Logger().Infof("refresh %s dependency cache: cached %d providerId(s) for 5min.", serviceId, len(providerIds))
-		providerCache.Set(serviceId, providerIds, 5*time.Minute)
+		util.Logger().Infof("refresh %s dependency cache: cached %d providerId(s) for 5min.", service.ServiceId, len(providerIds))
+		providerCache.Set(service.ServiceId, providerIds, 5*time.Minute)
 	}
 	return nil
 }
 
-func GetConsumerIds(ctx context.Context, domainProject string, provider *pb.MicroService) (allow []string, deny []string, _ error) {
+func GetConsumerIdsByProvider(ctx context.Context, domainProject string, provider *pb.MicroService) (allow []string, deny []string, _ error) {
 	if provider == nil || len(provider.ServiceId) == 0 {
 		return nil, nil, fmt.Errorf("invalid provider")
 	}
@@ -128,7 +129,7 @@ func GetConsumerIds(ctx context.Context, domainProject string, provider *pb.Micr
 		return nil, nil, err
 	}
 	if len(providerRules) == 0 {
-		return getConsumerIdsWithFilter(ctx, domainProject, provider.ServiceId, provider, noFilter)
+		return getConsumerIdsWithFilter(ctx, domainProject, provider, noFilter)
 	}
 
 	rf := RuleFilter{
@@ -137,16 +138,16 @@ func GetConsumerIds(ctx context.Context, domainProject string, provider *pb.Micr
 		ProviderRules: providerRules,
 	}
 
-	allow, deny, err = getConsumerIdsWithFilter(ctx, domainProject, provider.ServiceId, provider, rf.Filter)
+	allow, deny, err = getConsumerIdsWithFilter(ctx, domainProject, provider, rf.Filter)
 	if err != nil {
 		return nil, nil, err
 	}
 	return allow, deny, nil
 }
 
-func getConsumerIdsWithFilter(ctx context.Context, domainProject, providerId string, provider *pb.MicroService,
+func getConsumerIdsWithFilter(ctx context.Context, domainProject string, provider *pb.MicroService,
 	filter func(ctx context.Context, consumerId string) (bool, error)) (allow []string, deny []string, err error) {
-	consumerIds, err := GetConsumersInCache(ctx, domainProject, providerId, provider)
+	consumerIds, err := GetConsumersInCache(ctx, domainProject, provider)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -181,8 +182,8 @@ func noFilter(_ context.Context, _ string) (bool, error) {
 	return true, nil
 }
 
-func GetProviderIdsByConsumerId(ctx context.Context, domainProject, consumerId string, service *pb.MicroService) (allow []string, deny []string, _ error) {
-	providerIdsInCache, err := GetProvidersInCache(ctx, domainProject, consumerId, service)
+func GetProviderIdsByConsumer(ctx context.Context, domainProject string, service *pb.MicroService) (allow []string, deny []string, _ error) {
+	providerIdsInCache, err := GetProvidersInCache(ctx, domainProject, service)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -209,7 +210,7 @@ func GetProviderIdsByConsumerId(ctx context.Context, domainProject, consumerId s
 		}
 		rf.Provider = provider
 		rf.ProviderRules = providerRules
-		ok, err := rf.Filter(ctx, consumerId)
+		ok, err := rf.Filter(ctx, service.ServiceId)
 		if err != nil {
 			return nil, nil, err
 		}
@@ -224,8 +225,12 @@ func GetProviderIdsByConsumerId(ctx context.Context, domainProject, consumerId s
 	return providerIds[:allowIdx], providerIds[denyIdx:], nil
 }
 
-func ProviderDependencyRuleExist(ctx context.Context, domainProject string, provider *pb.MicroServiceKey, consumer *pb.MicroServiceKey) (bool, error) {
-	providerKey := apt.GenerateProviderDependencyRuleKey(domainProject, provider)
+func ProviderDependencyRuleExist(ctx context.Context, provider *pb.MicroServiceKey, consumer *pb.MicroServiceKey) (bool, error) {
+	targetDomainProject := provider.Tenant
+	if len(targetDomainProject) == 0 {
+		targetDomainProject = consumer.Tenant
+	}
+	providerKey := apt.GenerateProviderDependencyRuleKey(targetDomainProject, provider)
 	consumers, err := TransferToMicroServiceDependency(ctx, providerKey)
 	if err != nil {
 		return false, err
@@ -243,20 +248,33 @@ func ProviderDependencyRuleExist(ctx context.Context, domainProject string, prov
 	return false, nil
 }
 
-func AddServiceVersionRule(ctx context.Context, domainProject string, provider *pb.MicroServiceKey, consumer *pb.MicroServiceKey) error {
+func AddServiceVersionRule(ctx context.Context, domainProject string, consumer *pb.MicroService, provider *pb.MicroServiceKey) error {
 	//??????
-	exist, err := ProviderDependencyRuleExist(ctx, domainProject, provider, consumer)
+	consumerKey := pb.MicroServiceToKey(domainProject, consumer)
+	exist, err := ProviderDependencyRuleExist(ctx, provider, consumerKey)
 	if exist || err != nil {
 		return err
 	}
 
-	lock, err := mux.Lock(mux.GLOBAL_LOCK)
+	r := &pb.ConsumerDependency{
+		Consumer:  consumerKey,
+		Providers: []*pb.MicroServiceKey{provider},
+		Override:  false,
+	}
+	data, err := json.Marshal(r)
+	if err != nil {
+		return err
+	}
+
+	id := util.StringJoin([]string{provider.AppId, provider.ServiceName}, "_")
+	key := apt.GenerateConsumerDependencyQueueKey(domainProject, consumer.ServiceId, id)
+	_, err = backend.Registry().Do(ctx, registry.PUT, registry.WithStrKey(key), registry.WithValue(data))
 	if err != nil {
 		return err
 	}
-	err = CreateDependencyRuleForFind(ctx, domainProject, provider, consumer)
-	lock.Unlock()
-	return err
+
+	util.Logger().Infof("find request into dependency queue successfully, %s: %v", key, r)
+	return nil
 }
 
 func DeleteDependencyForService(ctx context.Context, consumer *pb.MicroServiceKey, serviceId string) ([]registry.PluginOp, error) {
@@ -545,97 +563,6 @@ func CreateDependencyRule(ctx context.Context, dep *Dependency) error {
 	return syncDependencyRule(ctx, dep, parseOverrideRules)
 }
 
-func CreateDependencyRuleForFind(ctx context.Context, domainProject string, provider *pb.MicroServiceKey, consumer *pb.MicroServiceKey) error {
-	//??consumer?providers??,consumer???????
-	consumerFlag := strings.Join([]string{consumer.AppId, consumer.ServiceName, consumer.Version}, "/")
-	conKey := apt.GenerateConsumerDependencyRuleKey(domainProject, consumer)
-
-	oldProviderRules, err := TransferToMicroServiceDependency(ctx, conKey)
-	if err != nil {
-		util.Logger().Errorf(err, "get dependency rule failed, consumer %s: get consumer depedency rule failed.", consumerFlag)
-		return err
-	}
-	if isDependencyAll(oldProviderRules) {
-		util.Logger().Infof("find update dep rule, exist * for %v", consumer)
-		return nil
-	}
-	opts := make([]registry.PluginOp, 0)
-	if oldProviderRule := isNeedUpdate(oldProviderRules.Dependency, provider); oldProviderRule != nil {
-		opt, err := deleteConsumerDepOfProviderRule(ctx, domainProject, oldProviderRule, consumer)
-		if err != nil {
-			util.Logger().Errorf(err, "marshal consumerDepRules failed for delete consumer rule from provider rule's dep.%s", consumerFlag)
-			return err
-		}
-		util.Logger().Infof("delete consumer %v from provider dep %v", consumer, oldProviderRule)
-		opts = append(opts, opt)
-
-		oldRule, opt, err := updateDepRuleUtil(conKey, oldProviderRules, provider)
-		if err != nil {
-			util.Logger().Errorf(err, "update provider rule into consumer's dep rule failed, %s", consumerFlag)
-			return err
-		}
-		util.Logger().Infof("update provider %v(from version '%s') into consumer dep %s", provider, oldRule, consumerFlag)
-		opts = append(opts, opt)
-
-		opt, err = updateProviderRuleDep(ctx, domainProject, provider, consumer)
-		if err != nil {
-			return err
-		}
-		opts = append(opts, opt)
-	} else {
-		if !isExist(oldProviderRules.Dependency, provider) {
-			opt, err := addDepRuleUtil(conKey, oldProviderRules, provider)
-			if err != nil {
-				util.Logger().Errorf(err, "add provider rule into consumer's dep rule failed, %s", consumerFlag)
-				return err
-			}
-			util.Logger().Infof("add consumer dep, %s, add %v", consumerFlag, provider)
-			opts = append(opts, opt)
-		}
-
-		proKey := apt.GenerateProviderDependencyRuleKey(domainProject, provider)
-		consumerDepRules, err := TransferToMicroServiceDependency(ctx, proKey)
-		if err != nil {
-			util.Logger().Errorf(err, "get consumer rule of provider failed,%v", provider)
-			return err
-		}
-		if !isExist(consumerDepRules.Dependency, consumer) {
-			opt, err := addDepRuleUtil(proKey, consumerDepRules, consumer)
-			if err != nil {
-				util.Logger().Errorf(err, "add consumer rule into provider's dep rule failed,%s", consumerFlag)
-				return err
-			}
-			util.Logger().Infof("add provider dep, %s, add %v", consumerFlag, provider)
-			opts = append(opts, opt)
-		}
-	}
-
-	if len(opts) != 0 {
-		_, err = backend.Registry().Txn(ctx, opts)
-		if err != nil {
-			util.Logger().Errorf(err, "update dep rule for consumer failed, %s", consumerFlag)
-			return err
-		}
-	}
-	return nil
-}
-
-func updateProviderRuleDep(ctx context.Context, domainProject string, providerRule, consumer *pb.MicroServiceKey) (registry.PluginOp, error) {
-	proKey := apt.GenerateProviderDependencyRuleKey(domainProject, providerRule)
-	consumerDepRules, err := TransferToMicroServiceDependency(ctx, proKey)
-	opt := registry.PluginOp{}
-	if err != nil {
-		util.Logger().Errorf(err, "get provider rule's dep failed, providerRule %v, consumer %v", providerRule, consumer)
-		return opt, err
-	}
-	opt, err = addDepRuleUtil(proKey, consumerDepRules, consumer)
-	if err != nil {
-		util.Logger().Errorf(err, "add consumer into provider's dep rule failed, providerRule %v, consumer %v", providerRule, consumer)
-		return opt, err
-	}
-	return opt, nil
-}
-
 func isDependencyAll(dep *pb.MicroServiceDependency) bool {
 	for _, servicedep := range dep.Dependency {
 		if servicedep.ServiceName == "*" {
@@ -798,7 +725,7 @@ func (dep *Dependency) removeConsumerOfProviderRule() {
 	ctx := context.TODO()
 	opts := make([]registry.PluginOp, 0, len(dep.removedDependencyRuleList))
 	for _, providerRule := range dep.removedDependencyRuleList {
-		proProkey := apt.GenerateProviderDependencyRuleKey(dep.DomainProject, providerRule)
+		proProkey := apt.GenerateProviderDependencyRuleKey(providerRule.Tenant, providerRule)
 		util.Logger().Debugf("This proProkey is %s.", proProkey)
 		consumerValue, err := TransferToMicroServiceDependency(ctx, proProkey)
 		if err != nil {
@@ -845,8 +772,8 @@ func (dep *Dependency) AddConsumerOfProviderRule() {
 func (dep *Dependency) addConsumerOfProviderRule() {
 	ctx := context.TODO()
 	opts := []registry.PluginOp{}
-	for _, prividerRule := range dep.NewDependencyRuleList {
-		proProkey := apt.GenerateProviderDependencyRuleKey(dep.DomainProject, prividerRule)
+	for _, providerRule := range dep.NewDependencyRuleList {
+		proProkey := apt.GenerateProviderDependencyRuleKey(providerRule.Tenant, providerRule)
 		tmpValue, err := TransferToMicroServiceDependency(ctx, proProkey)
 		if err != nil {
 			dep.err <- err
@@ -863,7 +790,7 @@ func (dep *Dependency) addConsumerOfProviderRule() {
 		opts = append(opts, registry.OpPut(
 			registry.WithStrKey(proProkey),
 			registry.WithValue(data)))
-		if prividerRule.ServiceName == "*" {
+		if providerRule.ServiceName == "*" {
 			break
 		}
 	}
@@ -900,52 +827,69 @@ func (dep *Dependency) UpdateProvidersRuleOfConsumer(conKey string) error {
 type DependencyRelation struct {
 	ctx           context.Context
 	domainProject string
-	consumerId    string
 	consumer      *pb.MicroService
-	providerId    string
 	provider      *pb.MicroService
 }
 
-func NewProviderDependencyRelation(ctx context.Context, domainProject string, providerId string, provider *pb.MicroService) *DependencyRelation {
-	return NewDependencyRelation(ctx, domainProject, "", nil, providerId, provider)
+func NewProviderDependencyRelation(ctx context.Context, domainProject string, provider *pb.MicroService) *DependencyRelation {
+	return NewDependencyRelation(ctx, domainProject, nil, provider)
 }
 
-func NewConsumerDependencyRelation(ctx context.Context, domainProject string, consumerId string, consumer *pb.MicroService) *DependencyRelation {
-	return NewDependencyRelation(ctx, domainProject, consumerId, consumer, "", nil)
+func NewConsumerDependencyRelation(ctx context.Context, domainProject string, consumer *pb.MicroService) *DependencyRelation {
+	return NewDependencyRelation(ctx, domainProject, consumer, nil)
 }
 
-func NewDependencyRelation(ctx context.Context, domainProject string, consumerId string, consumer *pb.MicroService, providerId string, provider *pb.MicroService) *DependencyRelation {
+func NewDependencyRelation(ctx context.Context, domainProject string, consumer *pb.MicroService, provider *pb.MicroService) *DependencyRelation {
 	return &DependencyRelation{
 		ctx:           ctx,
 		domainProject: domainProject,
-		consumerId:    consumerId,
 		consumer:      consumer,
-		providerId:    providerId,
 		provider:      provider,
 	}
 }
 
 func (dr *DependencyRelation) GetDependencyProviders() ([]*pb.MicroService, error) {
-	providerIds, err := dr.GetDependencyProviderIds()
+	keys, err := dr.getProviderKeys()
 	if err != nil {
 		return nil, err
 	}
-	services := make([]*pb.MicroService, 0)
-	for _, providerId := range providerIds {
-		provider, err := GetService(dr.ctx, dr.domainProject, providerId)
+	services := make([]*pb.MicroService, 0, len(keys))
+	for _, key := range keys {
+		providerIds, err := dr.parseDependencyRule(key)
 		if err != nil {
 			return nil, err
 		}
-		if provider == nil {
-			util.Logger().Warnf(nil, "Provider not exist, %s", providerId)
-			continue
+
+		if key.ServiceName == "*" {
+			services = services[:0]
+		}
+
+		for _, providerId := range providerIds {
+			provider, err := GetService(dr.ctx, key.Tenant, providerId)
+			if err != nil {
+				util.Logger().Warnf(nil, "Provider does not exist, %s/%s/%s",
+					key.AppId, key.ServiceName, key.Version)
+				continue
+			}
+			services = append(services, provider)
+		}
+
+		if key.ServiceName == "*" {
+			break
 		}
-		services = append(services, provider)
 	}
 	return services, nil
 }
 
 func (dr *DependencyRelation) GetDependencyProviderIds() ([]string, error) {
+	keys, err := dr.getProviderKeys()
+	if err != nil {
+		return nil, err
+	}
+	return dr.getDependencyProviderIds(keys)
+}
+
+func (dr *DependencyRelation) getProviderKeys() ([]*pb.MicroServiceKey, error) {
 	if dr.consumer == nil {
 		util.LOGGER.Infof("dr.consumer is nil ------->")
 		return nil, fmt.Errorf("Invalid consumer")
@@ -957,33 +901,21 @@ func (dr *DependencyRelation) GetDependencyProviderIds() ([]string, error) {
 	if err != nil {
 		return nil, err
 	}
-	return dr.getDependencyProviderIds(consumerDependency.Dependency)
+	return consumerDependency.Dependency, nil
 }
 
 func (dr *DependencyRelation) getDependencyProviderIds(providerRules []*pb.MicroServiceKey) ([]string, error) {
-	provideServiceIds := make([]string, 0)
-	opts := FromContext(dr.ctx)
+	provideServiceIds := make([]string, 0, len(providerRules))
 	for _, provider := range providerRules {
+		serviceIds, err := dr.parseDependencyRule(provider)
 		switch {
 		case provider.ServiceName == "*":
-			util.Logger().Infof("Rely all service,* type, consumerId %s", dr.consumerId)
-			splited := strings.Split(apt.GenerateServiceIndexKey(provider), "/")
-			allServiceKey := util.StringJoin(splited[:len(splited)-3], "/") + "/"
-			sopts := append(opts,
-				registry.WithStrKey(allServiceKey),
-				registry.WithPrefix())
-			resp, err := store.Store().Service().Search(dr.ctx, sopts...)
 			if err != nil {
 				util.Logger().Errorf(err, "Add dependency failed, rely all service: get all services failed.")
 				return provideServiceIds, err
 			}
-
-			for _, kv := range resp.Kvs {
-				provideServiceIds = append(provideServiceIds, util.BytesToStringWithNoCopy(kv.Value))
-			}
-			return provideServiceIds, nil
+			return serviceIds, nil
 		default:
-			serviceIds, err := FindServiceIds(dr.ctx, provider.Version, provider)
 			if err != nil {
 				util.Logger().Errorf(err, "Get providerIds failed, service: %s/%s/%s",
 					provider.AppId, provider.ServiceName, provider.Version)
@@ -1000,21 +932,45 @@ func (dr *DependencyRelation) getDependencyProviderIds(providerRules []*pb.Micro
 	return provideServiceIds, nil
 }
 
+func (dr *DependencyRelation) parseDependencyRule(dependencyRule *pb.MicroServiceKey) (serviceIds []string, err error) {
+	opts := FromContext(dr.ctx)
+	switch {
+	case dependencyRule.ServiceName == "*":
+		util.Logger().Infof("Rely all service, * type, consumerId %s", dr.consumer.ServiceId)
+		splited := strings.Split(apt.GenerateServiceIndexKey(dependencyRule), "/")
+		allServiceKey := util.StringJoin(splited[:len(splited)-3], "/") + "/"
+		sopts := append(opts,
+			registry.WithStrKey(allServiceKey),
+			registry.WithPrefix())
+		resp, err := store.Store().Service().Search(dr.ctx, sopts...)
+		if err != nil {
+			return nil, err
+		}
+
+		for _, kv := range resp.Kvs {
+			serviceIds = append(serviceIds, util.BytesToStringWithNoCopy(kv.Value))
+		}
+	default:
+		serviceIds, err = FindServiceIds(dr.ctx, dependencyRule.Version, dependencyRule)
+	}
+	return
+}
+
 func (dr *DependencyRelation) GetDependencyConsumers() ([]*pb.MicroService, error) {
 	consumerDependAllList, err := dr.getDependencyConsumersOfProvider()
 	if err != nil {
-		util.Logger().Errorf(err, "Get consumers of provider rule failed, %s", dr.providerId)
+		util.Logger().Errorf(err, "Get consumers of provider rule failed, %s", dr.provider.ServiceId)
 		return nil, err
 	}
 	consumers := make([]*pb.MicroService, 0)
 
 	for _, consumer := range consumerDependAllList {
-		service, err := dr.getServiceByMicroServiceKey(dr.domainProject, consumer)
+		service, err := dr.getServiceByMicroServiceKey(consumer)
 		if err != nil {
 			return nil, err
 		}
 		if service == nil {
-			util.Logger().Warnf(nil, "Consumer not exist,%v", service)
+			util.Logger().Warnf(nil, "Consumer does not exist, %v", consumer)
 			continue
 		}
 		consumers = append(consumers, service)
@@ -1022,7 +978,7 @@ func (dr *DependencyRelation) GetDependencyConsumers() ([]*pb.MicroService, erro
 	return consumers, nil
 }
 
-func (dr *DependencyRelation) getServiceByMicroServiceKey(domainProject string, service *pb.MicroServiceKey) (*pb.MicroService, error) {
+func (dr *DependencyRelation) getServiceByMicroServiceKey(service *pb.MicroServiceKey) (*pb.MicroService, error) {
 	serviceId, err := GetServiceId(dr.ctx, service)
 	if err != nil {
 		return nil, err
@@ -1031,7 +987,7 @@ func (dr *DependencyRelation) getServiceByMicroServiceKey(domainProject string,
 		util.Logger().Warnf(nil, "Service not exist,%v", service)
 		return nil, nil
 	}
-	return GetService(dr.ctx, domainProject, serviceId)
+	return GetService(dr.ctx, service.Tenant, serviceId)
 }
 
 func (dr *DependencyRelation) GetDependencyConsumerIds() ([]string, error) {
@@ -1039,9 +995,9 @@ func (dr *DependencyRelation) GetDependencyConsumerIds() ([]string, error) {
 	if err != nil {
 		return nil, err
 	}
-	consumerIds := make([]string, 0)
+	consumerIds := make([]string, 0, len(consumerDependAllList))
 	for _, consumer := range consumerDependAllList {
-		consumerId, err := GetServiceId(context.TODO(), consumer)
+		consumerId, err := GetServiceId(dr.ctx, consumer)
 		if err != nil {
 			util.Logger().Errorf(err, "Get consumer failed, %v", consumer)
 			return nil, err
@@ -1064,13 +1020,14 @@ func (dr *DependencyRelation) getDependencyConsumersOfProvider() ([]*pb.MicroSer
 	providerService := pb.MicroServiceToKey(dr.domainProject, dr.provider)
 	consumerDependAllList, err := dr.getConsumerOfDependAllServices()
 	if err != nil {
-		util.Logger().Errorf(err, "Get consumer that depend on all services failed, %s", dr.providerId)
+		util.Logger().Errorf(err, "Get consumer that depend on all services failed, %s", dr.provider.ServiceId)
 		return nil, err
 	}
 
 	consumerDependList, err := dr.getConsumerOfSameServiceNameAndAppId(providerService)
 	if err != nil {
-		util.Logger().Errorf(err, "Get consumer that depend on same serviceName and appid rule failed, %s", dr.providerId)
+		util.Logger().Errorf(err, "Get consumer that depend on same serviceName and appid rule failed, %s",
+			dr.provider.ServiceId)
 		return nil, err
 	}
 	consumerDependAllList = append(consumerDependAllList, consumerDependList...)
@@ -1135,7 +1092,7 @@ func (dr *DependencyRelation) getConsumerOfSameServiceNameAndAppId(provider *pb.
 				util.Logger().Infof("%s 's providerId is empty,no this service.", provider.ServiceName)
 				continue
 			}
-			if dr.providerId != latestServiceId[0] {
+			if dr.provider.ServiceId != latestServiceId[0] {
 				continue
 			}
 
diff --git a/server/service/util/dependency_test.go b/server/service/util/dependency_test.go
index d4208916..6695945d 100644
--- a/server/service/util/dependency_test.go
+++ b/server/service/util/dependency_test.go
@@ -25,7 +25,7 @@ import (
 )
 
 func TestRefreshDependencyCache(t *testing.T) {
-	err := RefreshDependencyCache(context.Background(), "", "", &proto.MicroService{})
+	err := RefreshDependencyCache(context.Background(), "", &proto.MicroService{})
 	if err == nil {
 		fmt.Printf(`RefreshDependencyCache failed`)
 		t.FailNow()
@@ -135,18 +135,12 @@ func TestCreateDependencyRule(t *testing.T) {
 		t.FailNow()
 	}
 
-	err = AddServiceVersionRule(context.Background(), "", &proto.MicroServiceKey{}, &proto.MicroServiceKey{})
+	err = AddServiceVersionRule(context.Background(), "", &proto.MicroService{}, &proto.MicroServiceKey{})
 	if err == nil {
 		fmt.Printf(`AddServiceVersionRule failed`)
 		t.FailNow()
 	}
 
-	err = CreateDependencyRuleForFind(context.Background(), "", &proto.MicroServiceKey{}, &proto.MicroServiceKey{})
-	if err == nil {
-		fmt.Printf(`CreateDependencyRuleForFind failed`)
-		t.FailNow()
-	}
-
 	_, err = addDepRuleUtil("", &proto.MicroServiceDependency{}, &proto.MicroServiceKey{})
 	if err != nil {
 		fmt.Printf(`addDepRuleUtil failed`)
@@ -320,13 +314,13 @@ func TestParamsChecker(t *testing.T) {
 }
 
 func TestServiceDependencyRuleExist(t *testing.T) {
-	_, err := ProviderDependencyRuleExist(util.SetContext(context.Background(), "cacheOnly", "1"), "", &proto.MicroServiceKey{}, &proto.MicroServiceKey{})
+	_, err := ProviderDependencyRuleExist(util.SetContext(context.Background(), "cacheOnly", "1"), &proto.MicroServiceKey{}, &proto.MicroServiceKey{})
 	if err != nil {
 		fmt.Printf(`ServiceDependencyRuleExist WithCacheOnly failed`)
 		t.FailNow()
 	}
 
-	_, err = ProviderDependencyRuleExist(context.Background(), "", &proto.MicroServiceKey{}, &proto.MicroServiceKey{})
+	_, err = ProviderDependencyRuleExist(context.Background(), &proto.MicroServiceKey{}, &proto.MicroServiceKey{})
 	if err == nil {
 		fmt.Printf(`ServiceDependencyRuleExist failed`)
 		t.FailNow()
@@ -358,7 +352,7 @@ func TestUpdateServiceForAddDependency(t *testing.T) {
 }
 
 func TestFilter(t *testing.T) {
-	_, _, err := getConsumerIdsWithFilter(context.Background(), "", "", &proto.MicroService{}, noFilter)
+	_, _, err := getConsumerIdsWithFilter(context.Background(), "", &proto.MicroService{}, noFilter)
 	if err == nil {
 		fmt.Printf(`getConsumerIdsWithFilter failed`)
 		t.FailNow()
@@ -440,7 +434,7 @@ func TestDependency(t *testing.T) {
 		t.FailNow()
 	}
 
-	_, err = dr.getServiceByMicroServiceKey("", &proto.MicroServiceKey{})
+	_, err = dr.getServiceByMicroServiceKey(&proto.MicroServiceKey{})
 	if err != nil {
 		fmt.Printf(`DependencyRelation_getServiceByMicroServiceKey WithCacheOnly failed`)
 		t.FailNow()
@@ -479,7 +473,7 @@ func TestDependency(t *testing.T) {
 		t.FailNow()
 	}
 
-	_, err = dr.getServiceByMicroServiceKey("", &proto.MicroServiceKey{})
+	_, err = dr.getServiceByMicroServiceKey(&proto.MicroServiceKey{})
 	if err == nil {
 		fmt.Printf(`DependencyRelation_getServiceByMicroServiceKey failed`)
 		t.FailNow()
diff --git a/server/service/util/instance_util.go b/server/service/util/instance_util.go
index c63496f1..eb5351fd 100644
--- a/server/service/util/instance_util.go
+++ b/server/service/util/instance_util.go
@@ -191,7 +191,7 @@ func DeleteServiceAllInstances(ctx context.Context, serviceId string) error {
 	return nil
 }
 
-func QueryAllProvidersIntances(ctx context.Context, selfServiceId string) (results []*pb.WatchInstanceResponse, rev int64) {
+func QueryAllProvidersInstances(ctx context.Context, selfServiceId string) (results []*pb.WatchInstanceResponse, rev int64) {
 	results = []*pb.WatchInstanceResponse{}
 
 	domainProject := util.ParseDomainProject(ctx)
@@ -205,7 +205,7 @@ func QueryAllProvidersIntances(ctx context.Context, selfServiceId string) (resul
 		util.Logger().Errorf(nil, "service not exist, %s", selfServiceId)
 		return
 	}
-	providerIds, _, err := GetProviderIdsByConsumerId(ctx, domainProject, selfServiceId, service)
+	providerIds, _, err := GetProviderIdsByConsumer(ctx, domainProject, service)
 	if err != nil {
 		util.Logger().Errorf(err, "get service %s providers id set failed.", selfServiceId)
 		return
diff --git a/server/service/util/instance_util_test.go b/server/service/util/instance_util_test.go
index 4bc955ed..5bba56c6 100644
--- a/server/service/util/instance_util_test.go
+++ b/server/service/util/instance_util_test.go
@@ -64,7 +64,7 @@ func TestGetInstance(t *testing.T) {
 		t.FailNow()
 	}
 
-	QueryAllProvidersIntances(context.Background(), "")
+	QueryAllProvidersInstances(context.Background(), "")
 
 	_, err = queryServiceInstancesKvs(context.Background(), "", 0)
 	if err == nil {
diff --git a/server/service/util/rule_util.go b/server/service/util/rule_util.go
index f2614b8f..50041b9f 100644
--- a/server/service/util/rule_util.go
+++ b/server/service/util/rule_util.go
@@ -143,7 +143,7 @@ func GetOneRule(ctx context.Context, domainProject, serviceId, ruleId string) (*
 	return rule, nil
 }
 
-func AllowAcrossDimension(providerService *pb.MicroService, consumerService *pb.MicroService) error {
+func AllowAcrossDimension(ctx context.Context, providerService *pb.MicroService, consumerService *pb.MicroService) error {
 	if providerService.AppId != consumerService.AppId {
 		if len(providerService.Properties) == 0 {
 			return fmt.Errorf("not allow across app access")
@@ -154,7 +154,9 @@ func AllowAcrossDimension(providerService *pb.MicroService, consumerService *pb.
 		}
 	}
 
-	if providerService.Environment != consumerService.Environment {
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	if !apt.IsShared(pb.MicroServiceToKey(targetDomainProject, providerService)) &&
+		providerService.Environment != consumerService.Environment {
 		return fmt.Errorf("not allow across environment access")
 	}
 
@@ -213,7 +215,10 @@ func MatchRules(rules []*pb.ServiceRule, service *pb.MicroService, serviceTags m
 	return nil
 }
 
-func Accessible(ctx context.Context, domainProject string, consumerId string, providerId string) *scerr.Error {
+func Accessible(ctx context.Context, consumerId string, providerId string) *scerr.Error {
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+
 	consumerService, err := GetService(ctx, domainProject, consumerId)
 	if err != nil {
 		return scerr.NewError(scerr.ErrInternal, fmt.Sprintf("An error occurred in query consumer(%s)", err.Error()))
@@ -223,7 +228,7 @@ func Accessible(ctx context.Context, domainProject string, consumerId string, pr
 	}
 
 	// ?????
-	providerService, err := GetService(ctx, domainProject, providerId)
+	providerService, err := GetService(ctx, targetDomainProject, providerId)
 	if err != nil {
 		return scerr.NewError(scerr.ErrInternal, fmt.Sprintf("An error occurred in query provider(%s)", err.Error()))
 	}
@@ -231,7 +236,7 @@ func Accessible(ctx context.Context, domainProject string, consumerId string, pr
 		return scerr.NewError(scerr.ErrServiceNotExists, "provider serviceId is invalid")
 	}
 
-	err = AllowAcrossDimension(providerService, consumerService)
+	err = AllowAcrossDimension(ctx, providerService, consumerService)
 	if err != nil {
 		return scerr.NewError(scerr.ErrPermissionDeny, err.Error())
 	}
@@ -239,7 +244,7 @@ func Accessible(ctx context.Context, domainProject string, consumerId string, pr
 	ctx = util.SetContext(util.CloneContext(ctx), "cacheOnly", "1")
 
 	// ????
-	rules, err := GetRulesUtil(ctx, domainProject, providerId)
+	rules, err := GetRulesUtil(ctx, targetDomainProject, providerId)
 	if err != nil {
 		return scerr.NewError(scerr.ErrInternal, fmt.Sprintf("An error occurred in query provider rules(%s)", err.Error()))
 	}
diff --git a/server/service/util/rule_util_test.go b/server/service/util/rule_util_test.go
index 4175aea0..5cf142a2 100644
--- a/server/service/util/rule_util_test.go
+++ b/server/service/util/rule_util_test.go
@@ -91,7 +91,7 @@ func TestGetServiceRuleType(t *testing.T) {
 }
 
 func TestAllowAcrossApp(t *testing.T) {
-	err := serviceUtil.AllowAcrossDimension(&proto.MicroService{
+	err := serviceUtil.AllowAcrossDimension(context.Background(), &proto.MicroService{
 		AppId: "a",
 	}, &proto.MicroService{
 		AppId: "a",
@@ -101,7 +101,7 @@ func TestAllowAcrossApp(t *testing.T) {
 		t.FailNow()
 	}
 
-	err = serviceUtil.AllowAcrossDimension(&proto.MicroService{
+	err = serviceUtil.AllowAcrossDimension(context.Background(), &proto.MicroService{
 		AppId: "a",
 	}, &proto.MicroService{
 		AppId: "c",
@@ -111,7 +111,7 @@ func TestAllowAcrossApp(t *testing.T) {
 		t.FailNow()
 	}
 
-	err = serviceUtil.AllowAcrossDimension(&proto.MicroService{
+	err = serviceUtil.AllowAcrossDimension(context.Background(), &proto.MicroService{
 		AppId: "a",
 		Properties: map[string]string{
 			proto.PROP_ALLOW_CROSS_APP: "true",
@@ -124,7 +124,7 @@ func TestAllowAcrossApp(t *testing.T) {
 		t.FailNow()
 	}
 
-	err = serviceUtil.AllowAcrossDimension(&proto.MicroService{
+	err = serviceUtil.AllowAcrossDimension(context.Background(), &proto.MicroService{
 		AppId: "a",
 		Properties: map[string]string{
 			proto.PROP_ALLOW_CROSS_APP: "true",
@@ -137,7 +137,7 @@ func TestAllowAcrossApp(t *testing.T) {
 		t.FailNow()
 	}
 
-	err = serviceUtil.AllowAcrossDimension(&proto.MicroService{
+	err = serviceUtil.AllowAcrossDimension(context.Background(), &proto.MicroService{
 		AppId: "a",
 		Properties: map[string]string{
 			proto.PROP_ALLOW_CROSS_APP: "false",
@@ -150,7 +150,7 @@ func TestAllowAcrossApp(t *testing.T) {
 		t.FailNow()
 	}
 
-	err = serviceUtil.AllowAcrossDimension(&proto.MicroService{
+	err = serviceUtil.AllowAcrossDimension(context.Background(), &proto.MicroService{
 		AppId: "a",
 		Properties: map[string]string{
 			proto.PROP_ALLOW_CROSS_APP: "",
@@ -289,21 +289,21 @@ func TestMatchRules(t *testing.T) {
 }
 
 func TestGetConsumer(t *testing.T) {
-	_, _, err := serviceUtil.GetConsumerIds(context.Background(), "", &proto.MicroService{})
+	_, _, err := serviceUtil.GetConsumerIdsByProvider(context.Background(), "", &proto.MicroService{})
 	if err == nil {
-		fmt.Printf("GetConsumerIds invalid failed")
+		fmt.Printf("GetConsumerIdsByProvider invalid failed")
 		t.FailNow()
 	}
 
-	_, _, err = serviceUtil.GetConsumerIds(context.Background(), "", &proto.MicroService{
+	_, _, err = serviceUtil.GetConsumerIdsByProvider(context.Background(), "", &proto.MicroService{
 		ServiceId: "a",
 	})
 	if err == nil {
-		fmt.Printf("GetConsumerIds not exist service failed")
+		fmt.Printf("GetConsumerIdsByProvider not exist service failed")
 		t.FailNow()
 	}
 
-	_, err = serviceUtil.GetConsumersInCache(util.SetContext(context.Background(), "cacheOnly", "1"), "", "",
+	_, err = serviceUtil.GetConsumersInCache(util.SetContext(context.Background(), "cacheOnly", "1"), "",
 		&proto.MicroService{
 			ServiceId: "a",
 		})
@@ -314,7 +314,7 @@ func TestGetConsumer(t *testing.T) {
 }
 
 func TestGetProvider(t *testing.T) {
-	_, err := serviceUtil.GetProvidersInCache(util.SetContext(context.Background(), "cacheOnly", "1"), "", "",
+	_, err := serviceUtil.GetProvidersInCache(util.SetContext(context.Background(), "cacheOnly", "1"), "",
 		&proto.MicroService{
 			ServiceId: "a",
 		})
@@ -323,28 +323,28 @@ func TestGetProvider(t *testing.T) {
 		t.FailNow()
 	}
 
-	_, _, err = serviceUtil.GetProviderIdsByConsumerId(context.Background(), "", "", &proto.MicroService{})
+	_, _, err = serviceUtil.GetProviderIdsByConsumer(context.Background(), "", &proto.MicroService{})
 	if err == nil {
-		fmt.Printf("GetProviderIdsByConsumerId invalid failed")
+		fmt.Printf("GetProviderIdsByConsumer invalid failed")
 		t.FailNow()
 	}
 
-	_, _, err = serviceUtil.GetProviderIdsByConsumerId(util.SetContext(context.Background(), "cacheOnly", "1"),
-		"", "", &proto.MicroService{})
+	_, _, err = serviceUtil.GetProviderIdsByConsumer(util.SetContext(context.Background(), "cacheOnly", "1"),
+		"", &proto.MicroService{})
 	if err != nil {
-		fmt.Printf("GetProviderIdsByConsumerId WithCacheOnly failed")
+		fmt.Printf("GetProviderIdsByConsumer WithCacheOnly failed")
 		t.FailNow()
 	}
 }
 
 func TestAccessible(t *testing.T) {
-	err := serviceUtil.Accessible(context.Background(), "", "", "")
+	err := serviceUtil.Accessible(context.Background(), "", "")
 	if err.StatusCode() != http.StatusInternalServerError {
 		fmt.Printf("Accessible invalid failed")
 		t.FailNow()
 	}
 
-	err = serviceUtil.Accessible(util.SetContext(context.Background(), "cacheOnly", "1"), "", "", "")
+	err = serviceUtil.Accessible(util.SetContext(context.Background(), "cacheOnly", "1"), "", "")
 	if err.StatusCode() == http.StatusInternalServerError {
 		fmt.Printf("Accessible WithCacheOnly failed")
 		t.FailNow()


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services