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

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


The following commit(s) were added to refs/heads/master by this push:
     new ad8f059  SCB-336 1.add ut about find instance with tag 2.optimize find 
api (#279)
ad8f059 is described below

commit ad8f059f8a57a1c531a33f14226d623188015776
Author: aseTo2016 <[email protected]>
AuthorDate: Wed Feb 28 10:28:57 2018 +0800

    SCB-336 1.add ut about find instance with tag 2.optimize find api (#279)
    
    * 1.add ut about find instance with tag
    2.optimize find api
    
    (cherry picked from commit 0e5cd8e)
    
    * 1.add ut about find instance with tag
    2.optimize find api
    
    * 1.add ut about find instance with tag
    2.optimize find api
    
    * 1.add ut about find instance with tag
    2.optimize find api
---
 pkg/rest/client.go               |   6 +-
 server/service/instances.go      |   7 +--
 server/service/tag_test.go       | 118 ++++++++++++++++++++++++++++++++++++++-
 server/service/util/rule_util.go | 118 +++++++++++++++++++++++----------------
 4 files changed, 193 insertions(+), 56 deletions(-)

diff --git a/pkg/rest/client.go b/pkg/rest/client.go
index 2cd68ab..f5b6c00 100644
--- a/pkg/rest/client.go
+++ b/pkg/rest/client.go
@@ -229,10 +229,10 @@ func (client *HttpClient) httpDo(method string, url 
string, headers map[string]s
        var bodyReader io.Reader = nil
        if body != nil {
                if headers == nil || len(headers["Content-Type"]) == 0 {
-                       // 
如果请求头未传入Conent-Type,则按照json格式进行编码(如果是非json类型,需要自行在headers里指定类型)
+                       // 
如果请求头未传入Content-Type,则按照json格式进行编码(如果是非json类型,需要自行在headers里指定类型)
                        bodyBytes, err = json.Marshal(body)
                        if err != nil {
-                               util.Logger().Errorf(err, "mashal object 
failed.")
+                               util.Logger().Errorf(err, "marshal object 
failed.")
                                return status, result
                        }
                } else {
@@ -293,7 +293,7 @@ func (client *HttpClient) HttpDo(method string, url string, 
headers map[string]s
                        // 
如果请求头未传入Conent-Type,则按照json格式进行编码(如果是非json类型,需要自行在headers里指定类型)
                        bodyBytes, err = json.Marshal(body)
                        if err != nil {
-                               util.Logger().Errorf(err, "mashal object 
failed.")
+                               util.Logger().Errorf(err, "marshal object 
failed.")
                                return nil, err
                        }
                } else {
diff --git a/server/service/instances.go b/server/service/instances.go
index 7008667..e387fb0 100644
--- a/server/service/instances.go
+++ b/server/service/instances.go
@@ -568,13 +568,12 @@ func (s *InstanceService) Find(ctx context.Context, in 
*pb.FindInstancesRequest)
        if apt.IsShared(provider) {
                // it means the shared micro-services must be the same env with 
SC.
                provider.Environment = apt.Service.Environment
-               findFlag += "(shared services in " + provider.Environment + " 
environment)"
+               findFlag += "(provider is shared service in " + 
provider.Environment + " environment)"
        } else {
                // provider is not a shared micro-service,
                // only allow shared micro-service instances found in different 
domains.
                util.SetTargetDomainProject(ctx, util.ParseDomain(ctx), 
util.ParseProject(ctx))
                provider.Tenant = util.ParseTargetDomainProject(ctx)
-               findFlag += "('" + provider.Environment + "' services of the 
same domain)"
        }
 
        // 版本规则
@@ -586,7 +585,7 @@ func (s *InstanceService) Find(ctx context.Context, in 
*pb.FindInstancesRequest)
                }, err
        }
        if len(ids) == 0 {
-               mes := fmt.Sprintf("no provider matched, %s", findFlag)
+               mes := fmt.Sprintf("provider not exist, %s", findFlag)
                util.Logger().Errorf(nil, "find instance failed, %s", mes)
                return &pb.FindInstancesResponse{
                        Response: pb.CreateResponse(scerr.ErrServiceNotExists, 
mes),
@@ -618,7 +617,7 @@ func (s *InstanceService) Find(ctx context.Context, in 
*pb.FindInstancesRequest)
        //维护version的规则,service name 可能是别名,所以重新获取
        providerService, err := serviceUtil.GetService(ctx, provider.Tenant, 
ids[0])
        if providerService == nil {
-               util.Logger().Errorf(err, "find instance failed, %s: no 
provider matched.", findFlag)
+               util.Logger().Errorf(err, "find instance failed, %s: provider 
%s not exist.", findFlag, ids[0])
                return &pb.FindInstancesResponse{
                        Response: pb.CreateResponse(scerr.ErrServiceNotExists, 
"No provider matched."),
                }, nil
diff --git a/server/service/tag_test.go b/server/service/tag_test.go
index 7a85869..267635c 100644
--- a/server/service/tag_test.go
+++ b/server/service/tag_test.go
@@ -191,7 +191,7 @@ var _ = Describe("'Tag' service", func() {
 
        })
 
-       Describe("execute 'update' operartion", func() {
+       Describe("execute 'update' operation", func() {
                var (
                        serviceId string
                )
@@ -283,9 +283,123 @@ var _ = Describe("'Tag' service", func() {
 
                })
 
+               Context("find instance, contain tag", func() {
+                       It("should pass", func() {
+                               By("create consumer")
+                               resp, err := 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+                                       Service: &pb.MicroService{
+                                               AppId:       
"find_inst_tag_group",
+                                               ServiceName: 
"find_inst_tag_consumer",
+                                               Version:     "1.0.0",
+                                               Level:       "FRONT",
+                                               Status:      pb.MS_UP,
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(resp.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               consumerId := resp.ServiceId
+
+                               By("create provider")
+                               resp, err = 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+                                       Service: &pb.MicroService{
+                                               AppId:       
"find_inst_tag_group",
+                                               ServiceName: 
"find_inst_tag_provider",
+                                               Version:     "1.0.1",
+                                               Level:       "FRONT",
+                                               Status:      pb.MS_UP,
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(resp.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               providerId := resp.ServiceId
+
+                               addTagResp, err := 
serviceResource.AddTags(getContext(), &pb.AddServiceTagsRequest{
+                                       ServiceId: providerId,
+                                       Tags:      
map[string]string{"filter_tag": "filter"},
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(addTagResp.Response.Code).To(Equal(pb.Response_SUCCESS))
+
+                               instanceResp, err := 
instanceResource.Register(getContext(), &pb.RegisterInstanceRequest{
+                                       Instance: &pb.MicroServiceInstance{
+                                               ServiceId: providerId,
+                                               Endpoints: []string{
+                                                       
"findInstanceForTagFilter:127.0.0.1:8080",
+                                               },
+                                               HostName: "UT-HOST",
+                                               Status:   pb.MSI_UP,
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(instanceResp.Response.Code).To(Equal(pb.Response_SUCCESS))
+
+                               findResp, err := 
instanceResource.Find(getContext(), &pb.FindInstancesRequest{
+                                       ConsumerServiceId: consumerId,
+                                       AppId:       "find_inst_tag_group",
+                                       ServiceName: "find_inst_tag_provider",
+                                       VersionRule: "1.0.0+",
+                                       Tags:        []string{"not-exist-tag"},
+                               })
+                               
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,
+                                       AppId:       "find_inst_tag_group",
+                                       ServiceName: "find_inst_tag_provider",
+                                       VersionRule: "1.0.0+",
+                                       Tags:        []string{"filter_tag"},
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(findResp.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               
Expect(findResp.Instances[0].InstanceId).To(Equal(instanceResp.InstanceId))
+
+                               respAddRule, err := 
serviceResource.AddRule(getContext(), &pb.AddServiceRulesRequest{
+                                       ServiceId: providerId,
+                                       Rules: []*pb.AddOrUpdateServiceRule{
+                                               &pb.AddOrUpdateServiceRule{
+                                                       RuleType: "WHITE",
+                                                       Attribute: 
"tag_filter_tag",
+                                                       Pattern: "f*",
+                                                       Description: "test 
white",
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respAddRule.Response.Code).To(Equal(pb.Response_SUCCESS))
+
+                               findResp, err = 
instanceResource.Find(getContext(), &pb.FindInstancesRequest{
+                                       ConsumerServiceId: consumerId,
+                                       AppId:       "find_inst_tag_group",
+                                       ServiceName: "find_inst_tag_provider",
+                                       VersionRule: "1.0.0+",
+                                       Tags:        []string{"filter_tag"},
+                               })
+                               
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,
+                                       Tags:      
map[string]string{"filter_tag": "filter"},
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(addTagResp.Response.Code).To(Equal(pb.Response_SUCCESS))
+
+                               findResp, err = 
instanceResource.Find(getContext(), &pb.FindInstancesRequest{
+                                       ConsumerServiceId: consumerId,
+                                       AppId:       "find_inst_tag_group",
+                                       ServiceName: "find_inst_tag_provider",
+                                       VersionRule: "1.0.0+",
+                                       Tags:        []string{"filter_tag"},
+                               })
+                               
Expect(findResp.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               
Expect(findResp.Instances[0].InstanceId).To(Equal(instanceResp.InstanceId))
+                       })
+               })
+
        })
 
-       Describe("execute 'delete' operartion", func() {
+       Describe("execute 'delete' operation", func() {
                var (
                        serviceId string
                )
diff --git a/server/service/util/rule_util.go b/server/service/util/rule_util.go
index 2ecabc0..df2047d 100644
--- a/server/service/util/rule_util.go
+++ b/server/service/util/rule_util.go
@@ -31,12 +31,6 @@ import (
        "strings"
 )
 
-var tagRegEx *regexp.Regexp
-
-func init() {
-       tagRegEx, _ = regexp.Compile("tag_(.*)")
-}
-
 type RuleFilter struct {
        DomainProject string
        Provider      *pb.MicroService
@@ -161,54 +155,84 @@ func AllowAcrossDimension(ctx context.Context, 
providerService *pb.MicroService,
        return nil
 }
 
-func MatchRules(rules []*pb.ServiceRule, service *pb.MicroService, serviceTags 
map[string]string) *scerr.Error {
-       if service == nil {
-               return scerr.NewError(scerr.ErrInvalidParams, "service is nil")
+func MatchRules(rulesOfProvider []*pb.ServiceRule, consumer *pb.MicroService, 
tagsOfConsumer map[string]string) *scerr.Error {
+       if consumer == nil {
+               return scerr.NewError(scerr.ErrInvalidParams, "consumer is nil")
        }
 
-       v := reflect.Indirect(reflect.ValueOf(service))
+       isWhite := false
+       if len(rulesOfProvider) <= 0 {
+               return nil
+       }
+       if rulesOfProvider[0].RuleType == "WHITE" {
+               isWhite = true
+       }
+       if isWhite {
+               return patternWhiteList(rulesOfProvider, tagsOfConsumer, 
consumer)
+       }
+       return patternBlackList(rulesOfProvider, tagsOfConsumer, consumer)
+}
 
-       hasWhite := false
-       for _, rule := range rules {
-               var value string
-               if tagRegEx.MatchString(rule.Attribute) {
-                       key := tagRegEx.FindStringSubmatch(rule.Attribute)[1]
-                       value = serviceTags[key]
-                       if len(value) == 0 {
-                               util.Logger().Infof("can not find service %s 
tag '%s'", service.ServiceId, key)
-                               continue
-                       }
-               } else {
-                       key := v.FieldByName(rule.Attribute)
-                       if !key.IsValid() {
-                               util.Logger().Errorf(nil, "can not find service 
%s field '%s', rule %s",
-                                       service.ServiceId, rule.Attribute, 
rule.RuleId)
-                               return scerr.NewError(scerr.ErrInternal, 
fmt.Sprintf("Can not find field '%s'", rule.Attribute))
-                       }
-                       value = key.String()
+func patternWhiteList(rulesOfProvider []*pb.ServiceRule, tagsOfConsumer 
map[string]string, consumer *pb.MicroService) *scerr.Error {
+       v := reflect.Indirect(reflect.ValueOf(consumer))
+       consumerId := consumer.ServiceId
+       for _, rule := range rulesOfProvider {
+               value, err := parsePattern(v, rule, tagsOfConsumer, consumerId)
+               if err != nil {
+                       return err
+               }
+               if len(value) == 0 {
+                       continue
+               }
+
+               match, _ := regexp.MatchString(rule.Pattern, value)
+               if match {
+                       util.Logger().Infof("consumer %s match white list, 
rule.Pattern is %s, value is %s",
+                               consumerId, rule.Pattern, value)
+                       return nil
                }
+       }
+       return scerr.NewError(scerr.ErrPermissionDeny, "Not found in white 
list")
+}
 
-               switch rule.RuleType {
-               case "WHITE":
-                       hasWhite = true
-                       match, _ := regexp.MatchString(rule.Pattern, value)
-                       if match {
-                               util.Logger().Infof("service %s match white 
list, rule.Pattern is %s, value is %s",
-                                       service.ServiceId, rule.Pattern, value)
-                               return nil
-                       }
-               case "BLACK":
-                       match, _ := regexp.MatchString(rule.Pattern, value)
-                       if match {
-                               util.Logger().Infof("service %s match black 
list, rule.Pattern is %s, value is %s",
-                                       service.ServiceId, rule.Pattern, value)
-                               return scerr.NewError(scerr.ErrPermissionDeny, 
"Found in black list")
-                       }
+func parsePattern(v reflect.Value, rule *pb.ServiceRule, tagsOfConsumer 
map[string]string, consumerId string) (string, *scerr.Error) {
+       if strings.HasPrefix(rule.Attribute, "tag_") {
+               key := rule.Attribute[4:]
+               value := tagsOfConsumer[key]
+               if len(value) == 0 {
+                       util.Logger().Infof("can not find service %s tag '%s'", 
consumerId, key)
                }
+               return value, nil
+       }
+       key := v.FieldByName(rule.Attribute)
+       if !key.IsValid() {
+               util.Logger().Errorf(nil, "can not find service %s field '%s', 
rule %s",
+                       consumerId, rule.Attribute, rule.RuleId)
+               return "", scerr.NewError(scerr.ErrInternal, fmt.Sprintf("Can 
not find field '%s'", rule.Attribute))
        }
-       if hasWhite {
-               util.Logger().Infof("service %s do not match white list", 
service.ServiceId)
-               return scerr.NewError(scerr.ErrPermissionDeny, "Not found in 
white list")
+       return key.String(), nil
+
+}
+
+func patternBlackList(rulesOfProvider []*pb.ServiceRule, tagsOfConsumer 
map[string]string, consumer *pb.MicroService) *scerr.Error {
+       v := reflect.Indirect(reflect.ValueOf(consumer))
+       consumerId := consumer.ServiceId
+       for _, rule := range rulesOfProvider {
+               var value string
+               value, err := parsePattern(v, rule, tagsOfConsumer, consumerId)
+               if err != nil {
+                       return err
+               }
+               if len(value) == 0 {
+                       continue
+               }
+
+               match, _ := regexp.MatchString(rule.Pattern, value)
+               if match {
+                       util.Logger().Infof("no permission to access, consumer 
%s match black list, rule.Pattern is %s, value is %s",
+                               consumerId, rule.Pattern, value)
+                       return scerr.NewError(scerr.ErrPermissionDeny, "Found 
in black list")
+               }
        }
        return nil
 }

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to