[ 
https://issues.apache.org/jira/browse/SCB-744?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16542987#comment-16542987
 ] 

ASF GitHub Bot commented on SCB-744:
------------------------------------

asifdxtreme closed pull request #390: SCB-744 Wrong error code returned in Find 
API
URL: https://github.com/apache/incubator-servicecomb-service-center/pull/390
 
 
   

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/pkg/chain/callback.go b/pkg/chain/callback.go
index 36577402..37e5ef59 100644
--- a/pkg/chain/callback.go
+++ b/pkg/chain/callback.go
@@ -18,8 +18,13 @@ package chain
 
 import (
        "github.com/apache/incubator-servicecomb-service-center/pkg/util"
+       "golang.org/x/net/context"
 )
 
+var pool = util.NewGo(context.Background())
+
+type CallbackFunc func(r Result)
+
 type Result struct {
        OK   bool
        Err  error
@@ -34,25 +39,27 @@ func (r Result) String() string {
 }
 
 type Callback struct {
-       Func  func(r Result)
+       Func  CallbackFunc
        Async bool
 }
 
 func (cb *Callback) Invoke(r Result) {
        if cb.Async {
-               go syncInvoke(cb.Func, r)
+               pool.Do(func(_ context.Context) {
+                       cb.syncInvoke(r)
+               })
                return
        }
-       syncInvoke(cb.Func, r)
+       cb.syncInvoke(r)
 }
 
-func syncInvoke(f func(r Result), r Result) {
+func (cb *Callback) syncInvoke(r Result) {
        defer util.RecoverAndReport()
-       if f == nil {
+       if cb.Func == nil {
                util.Logger().Errorf(nil, "Callback function is nil. result: 
%s,", r)
                return
        }
-       f(r)
+       cb.Func(r)
 }
 
 func (cb *Callback) Fail(err error, args ...interface{}) {
diff --git a/pkg/chain/chain_test.go b/pkg/chain/chain_test.go
index 4a4b2cbf..1bec1642 100644
--- a/pkg/chain/chain_test.go
+++ b/pkg/chain/chain_test.go
@@ -19,6 +19,7 @@ package chain_test
 import (
        "context"
        "github.com/apache/incubator-servicecomb-service-center/pkg/chain"
+       "github.com/apache/incubator-servicecomb-service-center/pkg/util"
        "testing"
 )
 
@@ -40,26 +41,46 @@ func (h *handler) Handle(i *chain.Invocation) {
        i.Next()
 }
 
-func syncFunc() {
-       for i := 0; i < count; i++ {
+func syncFunc(i int) {
+       if i >= count {
+               return
        }
+       syncFunc(i + 1)
+}
+
+func BenchmarkInvocationOption(b *testing.B) {
+       var (
+               op   chain.InvocationOp
+               f    = func(r chain.Result) {}
+               opts = []chain.InvocationOption{chain.WithFunc(f), 
chain.WithAsyncFunc(f)}
+       )
+       b.RunParallel(func(pb *testing.PB) {
+               for pb.Next() {
+                       for _, opt := range opts {
+                               op = opt(op)
+                       }
+               }
+       })
+       b.ReportAllocs()
+       // 50000000             26.8 ns/op             0 B/op          0 
allocs/op
 }
 
 func BenchmarkChain(b *testing.B) {
        var (
-               ctx = context.Background()
+               ctx = util.NewStringContext(context.Background())
                f   = func(r chain.Result) {}
        )
+
        b.N = times
        b.ResetTimer()
        b.RunParallel(func(pb *testing.PB) {
                for pb.Next() {
                        inv := chain.NewInvocation(ctx, 
chain.NewChain("_bench_chain_", chain.Handlers("_bench_handlers_")))
-                       inv.Next(chain.WithFunc(f))
+                       inv.Invoke(f)
                }
        })
        b.ReportAllocs()
-       // 1000000            5119 ns/op             176 B/op          3 
allocs/op
+       // 1000000            6607 ns/op              80 B/op          1 
allocs/op
 }
 
 func BenchmarkSync(b *testing.B) {
@@ -67,9 +88,9 @@ func BenchmarkSync(b *testing.B) {
        b.ResetTimer()
        b.RunParallel(func(pb *testing.PB) {
                for pb.Next() {
-                       syncFunc()
+                       syncFunc(0)
                }
        })
        b.ReportAllocs()
-       // 1000000              13.7 ns/op             0 B/op          0 
allocs/op
+       // 1000000              46.9 ns/op             0 B/op          0 
allocs/op
 }
diff --git a/pkg/chain/handler.go b/pkg/chain/handler.go
index f5a62ac1..372e8c7c 100644
--- a/pkg/chain/handler.go
+++ b/pkg/chain/handler.go
@@ -22,7 +22,7 @@ import (
 
 const CAP_SIZE = 10
 
-var handlersMap = make(map[string][]Handler, CAP_SIZE)
+var handlersMap = make(map[string][]Handler)
 
 type Handler interface {
        Handle(i *Invocation)
diff --git a/pkg/chain/invocation.go b/pkg/chain/invocation.go
index 0ab0df7b..5e5276cb 100644
--- a/pkg/chain/invocation.go
+++ b/pkg/chain/invocation.go
@@ -24,7 +24,7 @@ import (
 type InvocationOption func(op InvocationOp) InvocationOp
 
 type InvocationOp struct {
-       Func  func(r Result)
+       Func  CallbackFunc
        Async bool
 }
 
@@ -65,7 +65,7 @@ func (i *Invocation) Next(opts ...InvocationOption) {
        i.chain.Next(i)
 }
 
-func (i *Invocation) setCallback(f func(r Result), async bool) {
+func (i *Invocation) setCallback(f CallbackFunc, async bool) {
        if f == nil {
                return
        }
@@ -76,6 +76,10 @@ func (i *Invocation) setCallback(f func(r Result), async 
bool) {
                return
        }
 
+       // the callbacks seq like below
+       // i.Success() -> CB1 ---> CB3 ----------> END           goroutine 0
+       //                     \-> CB2(async) \                  goroutine 1
+       //                                     \-> CB4(async)    goroutine 1 or 
2
        cb := i.Func
        i.Func = func(r Result) {
                cb(r)
@@ -83,12 +87,12 @@ func (i *Invocation) setCallback(f func(r Result), async 
bool) {
        }
 }
 
-func callback(f func(r Result), async bool, r Result) {
+func callback(f CallbackFunc, async bool, r Result) {
        c := Callback{Func: f, Async: async}
        c.Invoke(r)
 }
 
-func (i *Invocation) Invoke(f func(r Result)) {
+func (i *Invocation) Invoke(f CallbackFunc) {
        i.Func = f
        i.chain.Next(i)
 }
diff --git a/pkg/rest/route.go b/pkg/rest/route.go
index f69c1f71..7e2088c2 100644
--- a/pkg/rest/route.go
+++ b/pkg/rest/route.go
@@ -111,45 +111,40 @@ func (this *ROAServerHandler) ServeHTTP(w 
http.ResponseWriter, r *http.Request)
 }
 
 func (this *ROAServerHandler) serve(ph *urlPatternHandler, w 
http.ResponseWriter, r *http.Request) {
-       hs := chain.Handlers(SERVER_CHAIN_NAME)
-       if len(hs) == 0 {
-               ph.ServeHTTP(w, r)
-               return
-       }
-
        ctx := util.NewStringContext(r.Context())
        if ctx != r.Context() {
                nr := r.WithContext(ctx)
                *r = *nr
        }
 
-       inv := chain.NewInvocation(ctx, chain.NewChain(SERVER_CHAIN_NAME, hs))
+       inv := chain.NewInvocation(ctx, chain.NewChain(SERVER_CHAIN_NAME, 
chain.Handlers(SERVER_CHAIN_NAME)))
        inv.WithContext(CTX_RESPONSE, w).
                WithContext(CTX_REQUEST, r).
                WithContext(CTX_MATCH_PATTERN, ph.Path).
-               WithContext(CTX_MATCH_FUNC, ph.Name)
-       inv.Next(chain.WithFunc(func(ret chain.Result) {
-               defer func() {
-                       err := ret.Err
-                       itf := recover()
-                       if itf != nil {
-                               util.LogPanic(itf)
-
-                               err = errorsEx.RaiseError(itf)
-                       }
-                       if _, ok := err.(errorsEx.InternalError); ok {
-                               http.Error(w, err.Error(), 
http.StatusInternalServerError)
-                               return
-                       }
-                       if err != nil {
-                               http.Error(w, err.Error(), 
http.StatusBadRequest)
-                               return
-                       }
-               }()
-               if ret.OK {
-                       ph.ServeHTTP(w, r)
-               }
-       }))
+               WithContext(CTX_MATCH_FUNC, ph.Name).
+               Invoke(
+                       func(ret chain.Result) {
+                               defer func() {
+                                       err := ret.Err
+                                       itf := recover()
+                                       if itf != nil {
+                                               util.LogPanic(itf)
+
+                                               err = errorsEx.RaiseError(itf)
+                                       }
+                                       if _, ok := 
err.(errorsEx.InternalError); ok {
+                                               http.Error(w, err.Error(), 
http.StatusInternalServerError)
+                                               return
+                                       }
+                                       if err != nil {
+                                               http.Error(w, err.Error(), 
http.StatusBadRequest)
+                                               return
+                                       }
+                               }()
+                               if ret.OK {
+                                       ph.ServeHTTP(w, r)
+                               }
+                       })
 }
 
 func (this *urlPatternHandler) try(path string) (p string, _ bool) {
@@ -210,8 +205,3 @@ func isDigit(ch byte) bool {
 func isAlnum(ch byte) bool {
        return isAlpha(ch) || isDigit(ch)
 }
-
-type Filter interface {
-       IsMatch(r *http.Request) bool
-       Do(r *http.Request) error
-}
diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go
index 596e9316..c50ae812 100644
--- a/pkg/util/util_test.go
+++ b/pkg/util/util_test.go
@@ -76,9 +76,7 @@ func TestFileLastName(t *testing.T) {
 
 func TestResetTimer(t *testing.T) {
        timer := time.NewTimer(time.Microsecond)
-       <-timer.C
        ResetTimer(timer, time.Microsecond)
-       <-timer.C
        ResetTimer(timer, time.Second)
        <-timer.C
 }
diff --git a/server/broker/controller.go b/server/broker/controller.go
index 24353d9f..05101f09 100644
--- a/server/broker/controller.go
+++ b/server/broker/controller.go
@@ -78,10 +78,11 @@ func (*BrokerController) PublishPact(w http.ResponseWriter, 
r *http.Request) {
                controller.WriteError(w, scerr.ErrInvalidParams, err.Error())
                return
        }
+       query := r.URL.Query()
        request := &PublishPactRequest{
-               ProviderId: r.URL.Query().Get(":providerId"),
-               ConsumerId: r.URL.Query().Get(":consumerId"),
-               Version:    r.URL.Query().Get(":number"),
+               ProviderId: query.Get(":providerId"),
+               ConsumerId: query.Get(":consumerId"),
+               Version:    query.Get(":number"),
                Pact:       message,
        }
        PactLogger.Infof("PublishPact: providerId = %s, consumerId = %s, 
version = %s\n",
@@ -113,10 +114,11 @@ func (*BrokerController) GetAllProviderPacts(w 
http.ResponseWriter, r *http.Requ
 }
 
 func (*BrokerController) GetPactsOfProvider(w http.ResponseWriter, r 
*http.Request) {
+       query := r.URL.Query()
        request := &GetProviderConsumerVersionPactRequest{
-               ProviderId: r.URL.Query().Get(":providerId"),
-               ConsumerId: r.URL.Query().Get(":consumerId"),
-               Version:    r.URL.Query().Get(":number"),
+               ProviderId: query.Get(":providerId"),
+               ConsumerId: query.Get(":consumerId"),
+               Version:    query.Get(":number"),
                BaseUrl: &BaseBrokerRequest{
                        HostAddress: r.Host,
                        Scheme:      getScheme(r),
@@ -152,9 +154,10 @@ func (*BrokerController) PublishVerificationResults(w 
http.ResponseWriter, r *ht
                controller.WriteError(w, scerr.ErrInvalidParams, err.Error())
                return
        }
-       request.ProviderId = r.URL.Query().Get(":providerId")
-       request.ConsumerId = r.URL.Query().Get(":consumerId")
-       i, err := strconv.ParseInt(r.URL.Query().Get(":sha"), 10, 32)
+       query := r.URL.Query()
+       request.ProviderId = query.Get(":providerId")
+       request.ConsumerId = query.Get(":consumerId")
+       i, err := strconv.ParseInt(query.Get(":sha"), 10, 32)
        if err != nil {
                PactLogger.Error("Invalid pactId", err)
                controller.WriteError(w, scerr.ErrInvalidParams, err.Error())
@@ -173,8 +176,9 @@ func (*BrokerController) PublishVerificationResults(w 
http.ResponseWriter, r *ht
 
 func (*BrokerController) RetrieveVerificationResults(w http.ResponseWriter, r 
*http.Request) {
        request := &RetrieveVerificationRequest{}
-       request.ConsumerId = r.URL.Query().Get(":consumerId")
-       request.ConsumerVersion = r.URL.Query().Get(":consumerVersion")
+       query := r.URL.Query()
+       request.ConsumerId = query.Get(":consumerId")
+       request.ConsumerVersion = query.Get(":consumerVersion")
        PactLogger.Infof("Retrieve verification results for: %s, %s\n",
                request.ConsumerId, request.ConsumerVersion)
        resp, _ := BrokerServiceAPI.RetrieveVerificationResults(r.Context(), 
request)
diff --git a/server/core/backend/cacher_kv.go b/server/core/backend/cacher_kv.go
index 6c6aa996..3d8a7939 100644
--- a/server/core/backend/cacher_kv.go
+++ b/server/core/backend/cacher_kv.go
@@ -410,8 +410,9 @@ func (c *KvCacher) doParse(src *mvccpb.KeyValue) (kv 
*KeyValue) {
        kv = new(KeyValue)
        if err := kv.From(c.Cfg.Parser, src); err != nil {
                util.Logger().Errorf(err, "parse %s value failed", 
util.BytesToStringWithNoCopy(src.Key))
+               return nil
        }
-       return kv
+       return
 }
 
 func (c *KvCacher) Cache() Cache {
diff --git a/server/core/backend/kv.go b/server/core/backend/kv.go
index 73f03936..f7b66881 100644
--- a/server/core/backend/kv.go
+++ b/server/core/backend/kv.go
@@ -28,13 +28,11 @@ type KeyValue struct {
        ModRevision    int64
 }
 
-func (kv *KeyValue) From(p *Parser, s *mvccpb.KeyValue) error {
+func (kv *KeyValue) From(p *Parser, s *mvccpb.KeyValue) (err error) {
        kv.Key = s.Key
        kv.Version = s.Version
        kv.CreateRevision = s.CreateRevision
        kv.ModRevision = s.ModRevision
-
-       v, err := p.Unmarshal(s.Value)
-       kv.Value = v
-       return err
+       kv.Value, err = p.Unmarshal(s.Value)
+       return
 }
diff --git a/server/core/backend/parser.go b/server/core/backend/parser.go
index 8873988d..dff9a2f4 100644
--- a/server/core/backend/parser.go
+++ b/server/core/backend/parser.go
@@ -73,8 +73,10 @@ type Parser struct {
 
 func (p *Parser) Unmarshal(src []byte) (interface{}, error) {
        v := p.c()
-       err := p.p(src, &v)
-       return v, err
+       if err := p.p(src, &v); err != nil {
+               return nil, err
+       }
+       return v, nil
 }
 
 var (
diff --git a/server/core/backend/parser_test.go 
b/server/core/backend/parser_test.go
index dc20af96..bf97d47c 100644
--- a/server/core/backend/parser_test.go
+++ b/server/core/backend/parser_test.go
@@ -38,6 +38,11 @@ func TestParseValueFunc(t *testing.T) {
                t.Fatalf("StringParser.Unmarshal failed, %s", v)
        }
 
+       r, err = ServiceParser.Unmarshal([]byte(`xxx`))
+       if err == nil || r != nil {
+               t.Fatalf("ServiceParser.Unmarshal failed")
+       }
+
        r, err = ServiceParser.Unmarshal([]byte(`{"serviceName": "abc"}`))
        if err != nil {
                t.Fatalf("ServiceParser.Unmarshal failed, %s", err.Error())
diff --git a/server/error/error.go b/server/error/error.go
index aca44a0f..163d67d7 100644
--- a/server/error/error.go
+++ b/server/error/error.go
@@ -24,10 +24,11 @@ import (
 var errors = map[int32]string{
        ErrInvalidParams: "Invalid parameter(s)",
 
-       ErrServiceAlreadyExists: "Micro-service already exists",
-       ErrServiceNotExists:     "Micro-service does not exist",
-       ErrDeployedInstance:     "Micro-service has deployed instance(s)",
-       ErrDependedOnConsumer:   "Consumer(s) depends on this micro-service",
+       ErrServiceAlreadyExists:    "Micro-service already exists",
+       ErrServiceNotExists:        "Micro-service does not exist",
+       ErrServiceVersionNotExists: "Micro-service version does not exist",
+       ErrDeployedInstance:        "Micro-service has deployed instance(s)",
+       ErrDependedOnConsumer:      "Consumer(s) depends on this micro-service",
 
        ErrUndefinedSchemaId:    "Undefined schema id",
        ErrModifySchemaNotAllow: "Not allowed to modify schema",
@@ -85,6 +86,8 @@ const (
 
        ErrEndpointAlreadyExists int32 = 400025
 
+       ErrServiceVersionNotExists int32 = 400026
+
        ErrNotEnoughQuota   int32 = 400100
        ErrUnavailableQuota int32 = 500101
 )
diff --git a/server/govern/controller_v4.go b/server/govern/controller_v4.go
index be40fee0..46583287 100644
--- a/server/govern/controller_v4.go
+++ b/server/govern/controller_v4.go
@@ -151,11 +151,12 @@ func (governService *GovernServiceControllerV4) 
GetServiceDetail(w http.Response
 func (governService *GovernServiceControllerV4) GetAllServicesInfo(w 
http.ResponseWriter, r *http.Request) {
        request := &pb.GetServicesInfoRequest{}
        ctx := r.Context()
-       optsStr := r.URL.Query().Get("options")
+       query := r.URL.Query()
+       optsStr := query.Get("options")
        request.Options = strings.Split(optsStr, ",")
-       request.AppId = r.URL.Query().Get("appId")
-       request.ServiceName = r.URL.Query().Get("serviceName")
-       countOnly := r.URL.Query().Get("countOnly")
+       request.AppId = query.Get("appId")
+       request.ServiceName = query.Get("serviceName")
+       countOnly := query.Get("countOnly")
        if countOnly != "0" && countOnly != "1" && strings.TrimSpace(countOnly) 
!= "" {
                controller.WriteError(w, scerr.ErrInvalidParams, "parameter 
countOnly must be 1 or 0")
                return
diff --git a/server/govern/service.go b/server/govern/service.go
index 139fe7bc..fbc19de7 100644
--- a/server/govern/service.go
+++ b/server/govern/service.go
@@ -41,7 +41,7 @@ type ServiceDetailOpt struct {
 }
 
 func (governService *GovernService) GetServicesInfo(ctx context.Context, in 
*pb.GetServicesInfoRequest) (*pb.GetServicesInfoResponse, error) {
-       util.SetContext(ctx, serviceUtil.CTX_CACHEONLY, "1")
+       ctx = util.SetContext(ctx, serviceUtil.CTX_CACHEONLY, "1")
 
        optionMap := make(map[string]struct{}, len(in.Options))
        for _, opt := range in.Options {
@@ -119,7 +119,7 @@ func (governService *GovernService) GetServicesInfo(ctx 
context.Context, in *pb.
 }
 
 func (governService *GovernService) GetServiceDetail(ctx context.Context, in 
*pb.GetServiceRequest) (*pb.GetServiceDetailResponse, error) {
-       util.SetContext(ctx, serviceUtil.CTX_CACHEONLY, "1")
+       ctx = util.SetContext(ctx, serviceUtil.CTX_CACHEONLY, "1")
 
        domainProject := util.ParseDomainProject(ctx)
        options := []string{"tags", "rules", "instances", "schemas", 
"dependencies"}
diff --git a/server/handler/cache/cache.go b/server/handler/cache/cache.go
index 6fdb69c5..3c473f71 100644
--- a/server/handler/cache/cache.go
+++ b/server/handler/cache/cache.go
@@ -30,21 +30,21 @@ func (l *CacheResponse) Handle(i *chain.Invocation) {
        defer i.Next()
 
        r := i.Context().Value(rest.CTX_REQUEST).(*http.Request)
+       query := r.URL.Query()
 
-       noCache := r.URL.Query().Get(serviceUtil.CTX_NOCACHE) == "1"
-       cacheOnly := r.URL.Query().Get(serviceUtil.CTX_CACHEONLY) == "1"
-       rev := r.URL.Query().Get("rev")
-
+       noCache := query.Get(serviceUtil.CTX_NOCACHE) == "1"
        if noCache {
                i.WithContext(serviceUtil.CTX_NOCACHE, "1")
                return
        }
 
+       cacheOnly := query.Get(serviceUtil.CTX_CACHEONLY) == "1"
        if cacheOnly {
                i.WithContext(serviceUtil.CTX_CACHEONLY, "1")
                return
        }
 
+       rev := query.Get("rev")
        if len(rev) > 0 {
                i.WithContext(serviceUtil.CTX_REQUEST_REVISION, rev)
                return
diff --git a/server/plugin/infra/quota/buildin/buildin.go 
b/server/plugin/infra/quota/buildin/buildin.go
index 6c90e756..f783725b 100644
--- a/server/plugin/infra/quota/buildin/buildin.go
+++ b/server/plugin/infra/quota/buildin/buildin.go
@@ -47,6 +47,9 @@ func init() {
 }
 
 func New() mgr.PluginInstance {
+       util.Logger().Infof("quota init, service: %d, instance: %d, schema: 
%d/service, tag: %d/service, rule: %d/service",
+               SERVICE_NUM_MAX_LIMIT, INSTANCE_NUM_MAX_LIMIT,
+               quota.DefaultSchemaQuota, quota.DefaultTagQuota, 
quota.DefaultRuleQuota)
        return &BuildInQuota{}
 }
 
@@ -93,15 +96,15 @@ func ResourceLimitHandler(ctx context.Context, res 
*quota.ApplyQuotaResource) *q
        switch res.QuotaType {
        case quota.RuleQuotaType:
                key = core.GenerateServiceRuleKey(domainProject, serviceId, "")
-               max = RULE_NUM_MAX_LIMIT_PER_SERVICE
+               max = int64(quota.DefaultRuleQuota)
                indexer = backend.Store().Rule()
        case quota.SchemaQuotaType:
                key = core.GenerateServiceSchemaKey(domainProject, serviceId, 
"")
-               max = SCHEMA_NUM_MAX_LIMIT_PER_SERVICE
+               max = int64(quota.DefaultSchemaQuota)
                indexer = backend.Store().Schema()
        case quota.TagQuotaType:
                applyNum := res.QuotaSize
-               max = TAG_NUM_MAX_LIMIT_PER_SERVICE
+               max = int64(quota.DefaultTagQuota)
                tags, err := serviceUtil.GetTagsUtils(ctx, domainProject, 
serviceId)
                if err != nil {
                        return quota.NewApplyQuotaResult(nil, 
scerr.NewError(scerr.ErrInternal, err.Error()))
diff --git a/server/plugin/infra/tracing/buildin/buildin.go 
b/server/plugin/infra/tracing/buildin/buildin.go
index 0150cee2..4c8bf157 100644
--- a/server/plugin/infra/tracing/buildin/buildin.go
+++ b/server/plugin/infra/tracing/buildin/buildin.go
@@ -74,7 +74,7 @@ func (zp *Zipkin) ServerBegin(operationName string, itf 
tracing.Request) tracing
                return nil
        }
 
-       util.SetContext(ctx, tracing.CTX_TRACE_SPAN, span)
+       ctx = util.SetContext(ctx, tracing.CTX_TRACE_SPAN, span)
        return span
 }
 
@@ -148,7 +148,7 @@ func (zp *Zipkin) ClientBegin(operationName string, itf 
tracing.Request) tracing
                }
                // inject context
                carrier.ForeachKey(func(key, val string) error {
-                       util.SetContext(ctx, key, val)
+                       ctx = util.SetContext(ctx, key, val)
                        return nil
                })
        default:
diff --git a/server/rest/controller/v4/dependency_controller.go 
b/server/rest/controller/v4/dependency_controller.go
index bafdd8b7..2d3b601d 100644
--- a/server/rest/controller/v4/dependency_controller.go
+++ b/server/rest/controller/v4/dependency_controller.go
@@ -80,10 +80,11 @@ func (this *DependencyService) 
CreateDependenciesForMicroServices(w http.Respons
 }
 
 func (this *DependencyService) GetConProDependencies(w http.ResponseWriter, r 
*http.Request) {
+       query := r.URL.Query()
        request := &pb.GetDependenciesRequest{
-               ServiceId:  r.URL.Query().Get(":consumerId"),
-               SameDomain: r.URL.Query().Get("sameDomain") == "1",
-               NoSelf:     r.URL.Query().Get("noSelf") == "1",
+               ServiceId:  query.Get(":consumerId"),
+               SameDomain: query.Get("sameDomain") == "1",
+               NoSelf:     query.Get("noSelf") == "1",
        }
        resp, _ := core.ServiceAPI.GetConsumerDependencies(r.Context(), request)
        respInternal := resp.Response
@@ -92,10 +93,11 @@ func (this *DependencyService) GetConProDependencies(w 
http.ResponseWriter, r *h
 }
 
 func (this *DependencyService) GetProConDependencies(w http.ResponseWriter, r 
*http.Request) {
+       query := r.URL.Query()
        request := &pb.GetDependenciesRequest{
-               ServiceId:  r.URL.Query().Get(":providerId"),
-               SameDomain: r.URL.Query().Get("sameDomain") == "1",
-               NoSelf:     r.URL.Query().Get("noSelf") == "1",
+               ServiceId:  query.Get(":providerId"),
+               SameDomain: query.Get("sameDomain") == "1",
+               NoSelf:     query.Get("noSelf") == "1",
        }
        resp, _ := core.ServiceAPI.GetProviderDependencies(r.Context(), request)
        respInternal := resp.Response
diff --git a/server/rest/controller/v4/instance_controller.go 
b/server/rest/controller/v4/instance_controller.go
index 87cfe30c..a0ff0535 100644
--- a/server/rest/controller/v4/instance_controller.go
+++ b/server/rest/controller/v4/instance_controller.go
@@ -75,9 +75,10 @@ func (this *MicroServiceInstanceService) RegisterInstance(w 
http.ResponseWriter,
 
 //TODO 什么样的服务允许更新服务心跳,只能是本服务才可以更新自己,如何屏蔽其他服务伪造的心跳更新?
 func (this *MicroServiceInstanceService) Heartbeat(w http.ResponseWriter, r 
*http.Request) {
+       query := r.URL.Query()
        request := &pb.HeartbeatRequest{
-               ServiceId:  r.URL.Query().Get(":serviceId"),
-               InstanceId: r.URL.Query().Get(":instanceId"),
+               ServiceId:  query.Get(":serviceId"),
+               InstanceId: query.Get(":instanceId"),
        }
        resp, _ := core.InstanceAPI.Heartbeat(r.Context(), request)
        controller.WriteResponse(w, resp.Response, nil)
@@ -111,9 +112,10 @@ func (this *MicroServiceInstanceService) HeartbeatSet(w 
http.ResponseWriter, r *
 }
 
 func (this *MicroServiceInstanceService) UnregisterInstance(w 
http.ResponseWriter, r *http.Request) {
+       query := r.URL.Query()
        request := &pb.UnregisterInstanceRequest{
-               ServiceId:  r.URL.Query().Get(":serviceId"),
-               InstanceId: r.URL.Query().Get(":instanceId"),
+               ServiceId:  query.Get(":serviceId"),
+               InstanceId: query.Get(":instanceId"),
        }
        resp, _ := core.InstanceAPI.Unregister(r.Context(), request)
        controller.WriteResponse(w, resp.Response, nil)
@@ -121,19 +123,20 @@ func (this *MicroServiceInstanceService) 
UnregisterInstance(w http.ResponseWrite
 
 func (this *MicroServiceInstanceService) FindInstances(w http.ResponseWriter, 
r *http.Request) {
        var ids []string
-       keys := r.URL.Query().Get("tags")
+       query := r.URL.Query()
+       keys := query.Get("tags")
        if len(keys) > 0 {
                ids = strings.Split(keys, ",")
        }
        request := &pb.FindInstancesRequest{
                ConsumerServiceId: r.Header.Get("X-ConsumerId"),
-               AppId:             r.URL.Query().Get("appId"),
-               ServiceName:       r.URL.Query().Get("serviceName"),
-               VersionRule:       r.URL.Query().Get("version"),
+               AppId:             query.Get("appId"),
+               ServiceName:       query.Get("serviceName"),
+               VersionRule:       query.Get("version"),
                Tags:              ids,
        }
 
-       util.SetTargetDomainProject(r.Context(), r.Header.Get("X-Domain-Name"), 
r.URL.Query().Get(":project"))
+       util.SetTargetDomainProject(r.Context(), r.Header.Get("X-Domain-Name"), 
query.Get(":project"))
 
        resp, _ := core.InstanceAPI.Find(r.Context(), request)
        respInternal := resp.Response
@@ -152,14 +155,15 @@ func (this *MicroServiceInstanceService) FindInstances(w 
http.ResponseWriter, r
 
 func (this *MicroServiceInstanceService) GetOneInstance(w http.ResponseWriter, 
r *http.Request) {
        var ids []string
-       keys := r.URL.Query().Get("tags")
+       query := r.URL.Query()
+       keys := query.Get("tags")
        if len(keys) > 0 {
                ids = strings.Split(keys, ",")
        }
        request := &pb.GetOneInstanceRequest{
                ConsumerServiceId:  r.Header.Get("X-ConsumerId"),
-               ProviderServiceId:  r.URL.Query().Get(":serviceId"),
-               ProviderInstanceId: r.URL.Query().Get(":instanceId"),
+               ProviderServiceId:  query.Get(":serviceId"),
+               ProviderInstanceId: query.Get(":instanceId"),
                Tags:               ids,
        }
        resp, _ := core.InstanceAPI.GetOneInstance(r.Context(), request)
@@ -170,13 +174,14 @@ func (this *MicroServiceInstanceService) GetOneInstance(w 
http.ResponseWriter, r
 
 func (this *MicroServiceInstanceService) GetInstances(w http.ResponseWriter, r 
*http.Request) {
        var ids []string
-       keys := r.URL.Query().Get("tags")
+       query := r.URL.Query()
+       keys := query.Get("tags")
        if len(keys) > 0 {
                ids = strings.Split(keys, ",")
        }
        request := &pb.GetInstancesRequest{
                ConsumerServiceId: r.Header.Get("X-ConsumerId"),
-               ProviderServiceId: r.URL.Query().Get(":serviceId"),
+               ProviderServiceId: query.Get(":serviceId"),
                Tags:              ids,
        }
        resp, _ := core.InstanceAPI.GetInstances(r.Context(), request)
@@ -186,10 +191,11 @@ func (this *MicroServiceInstanceService) GetInstances(w 
http.ResponseWriter, r *
 }
 
 func (this *MicroServiceInstanceService) UpdateStatus(w http.ResponseWriter, r 
*http.Request) {
-       status := r.URL.Query().Get("value")
+       query := r.URL.Query()
+       status := query.Get("value")
        request := &pb.UpdateInstanceStatusRequest{
-               ServiceId:  r.URL.Query().Get(":serviceId"),
-               InstanceId: r.URL.Query().Get(":instanceId"),
+               ServiceId:  query.Get(":serviceId"),
+               InstanceId: query.Get(":instanceId"),
                Status:     status,
        }
        resp, _ := core.InstanceAPI.UpdateStatus(r.Context(), request)
@@ -197,6 +203,7 @@ func (this *MicroServiceInstanceService) UpdateStatus(w 
http.ResponseWriter, r *
 }
 
 func (this *MicroServiceInstanceService) UpdateMetadata(w http.ResponseWriter, 
r *http.Request) {
+       query := r.URL.Query()
        message, err := ioutil.ReadAll(r.Body)
        if err != nil {
                util.Logger().Error("body err", err)
@@ -204,8 +211,8 @@ func (this *MicroServiceInstanceService) UpdateMetadata(w 
http.ResponseWriter, r
                return
        }
        request := &pb.UpdateInstancePropsRequest{
-               ServiceId:  r.URL.Query().Get(":serviceId"),
-               InstanceId: r.URL.Query().Get(":instanceId"),
+               ServiceId:  query.Get(":serviceId"),
+               InstanceId: query.Get(":instanceId"),
        }
        err = json.Unmarshal(message, request)
        if err != nil {
diff --git a/server/rest/controller/v4/microservice_controller.go 
b/server/rest/controller/v4/microservice_controller.go
index ce578c76..60b4d7cd 100644
--- a/server/rest/controller/v4/microservice_controller.go
+++ b/server/rest/controller/v4/microservice_controller.go
@@ -87,8 +87,9 @@ func (this *MicroServiceService) Update(w 
http.ResponseWriter, r *http.Request)
 }
 
 func (this *MicroServiceService) Unregister(w http.ResponseWriter, r 
*http.Request) {
-       serviceId := r.URL.Query().Get(":serviceId")
-       force := r.URL.Query().Get("force")
+       query := r.URL.Query()
+       serviceId := query.Get(":serviceId")
+       force := query.Get("force")
 
        b, ok := trueOrFalse[force]
        if force != "" && !ok {
@@ -113,14 +114,15 @@ func (this *MicroServiceService) GetServices(w 
http.ResponseWriter, r *http.Requ
 }
 
 func (this *MicroServiceService) GetExistence(w http.ResponseWriter, r 
*http.Request) {
+       query := r.URL.Query()
        request := &pb.GetExistenceRequest{
-               Type:        r.URL.Query().Get("type"),
-               Environment: r.URL.Query().Get("env"),
-               AppId:       r.URL.Query().Get("appId"),
-               ServiceName: r.URL.Query().Get("serviceName"),
-               Version:     r.URL.Query().Get("version"),
-               ServiceId:   r.URL.Query().Get("serviceId"),
-               SchemaId:    r.URL.Query().Get("schemaId"),
+               Type:        query.Get("type"),
+               Environment: query.Get("env"),
+               AppId:       query.Get("appId"),
+               ServiceName: query.Get("serviceName"),
+               Version:     query.Get("version"),
+               ServiceId:   query.Get("serviceId"),
+               SchemaId:    query.Get("schemaId"),
        }
        resp, _ := core.ServiceAPI.Exist(r.Context(), request)
        w.Header().Add("X-Schema-Summary", resp.Summary)
diff --git a/server/rest/controller/v4/query_rule_controller.go 
b/server/rest/controller/v4/query_rule_controller.go
index 8ac97f20..539ce4d0 100644
--- a/server/rest/controller/v4/query_rule_controller.go
+++ b/server/rest/controller/v4/query_rule_controller.go
@@ -66,11 +66,12 @@ func (this *RuleService) AddRule(w http.ResponseWriter, r 
*http.Request) {
 }
 
 func (this *RuleService) DeleteRule(w http.ResponseWriter, r *http.Request) {
-       rule_id := r.URL.Query().Get(":rule_id")
+       query := r.URL.Query()
+       rule_id := query.Get(":rule_id")
        ids := strings.Split(rule_id, ",")
 
        resp, _ := core.ServiceAPI.DeleteRule(r.Context(), 
&pb.DeleteServiceRulesRequest{
-               ServiceId: r.URL.Query().Get(":serviceId"),
+               ServiceId: query.Get(":serviceId"),
                RuleIds:   ids,
        })
        controller.WriteResponse(w, resp.Response, nil)
@@ -91,9 +92,10 @@ func (this *RuleService) UpdateRule(w http.ResponseWriter, r 
*http.Request) {
                controller.WriteError(w, scerr.ErrInvalidParams, err.Error())
                return
        }
+       query := r.URL.Query()
        resp, err := core.ServiceAPI.UpdateRule(r.Context(), 
&pb.UpdateServiceRuleRequest{
-               ServiceId: r.URL.Query().Get(":serviceId"),
-               RuleId:    r.URL.Query().Get(":rule_id"),
+               ServiceId: query.Get(":serviceId"),
+               RuleId:    query.Get(":rule_id"),
                Rule:      &rule,
        })
        controller.WriteResponse(w, resp.Response, nil)
diff --git a/server/rest/controller/v4/schema_controller.go 
b/server/rest/controller/v4/schema_controller.go
index 5fd37e22..71e4cde0 100644
--- a/server/rest/controller/v4/schema_controller.go
+++ b/server/rest/controller/v4/schema_controller.go
@@ -44,9 +44,10 @@ func (this *SchemaService) URLPatterns() []rest.Route {
 }
 
 func (this *SchemaService) GetSchemas(w http.ResponseWriter, r *http.Request) {
+       query := r.URL.Query()
        request := &pb.GetSchemaRequest{
-               ServiceId: r.URL.Query().Get(":serviceId"),
-               SchemaId:  r.URL.Query().Get(":schemaId"),
+               ServiceId: query.Get(":serviceId"),
+               SchemaId:  query.Get(":schemaId"),
        }
        resp, _ := core.ServiceAPI.GetSchemaInfo(r.Context(), request)
        w.Header().Add("X-Schema-Summary", resp.SchemaSummary)
@@ -71,8 +72,9 @@ func (this *SchemaService) ModifySchema(w 
http.ResponseWriter, r *http.Request)
                controller.WriteError(w, scerr.ErrInvalidParams, err.Error())
                return
        }
-       request.ServiceId = r.URL.Query().Get(":serviceId")
-       request.SchemaId = r.URL.Query().Get(":schemaId")
+       query := r.URL.Query()
+       request.ServiceId = query.Get(":serviceId")
+       request.SchemaId = query.Get(":schemaId")
        resp, err := core.ServiceAPI.ModifySchema(r.Context(), request)
        controller.WriteResponse(w, resp.Response, nil)
 }
@@ -98,17 +100,19 @@ func (this *SchemaService) ModifySchemas(w 
http.ResponseWriter, r *http.Request)
 }
 
 func (this *SchemaService) DeleteSchemas(w http.ResponseWriter, r 
*http.Request) {
+       query := r.URL.Query()
        request := &pb.DeleteSchemaRequest{
-               ServiceId: r.URL.Query().Get(":serviceId"),
-               SchemaId:  r.URL.Query().Get(":schemaId"),
+               ServiceId: query.Get(":serviceId"),
+               SchemaId:  query.Get(":schemaId"),
        }
        resp, _ := core.ServiceAPI.DeleteSchema(r.Context(), request)
        controller.WriteResponse(w, resp.Response, nil)
 }
 
 func (this *SchemaService) GetAllSchemas(w http.ResponseWriter, r 
*http.Request) {
-       withSchema := r.URL.Query().Get("withSchema")
-       serviceId := r.URL.Query().Get(":serviceId")
+       query := r.URL.Query()
+       withSchema := query.Get("withSchema")
+       serviceId := query.Get(":serviceId")
        if withSchema != "0" && withSchema != "1" && 
strings.TrimSpace(withSchema) != "" {
                controller.WriteError(w, scerr.ErrInvalidParams, "parameter 
withSchema must be 1 or 0")
                return
diff --git a/server/rest/controller/v4/tag_controller.go 
b/server/rest/controller/v4/tag_controller.go
index dccf0d57..71704989 100644
--- a/server/rest/controller/v4/tag_controller.go
+++ b/server/rest/controller/v4/tag_controller.go
@@ -65,10 +65,11 @@ func (this *TagService) AddTags(w http.ResponseWriter, r 
*http.Request) {
 }
 
 func (this *TagService) UpdateTag(w http.ResponseWriter, r *http.Request) {
+       query := r.URL.Query()
        resp, _ := core.ServiceAPI.UpdateTag(r.Context(), 
&pb.UpdateServiceTagRequest{
-               ServiceId: r.URL.Query().Get(":serviceId"),
-               Key:       r.URL.Query().Get(":key"),
-               Value:     r.URL.Query().Get("value"),
+               ServiceId: query.Get(":serviceId"),
+               Key:       query.Get(":key"),
+               Value:     query.Get("value"),
        })
        controller.WriteResponse(w, resp.Response, nil)
 }
@@ -83,11 +84,12 @@ func (this *TagService) GetTags(w http.ResponseWriter, r 
*http.Request) {
 }
 
 func (this *TagService) DeleteTags(w http.ResponseWriter, r *http.Request) {
-       keys := r.URL.Query().Get(":key")
+       query := r.URL.Query()
+       keys := query.Get(":key")
        ids := strings.Split(keys, ",")
 
        resp, _ := core.ServiceAPI.DeleteTags(r.Context(), 
&pb.DeleteServiceTagsRequest{
-               ServiceId: r.URL.Query().Get(":serviceId"),
+               ServiceId: query.Get(":serviceId"),
                Keys:      ids,
        })
        controller.WriteResponse(w, resp.Response, nil)
diff --git a/server/service/cache/filter_permission.go 
b/server/service/cache/filter_permission.go
index 69e4dd8d..ef859440 100644
--- a/server/service/cache/filter_permission.go
+++ b/server/service/cache/filter_permission.go
@@ -48,10 +48,6 @@ func (f *AccessibleFilter) Init(ctx context.Context, parent 
*cache.Node) (node *
                ids = append(ids, providerServiceId)
        }
 
-       if len(ids) == 0 {
-               return
-       }
-
        pCopy.ServiceIds = ids
 
        node = cache.NewNode()
diff --git a/server/service/cache/filter_tags.go 
b/server/service/cache/filter_tags.go
index 1964f157..da418c8d 100644
--- a/server/service/cache/filter_tags.go
+++ b/server/service/cache/filter_tags.go
@@ -71,10 +71,6 @@ loopProviderIds:
                ids = append(ids, providerServiceId)
        }
 
-       if len(ids) == 0 {
-               return
-       }
-
        pCopy.ServiceIds = ids
 
        node = cache.NewNode()
diff --git a/server/service/cache/filter_version.go 
b/server/service/cache/filter_version.go
index f5bb708b..df9da3d0 100644
--- a/server/service/cache/filter_version.go
+++ b/server/service/cache/filter_version.go
@@ -36,7 +36,7 @@ func (f *VersionRuleFilter) Name(ctx context.Context) string {
 func (f *VersionRuleFilter) Init(ctx context.Context, parent *cache.Node) 
(node *cache.Node, err error) {
        provider := ctx.Value(CTX_FIND_PROVIDER).(*pb.MicroServiceKey)
        // 版本规则
-       ids, err := serviceUtil.FindServiceIds(ctx, provider.Version, provider)
+       ids, exist, err := serviceUtil.FindServiceIds(ctx, provider.Version, 
provider)
        if err != nil {
                consumer := ctx.Value(CTX_FIND_CONSUMER).(*pb.MicroService)
                findFlag := fmt.Sprintf("consumer %s find provider %s/%s/%s", 
consumer.ServiceId,
@@ -44,7 +44,7 @@ func (f *VersionRuleFilter) Init(ctx context.Context, parent 
*cache.Node) (node
                util.Logger().Errorf(err, "VersionRuleFilter failed, %s", 
findFlag)
                return
        }
-       if len(ids) == 0 {
+       if !exist {
                return
        }
 
diff --git a/server/service/instance.go b/server/service/instance.go
index 848291fe..9b1ebaa0 100644
--- a/server/service/instance.go
+++ b/server/service/instance.go
@@ -572,11 +572,11 @@ func (s *InstanceService) Find(ctx context.Context, in 
*pb.FindInstancesRequest)
                if noCache || cacheOnly || reqRev <= cacheRev {
                        break
                }
-               util.SetContext(cloneCtx, serviceUtil.CTX_NOCACHE, "1")
+               cloneCtx = util.SetContext(cloneCtx, serviceUtil.CTX_NOCACHE, 
"1")
        }
 
        // add dependency queue
-       if newVersionRule {
+       if newVersionRule && len(item.ServiceIds) > 0 {
                provider, err = s.reshapeProviderKey(ctx, provider, 
item.ServiceIds[0])
                if provider != nil {
                        err = serviceUtil.AddServiceVersionRule(ctx, 
domainProject, service, provider)
@@ -599,7 +599,7 @@ func (s *InstanceService) Find(ctx context.Context, in 
*pb.FindInstancesRequest)
        if rev == item.Rev {
                instances = instances[:0]
        }
-       util.SetContext(ctx, serviceUtil.CTX_RESPONSE_REVISION, item.Rev)
+       ctx = util.SetContext(ctx, serviceUtil.CTX_RESPONSE_REVISION, item.Rev)
        return &pb.FindInstancesResponse{
                Response:  pb.CreateResponse(pb.Response_SUCCESS, "Query 
service instances successfully."),
                Instances: instances,
diff --git a/server/service/instance_test.go b/server/service/instance_test.go
index 692e4d19..1e54a97f 100644
--- a/server/service/instance_test.go
+++ b/server/service/instance_test.go
@@ -1085,7 +1085,8 @@ var _ = Describe("'Instance' service", func() {
                                        VersionRule:       "3.0.0+",
                                })
                                Expect(err).To(BeNil())
-                               
Expect(respFind.Response.Code).ToNot(Equal(pb.Response_SUCCESS))
+                               
Expect(respFind.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               Expect(len(respFind.Instances)).To(Equal(0))
 
                                By("provider does not contain 2.0.0-2.0.1 
versions")
                                respFind, err = 
instanceResource.Find(getContext(), &pb.FindInstancesRequest{
@@ -1095,7 +1096,8 @@ var _ = Describe("'Instance' service", func() {
                                        VersionRule:       "2.0.0-2.0.1",
                                })
                                Expect(err).To(BeNil())
-                               
Expect(respFind.Response.Code).ToNot(Equal(pb.Response_SUCCESS))
+                               
Expect(respFind.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               Expect(len(respFind.Instances)).To(Equal(0))
 
                                By("provider does not contain 2.0.0 version")
                                respFind, err = 
instanceResource.Find(getContext(), &pb.FindInstancesRequest{
@@ -1121,6 +1123,7 @@ var _ = Describe("'Instance' service", func() {
 
                Context("when query instances", func() {
                        It("should be passed", func() {
+                               By("find with version rule")
                                respFind, err := 
instanceResource.Find(getContext(), &pb.FindInstancesRequest{
                                        ConsumerServiceId: serviceId1,
                                        AppId:             "query_instance",
@@ -1162,6 +1165,16 @@ var _ = Describe("'Instance' service", func() {
                                
Expect(respFind.Response.Code).To(Equal(pb.Response_SUCCESS))
                                
Expect(respFind.Instances[0].InstanceId).To(Equal(instanceId1))
 
+                               respFind, err = 
instanceResource.Find(getContext(), &pb.FindInstancesRequest{
+                                       ConsumerServiceId: serviceId1,
+                                       AppId:             "query_instance",
+                                       ServiceName:       
"query_instance_service",
+                                       VersionRule:       "0.0.0",
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respFind.Response.Code).To(Equal(scerr.ErrServiceNotExists))
+
+                               By("find with env")
                                respFind, err = 
instanceResource.Find(getContext(), &pb.FindInstancesRequest{
                                        ConsumerServiceId: serviceId4,
                                        AppId:             "query_instance",
@@ -1235,7 +1248,8 @@ var _ = Describe("'Instance' service", func() {
                                        VersionRule:       "1.0.5",
                                })
                                Expect(err).To(BeNil())
-                               
Expect(respFind.Response.Code).To(Equal(scerr.ErrServiceNotExists))
+                               
Expect(respFind.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               Expect(len(respFind.Instances)).To(Equal(0))
 
                                By("provider tag does not exist")
                                respFind, err = 
instanceResource.Find(getContext(), &pb.FindInstancesRequest{
@@ -1246,7 +1260,8 @@ var _ = Describe("'Instance' service", func() {
                                        Tags:              
[]string{"notexisttag"},
                                })
                                Expect(err).To(BeNil())
-                               
Expect(respFind.Response.Code).To(Equal(scerr.ErrServiceNotExists))
+                               
Expect(respFind.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               Expect(len(respFind.Instances)).To(Equal(0))
 
                                By("shared service discovery")
                                os.Setenv("CSE_SHARED_SERVICES", 
"query_instance_shared_provider")
diff --git a/server/service/microservice.go b/server/service/microservice.go
index b5046485..b819caf5 100644
--- a/server/service/microservice.go
+++ b/server/service/microservice.go
@@ -403,7 +403,7 @@ func (s *MicroServiceService) DeleteServices(ctx 
context.Context, request *pb.De
                }
        }
 
-       util.Logger().Infof("Batch DeleteServices, count is %s, serviceId = %v 
, result = %d, ", len(request.ServiceIds), request.ServiceIds, responseCode)
+       util.Logger().Infof("Batch DeleteServices, count is %d, serviceId = %v 
, result = %d, ", len(request.ServiceIds), request.ServiceIds, responseCode)
 
        resp := &pb.DelServicesResponse{
                Services: delServiceRspInfo,
@@ -556,7 +556,7 @@ func (s *MicroServiceService) Exist(ctx context.Context, in 
*pb.GetExistenceRequ
                        }, nil
                }
 
-               ids, err := serviceUtil.FindServiceIds(ctx, in.Version, 
&pb.MicroServiceKey{
+               ids, exist, err := serviceUtil.FindServiceIds(ctx, in.Version, 
&pb.MicroServiceKey{
                        Environment: in.Environment,
                        AppId:       in.AppId,
                        ServiceName: in.ServiceName,
@@ -565,15 +565,21 @@ func (s *MicroServiceService) Exist(ctx context.Context, 
in *pb.GetExistenceRequ
                        Tenant:      domainProject,
                })
                if err != nil {
-                       util.Logger().Errorf(err, "micro-service exist failed, 
service %s: find serviceIds failed.", serviceFlag)
+                       util.Logger().Errorf(err, "micro-service exist failed, 
find %s serviceIds failed.", serviceFlag)
                        return &pb.GetExistenceResponse{
                                Response: pb.CreateResponse(scerr.ErrInternal, 
err.Error()),
                        }, err
                }
-               if len(ids) <= 0 {
-                       util.Logger().Infof("micro-service exist failed, 
service %s: service not exist.", serviceFlag)
+               if !exist {
+                       util.Logger().Infof("micro-service exist failed, 
service %s does not exist.", serviceFlag)
                        return &pb.GetExistenceResponse{
-                               Response: 
pb.CreateResponse(scerr.ErrServiceNotExists, "service does not exist."),
+                               Response: 
pb.CreateResponse(scerr.ErrServiceNotExists, serviceFlag+" does not exist."),
+                       }, nil
+               }
+               if len(ids) == 0 {
+                       util.Logger().Infof("micro-service exist failed, %s 
version mismatch.", serviceFlag)
+                       return &pb.GetExistenceResponse{
+                               Response: 
pb.CreateResponse(scerr.ErrServiceVersionNotExists, serviceFlag+" version 
mismatch."),
                        }, nil
                }
                return &pb.GetExistenceResponse{
diff --git a/server/service/microservice_test.go 
b/server/service/microservice_test.go
index 9e419c7f..213ed4d2 100644
--- a/server/service/microservice_test.go
+++ b/server/service/microservice_test.go
@@ -830,6 +830,24 @@ var _ = Describe("'Micro-service' service", func() {
                                })
                                Expect(err).To(BeNil())
                                
Expect(resp.Response.Code).To(Equal(scerr.ErrServiceNotExists))
+
+                               By("version mismatch")
+                               resp, err = serviceResource.Exist(getContext(), 
&pb.GetExistenceRequest{
+                                       Type:        "microservice",
+                                       AppId:       "exist_appId",
+                                       ServiceName: "exist_service",
+                                       Version:     "2.0.0",
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(resp.Response.Code).To(Equal(scerr.ErrServiceNotExists))
+                               resp, err = serviceResource.Exist(getContext(), 
&pb.GetExistenceRequest{
+                                       Type:        "microservice",
+                                       AppId:       "exist_appId",
+                                       ServiceName: "exist_service",
+                                       Version:     "0.0.0-1.0.0",
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(resp.Response.Code).To(Equal(scerr.ErrServiceVersionNotExists))
                        })
                })
 
diff --git a/server/service/notification/notification_test.go 
b/server/service/notification/notification_test.go
index d7da51e5..014e06e9 100644
--- a/server/service/notification/notification_test.go
+++ b/server/service/notification/notification_test.go
@@ -24,6 +24,11 @@ import (
 )
 
 func TestGetNotifyService(t *testing.T) {
+       n := NotifyType(999)
+       if n.String() != "NotifyType999" {
+               t.Fatalf("TestGetNotifyService failed")
+       }
+
        notifyService := &NotifyService{
                isClose:   true,
                goroutine: util.NewGo(context.Background()),
diff --git a/server/service/notification/websocket_test.go 
b/server/service/notification/websocket_test.go
index 5b0a9f47..d6d011fb 100644
--- a/server/service/notification/websocket_test.go
+++ b/server/service/notification/websocket_test.go
@@ -59,11 +59,34 @@ func TestDoWebSocketListAndWatch(t *testing.T) {
        conn, _, _ := websocket.DefaultDialer.Dial(
                strings.Replace(s.URL, "http://";, "ws://", 1), nil)
 
-       go DoWebSocketListAndWatch(context.Background(), "", nil, conn)
+       go func() {
+               DoWebSocketListAndWatch(context.Background(), "", nil, conn)
+
+               w2 := NewListWatcher("g", "s", func() (results 
[]*proto.WatchInstanceResponse, rev int64) {
+                       return
+               })
+               ws2 := &WebSocket{
+                       ctx:             context.Background(),
+                       conn:            conn,
+                       watcher:         w2,
+                       needPingWatcher: true,
+                       closed:          make(chan struct{}),
+               }
+               err := ws2.Init()
+               if err != nil {
+                       t.Fatalf("TestPublisher_Run")
+               }
+       }()
 
        EstablishWebSocketError(conn, errors.New("error"))
 
        w := NewListWatcher("g", "s", func() (results 
[]*proto.WatchInstanceResponse, rev int64) {
+               results = append(results, &proto.WatchInstanceResponse{
+                       Response: proto.CreateResponse(proto.Response_SUCCESS, 
"ok"),
+                       Action:   string(proto.EVT_CREATE),
+                       Key:      &proto.MicroServiceKey{},
+                       Instance: &proto.MicroServiceInstance{},
+               })
                return
        })
        w.nType = -1
@@ -87,9 +110,6 @@ func TestDoWebSocketListAndWatch(t *testing.T) {
        }
        go ws.HandleWatchWebSocketControlMessage()
 
-       w.SetError(errors.New("err"))
-       w.OnMessage(nil)
-       w.SetError(nil)
        w.OnMessage(nil)
        w.OnMessage(&WatchJob{})
 
@@ -116,5 +136,8 @@ func TestDoWebSocketListAndWatch(t *testing.T) {
        ws.heartbeat(websocket.PingMessage)
        ws.heartbeat(websocket.PongMessage)
 
+       w.SetError(errors.New("err"))
+       w.OnMessage(nil)
+
        publisher.Stop()
 }
diff --git a/server/service/tag_test.go b/server/service/tag_test.go
index 1ca9112d..3cdd30fb 100644
--- a/server/service/tag_test.go
+++ b/server/service/tag_test.go
@@ -375,7 +375,9 @@ var _ = Describe("'Tag' service", func() {
                                        VersionRule:       "1.0.0+",
                                        Tags:              
[]string{"not-exist-tag"},
                                })
-                               
Expect(findResp.Response.Code).To(Equal(scerr.ErrServiceNotExists))
+                               Expect(err).To(BeNil())
+                               
Expect(findResp.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               Expect(len(findResp.Instances)).To(Equal(0))
 
                                findResp, err = 
instanceResource.Find(getContext(), &pb.FindInstancesRequest{
                                        ConsumerServiceId: consumerId,
@@ -391,7 +393,7 @@ var _ = Describe("'Tag' service", func() {
                                respAddRule, err := 
serviceResource.AddRule(getContext(), &pb.AddServiceRulesRequest{
                                        ServiceId: providerId,
                                        Rules: []*pb.AddOrUpdateServiceRule{
-                                               &pb.AddOrUpdateServiceRule{
+                                               {
                                                        RuleType:    "WHITE",
                                                        Attribute:   
"tag_consumer_tag",
                                                        Pattern:     "f*",
@@ -409,7 +411,9 @@ var _ = Describe("'Tag' service", func() {
                                        VersionRule:       "1.0.0+",
                                        Tags:              
[]string{"filter_tag"},
                                })
-                               
Expect(findResp.Response.Code).To(Equal(scerr.ErrServiceNotExists))
+                               Expect(err).To(BeNil())
+                               
Expect(findResp.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               Expect(len(findResp.Instances)).To(Equal(0))
 
                                addTagResp, err = 
serviceResource.AddTags(getContext(), &pb.AddServiceTagsRequest{
                                        ServiceId: consumerId,
diff --git a/server/service/util/dependency_query.go 
b/server/service/util/dependency_query.go
index 343e9fa7..15bff785 100644
--- a/server/service/util/dependency_query.go
+++ b/server/service/util/dependency_query.go
@@ -175,7 +175,7 @@ func (dr *DependencyRelation) 
parseDependencyRule(dependencyRule *pb.MicroServic
                        serviceIds = append(serviceIds, kv.Value.(string))
                }
        default:
-               serviceIds, err = FindServiceIds(dr.ctx, 
dependencyRule.Version, dependencyRule)
+               serviceIds, _, err = FindServiceIds(dr.ctx, 
dependencyRule.Version, dependencyRule)
        }
        return
 }
@@ -307,7 +307,7 @@ func (dr *DependencyRelation) 
getConsumerOfSameServiceNameAndAppId(provider *pb.
                providerVersionRule := 
providerVersionRuleArr[len(providerVersionRuleArr)-1]
                if providerVersionRule == "latest" {
                        if latestServiceId == nil {
-                               latestServiceId, err = FindServiceIds(dr.ctx, 
providerVersionRule, provider)
+                               latestServiceId, _, err = 
FindServiceIds(dr.ctx, providerVersionRule, provider)
                                if err != nil {
                                        util.Logger().Errorf(err, "Get latest 
service failed.")
                                        return nil, err
diff --git a/server/service/util/microservice_util.go 
b/server/service/util/microservice_util.go
index aba9a98f..e5a89a92 100644
--- a/server/service/util/microservice_util.go
+++ b/server/service/util/microservice_util.go
@@ -142,21 +142,20 @@ func GetServiceAllVersions(ctx context.Context, key 
*pb.MicroServiceKey, alias b
        return resp, err
 }
 
-func FindServiceIds(ctx context.Context, versionRule string, key 
*pb.MicroServiceKey) ([]string, error) {
+func FindServiceIds(ctx context.Context, versionRule string, key 
*pb.MicroServiceKey) ([]string, bool, error) {
        // 版本规则
-       ids := []string{}
        match := ParseVersionRule(versionRule)
        if match == nil {
                copy := *key
                copy.Version = versionRule
                serviceId, err := GetServiceId(ctx, &copy)
                if err != nil {
-                       return nil, err
+                       return nil, false, err
                }
                if len(serviceId) > 0 {
-                       ids = append(ids, serviceId)
+                       return []string{serviceId}, true, nil
                }
-               return ids, nil
+               return nil, false, nil
        }
 
        searchAlias := false
@@ -165,17 +164,17 @@ func FindServiceIds(ctx context.Context, versionRule 
string, key *pb.MicroServic
 FIND_RULE:
        resp, err := GetServiceAllVersions(ctx, key, searchAlias)
        if err != nil {
-               return nil, err
-       }
-       if len(resp.Kvs) > 0 {
-               ids = match(resp.Kvs)
+               return nil, false, err
        }
-       if len(ids) == 0 && alsoFindAlias {
+       if len(resp.Kvs) == 0 {
+               if !alsoFindAlias {
+                       return nil, false, nil
+               }
                searchAlias = true
                alsoFindAlias = false
                goto FIND_RULE
        }
-       return ids, nil
+       return match(resp.Kvs), true, nil
 }
 
 func ServiceExist(ctx context.Context, domainProject string, serviceId string) 
bool {
diff --git a/server/service/util/util_suite_test.go 
b/server/service/util/util_suite_test.go
index fb306709..3aca853a 100644
--- a/server/service/util/util_suite_test.go
+++ b/server/service/util/util_suite_test.go
@@ -43,19 +43,19 @@ func TestMicroservice(t *testing.T) {
 }
 
 func TestFindServiceIds(t *testing.T) {
-       _, err := serviceUtil.FindServiceIds(context.Background(),
+       _, _, err := serviceUtil.FindServiceIds(context.Background(),
                "latest", &proto.MicroServiceKey{})
        if err == nil {
                t.FailNow()
        }
 
-       _, err = serviceUtil.FindServiceIds(context.Background(),
+       _, _, err = serviceUtil.FindServiceIds(context.Background(),
                "1.0.0", &proto.MicroServiceKey{})
        if err == nil {
                t.FailNow()
        }
 
-       _, err = serviceUtil.FindServiceIds(context.Background(),
+       _, _, err = serviceUtil.FindServiceIds(context.Background(),
                "1.0+", &proto.MicroServiceKey{Alias: "test"})
        if err == nil {
                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:
us...@infra.apache.org


> Wrong error code returned in Find API
> -------------------------------------
>
>                 Key: SCB-744
>                 URL: https://issues.apache.org/jira/browse/SCB-744
>             Project: Apache ServiceComb
>          Issue Type: Bug
>          Components: Service-Center
>            Reporter: little-cui
>            Assignee: little-cui
>            Priority: Major
>             Fix For: service-center-1.1.0
>
>




--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to