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].