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

(servicecomb-service-center) branch dev updated: fix lint problems and readWrite lock optimization (#1455)

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

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


The following commit(s) were added to refs/heads/dev by this push:
     new 58dd5cde fix lint problems and readWrite lock optimization (#1455)
58dd5cde is described below

commit 58dd5cde763a6dbdea26fcebbd2b19ab157f87f9
Author: Dantlian <47...@users.noreply.github.com>
AuthorDate: Wed Jan 17 09:17:35 2024 +0800

    fix lint problems and readWrite lock optimization (#1455)
    
    * fix lint problems (#1451)
    
    Co-authored-by: l00618052 <li...@huawei.com>
    
    * readWrite lock optimization
    
    * add local storage test
    
    ---------
    
    Co-authored-by: l00618052 <li...@huawei.com>
---
 .github/workflows/static_check.yml                 | 14 ++++++
 client/client.go                                   |  2 +-
 client/websocket.go                                |  2 +-
 datasource/dependency_util.go                      |  4 +-
 datasource/etcd/account.go                         |  4 +-
 datasource/etcd/cache/filter_consumer.go           |  2 +-
 datasource/etcd/cache/filter_service.go            |  2 +-
 datasource/etcd/cache/filter_version.go            |  2 +-
 datasource/etcd/cache/instance.go                  |  6 +--
 datasource/etcd/ms.go                              | 31 +++++++------
 datasource/etcd/schema.go                          |  2 +-
 datasource/etcd/sd/aggregate/repo.go               |  2 +-
 datasource/etcd/sd/k8s/adaptor/listwatcher.go      |  2 +-
 datasource/etcd/sd/k8s/repo.go                     |  2 +-
 datasource/etcd/sd/servicecenter/repo.go           |  2 +-
 datasource/etcd/sd/servicecenter/syncer.go         |  2 +-
 datasource/etcd/state/etcd/repo.go                 |  2 +-
 datasource/etcd/state/kvstore/cache_null.go        | 22 +++++-----
 datasource/etcd/state/kvstore/indexer_cache.go     |  2 +-
 datasource/etcd/util/dependency_query.go           |  9 ++--
 datasource/etcd/util/microservice_util.go          | 37 ++++++++++++++--
 datasource/etcd/util/versionrule.go                |  4 +-
 datasource/local/schema.go                         | 51 ++++++++++++----------
 datasource/mongo/account.go                        |  2 +-
 datasource/mongo/dep.go                            |  5 +--
 datasource/mongo/dependency_query.go               |  2 +-
 datasource/mongo/engine.go                         |  4 +-
 datasource/mongo/heartbeat/cache/heartbeatcache.go |  2 +-
 .../mongo/heartbeat/checker/heartbeatchecker.go    |  2 +-
 datasource/mongo/ms.go                             | 17 ++++----
 datasource/mongo/retire.go                         |  2 +-
 datasource/mongo/role.go                           |  2 +-
 datasource/mongo/schema.go                         | 14 +++---
 datasource/schema/init.go                          | 10 +++--
 frontend/schema/schemahandler.go                   |  4 +-
 pkg/chain/invocation.go                            |  4 +-
 pkg/event/bus.go                                   |  2 +-
 pkg/event/subscriber.go                            |  2 +-
 pkg/log/zap_logger.go                              |  6 +--
 pkg/queue/uniqueue.go                              |  2 -
 scctl/pkg/plugin/diagnose/diagnose.go              |  2 +-
 scctl/pkg/plugin/get/cluster/cluster_cmd.go        |  2 +-
 scctl/pkg/plugin/get/cluster/printer.go            |  2 +-
 scctl/pkg/plugin/get/instance/instance_cmd.go      |  2 +-
 scctl/pkg/plugin/get/schema/schema_cmd.go          |  2 +-
 scctl/pkg/plugin/get/service/service_cmd.go        |  2 +-
 scctl/pkg/plugin/health/cmd.go                     |  2 +-
 scripts/ut_test_in_docker.sh                       | 11 +++++
 server/interceptor/interceptors.go                 |  2 -
 server/metrics/http.go                             |  2 +-
 server/plugin/quota/buildin/buildin.go             |  2 +-
 server/resource/disco/schema_resource.go           |  2 +-
 server/service/admin/admin.go                      |  6 +--
 server/service/disco/metadata.go                   |  5 +--
 server/service/disco/schema.go                     |  2 +-
 server/service/grc/kie/kie_distributor.go          |  4 +-
 server/service/grc/mock/mock.go                    | 16 +++----
 server/service/rbac/authr_plugin.go                |  4 +-
 server/service/rbac/decision.go                    |  2 +-
 test/test.go                                       | 12 +++++
 60 files changed, 218 insertions(+), 156 deletions(-)

diff --git a/.github/workflows/static_check.yml b/.github/workflows/static_check.yml
index 404a1c8b..fe95ef40 100644
--- a/.github/workflows/static_check.yml
+++ b/.github/workflows/static_check.yml
@@ -43,6 +43,20 @@ jobs:
           sudo docker-compose -f ./scripts/docker-compose.yaml up -d
           sleep 20
           bash -x scripts/ut_test_in_docker.sh mongo
+  local:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Set up Go 1.18
+        uses: actions/setup-go@v1
+        with:
+          go-version: 1.18
+        id: go
+      - name: Check out code into the Go module directory
+        uses: actions/checkout@v1
+      - name: UT-LOCAL_STORAGE
+        run: |
+          rm -rf /data/schemas
+          bash -x scripts/ut_test_in_docker.sh local
   integration-test:
     runs-on: ubuntu-latest
     steps:
diff --git a/client/client.go b/client/client.go
index 5d018d03..88b8a454 100644
--- a/client/client.go
+++ b/client/client.go
@@ -35,7 +35,7 @@ type Client struct {
 	Cfg Config
 }
 
-func (c *Client) CommonHeaders(ctx context.Context) http.Header {
+func (c *Client) CommonHeaders(_ context.Context) http.Header {
 	var headers = make(http.Header)
 	// TODO overwrote by context values
 	if len(c.Cfg.Token) > 0 {
diff --git a/client/websocket.go b/client/websocket.go
index a9cc5ce4..ad58425d 100644
--- a/client/websocket.go
+++ b/client/websocket.go
@@ -29,7 +29,7 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/util"
 )
 
-func (c *LBClient) WebsocketDial(ctx context.Context, api string, headers http.Header) (conn *websocket.Conn, err error) {
+func (c *LBClient) WebsocketDial(_ context.Context, api string, headers http.Header) (conn *websocket.Conn, err error) {
 	dialer := &websocket.Dialer{TLSClientConfig: c.TLS}
 	var errs []string
 	for i := 0; i < c.Retries; i++ {
diff --git a/datasource/dependency_util.go b/datasource/dependency_util.go
index e9187465..fdb8683f 100644
--- a/datasource/dependency_util.go
+++ b/datasource/dependency_util.go
@@ -60,7 +60,7 @@ func toString(in *discovery.MicroServiceKey) string {
 	return path.GenerateProviderDependencyRuleKey(in.Tenant, in)
 }
 
-func ParseAddOrUpdateRules(ctx context.Context, dep *Dependency, oldProviderRules *discovery.MicroServiceDependency) {
+func ParseAddOrUpdateRules(_ context.Context, dep *Dependency, oldProviderRules *discovery.MicroServiceDependency) {
 	deleteDependencyRuleList := make([]*discovery.MicroServiceKey, 0, len(oldProviderRules.Dependency))
 	createDependencyRuleList := make([]*discovery.MicroServiceKey, 0, len(dep.ProvidersRule))
 	existDependencyRuleList := make([]*discovery.MicroServiceKey, 0, len(oldProviderRules.Dependency))
@@ -83,7 +83,7 @@ func ParseAddOrUpdateRules(ctx context.Context, dep *Dependency, oldProviderRule
 	setDep(dep, createDependencyRuleList, existDependencyRuleList, deleteDependencyRuleList)
 }
 
-func ParseOverrideRules(ctx context.Context, dep *Dependency, oldProviderRules *discovery.MicroServiceDependency) {
+func ParseOverrideRules(_ context.Context, dep *Dependency, oldProviderRules *discovery.MicroServiceDependency) {
 	deleteDependencyRuleList := make([]*discovery.MicroServiceKey, 0, len(oldProviderRules.Dependency))
 	createDependencyRuleList := make([]*discovery.MicroServiceKey, 0, len(dep.ProvidersRule))
 	existDependencyRuleList := make([]*discovery.MicroServiceKey, 0, len(oldProviderRules.Dependency))
diff --git a/datasource/etcd/account.go b/datasource/etcd/account.go
index 149ce022..280eaa74 100644
--- a/datasource/etcd/account.go
+++ b/datasource/etcd/account.go
@@ -40,7 +40,7 @@ func init() {
 	rbac.Install("embedded_etcd", NewRbacDAO)
 }
 
-func NewRbacDAO(opts rbac.Options) (rbac.DAO, error) {
+func NewRbacDAO(_ rbac.Options) (rbac.DAO, error) {
 	return &RbacDAO{}, nil
 }
 
@@ -187,7 +187,7 @@ func (ds *RbacDAO) DeleteAccount(ctx context.Context, names []string) (bool, err
 	return true, nil
 }
 
-func (ds *RbacDAO) UpdateAccount(ctx context.Context, name string, account *crbac.Account) error {
+func (ds *RbacDAO) UpdateAccount(ctx context.Context, _ string, account *crbac.Account) error {
 	var (
 		opts []etcdadpt.OpOptions
 		err  error
diff --git a/datasource/etcd/cache/filter_consumer.go b/datasource/etcd/cache/filter_consumer.go
index e16135da..45491eca 100644
--- a/datasource/etcd/cache/filter_consumer.go
+++ b/datasource/etcd/cache/filter_consumer.go
@@ -30,7 +30,7 @@ func (f *ConsumerFilter) Name(ctx context.Context, _ *cache.Node) string {
 	return ctx.Value(CtxConsumerID).(string)
 }
 
-func (f *ConsumerFilter) Init(ctx context.Context, parent *cache.Node) (node *cache.Node, err error) {
+func (f *ConsumerFilter) Init(_ context.Context, _ *cache.Node) (node *cache.Node, err error) {
 	node = cache.NewNode()
 	node.Cache.Set(DepResult, &DependencyRuleItem{})
 	return
diff --git a/datasource/etcd/cache/filter_service.go b/datasource/etcd/cache/filter_service.go
index de0416df..ff186b64 100644
--- a/datasource/etcd/cache/filter_service.go
+++ b/datasource/etcd/cache/filter_service.go
@@ -38,7 +38,7 @@ func (f *ServiceFilter) Name(ctx context.Context, _ *cache.Node) string {
 		provider.ServiceName}, "/")
 }
 
-func (f *ServiceFilter) Init(ctx context.Context, parent *cache.Node) (node *cache.Node, err error) {
+func (f *ServiceFilter) Init(_ context.Context, _ *cache.Node) (node *cache.Node, err error) {
 	node = cache.NewNode()
 	return
 }
diff --git a/datasource/etcd/cache/filter_version.go b/datasource/etcd/cache/filter_version.go
index 356a3a41..69c0dad8 100644
--- a/datasource/etcd/cache/filter_version.go
+++ b/datasource/etcd/cache/filter_version.go
@@ -39,7 +39,7 @@ func (f *VersionFilter) Name(ctx context.Context, _ *cache.Node) string {
 	return ""
 }
 
-func (f *VersionFilter) Init(ctx context.Context, parent *cache.Node) (node *cache.Node, err error) {
+func (f *VersionFilter) Init(ctx context.Context, _ *cache.Node) (node *cache.Node, err error) {
 	instance, ok := ctx.Value(CtxProviderInstanceKey).(*pb.HeartbeatSetElement)
 	if ok {
 		node = cache.NewNode()
diff --git a/datasource/etcd/cache/instance.go b/datasource/etcd/cache/instance.go
index 463f3ec4..74525bc2 100644
--- a/datasource/etcd/cache/instance.go
+++ b/datasource/etcd/cache/instance.go
@@ -96,8 +96,8 @@ func (f *FindInstancesCache) GetWithProviderID(ctx context.Context, consumer *pb
 func (f *FindInstancesCache) Remove(provider *pb.MicroServiceKey) {
 	f.Tree.Remove(context.WithValue(context.Background(), CtxProviderKey, provider))
 	if len(provider.Alias) > 0 {
-		copy := *provider
-		copy.ServiceName = copy.Alias
-		f.Tree.Remove(context.WithValue(context.Background(), CtxProviderKey, &copy))
+		copyProvider := *provider
+		copyProvider.ServiceName = copyProvider.Alias
+		f.Tree.Remove(context.WithValue(context.Background(), CtxProviderKey, &copyProvider))
 	}
 }
diff --git a/datasource/etcd/ms.go b/datasource/etcd/ms.go
index cc2c8705..f3b1499e 100644
--- a/datasource/etcd/ms.go
+++ b/datasource/etcd/ms.go
@@ -22,18 +22,11 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"github.com/apache/servicecomb-service-center/datasource/local"
+	"os"
 	"path/filepath"
 	"strconv"
 	"time"
 
-	"github.com/apache/servicecomb-service-center/syncer/service/event"
-	pb "github.com/go-chassis/cari/discovery"
-	"github.com/go-chassis/cari/pkg/errsvc"
-	"github.com/go-chassis/cari/sync"
-	"github.com/go-chassis/foundation/gopool"
-	"github.com/little-cui/etcdadpt"
-
 	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/etcd/cache"
 	"github.com/apache/servicecomb-service-center/datasource/etcd/path"
@@ -42,12 +35,19 @@ import (
 	esync "github.com/apache/servicecomb-service-center/datasource/etcd/sync"
 	eutil "github.com/apache/servicecomb-service-center/datasource/etcd/util"
 	serviceUtil "github.com/apache/servicecomb-service-center/datasource/etcd/util"
+	"github.com/apache/servicecomb-service-center/datasource/local"
 	"github.com/apache/servicecomb-service-center/datasource/schema"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/core"
 	"github.com/apache/servicecomb-service-center/server/plugin/uuid"
 	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
+	"github.com/apache/servicecomb-service-center/syncer/service/event"
+	pb "github.com/go-chassis/cari/discovery"
+	"github.com/go-chassis/cari/pkg/errsvc"
+	"github.com/go-chassis/cari/sync"
+	"github.com/go-chassis/foundation/gopool"
+	"github.com/little-cui/etcdadpt"
 )
 
 type MetadataManager struct {
@@ -188,7 +188,7 @@ func (ds *MetadataManager) RegisterService(ctx context.Context, request *pb.Crea
 	}, nil
 }
 
-func (ds *MetadataManager) ListService(ctx context.Context, request *pb.GetServicesRequest) (
+func (ds *MetadataManager) ListService(ctx context.Context, _ *pb.GetServicesRequest) (
 	*pb.GetServicesResponse, error) {
 	services, err := eutil.GetAllServiceUtil(ctx)
 	if err != nil {
@@ -217,7 +217,7 @@ func (ds *MetadataManager) GetService(ctx context.Context, request *pb.GetServic
 	return singleService, nil
 }
 
-func (ds *MetadataManager) GetOverview(ctx context.Context, request *pb.GetServicesRequest) (
+func (ds *MetadataManager) GetOverview(ctx context.Context, _ *pb.GetServicesRequest) (
 	*pb.Statistics, error) {
 	ctx = util.WithCacheOnly(ctx)
 	st, err := statistics(ctx, false)
@@ -879,10 +879,9 @@ func (ds *MetadataManager) SendManyHeartbeat(ctx context.Context, request *pb.He
 			log.Warn(fmt.Sprintf("instance[%s/%s] is duplicate request heartbeat set",
 				heartbeatElement.ServiceId, heartbeatElement.InstanceId))
 			continue
-		} else {
-			existFlag[heartbeatElement.ServiceId+heartbeatElement.InstanceId] = true
-			noMultiCounter++
 		}
+		existFlag[heartbeatElement.ServiceId+heartbeatElement.InstanceId] = true
+		noMultiCounter++
 		gopool.Go(getHeartbeatFunc(ctx, domainProject, instancesHbRst, heartbeatElement))
 	}
 	count := 0
@@ -944,7 +943,7 @@ func (ds *MetadataManager) SendHeartbeat(ctx context.Context, request *pb.Heartb
 	return nil
 }
 
-func (ds *MetadataManager) ListManyInstances(ctx context.Context, request *pb.GetAllInstancesRequest) (*pb.GetAllInstancesResponse, error) {
+func (ds *MetadataManager) ListManyInstances(ctx context.Context, _ *pb.GetAllInstancesRequest) (*pb.GetAllInstancesResponse, error) {
 	domainProject := util.ParseDomainProject(ctx)
 	key := path.GetInstanceRootKey(domainProject) + path.SPLIT
 	opts := append(eutil.FromContext(ctx), etcdadpt.WithStrKey(key), etcdadpt.WithPrefix())
@@ -1506,6 +1505,10 @@ func (ds *MetadataManager) UnregisterService(ctx context.Context, request *pb.De
 				if rollbackErr != nil {
 					log.Error("clean tmp dir error when rollback in UnregisterService", err)
 				}
+				rollbackErr = os.Remove(originPath)
+				if rollbackErr != nil {
+					log.Error("clean origin dir error when rollback in UnregisterService", err)
+				}
 			}
 		}
 	}()
diff --git a/datasource/etcd/schema.go b/datasource/etcd/schema.go
index f32c5eb8..32488f08 100644
--- a/datasource/etcd/schema.go
+++ b/datasource/etcd/schema.go
@@ -43,7 +43,7 @@ func init() {
 	schema.Install("embedded_etcd", NewSchemaDAO)
 }
 
-func NewSchemaDAO(opts schema.Options) (schema.DAO, error) {
+func NewSchemaDAO(_ schema.Options) (schema.DAO, error) {
 	return &SchemaDAO{}, nil
 }
 
diff --git a/datasource/etcd/sd/aggregate/repo.go b/datasource/etcd/sd/aggregate/repo.go
index 79f94399..aee5dcd8 100644
--- a/datasource/etcd/sd/aggregate/repo.go
+++ b/datasource/etcd/sd/aggregate/repo.go
@@ -33,6 +33,6 @@ func (r *Repository) New(t kvstore.Type, cfg *kvstore.Options) state.State {
 	return NewAggregator(t, cfg)
 }
 
-func NewRepository(opts state.Config) state.Repository {
+func NewRepository(_ state.Config) state.Repository {
 	return &Repository{}
 }
diff --git a/datasource/etcd/sd/k8s/adaptor/listwatcher.go b/datasource/etcd/sd/k8s/adaptor/listwatcher.go
index 050bbe02..28091ce3 100644
--- a/datasource/etcd/sd/k8s/adaptor/listwatcher.go
+++ b/datasource/etcd/sd/k8s/adaptor/listwatcher.go
@@ -50,7 +50,7 @@ type k8sListWatcher struct {
 	cb OnEventFunc
 }
 
-func (w *k8sListWatcher) Handle(ctx context.Context, obj interface{}) {
+func (w *k8sListWatcher) Handle(_ context.Context, obj interface{}) {
 	if w.cb == nil {
 		return
 	}
diff --git a/datasource/etcd/sd/k8s/repo.go b/datasource/etcd/sd/k8s/repo.go
index ae4efeff..b22cbe94 100644
--- a/datasource/etcd/sd/k8s/repo.go
+++ b/datasource/etcd/sd/k8s/repo.go
@@ -37,6 +37,6 @@ func (r *Repository) New(t kvstore.Type, cfg *kvstore.Options) state.State {
 	return adaptor.NewK8sAdaptor(t, cfg)
 }
 
-func NewRepository(opts state.Config) state.Repository {
+func NewRepository(_ state.Config) state.Repository {
 	return &Repository{}
 }
diff --git a/datasource/etcd/sd/servicecenter/repo.go b/datasource/etcd/sd/servicecenter/repo.go
index 671374e6..15c6eb37 100644
--- a/datasource/etcd/sd/servicecenter/repo.go
+++ b/datasource/etcd/sd/servicecenter/repo.go
@@ -33,6 +33,6 @@ func (r *Repository) New(t kvstore.Type, cfg *kvstore.Options) state.State {
 	return NewServiceCenterAdaptor(t, cfg)
 }
 
-func NewRepository(opts state.Config) state.Repository {
+func NewRepository(_ state.Config) state.Repository {
 	return &Repository{}
 }
diff --git a/datasource/etcd/sd/servicecenter/syncer.go b/datasource/etcd/sd/servicecenter/syncer.go
index d6241757..e5fedfaa 100644
--- a/datasource/etcd/sd/servicecenter/syncer.go
+++ b/datasource/etcd/sd/servicecenter/syncer.go
@@ -175,7 +175,7 @@ func (c *Syncer) checkWithConflictHandleFunc(local *Cacher, remote dump.Getter,
 	}
 }
 
-func (c *Syncer) skipHandleFunc(origin *dump.KV, conflict dump.Getter, index int) {
+func (c *Syncer) skipHandleFunc(_ *dump.KV, _ dump.Getter, _ int) {
 }
 
 func (c *Syncer) logConflictFunc(origin *dump.KV, conflict dump.Getter, index int) {
diff --git a/datasource/etcd/state/etcd/repo.go b/datasource/etcd/state/etcd/repo.go
index 905cafa6..fbf08aef 100644
--- a/datasource/etcd/state/etcd/repo.go
+++ b/datasource/etcd/state/etcd/repo.go
@@ -34,6 +34,6 @@ func (r *Repository) New(t kvstore.Type, cfg *kvstore.Options) state.State {
 	return NewEtcdState(t.String(), cfg)
 }
 
-func NewRepository(opts state.Config) state.Repository {
+func NewRepository(_ state.Config) state.Repository {
 	return &Repository{}
 }
diff --git a/datasource/etcd/state/kvstore/cache_null.go b/datasource/etcd/state/kvstore/cache_null.go
index 4d3b2a78..0a6dea03 100644
--- a/datasource/etcd/state/kvstore/cache_null.go
+++ b/datasource/etcd/state/kvstore/cache_null.go
@@ -25,17 +25,17 @@ var (
 type nullCache struct {
 }
 
-func (n *nullCache) Name() string                                         { return "NULL" }
-func (n *nullCache) Size() int                                            { return 0 }
-func (n *nullCache) Get(k string) *KeyValue                               { return nil }
-func (n *nullCache) GetAll(arr *[]*KeyValue) int                          { return 0 }
-func (n *nullCache) GetPrefix(prefix string, arr *[]*KeyValue) int        { return 0 }
-func (n *nullCache) ForEach(iter func(k string, v *KeyValue) (next bool)) {}
-func (n *nullCache) Put(k string, v *KeyValue)                            {}
-func (n *nullCache) Remove(k string)                                      {}
-func (n *nullCache) MarkDirty()                                           {}
-func (n *nullCache) Dirty() bool                                          { return false }
-func (n *nullCache) Clear()                                               {}
+func (n *nullCache) Name() string                                      { return "NULL" }
+func (n *nullCache) Size() int                                         { return 0 }
+func (n *nullCache) Get(_ string) *KeyValue                            { return nil }
+func (n *nullCache) GetAll(_ *[]*KeyValue) int                         { return 0 }
+func (n *nullCache) GetPrefix(_ string, _ *[]*KeyValue) int            { return 0 }
+func (n *nullCache) ForEach(_ func(k string, v *KeyValue) (next bool)) {}
+func (n *nullCache) Put(_ string, _ *KeyValue)                         {}
+func (n *nullCache) Remove(_ string)                                   {}
+func (n *nullCache) MarkDirty()                                        {}
+func (n *nullCache) Dirty() bool                                       { return false }
+func (n *nullCache) Clear()                                            {}
 
 type nullCacher struct {
 }
diff --git a/datasource/etcd/state/kvstore/indexer_cache.go b/datasource/etcd/state/kvstore/indexer_cache.go
index 5e1bce2b..fa6ca68b 100644
--- a/datasource/etcd/state/kvstore/indexer_cache.go
+++ b/datasource/etcd/state/kvstore/indexer_cache.go
@@ -33,7 +33,7 @@ type CacheIndexer struct {
 	Cache CacheReader
 }
 
-func (i *CacheIndexer) Search(ctx context.Context, opts ...etcdadpt.OpOption) (resp *Response, _ error) {
+func (i *CacheIndexer) Search(_ context.Context, opts ...etcdadpt.OpOption) (resp *Response, _ error) {
 	op := etcdadpt.OpGet(opts...)
 	if op.Prefix {
 		resp = i.searchByPrefix(op)
diff --git a/datasource/etcd/util/dependency_query.go b/datasource/etcd/util/dependency_query.go
index 0498c6d1..f47a2f69 100644
--- a/datasource/etcd/util/dependency_query.go
+++ b/datasource/etcd/util/dependency_query.go
@@ -168,9 +168,8 @@ func (dr *DependencyRelation) GetDependencyConsumers(opts ...DependencyRelationF
 				log.Warn(fmt.Sprintf("consumer[%s/%s/%s/%s] does not exist",
 					consumer.Environment, consumer.AppId, consumer.ServiceName, consumer.Version))
 				continue
-			} else {
-				return nil, err
 			}
+			return nil, err
 		}
 
 		if op.NonSelf && service.ServiceId == dr.provider.ServiceId {
@@ -234,9 +233,9 @@ func (dr *DependencyRelation) GetDependencyConsumersOfProvider() ([]*pb.MicroSer
 }
 
 func (dr *DependencyRelation) GetConsumerOfSameServiceNameAndAppID(provider *pb.MicroServiceKey) ([]*pb.MicroServiceKey, error) {
-	copy := *provider
-	copy.Version = ""
-	prefix := path.GenerateProviderDependencyRuleKey(dr.domainProject, &copy)
+	copyProvider := *provider
+	copyProvider.Version = ""
+	prefix := path.GenerateProviderDependencyRuleKey(dr.domainProject, &copyProvider)
 
 	opts := append(FromContext(dr.ctx),
 		etcdadpt.WithStrKey(prefix),
diff --git a/datasource/etcd/util/microservice_util.go b/datasource/etcd/util/microservice_util.go
index 2311e430..79077477 100644
--- a/datasource/etcd/util/microservice_util.go
+++ b/datasource/etcd/util/microservice_util.go
@@ -21,6 +21,7 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"path/filepath"
 	"strings"
 
 	pb "github.com/go-chassis/cari/discovery"
@@ -31,6 +32,8 @@ import (
 	"github.com/apache/servicecomb-service-center/datasource/etcd/sd"
 	"github.com/apache/servicecomb-service-center/datasource/etcd/state/kvstore"
 	"github.com/apache/servicecomb-service-center/datasource/etcd/sync"
+	"github.com/apache/servicecomb-service-center/datasource/local"
+	"github.com/apache/servicecomb-service-center/datasource/schema"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/config"
@@ -163,17 +166,17 @@ func searchServiceIDFromAlias(ctx context.Context, key *pb.MicroServiceKey) (str
 }
 
 func GetServiceAllVersions(ctx context.Context, key *pb.MicroServiceKey, alias bool) (*kvstore.Response, error) {
-	copy := *key
-	copy.Version = ""
+	copyKey := *key
+	copyKey.Version = ""
 	var (
 		prefix  string
 		indexer kvstore.Indexer
 	)
 	if alias {
-		prefix = path.GenerateServiceAliasKey(&copy)
+		prefix = path.GenerateServiceAliasKey(&copyKey)
 		indexer = sd.ServiceAlias()
 	} else {
-		prefix = path.GenerateServiceIndexKey(&copy)
+		prefix = path.GenerateServiceIndexKey(&copyKey)
 		indexer = sd.ServiceIndex()
 	}
 	opts := append(FromContext(ctx),
@@ -247,6 +250,32 @@ func UpdateService(ctx context.Context, domainProject string, serviceID string,
 		log.Error("marshal service file failed", err)
 		return opts, err
 	}
+
+	if schema.StorageType == "local" {
+		contents := make([]*schema.ContentItem, len(service.Schemas))
+		err = schema.Instance().PutManyContent(ctx, &schema.PutManyContentRequest{
+			ServiceID: service.ServiceId,
+			SchemaIDs: service.Schemas,
+			Contents:  contents,
+			Init:      true,
+		})
+		if err != nil {
+			return nil, err
+		}
+
+		serviceMutex := local.GetOrCreateMutex(service.ServiceId)
+		serviceMutex.Lock()
+		defer serviceMutex.Unlock()
+	}
+	defer func() {
+		if schema.StorageType == "local" && err != nil {
+			cleanDirErr := local.CleanDir(filepath.Join(schema.RootFilePath, domainProject, service.ServiceId))
+			if cleanDirErr != nil {
+				log.Error("clean dir error when rollback in RegisterService", cleanDirErr)
+			}
+		}
+	}()
+
 	opt := etcdadpt.OpPut(etcdadpt.WithStrKey(key), etcdadpt.WithValue(data))
 	opts = append(opts, opt)
 	syncOpts, err := sync.GenUpdateOpts(ctx, datasource.ResourceKV, data, sync.WithOpts(map[string]string{"key": key}))
diff --git a/datasource/etcd/util/versionrule.go b/datasource/etcd/util/versionrule.go
index 84c8af6e..602e847f 100644
--- a/datasource/etcd/util/versionrule.go
+++ b/datasource/etcd/util/versionrule.go
@@ -97,7 +97,7 @@ func LessEqual(start, end string) bool {
 }
 
 // Latest return latest version kv
-func Latest(sorted []string, kvs []*kvstore.KeyValue, start, end string) []string {
+func Latest(sorted []string, kvs []*kvstore.KeyValue, _, _ string) []string {
 	if len(sorted) == 0 {
 		return []string{}
 	}
@@ -139,7 +139,7 @@ func Range(sorted []string, kvs []*kvstore.KeyValue, start, end string) []string
 }
 
 // AtLess return version >= start
-func AtLess(sorted []string, kvs []*kvstore.KeyValue, start, end string) []string {
+func AtLess(sorted []string, kvs []*kvstore.KeyValue, start, _ string) []string {
 	total := len(sorted)
 	if total == 0 {
 		return []string{}
diff --git a/datasource/local/schema.go b/datasource/local/schema.go
index 69aab4ed..0c7d6fbe 100644
--- a/datasource/local/schema.go
+++ b/datasource/local/schema.go
@@ -21,6 +21,13 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"io/fs"
+	"os"
+	pathutil "path"
+	"path/filepath"
+	"strings"
+	"sync"
+
 	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/etcd/path"
 	etcdsync "github.com/apache/servicecomb-service-center/datasource/etcd/sync"
@@ -30,33 +37,26 @@ import (
 	"github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/openlog"
 	"github.com/little-cui/etcdadpt"
-	"io/fs"
-	"os"
-	pathutil "path"
-	"path/filepath"
-	"strings"
-	"sync"
 )
 
-var MutexMap = make(map[string]*sync.Mutex)
+var MutexMap = make(map[string]*sync.RWMutex)
 var mutexMapLock = &sync.Mutex{}
 var rollbackMutexLock = &sync.Mutex{}
 var createDirMutexLock = &sync.Mutex{}
 
 func init() {
-	schema.Install("local_with_embeded_etcd", NewSchemaDAO)
-	schema.Install("local_with_embedded_etcd", NewSchemaDAO)
+	schema.Install("local", NewSchemaDAO)
 }
 
-func NewSchemaDAO(opts schema.Options) (schema.DAO, error) {
+func NewSchemaDAO(_ schema.Options) (schema.DAO, error) {
 	return &SchemaDAO{}, nil
 }
 
-func GetOrCreateMutex(path string) *sync.Mutex {
+func GetOrCreateMutex(path string) *sync.RWMutex {
 	mutexMapLock.Lock()
 	mutex, ok := MutexMap[path]
 	if !ok {
-		mutex = &sync.Mutex{}
+		mutex = &sync.RWMutex{}
 		MutexMap[path] = mutex
 	}
 	mutexMapLock.Unlock()
@@ -244,8 +244,8 @@ func CleanDir(dir string) error {
 
 func ReadFile(filepath string) ([]byte, error) {
 	mutex := GetOrCreateMutex(filepath)
-	mutex.Lock()
-	defer mutex.Unlock()
+	mutex.RLock()
+	defer mutex.RUnlock()
 
 	// check the file is empty
 	content, err := os.ReadFile(filepath)
@@ -355,6 +355,9 @@ func (s *SchemaDAO) ListRef(ctx context.Context, refRequest *schema.RefRequest)
 	schemaIDs, contents, err := ReadAllFiles(dir)
 
 	if err != nil {
+		if os.IsNotExist(err) {
+			return make([]*schema.Ref, 0), nil
+		}
 		log.Error(fmt.Sprintf("read service[%s] schema content files failed ", serviceID), err)
 		return nil, err
 	}
@@ -432,7 +435,7 @@ func (s *SchemaDAO) DeleteRef(ctx context.Context, refRequest *schema.RefRequest
 	return nil
 }
 
-func (s *SchemaDAO) GetContent(ctx context.Context, contentRequest *schema.ContentRequest) (*schema.Content, error) {
+func (s *SchemaDAO) GetContent(_ context.Context, _ *schema.ContentRequest) (*schema.Content, error) {
 	// no usage, should not be called
 	log.Error("Occur error when call SchemaDAO.GetContent, this method should not be called in any condition", schema.ErrSchemaNotFound)
 	return nil, schema.ErrSchemaNotFound
@@ -476,13 +479,13 @@ func (s *SchemaDAO) PutContent(ctx context.Context, contentRequest *schema.PutCo
 		return err
 	}
 
-	var schemaIdValid = false
-	for _, serviceSchemaId := range service.Schemas {
-		if serviceSchemaId == contentRequest.SchemaID {
-			schemaIdValid = true
+	var schemaIDValid = false
+	for _, serviceSchemaID := range service.Schemas {
+		if serviceSchemaID == contentRequest.SchemaID {
+			schemaIDValid = true
 		}
 	}
-	if !schemaIdValid {
+	if !schemaIDValid {
 		err = schema.ErrSchemaNotFound
 		log.Error(fmt.Sprintf("update service[%s] failed when valide schema id", serviceID), err)
 		return err
@@ -570,7 +573,7 @@ func (s *SchemaDAO) PutManyContent(ctx context.Context, contentRequest *schema.P
 
 	// create or update files
 	for i := 0; i < len(contentRequest.SchemaIDs); i++ {
-		schemaId := contentRequest.SchemaIDs[i]
+		schemaID := contentRequest.SchemaIDs[i]
 		schema := contentRequest.Contents[i]
 
 		schemaBytes, marshalErr := json.Marshal(schema)
@@ -579,7 +582,7 @@ func (s *SchemaDAO) PutManyContent(ctx context.Context, contentRequest *schema.P
 			openlog.Error("fail to marshal kv " + err.Error())
 			return err
 		}
-		err = createOrUpdateFile(servicepath+"/"+schemaId+".json", schemaBytes, &rollbackOperations, false)
+		err = createOrUpdateFile(servicepath+"/"+schemaID+".json", schemaBytes, &rollbackOperations, false)
 		if err != nil {
 			break
 		}
@@ -613,13 +616,13 @@ func (s *SchemaDAO) PutManyContent(ctx context.Context, contentRequest *schema.P
 	return err
 }
 
-func (s *SchemaDAO) DeleteContent(ctx context.Context, contentRequest *schema.ContentRequest) error {
+func (s *SchemaDAO) DeleteContent(_ context.Context, _ *schema.ContentRequest) error {
 	// no usage, should not be called
 	log.Error("Occur error when call SchemaDAO.DeleteContent, this method should not be called in any condition", schema.ErrSchemaContentNotFound)
 	return schema.ErrSchemaContentNotFound
 }
 
-func (s *SchemaDAO) DeleteNoRefContents(ctx context.Context) (int, error) {
+func (s *SchemaDAO) DeleteNoRefContents(_ context.Context) (int, error) {
 	// no usage, should not be called
 	log.Error("Occur error when call SchemaDAO.DeleteNoRefContents, this method should not be called in any condition", schema.ErrSchemaNotFound)
 	return 0, schema.ErrSchemaNotFound
diff --git a/datasource/mongo/account.go b/datasource/mongo/account.go
index bcf99911..92fe76cd 100644
--- a/datasource/mongo/account.go
+++ b/datasource/mongo/account.go
@@ -41,7 +41,7 @@ func init() {
 	rbac.Install("mongo", NewRbacDAO)
 }
 
-func NewRbacDAO(opts rbac.Options) (rbac.DAO, error) {
+func NewRbacDAO(_ rbac.Options) (rbac.DAO, error) {
 	return &RbacDAO{}, nil
 }
 
diff --git a/datasource/mongo/dep.go b/datasource/mongo/dep.go
index bee0c50e..9b2988c1 100644
--- a/datasource/mongo/dep.go
+++ b/datasource/mongo/dep.go
@@ -161,7 +161,7 @@ func updateDepTxn(ctx context.Context, dependencyInfos []*discovery.ConsumerDepe
 	})
 }
 
-func (ds *DepManager) DependencyHandle(ctx context.Context) (err error) {
+func (ds *DepManager) DependencyHandle(_ context.Context) (err error) {
 	return nil
 }
 
@@ -326,10 +326,9 @@ func removeProviderDeps(ctx context.Context, depRule *model.DependencyRule, cach
 	if !ok {
 		_, exist, err = FindServiceIds(ctx, depRule.ServiceKey, false)
 		if err != nil {
+			cache[id] = exist
 			return err
 		}
-
-		cache[id] = exist
 	}
 
 	filter := bson.M{
diff --git a/datasource/mongo/dependency_query.go b/datasource/mongo/dependency_query.go
index 4ea1fab8..4d5ba627 100644
--- a/datasource/mongo/dependency_query.go
+++ b/datasource/mongo/dependency_query.go
@@ -325,7 +325,7 @@ func findServiceKeysByAlias(ctx context.Context, key *discovery.MicroServiceKey,
 
 type ServiceVersionFilter func(ctx context.Context, filter bson.D) ([]string, error)
 
-func findServiceKeys(ctx context.Context, version string, filter bson.D) (newFilter bson.D) {
+func findServiceKeys(_ context.Context, version string, filter bson.D) (newFilter bson.D) {
 	filter = append(filter, bson.E{Key: util.ConnectWithDot([]string{model.ColumnService, model.ColumnVersion}), Value: version})
 	return filter
 }
diff --git a/datasource/mongo/engine.go b/datasource/mongo/engine.go
index 7be13da9..f50cc5c1 100644
--- a/datasource/mongo/engine.go
+++ b/datasource/mongo/engine.go
@@ -26,10 +26,10 @@ import (
 type SCManager struct {
 }
 
-func (ds *SCManager) UpgradeVersion(ctx context.Context) error {
+func (ds *SCManager) UpgradeVersion(_ context.Context) error {
 	return nil
 }
 
-func (ds *SCManager) GetClusters(ctx context.Context) (etcdadpt.Clusters, error) {
+func (ds *SCManager) GetClusters(_ context.Context) (etcdadpt.Clusters, error) {
 	return nil, nil
 }
diff --git a/datasource/mongo/heartbeat/cache/heartbeatcache.go b/datasource/mongo/heartbeat/cache/heartbeatcache.go
index 1052cc09..2b6326a8 100644
--- a/datasource/mongo/heartbeat/cache/heartbeatcache.go
+++ b/datasource/mongo/heartbeat/cache/heartbeatcache.go
@@ -58,7 +58,7 @@ func (h *HeartBeatCache) Heartbeat(ctx context.Context, request *pb.HeartbeatReq
 }
 
 // CheckInstance func is to add instance related information to the cache
-func (h *HeartBeatCache) CheckInstance(ctx context.Context, instance *pb.MicroServiceInstance) error {
+func (h *HeartBeatCache) CheckInstance(_ context.Context, instance *pb.MicroServiceInstance) error {
 	return h.Cfg.AddHeartbeatTask(instance.ServiceId, instance.InstanceId, instance.HealthCheck.Interval*(instance.HealthCheck.Times+1))
 }
 
diff --git a/datasource/mongo/heartbeat/checker/heartbeatchecker.go b/datasource/mongo/heartbeat/checker/heartbeatchecker.go
index 33774ddd..f9fa55c1 100644
--- a/datasource/mongo/heartbeat/checker/heartbeatchecker.go
+++ b/datasource/mongo/heartbeat/checker/heartbeatchecker.go
@@ -55,7 +55,7 @@ func (h *HeartBeatChecker) Heartbeat(ctx context.Context, request *pb.HeartbeatR
 	}, nil
 }
 
-func (h *HeartBeatChecker) CheckInstance(ctx context.Context, instance *pb.MicroServiceInstance) error {
+func (h *HeartBeatChecker) CheckInstance(_ context.Context, _ *pb.MicroServiceInstance) error {
 	// do nothing
 	return nil
 }
diff --git a/datasource/mongo/ms.go b/datasource/mongo/ms.go
index 78451de8..23448454 100644
--- a/datasource/mongo/ms.go
+++ b/datasource/mongo/ms.go
@@ -139,7 +139,7 @@ func createServiceTxn(ctx context.Context, request *discovery.CreateServiceReque
 	})
 }
 
-func (ds *MetadataManager) ListService(ctx context.Context, request *discovery.GetServicesRequest) (*discovery.GetServicesResponse, error) {
+func (ds *MetadataManager) ListService(ctx context.Context, _ *discovery.GetServicesRequest) (*discovery.GetServicesResponse, error) {
 	services, err := GetAllMicroServicesByDomainProject(ctx)
 	if err != nil {
 		return nil, discovery.NewError(discovery.ErrInternal, "get services data failed.")
@@ -391,7 +391,7 @@ func updateServiceTxn(ctx context.Context, request *discovery.UpdateServiceProps
 	})
 }
 
-func (ds *MetadataManager) GetOverview(ctx context.Context, request *discovery.GetServicesRequest) (
+func (ds *MetadataManager) GetOverview(ctx context.Context, _ *discovery.GetServicesRequest) (
 	*discovery.Statistics, error) {
 	ctx = util.WithCacheOnly(ctx)
 	st, err := statistics(ctx, false)
@@ -1070,7 +1070,7 @@ func (ds *MetadataManager) ListInstance(ctx context.Context, request *discovery.
 	}, nil
 }
 
-func (ds *MetadataManager) ListManyInstances(ctx context.Context, request *discovery.GetAllInstancesRequest) (*discovery.GetAllInstancesResponse, error) {
+func (ds *MetadataManager) ListManyInstances(ctx context.Context, _ *discovery.GetAllInstancesRequest) (*discovery.GetAllInstancesResponse, error) {
 	findRes, err := GetInstances(ctx)
 	if err != nil {
 		return nil, err
@@ -1241,10 +1241,9 @@ func (ds *MetadataManager) SendManyHeartbeat(ctx context.Context, request *disco
 			log.Warn(fmt.Sprintf("instance[%s/%s] is duplicate request heartbeat set",
 				heartbeatElement.ServiceId, heartbeatElement.InstanceId))
 			continue
-		} else {
-			existFlag[heartbeatElement.ServiceId+heartbeatElement.InstanceId] = true
-			noMultiCounter++
 		}
+		existFlag[heartbeatElement.ServiceId+heartbeatElement.InstanceId] = true
+		noMultiCounter++
 		gopool.Go(getHeartbeatFunc(ctx, domainProject, instancesHbRst, heartbeatElement))
 	}
 
@@ -1511,7 +1510,7 @@ func KeepAliveLease(ctx context.Context, request *discovery.HeartbeatRequest) er
 	return nil
 }
 
-func getHeartbeatFunc(ctx context.Context, domainProject string, instancesHbRst chan<- *discovery.InstanceHbRst, element *discovery.HeartbeatSetElement) func(context.Context) {
+func getHeartbeatFunc(ctx context.Context, _ string, instancesHbRst chan<- *discovery.InstanceHbRst, element *discovery.HeartbeatSetElement) func(context.Context) {
 	return func(_ context.Context) {
 		hbRst := &discovery.InstanceHbRst{
 			ServiceId:  element.ServiceId,
@@ -1646,7 +1645,7 @@ func allowAcrossDimension(ctx context.Context, providerService *model.Service, c
 	return nil
 }
 
-func DeleteDependencyForDeleteService(domainProject string, serviceID string, service *discovery.MicroServiceKey) error {
+func DeleteDependencyForDeleteService(domainProject string, _ string, service *discovery.MicroServiceKey) error {
 	conDep := new(discovery.ConsumerDependency)
 	conDep.Consumer = service
 	conDep.Providers = []*discovery.MicroServiceKey{}
@@ -1678,6 +1677,6 @@ func (ds *MetadataManager) Statistics(ctx context.Context, withShared bool) (*di
 	return statistics(ctx, withShared)
 }
 
-func (ds *MetadataManager) UpdateManyInstanceStatus(ctx context.Context, match *datasource.MatchPolicy, status string) error {
+func (ds *MetadataManager) UpdateManyInstanceStatus(_ context.Context, _ *datasource.MatchPolicy, _ string) error {
 	return nil
 }
diff --git a/datasource/mongo/retire.go b/datasource/mongo/retire.go
index 88e76e42..0ba8a8bd 100644
--- a/datasource/mongo/retire.go
+++ b/datasource/mongo/retire.go
@@ -23,6 +23,6 @@ import (
 	"github.com/apache/servicecomb-service-center/datasource"
 )
 
-func (ds *MetadataManager) RetireService(ctx context.Context, plan *datasource.RetirePlan) error {
+func (ds *MetadataManager) RetireService(_ context.Context, _ *datasource.RetirePlan) error {
 	return nil
 }
diff --git a/datasource/mongo/role.go b/datasource/mongo/role.go
index 022696f7..0551d6a3 100644
--- a/datasource/mongo/role.go
+++ b/datasource/mongo/role.go
@@ -166,6 +166,6 @@ func updateRoleTxn(ctx context.Context, filter bson.M, updateFilter bson.M, role
 	})
 }
 
-func (ds *RbacDAO) MigrateOldRoles(ctx context.Context) error {
+func (ds *RbacDAO) MigrateOldRoles(_ context.Context) error {
 	return nil
 }
diff --git a/datasource/mongo/schema.go b/datasource/mongo/schema.go
index e846c757..1202baee 100644
--- a/datasource/mongo/schema.go
+++ b/datasource/mongo/schema.go
@@ -30,25 +30,25 @@ func init() {
 	schema.Install("mongo", NewSchemaDAO)
 }
 
-func NewSchemaDAO(opts schema.Options) (schema.DAO, error) {
+func NewSchemaDAO(_ schema.Options) (schema.DAO, error) {
 	return &SchemaDAO{}, nil
 }
 
 type SchemaDAO struct{}
 
-func (s *SchemaDAO) GetRef(ctx context.Context, refRequest *schema.RefRequest) (*schema.Ref, error) {
+func (s *SchemaDAO) GetRef(_ context.Context, _ *schema.RefRequest) (*schema.Ref, error) {
 	return nil, schema.ErrSchemaNotFound
 }
 
-func (s *SchemaDAO) ListRef(ctx context.Context, refRequest *schema.RefRequest) ([]*schema.Ref, error) {
+func (s *SchemaDAO) ListRef(_ context.Context, _ *schema.RefRequest) ([]*schema.Ref, error) {
 	return nil, nil
 }
 
-func (s *SchemaDAO) DeleteRef(ctx context.Context, refRequest *schema.RefRequest) error {
+func (s *SchemaDAO) DeleteRef(_ context.Context, _ *schema.RefRequest) error {
 	return schema.ErrSchemaNotFound
 }
 
-func (s *SchemaDAO) GetContent(ctx context.Context, contentRequest *schema.ContentRequest) (*schema.Content, error) {
+func (s *SchemaDAO) GetContent(_ context.Context, _ *schema.ContentRequest) (*schema.Content, error) {
 	return nil, schema.ErrSchemaNotFound
 }
 
@@ -85,10 +85,10 @@ func (s *SchemaDAO) PutManyContent(ctx context.Context, contentRequest *schema.P
 	return nil
 }
 
-func (s *SchemaDAO) DeleteContent(ctx context.Context, contentRequest *schema.ContentRequest) error {
+func (s *SchemaDAO) DeleteContent(_ context.Context, _ *schema.ContentRequest) error {
 	return schema.ErrSchemaContentNotFound
 }
 
-func (s *SchemaDAO) DeleteNoRefContents(ctx context.Context) (int, error) {
+func (s *SchemaDAO) DeleteNoRefContents(_ context.Context) (int, error) {
 	return 0, nil
 }
diff --git a/datasource/schema/init.go b/datasource/schema/init.go
index 77934ab2..c9364009 100644
--- a/datasource/schema/init.go
+++ b/datasource/schema/init.go
@@ -19,9 +19,10 @@ package schema
 
 import (
 	"fmt"
+	"strings"
+
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/server/config"
-	"strings"
 )
 
 var StorageType = ""
@@ -46,10 +47,11 @@ func Init(opts Options) error {
 		return nil
 	}
 	kind := opts.Kind
-	if strings.Trim(config.GetRegistry().SchemaRootPath, " ") != "" {
-		kind = "local_with_embeded_etcd"
+	rootFilePath := config.GetString("schema.root.path", "", config.WithStandby("schemaRootPath"))
+	if strings.Trim(rootFilePath, " ") != "" {
+		kind = "local"
 		StorageType = "local"
-		RootFilePath = config.GetRegistry().SchemaRootPath
+		RootFilePath = rootFilePath
 	}
 
 	engineFunc, ok := plugins[kind]
diff --git a/frontend/schema/schemahandler.go b/frontend/schema/schemahandler.go
index 380973de..8ff5c373 100644
--- a/frontend/schema/schemahandler.go
+++ b/frontend/schema/schemahandler.go
@@ -93,10 +93,8 @@ func (m *Mux) SchemaHandleFunc(c echo.Context) (err error) {
 		for _, val := range values {
 			if key == "Accept-Encoding" || key == "Connection" || key == "X-Schemaname" || key == "Cookie" || key == "User-Agent" || key == "AppleWebKit" || key == "Dnt" || key == "Referer" || key == "Accept-Language" {
 				continue
-			} else {
-				req.Header.Add(key, val)
 			}
-
+			req.Header.Add(key, val)
 		}
 	}
 	req.Header.Add("Content-Type", "application/json")
diff --git a/pkg/chain/invocation.go b/pkg/chain/invocation.go
index 0dab7e12..36fbb5f7 100644
--- a/pkg/chain/invocation.go
+++ b/pkg/chain/invocation.go
@@ -19,11 +19,9 @@ package chain
 
 import (
 	"context"
-	"fmt"
 
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
-	"github.com/go-chassis/cari/discovery"
 )
 
 type InvocationOption func(op InvocationOp) InvocationOp
@@ -121,7 +119,7 @@ func (i *Invocation) Invoke(last CallbackFunc) {
 		// this recover only catch the exceptions raised in sync invocations.
 		// The async invocations will be catch by gopool pkg then it never
 		// change the callback results.
-		i.Fail(discovery.NewError(discovery.ErrInternal, fmt.Sprintf("%v", itf)))
+		// i.Fail(discovery.NewError(discovery.ErrInternal, fmt.Sprintf("%v", itf)))
 	}()
 	i.Func = last
 	i.chain.Next(i)
diff --git a/pkg/event/bus.go b/pkg/event/bus.go
index 4e7fe777..8decbc71 100644
--- a/pkg/event/bus.go
+++ b/pkg/event/bus.go
@@ -41,7 +41,7 @@ func (bus *Bus) Fire(evt Event) {
 	bus.Add(queue.Task{Payload: evt})
 }
 
-func (bus *Bus) Handle(ctx context.Context, payload interface{}) {
+func (bus *Bus) Handle(_ context.Context, payload interface{}) {
 	bus.fireAtOnce(payload.(Event))
 }
 
diff --git a/pkg/event/subscriber.go b/pkg/event/subscriber.go
index df771dda..96c960f2 100644
--- a/pkg/event/subscriber.go
+++ b/pkg/event/subscriber.go
@@ -62,7 +62,7 @@ func (s *baseSubscriber) Err() error             { return s.err }
 func (s *baseSubscriber) SetError(err error)     { s.err = err }
 func (s *baseSubscriber) Close()                 {}
 func (s *baseSubscriber) OnAccept()              {}
-func (s *baseSubscriber) OnMessage(job Event) {
+func (s *baseSubscriber) OnMessage(_ Event) {
 	s.SetError(errors.New("do not call base notifier OnMessage method"))
 }
 
diff --git a/pkg/log/zap_logger.go b/pkg/log/zap_logger.go
index 108e2106..fbb816c1 100644
--- a/pkg/log/zap_logger.go
+++ b/pkg/log/zap_logger.go
@@ -114,15 +114,15 @@ type ZapLogger struct {
 	zapSugar  *zap.SugaredLogger
 }
 
-func (l *ZapLogger) Debug(msg string, opts ...openlog.Option) {
+func (l *ZapLogger) Debug(msg string, _ ...openlog.Option) {
 	l.zapLogger.Debug(msg)
 }
 
-func (l *ZapLogger) Info(msg string, opts ...openlog.Option) {
+func (l *ZapLogger) Info(msg string, _ ...openlog.Option) {
 	l.zapLogger.Info(msg)
 }
 
-func (l *ZapLogger) Warn(msg string, opts ...openlog.Option) {
+func (l *ZapLogger) Warn(msg string, _ ...openlog.Option) {
 	l.zapLogger.Warn(msg)
 }
 
diff --git a/pkg/queue/uniqueue.go b/pkg/queue/uniqueue.go
index d6e9c41f..174c087e 100644
--- a/pkg/queue/uniqueue.go
+++ b/pkg/queue/uniqueue.go
@@ -45,8 +45,6 @@ func (uq *UniQueue) Put(value interface{}) (e error) {
 	defer func() {
 		if r := recover(); r != nil {
 			log.Panic(r)
-
-			e = fmt.Errorf("%v", r)
 		}
 	}()
 
diff --git a/scctl/pkg/plugin/diagnose/diagnose.go b/scctl/pkg/plugin/diagnose/diagnose.go
index bc2abc90..ecbe80de 100644
--- a/scctl/pkg/plugin/diagnose/diagnose.go
+++ b/scctl/pkg/plugin/diagnose/diagnose.go
@@ -49,7 +49,7 @@ var typeMap = map[string]string{
 
 type etcdResponse map[string][]*mvccpb.KeyValue
 
-func CommandFunc(_ *cobra.Command, args []string) {
+func CommandFunc(_ *cobra.Command, _ []string) {
 	// initialize sc/etcd clients
 	scClient, err := client.NewSCClient(cmd.ScClientConfig)
 	if err != nil {
diff --git a/scctl/pkg/plugin/get/cluster/cluster_cmd.go b/scctl/pkg/plugin/get/cluster/cluster_cmd.go
index 0ac1a356..971e8b3e 100644
--- a/scctl/pkg/plugin/get/cluster/cluster_cmd.go
+++ b/scctl/pkg/plugin/get/cluster/cluster_cmd.go
@@ -42,7 +42,7 @@ func NewClusterCommand(parent *cobra.Command) *cobra.Command {
 	return cmd
 }
 
-func CommandFunc(_ *cobra.Command, args []string) {
+func CommandFunc(_ *cobra.Command, _ []string) {
 	scClient, err := client.NewSCClient(cmd.ScClientConfig)
 	if err != nil {
 		cmd.StopAndExit(cmd.ExitError, err)
diff --git a/scctl/pkg/plugin/get/cluster/printer.go b/scctl/pkg/plugin/get/cluster/printer.go
index d1f133a9..165b97f5 100644
--- a/scctl/pkg/plugin/get/cluster/printer.go
+++ b/scctl/pkg/plugin/get/cluster/printer.go
@@ -35,7 +35,7 @@ func (s *Record) EndpointsString() string {
 	return util.StringJoin(s.Endpoints, "\n")
 }
 
-func (s *Record) PrintBody(fmt string) []string {
+func (s *Record) PrintBody(_ string) []string {
 	return []string{s.Name, s.EndpointsString()}
 }
 
diff --git a/scctl/pkg/plugin/get/instance/instance_cmd.go b/scctl/pkg/plugin/get/instance/instance_cmd.go
index ce2a88a7..e7e1ec11 100644
--- a/scctl/pkg/plugin/get/instance/instance_cmd.go
+++ b/scctl/pkg/plugin/get/instance/instance_cmd.go
@@ -46,7 +46,7 @@ func NewInstanceCommand(parent *cobra.Command) *cobra.Command {
 	return cmd
 }
 
-func CommandFunc(_ *cobra.Command, args []string) {
+func CommandFunc(_ *cobra.Command, _ []string) {
 	scClient, err := client.NewSCClient(cmd.ScClientConfig)
 	if err != nil {
 		cmd.StopAndExit(cmd.ExitError, err)
diff --git a/scctl/pkg/plugin/get/schema/schema_cmd.go b/scctl/pkg/plugin/get/schema/schema_cmd.go
index 85cd7705..decf4790 100644
--- a/scctl/pkg/plugin/get/schema/schema_cmd.go
+++ b/scctl/pkg/plugin/get/schema/schema_cmd.go
@@ -82,7 +82,7 @@ func saveDirectory(root string, ms *dump.Microservice) string {
 	return filepath.Join(root, "schemas", domain, project, ms.Value.Environment, ms.Value.AppId, ms.Value.ServiceName+".v"+ms.Value.Version)
 }
 
-func CommandFunc(_ *cobra.Command, args []string) {
+func CommandFunc(_ *cobra.Command, _ []string) {
 	scClient, err := client.NewSCClient(cmd.ScClientConfig)
 	if err != nil {
 		cmd.StopAndExit(cmd.ExitError, err)
diff --git a/scctl/pkg/plugin/get/service/service_cmd.go b/scctl/pkg/plugin/get/service/service_cmd.go
index f3ab41b0..9d68a199 100644
--- a/scctl/pkg/plugin/get/service/service_cmd.go
+++ b/scctl/pkg/plugin/get/service/service_cmd.go
@@ -47,7 +47,7 @@ func NewServiceCommand(parent *cobra.Command) *cobra.Command {
 	return cmd
 }
 
-func CommandFunc(_ *cobra.Command, args []string) {
+func CommandFunc(_ *cobra.Command, _ []string) {
 	scClient, err := client.NewSCClient(cmd.ScClientConfig)
 	if err != nil {
 		cmd.StopAndExit(cmd.ExitError, err)
diff --git a/scctl/pkg/plugin/health/cmd.go b/scctl/pkg/plugin/health/cmd.go
index 4513c842..c62c9dd3 100644
--- a/scctl/pkg/plugin/health/cmd.go
+++ b/scctl/pkg/plugin/health/cmd.go
@@ -47,7 +47,7 @@ func NewHealthCommand(parent *cobra.Command) *cobra.Command {
 	return cmd
 }
 
-func CommandFunc(_ *cobra.Command, args []string) {
+func CommandFunc(_ *cobra.Command, _ []string) {
 	scClient, err := client.NewSCClient(cmd.ScClientConfig)
 	if err != nil {
 		cmd.StopAndExit(ExistInternal, err)
diff --git a/scripts/ut_test_in_docker.sh b/scripts/ut_test_in_docker.sh
index 946305c1..9e76d121 100644
--- a/scripts/ut_test_in_docker.sh
+++ b/scripts/ut_test_in_docker.sh
@@ -43,6 +43,14 @@ elif [ ${db_name} == "mongo" ];then
     sleep 1
   done
   echo "${green}mongodb is running......${reset}"
+elif [ ${db_name} == "local" ];then
+  echo "${green}Starting etcd in docker${reset}"
+  docker run -d -v /usr/share/ca-certificates/:/etc/ssl/certs -p 40010:40010 -p 23800:23800 -p 2379:2379 --name etcd quay.io/coreos/etcd etcd -name etcd0 -advertise-client-urls http://127.0.0.1:2379,http://127.0.0.1:40010 -listen-client-urls http://0.0.0.0:2379,http://0.0.0.0:40010 -initial-advertise-peer-urls http://127.0.0.1:23800 -listen-peer-urls http://0.0.0.0:23800 -initial-cluster-token etcd-cluster-1 -initial-cluster etcd0=http://127.0.0.1:23800 -initial-cluster-state new
+  while ! nc -z 127.0.0.1 2379; do
+    echo "Waiting Etcd to launch on 2379..."
+    sleep 1
+  done
+  echo "${green}Etcd is running......${reset}"
 else
   echo "${db_name} non-existent"
 	exit 1
@@ -57,6 +65,9 @@ if [ ${db_name} == "etcd" ];then
 elif [ ${db_name} == "mongo" ];then
   export TEST_MODE=mongo
   [ $? == 0 ] && ut_for_dir 'datasource/etcd\|datasource/schema'
+elif [ ${db_name} == "local" ];then
+  export TEST_MODE=local
+  [ $? == 0 ] && ut_for_dir 'datasource/etcd\|datasource/schema'
 else
   echo "${db_name} non-existent"
 	exit 1
diff --git a/server/interceptor/interceptors.go b/server/interceptor/interceptors.go
index 31eb4d1a..098eda3b 100644
--- a/server/interceptor/interceptors.go
+++ b/server/interceptor/interceptors.go
@@ -58,8 +58,6 @@ func InvokeInterceptors(w http.ResponseWriter, req *http.Request) (err error) {
 	defer func() {
 		if itf := recover(); itf != nil {
 			log.Panic(itf)
-			err = fmt.Errorf("%v", itf)
-			http.Error(w, err.Error(), http.StatusInternalServerError)
 		}
 	}()
 	for _, intc = range interceptors {
diff --git a/server/metrics/http.go b/server/metrics/http.go
index 8ffb0c00..fedaea91 100644
--- a/server/metrics/http.go
+++ b/server/metrics/http.go
@@ -67,7 +67,7 @@ var (
 		}, []string{"method", "instance", "api", "domain"})
 )
 
-func ReportRequestCompleted(w http.ResponseWriter, r *http.Request, start time.Time) {
+func ReportRequestCompleted(_ http.ResponseWriter, r *http.Request, start time.Time) {
 	instance := metrics.InstanceName()
 	elapsed := float64(time.Since(start).Nanoseconds()) / float64(time.Microsecond)
 	route, _ := r.Context().Value(rest.CtxMatchFunc).(string)
diff --git a/server/plugin/quota/buildin/buildin.go b/server/plugin/quota/buildin/buildin.go
index 4f8ccfc4..de20ce26 100644
--- a/server/plugin/quota/buildin/buildin.go
+++ b/server/plugin/quota/buildin/buildin.go
@@ -70,7 +70,7 @@ type Quota struct {
 	RoleQuota     int64
 }
 
-func (q *Quota) GetQuota(ctx context.Context, t quota.ResourceType) int64 {
+func (q *Quota) GetQuota(_ context.Context, t quota.ResourceType) int64 {
 	switch t {
 	case quotasvc.TypeInstance:
 		return q.InstanceQuota
diff --git a/server/resource/disco/schema_resource.go b/server/resource/disco/schema_resource.go
index 12905c5a..5494a421 100644
--- a/server/resource/disco/schema_resource.go
+++ b/server/resource/disco/schema_resource.go
@@ -56,7 +56,7 @@ func (s *SchemaResource) URLPatterns() []rest.Route {
 	return r
 }
 
-func (s *SchemaResource) DisableSchema(w http.ResponseWriter, r *http.Request) {
+func (s *SchemaResource) DisableSchema(w http.ResponseWriter, _ *http.Request) {
 	rest.WriteError(w, pb.ErrForbidden, errModifySchemaDisabled.Error())
 }
 
diff --git a/server/service/admin/admin.go b/server/service/admin/admin.go
index 0f25091d..6d061586 100644
--- a/server/service/admin/admin.go
+++ b/server/service/admin/admin.go
@@ -26,7 +26,7 @@ import (
 	"github.com/apache/servicecomb-service-center/server/alarm"
 )
 
-func Clusters(ctx context.Context, in *dump.ClustersRequest) (*dump.ClustersResponse, error) {
+func Clusters(ctx context.Context, _ *dump.ClustersRequest) (*dump.ClustersResponse, error) {
 	clusters, err := datasource.GetSCManager().GetClusters(ctx)
 	if err != nil {
 		return nil, err
@@ -36,13 +36,13 @@ func Clusters(ctx context.Context, in *dump.ClustersRequest) (*dump.ClustersResp
 	}, nil
 }
 
-func AlarmList(ctx context.Context, in *dump.AlarmListRequest) (*dump.AlarmListResponse, error) {
+func AlarmList(_ context.Context, _ *dump.AlarmListRequest) (*dump.AlarmListResponse, error) {
 	return &dump.AlarmListResponse{
 		Alarms: alarm.ListAll(),
 	}, nil
 }
 
-func ClearAlarm(ctx context.Context, in *dump.ClearAlarmRequest) (*dump.ClearAlarmResponse, error) {
+func ClearAlarm(_ context.Context, _ *dump.ClearAlarmRequest) (*dump.ClearAlarmResponse, error) {
 	alarm.ClearAll()
 	log.Info("service center alarms are cleared")
 	return &dump.ClearAlarmResponse{}, nil
diff --git a/server/service/disco/metadata.go b/server/service/disco/metadata.go
index fc2478b2..8ba736f8 100644
--- a/server/service/disco/metadata.go
+++ b/server/service/disco/metadata.go
@@ -202,10 +202,9 @@ func UnregisterManyService(ctx context.Context, request *pb.DelServicesRequest)
 		if _, ok := existFlag[serviceID]; ok {
 			log.Warn(fmt.Sprintf("duplicate micro-service[%s] serviceID", serviceID))
 			continue
-		} else {
-			existFlag[serviceID] = true
-			nuoMultiCount++
 		}
+		existFlag[serviceID] = true
+		nuoMultiCount++
 
 		//执行删除服务操作
 		gopool.Go(getDeleteServiceFunc(ctx, serviceID, request.Force, serviceRespChan))
diff --git a/server/service/disco/schema.go b/server/service/disco/schema.go
index 98d224b3..646a592c 100644
--- a/server/service/disco/schema.go
+++ b/server/service/disco/schema.go
@@ -235,7 +235,7 @@ func getOldSchemaIDs(ctx context.Context, serviceID string) ([]string, error) {
 	return schemaIDs, nil
 }
 
-func mergeRequests(ctx context.Context, serviceID string, refs []*schema.Ref, oldSchemaIDs []string) ([]*pb.GetSchemaRequest, error) {
+func mergeRequests(_ context.Context, serviceID string, refs []*schema.Ref, oldSchemaIDs []string) ([]*pb.GetSchemaRequest, error) {
 	set := mapset.NewSet()
 	for _, schemaID := range oldSchemaIDs {
 		set.Add(schemaID)
diff --git a/server/service/grc/kie/kie_distributor.go b/server/service/grc/kie/kie_distributor.go
index 79b149d6..2d43bbe7 100644
--- a/server/service/grc/kie/kie_distributor.go
+++ b/server/service/grc/kie/kie_distributor.go
@@ -259,7 +259,7 @@ func initClient(endpoint string) *kie.Client {
 	return client
 }
 
-func new(opts config.DistributorOptions) (grcsvc.ConfigDistributor, error) {
+func kieDistributorNew(opts config.DistributorOptions) (grcsvc.ConfigDistributor, error) {
 	return &Distributor{name: opts.Name, client: initClient(opts.Endpoint)}, nil
 }
 
@@ -355,5 +355,5 @@ func toGovKeyPrefix(kind string) string {
 }
 
 func init() {
-	grcsvc.InstallDistributor(grcsvc.ConfigDistributorKie, new)
+	grcsvc.InstallDistributor(grcsvc.ConfigDistributorKie, kieDistributorNew)
 }
diff --git a/server/service/grc/mock/mock.go b/server/service/grc/mock/mock.go
index 53f5582d..f1e68281 100644
--- a/server/service/grc/mock/mock.go
+++ b/server/service/grc/mock/mock.go
@@ -37,7 +37,7 @@ type Distributor struct {
 
 const MatchGroup = "match-group"
 
-func (d *Distributor) Create(ctx context.Context, kind, project string, p *gov.Policy) ([]byte, error) {
+func (d *Distributor) Create(_ context.Context, kind, _ string, p *gov.Policy) ([]byte, error) {
 	id, _ := uuid.NewV4()
 	p.ID = id.String()
 	p.Kind = kind
@@ -46,7 +46,7 @@ func (d *Distributor) Create(ctx context.Context, kind, project string, p *gov.P
 	return []byte(p.ID), nil
 }
 
-func (d *Distributor) Update(ctx context.Context, kind, id, project string, p *gov.Policy) error {
+func (d *Distributor) Update(_ context.Context, kind, id, _ string, p *gov.Policy) error {
 	if d.lbPolicies[id] == nil {
 		return fmt.Errorf("id not exsit")
 	}
@@ -57,12 +57,12 @@ func (d *Distributor) Update(ctx context.Context, kind, id, project string, p *g
 	return nil
 }
 
-func (d *Distributor) Delete(ctx context.Context, kind, id, project string) error {
+func (d *Distributor) Delete(_ context.Context, _, id, _ string) error {
 	delete(d.lbPolicies, id)
 	return nil
 }
 
-func (d *Distributor) Display(ctx context.Context, project, app, env string) ([]byte, error) {
+func (d *Distributor) Display(_ context.Context, _, app, env string) ([]byte, error) {
 	list := make([]*gov.Policy, 0)
 	for _, g := range d.lbPolicies {
 		if checkPolicy(g, MatchGroup, app, env) {
@@ -91,7 +91,7 @@ func (d *Distributor) Display(ctx context.Context, project, app, env string) ([]
 	b, _ := json.MarshalIndent(r, "", "  ")
 	return b, nil
 }
-func (d *Distributor) List(ctx context.Context, kind, project, app, env string) ([]byte, error) {
+func (d *Distributor) List(_ context.Context, kind, _, app, env string) ([]byte, error) {
 	r := make([]*gov.Policy, 0, len(d.lbPolicies))
 	for _, g := range d.lbPolicies {
 		if checkPolicy(g, kind, app, env) {
@@ -106,7 +106,7 @@ func checkPolicy(g *gov.Policy, kind, app, env string) bool {
 	return g.Kind == kind && g.Selector != nil && g.Selector["app"] == app && g.Selector["environment"] == env
 }
 
-func (d *Distributor) Get(ctx context.Context, kind, id, project string) ([]byte, error) {
+func (d *Distributor) Get(_ context.Context, _, id, _ string) ([]byte, error) {
 	r := d.lbPolicies[id]
 	if r == nil {
 		return nil, nil
@@ -121,9 +121,9 @@ func (d *Distributor) Type() string {
 func (d *Distributor) Name() string {
 	return d.name
 }
-func new(opts config.DistributorOptions) (grcsvc.ConfigDistributor, error) {
+func newMock(opts config.DistributorOptions) (grcsvc.ConfigDistributor, error) {
 	return &Distributor{name: opts.Name, lbPolicies: map[string]*gov.Policy{}}, nil
 }
 func init() {
-	grcsvc.InstallDistributor(grcsvc.ConfigDistributorMock, new)
+	grcsvc.InstallDistributor(grcsvc.ConfigDistributorMock, newMock)
 }
diff --git a/server/service/rbac/authr_plugin.go b/server/service/rbac/authr_plugin.go
index 4122ae23..18adb12c 100644
--- a/server/service/rbac/authr_plugin.go
+++ b/server/service/rbac/authr_plugin.go
@@ -36,7 +36,7 @@ import (
 type EmbeddedAuthenticator struct {
 }
 
-func newEmbeddedAuthenticator(opts *authr.Options) (authr.Authenticator, error) {
+func newEmbeddedAuthenticator(_ *authr.Options) (authr.Authenticator, error) {
 	return &EmbeddedAuthenticator{}, nil
 }
 
@@ -84,7 +84,7 @@ func (a *EmbeddedAuthenticator) Login(ctx context.Context, user string, password
 }
 
 // Authenticate parse a token to claims
-func (a *EmbeddedAuthenticator) Authenticate(ctx context.Context, tokenStr string) (interface{}, error) {
+func (a *EmbeddedAuthenticator) Authenticate(_ context.Context, tokenStr string) (interface{}, error) {
 	p, err := jwt.ParseRSAPublicKeyFromPEM([]byte(PublicKey()))
 	if err != nil {
 		log.Error("can not parse public key", err)
diff --git a/server/service/rbac/decision.go b/server/service/rbac/decision.go
index 4a825779..2ffb0036 100644
--- a/server/service/rbac/decision.go
+++ b/server/service/rbac/decision.go
@@ -28,7 +28,7 @@ import (
 )
 
 // Allow return: matched labels(empty if no label defined), error
-func Allow(ctx context.Context, project string, roleList []string,
+func Allow(ctx context.Context, _ string, roleList []string,
 	targetResource *auth.ResourceScope) ([]map[string]string, error) {
 	//TODO check project
 	allPerms, err := getPermsByRoles(ctx, roleList)
diff --git a/test/test.go b/test/test.go
index 5e2333e5..7683802c 100644
--- a/test/test.go
+++ b/test/test.go
@@ -49,6 +49,13 @@ func init() {
 		_ = archaius.Set("registry.kind", "etcd")
 		_ = archaius.Set("registry.etcd.cluster.name", "sc-0")
 		_ = archaius.Set("registry.etcd.cluster.endpoints", "sc-0="+uri+",sc-1=http://127.0.0.2:2379")
+	} else if IsLOCAL() {
+		_ = archaius.Set("registry.cache.mode", 0)
+		_ = archaius.Set("discovery.kind", "etcd")
+		_ = archaius.Set("registry.kind", "etcd")
+		_ = archaius.Set("registry.etcd.cluster.name", "sc-0")
+		_ = archaius.Set("registry.etcd.cluster.endpoints", "sc-0="+uri+",sc-1=http://127.0.0.2:2379")
+		_ = archaius.Set("schema.root.path", "/data/schemas")
 	} else {
 		_ = archaius.Set("registry.heartbeat.kind", "checker")
 		kind = "mongo"
@@ -81,3 +88,8 @@ func IsETCD() bool {
 	}
 	return t == "etcd"
 }
+
+func IsLOCAL() bool {
+	t := archaius.Get("TEST_MODE")
+	return t == "local"
+}