You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by GitBox <gi...@apache.org> on 2020/12/10 12:10:42 UTC

[GitHub] [servicecomb-service-center] robotLJW opened a new pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

robotLJW opened a new pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782


   Follow this checklist to help us incorporate your contribution quickly and easily:
   
    - [ ] Make sure there is a [JIRA issue](https://issues.apache.org/jira/browse/SCB) filed for the change (usually before you start working on it).  Trivial changes like typos do not require a JIRA issue.  Your pull request should address just this issue, without pulling in other changes.
    - [ ] Each commit in the pull request should have a meaningful subject line and body.
    - [ ] Format the pull request title like `[SCB-XXX] Fixes bug in ApproximateQuantiles`, where you replace `SCB-XXX` with the appropriate JIRA issue.
    - [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
    - [ ] Run `go build` `go test` `go fmt` `go vet` to make sure basic checks pass. A more thorough check will be performed on your pull request automatically.
    - [ ] If this contribution is large, please file an Apache [Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf).
    - [ ] Never comment source code, delete it.
    - [ ] UT should has "context, subject, expected result" result as test case name, when you call t.Run().
   ---
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] little-cui commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
little-cui commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540227357



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,363 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gt": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}

Review comment:
       同上的问题

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,363 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gt": start}}

Review comment:
       确认算法是否正确,1.0+,表示1.0,1.1,2.0都满足




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] tianxiaoliang commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
tianxiaoliang commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540660810



##########
File path: datasource/mongo/ms.go
##########
@@ -1547,40 +1559,36 @@ func (ds *DataSource) GetInstances(ctx context.Context, request *pb.GetInstances
 		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
 		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version)
 
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, filter)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		log.Error(fmt.Sprintf("FindInstancesCache.Get failed %s failed", findFlag), err)
+		log.Error(fmt.Sprintf("FindInstances.Get failed %s failed", findFlag), err)

Review comment:
       小写,一样的问题

##########
File path: datasource/mongo/ms.go
##########
@@ -1547,40 +1559,36 @@ func (ds *DataSource) GetInstances(ctx context.Context, request *pb.GetInstances
 		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
 		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version)
 
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, filter)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		log.Error(fmt.Sprintf("FindInstancesCache.Get failed %s failed", findFlag), err)
+		log.Error(fmt.Sprintf("FindInstances.Get failed %s failed", findFlag), err)
 		return &pb.GetInstancesResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
 		}, err
 	}
-	if resp == nil {
+	if services == nil {
 		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
-		log.Error("FindInstancesCache.Get failed", mes)
+		log.Error("FindInstances.Get failed", mes)
 		return &pb.GetInstancesResponse{
 			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
 		}, nil
 	}
-
-	var instances []*pb.MicroServiceInstance
-	for resp.Next(ctx) {
-		var instance Instance
-		err := resp.Decode(&instance)
-		if err != nil {
-			log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag), err)
-			return &pb.GetInstancesResponse{
-				Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
-			}, err
-		}
-		instances = append(instances, instance.InstanceInfo)
+	serviceIDs := filterServiceIDs(ctx, request.ConsumerServiceId, request.Tags, services)
+	if len(serviceIDs) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)

Review comment:
       类似问题检查,抽常量

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {

Review comment:
       这是JPA风格代码,不提倡,改下

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:

Review comment:
       不允许使用goto

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],

Review comment:
       没判断长度 不可以调用

##########
File path: datasource/mongo/ms.go
##########
@@ -1547,40 +1559,36 @@ func (ds *DataSource) GetInstances(ctx context.Context, request *pb.GetInstances
 		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
 		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version)
 
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, filter)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		log.Error(fmt.Sprintf("FindInstancesCache.Get failed %s failed", findFlag), err)
+		log.Error(fmt.Sprintf("FindInstances.Get failed %s failed", findFlag), err)
 		return &pb.GetInstancesResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
 		}, err
 	}
-	if resp == nil {
+	if services == nil {
 		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
-		log.Error("FindInstancesCache.Get failed", mes)
+		log.Error("FindInstances.Get failed", mes)

Review comment:
       类似问题检查下

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":

Review comment:
       可能越界

##########
File path: datasource/mongo/ms.go
##########
@@ -1910,14 +1922,53 @@ func registryInstance(ctx context.Context, request *pb.RegisterInstanceRequest)
 		}, err
 	}
 
-	log.Infof("register instance %s, instanceID %s, operator %s",
-		instanceFlag, insertRes.InsertedID, remoteIP)
+	log.Info(fmt.Sprintf("register instance %s, instanceID %s, operator %s",
+		instanceFlag, insertRes.InsertedID, remoteIP))
 	return &pb.RegisterInstanceResponse{
 		Response:   pb.CreateResponse(pb.ResponseSuccess, "Register service instance successfully."),
 		InstanceId: instanceID,
 	}, nil
 }
 
+func (ds *DataSource) findSharedServiceInstance(ctx context.Context, request *pb.FindInstancesRequest, provider *pb.MicroServiceKey) (*pb.FindInstancesResponse, error) {
+	var err error
+	// it means the shared micro-services must be the same env with SC.
+	provider.Environment = core.Service.Environment
+	findFlag := fmt.Sprintf("find shared provider[%s/%s/%s/%s]", provider.Environment, provider.AppId, provider.ServiceName, provider.Version)
+	services, err := findServices(ctx, provider)
+	if err != nil {
+		log.Error(fmt.Sprintf("FindInstances.Get failed %s failed", findFlag), err)

Review comment:
       类似问题,不要用代码语言搞日志信息




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540749162



##########
File path: datasource/mongo/ms.go
##########
@@ -1464,44 +1469,51 @@ func (ds *DataSource) GetInstance(ctx context.Context, request *pb.GetOneInstanc
 				fmt.Sprintf("Provider[%s] does not exist.", request.ProviderServiceId)),
 		}, nil
 	}
+	findFlag := fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
+		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
+		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
+		request.ProviderInstanceId)
 
-	findFlag := func() string {
-		return fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
-			request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
-			provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
-			request.ProviderInstanceId)
-	}
-
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	findOneRes, err := client.GetMongoClient().FindOne(ctx, CollectionInstance, filter)
+	domainProject := util.ParseDomainProject(ctx)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag())
-		log.Error("FindInstances.GetWithProviderID failed", err)
+		log.Error(fmt.Sprintf("GetInstance.Get failed %s failed", findFlag), err)
 		return &pb.GetOneInstanceResponse{
-			Response: pb.CreateResponse(pb.ErrInstanceNotExists, mes.Error()),
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if services == nil {
+		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
+		log.Error("GetInstance.Get failed", mes)
+		return &pb.GetOneInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
 		}, nil
 	}
-	var instance Instance
-	err = findOneRes.Decode(&instance)
-	if err != nil {
-		log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag()), err)
+	serviceIDs := filterServiceIDs(ctx, request.ConsumerServiceId, request.Tags, services)
+	if len(serviceIDs) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)
+		log.Error("GetInstances.GetWithProviderID failed", mes)

Review comment:
       已经修改,非常感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540748032



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:
+	for _, service := range services {
+		for _, tag := range tags {
+			if _, ok := service.Tags[tag]; !ok {
+				continue loop
+			}
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func accessibleFilter(ctx context.Context, consumerID string, services []*Service) []*Service {
+	var newServices []*Service
+	for _, service := range services {
+		if err := accessible(ctx, consumerID, service.ServiceInfo.ServiceId); err != nil {
+			findFlag := fmt.Sprintf("consumer '%s' find provider %s/%s/%s", consumerID,
+				service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version)
+			log.Error(fmt.Sprintf("AccessibleFilter failed, %s", findFlag), err)
+			continue
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func filterServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+	}
+	return services, nil
+}
+
+func filterLatestServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+		if services != nil {
+			return services, nil
+		}
+	}
+	return services, nil
+}
+
+func getTags(ctx context.Context, domain string, project string, serviceID string) (tags map[string]string, err error) {
+	filter := bson.M{
+		ColumnDomain:    domain,
+		ColumnProject:   project,
+		ColumnServiceID: serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var service Service
+	err = result.Decode(&service)
+	if err != nil {
+		log.Error("type conversion error", err)
+		return nil, err
+	}
+	return service.Tags, nil
+}
+
+func getService(ctx context.Context, domain string, project string, serviceID string) (*Service, error) {
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceID}): serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var svc Service
+	err = result.Decode(&svc)
+	if err != nil {
+		return nil, err
+	}
+	return &svc, nil
+}
+
+func accessible(ctx context.Context, consumerID string, providerID string) *pb.Error {
+	if len(consumerID) == 0 {
+		return nil
+	}
+
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	consumerTenant := strings.Split(domainProject, "/")
+	providerTenant := strings.Split(targetDomainProject, "/")
+
+	consumerService, err := getService(ctx, consumerTenant[0], consumerTenant[1], consumerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query consumer(%s)", err.Error())
+	}
+	if consumerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "consumer serviceID is invalid")
+	}
+
+	// 跨应用权限
+	providerService, err := getService(ctx, providerTenant[0], providerTenant[1], providerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query provider(%s)", err.Error())
+	}
+	if providerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "provider serviceID is invalid")
+	}
+	err = allowAcrossDimension(ctx, providerService, consumerService)
+	if err != nil {
+		return pb.NewError(pb.ErrPermissionDeny, err.Error())
+	}
+
+	// 黑白名单
+	rules, err := getRulesUtil(ctx, providerTenant[0], providerTenant[1], providerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query provider rules(%s)", err.Error())
+	}
+
+	if len(rules) == 0 {
+		return nil
+	}
+
+	validateTags, err := getTags(ctx, consumerTenant[0], consumerTenant[1], consumerService.ServiceInfo.ServiceId)

Review comment:
       已经修改,非常感谢

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:
+	for _, service := range services {
+		for _, tag := range tags {
+			if _, ok := service.Tags[tag]; !ok {
+				continue loop
+			}
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func accessibleFilter(ctx context.Context, consumerID string, services []*Service) []*Service {
+	var newServices []*Service
+	for _, service := range services {
+		if err := accessible(ctx, consumerID, service.ServiceInfo.ServiceId); err != nil {
+			findFlag := fmt.Sprintf("consumer '%s' find provider %s/%s/%s", consumerID,
+				service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version)
+			log.Error(fmt.Sprintf("AccessibleFilter failed, %s", findFlag), err)
+			continue
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func filterServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+	}
+	return services, nil
+}
+
+func filterLatestServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+		if services != nil {
+			return services, nil
+		}
+	}
+	return services, nil
+}
+
+func getTags(ctx context.Context, domain string, project string, serviceID string) (tags map[string]string, err error) {
+	filter := bson.M{
+		ColumnDomain:    domain,
+		ColumnProject:   project,
+		ColumnServiceID: serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var service Service
+	err = result.Decode(&service)
+	if err != nil {
+		log.Error("type conversion error", err)
+		return nil, err
+	}
+	return service.Tags, nil
+}
+
+func getService(ctx context.Context, domain string, project string, serviceID string) (*Service, error) {
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceID}): serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var svc Service
+	err = result.Decode(&svc)
+	if err != nil {
+		return nil, err
+	}
+	return &svc, nil
+}
+
+func accessible(ctx context.Context, consumerID string, providerID string) *pb.Error {
+	if len(consumerID) == 0 {
+		return nil
+	}
+
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	consumerTenant := strings.Split(domainProject, "/")
+	providerTenant := strings.Split(targetDomainProject, "/")
+
+	consumerService, err := getService(ctx, consumerTenant[0], consumerTenant[1], consumerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query consumer(%s)", err.Error())
+	}
+	if consumerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "consumer serviceID is invalid")
+	}
+
+	// 跨应用权限
+	providerService, err := getService(ctx, providerTenant[0], providerTenant[1], providerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query provider(%s)", err.Error())
+	}
+	if providerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "provider serviceID is invalid")
+	}
+	err = allowAcrossDimension(ctx, providerService, consumerService)
+	if err != nil {
+		return pb.NewError(pb.ErrPermissionDeny, err.Error())
+	}
+
+	// 黑白名单
+	rules, err := getRulesUtil(ctx, providerTenant[0], providerTenant[1], providerID)

Review comment:
       已经修改,非常感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540748208



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:
+	for _, service := range services {
+		for _, tag := range tags {
+			if _, ok := service.Tags[tag]; !ok {
+				continue loop
+			}
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func accessibleFilter(ctx context.Context, consumerID string, services []*Service) []*Service {
+	var newServices []*Service
+	for _, service := range services {
+		if err := accessible(ctx, consumerID, service.ServiceInfo.ServiceId); err != nil {
+			findFlag := fmt.Sprintf("consumer '%s' find provider %s/%s/%s", consumerID,
+				service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version)
+			log.Error(fmt.Sprintf("AccessibleFilter failed, %s", findFlag), err)
+			continue
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func filterServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+	}
+	return services, nil
+}
+
+func filterLatestServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+		if services != nil {
+			return services, nil
+		}
+	}
+	return services, nil
+}
+
+func getTags(ctx context.Context, domain string, project string, serviceID string) (tags map[string]string, err error) {
+	filter := bson.M{
+		ColumnDomain:    domain,
+		ColumnProject:   project,
+		ColumnServiceID: serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var service Service
+	err = result.Decode(&service)
+	if err != nil {
+		log.Error("type conversion error", err)
+		return nil, err
+	}
+	return service.Tags, nil
+}
+
+func getService(ctx context.Context, domain string, project string, serviceID string) (*Service, error) {
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceID}): serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var svc Service
+	err = result.Decode(&svc)
+	if err != nil {
+		return nil, err
+	}
+	return &svc, nil
+}
+
+func accessible(ctx context.Context, consumerID string, providerID string) *pb.Error {
+	if len(consumerID) == 0 {
+		return nil
+	}
+
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	consumerTenant := strings.Split(domainProject, "/")
+	providerTenant := strings.Split(targetDomainProject, "/")
+
+	consumerService, err := getService(ctx, consumerTenant[0], consumerTenant[1], consumerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query consumer(%s)", err.Error())
+	}
+	if consumerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "consumer serviceID is invalid")
+	}
+
+	// 跨应用权限
+	providerService, err := getService(ctx, providerTenant[0], providerTenant[1], providerID)

Review comment:
       已经修改,非常感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540752177



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],

Review comment:
       已经修改,非常感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540753750



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],

Review comment:
       `if len(tenant) != 2 {
   		return nil, errors.New("invalid 'domain' or 'project'")
   	}`




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540641582



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,363 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gt": start}}

Review comment:
       这个有问题gt表达大于,已经修改,改成gte




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] DFSOrange commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
DFSOrange commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540152002



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,363 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gt": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, versionRule string, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:
+	for _, service := range services {
+		for _, tag := range tags {
+			if _, ok := service.Tags[tag]; !ok {
+				continue loop
+			}
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func accessibleFilter(ctx context.Context, consumerID string, services []*Service) []*Service {
+	var newServices []*Service
+	for _, service := range services {
+		if err := accessible(ctx, consumerID, service.ServiceInfo.ServiceId); err != nil {
+			findFlag := fmt.Sprintf("consumer '%s' find provider %s/%s/%s", consumerID,
+				service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version)
+			log.Errorf(err, "AccessibleFilter failed, %s", findFlag)
+			continue
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func filterServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Errorf(err, "type conversion error")
+			return nil, err
+		}
+		services = append(services, &service)
+	}
+	return services, nil
+}
+
+func filterLatestServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Errorf(err, "type conversion error")
+			return nil, err
+		}
+		services = append(services, &service)
+		if services != nil {
+			return services, nil
+		}
+	}
+	return services, nil
+}
+
+func getTags(ctx context.Context, domain string, project string, serviceID string) (tags map[string]string, err error) {
+	filter := bson.M{
+		ColumnDomain:    domain,
+		ColumnProject:   project,
+		ColumnServiceID: serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var service Service
+	err = result.Decode(&service)
+	if err != nil {
+		log.Errorf(err, "type conversion error")
+		return nil, err
+	}
+	return service.Tags, nil
+}
+
+func getService(ctx context.Context, domain string, project string, serviceID string) (*Service, error) {
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceID}): serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var svc Service
+	err = result.Decode(&svc)
+	if err != nil {
+		return nil, err
+	}
+	return &svc, nil
+}
+
+func accessible(ctx context.Context, consumerID string, providerID string) *pb.Error {
+	if len(consumerID) == 0 {
+		return nil
+	}
+
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	consumerTenant := strings.Split(domainProject, "/")
+	providerTenant := strings.Split(targetDomainProject, "/")
+
+	consumerService, err := getService(ctx, consumerTenant[0], consumerTenant[1], consumerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query consumer(%s)", err.Error())
+	}
+	if consumerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "consumer serviceID is invalid")
+	}
+
+	// 跨应用权限
+	providerService, err := getService(ctx, providerTenant[0], providerTenant[1], providerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query provider(%s)", err.Error())
+	}
+	if providerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "provider serviceID is invalid")
+	}
+	err = allowAcrossDimension(ctx, providerService, consumerService)
+	if err != nil {
+		return pb.NewError(pb.ErrPermissionDeny, err.Error())
+	}
+
+	// 黑白名单
+	rules, err := getRulesUtil(ctx, providerTenant[0], providerTenant[1], providerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query provider rules(%s)", err.Error())
+	}
+
+	if len(rules) == 0 {
+		return nil
+	}
+
+	validateTags, err := getTags(ctx, consumerTenant[0], consumerTenant[1], consumerService.ServiceInfo.ServiceId)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query consumer tags(%s)", err.Error())
+	}
+	return matchRules(rules, consumerService.ServiceInfo, validateTags)
+}
+
+func matchRules(rulesOfProvider []*Rule, consumer *pb.MicroService, tagsOfConsumer map[string]string) *pb.Error {
+	if consumer == nil {
+		return pb.NewError(pb.ErrInvalidParams, "consumer is nil")
+	}
+
+	if len(rulesOfProvider) <= 0 {
+		return nil
+	}
+	if rulesOfProvider[0].RuleInfo.RuleType == "WHITE" {
+		return patternWhiteList(rulesOfProvider, tagsOfConsumer, consumer)
+	}
+	return patternBlackList(rulesOfProvider, tagsOfConsumer, consumer)
+}
+
+func parsePattern(v reflect.Value, rule *pb.ServiceRule, tagsOfConsumer map[string]string, consumerID string) (string, *pb.Error) {
+	if strings.HasPrefix(rule.Attribute, "tag_") {
+		key := rule.Attribute[4:]
+		value := tagsOfConsumer[key]
+		if len(value) == 0 {
+			log.Infof("can not find service[%s] tag[%s]", consumerID, key)
+		}
+		return value, nil
+	}
+	key := v.FieldByName(rule.Attribute)
+	if !key.IsValid() {
+		log.Errorf(nil, "can not find service[%] field[%s], ruleID is %s",
+			consumerID, rule.Attribute, rule.RuleId)
+		return "", pb.NewErrorf(pb.ErrInternal, "Can not find field '%s'", rule.Attribute)
+	}
+	return key.String(), nil
+
+}
+
+func patternWhiteList(rulesOfProvider []*Rule, tagsOfConsumer map[string]string, consumer *pb.MicroService) *pb.Error {
+	v := reflect.Indirect(reflect.ValueOf(consumer))
+	consumerID := consumer.ServiceId
+	for _, rule := range rulesOfProvider {
+		value, err := parsePattern(v, rule.RuleInfo, tagsOfConsumer, consumerID)
+		if err != nil {
+			return err
+		}
+		if len(value) == 0 {
+			continue
+		}
+
+		match, _ := regexp.MatchString(rule.RuleInfo.Pattern, value)
+		if match {
+			log.Infof("consumer[%s][%s/%s/%s/%s] match white list, rule.Pattern is %s, value is %s",
+				consumerID, consumer.Environment, consumer.AppId, consumer.ServiceName, consumer.Version,
+				rule.RuleInfo.Pattern, value)
+			return nil
+		}
+	}
+	return pb.NewError(pb.ErrPermissionDeny, "Not found in white list")
+}
+
+func patternBlackList(rulesOfProvider []*Rule, tagsOfConsumer map[string]string, consumer *pb.MicroService) *pb.Error {
+	v := reflect.Indirect(reflect.ValueOf(consumer))
+	consumerID := consumer.ServiceId
+	for _, rule := range rulesOfProvider {
+		var value string
+		value, err := parsePattern(v, rule.RuleInfo, tagsOfConsumer, consumerID)
+		if err != nil {
+			return err
+		}
+		if len(value) == 0 {
+			continue
+		}
+
+		match, _ := regexp.MatchString(rule.RuleInfo.Pattern, value)
+		if match {
+			log.Warnf("no permission to access, consumer[%s][%s/%s/%s/%s] match black list, rule.Pattern is %s, value is %s",

Review comment:
       log.xxxf




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540747894



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:
+	for _, service := range services {
+		for _, tag := range tags {
+			if _, ok := service.Tags[tag]; !ok {
+				continue loop
+			}
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func accessibleFilter(ctx context.Context, consumerID string, services []*Service) []*Service {
+	var newServices []*Service
+	for _, service := range services {
+		if err := accessible(ctx, consumerID, service.ServiceInfo.ServiceId); err != nil {
+			findFlag := fmt.Sprintf("consumer '%s' find provider %s/%s/%s", consumerID,
+				service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version)
+			log.Error(fmt.Sprintf("AccessibleFilter failed, %s", findFlag), err)
+			continue
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func filterServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+	}
+	return services, nil
+}
+
+func filterLatestServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+		if services != nil {
+			return services, nil
+		}
+	}
+	return services, nil
+}
+
+func getTags(ctx context.Context, domain string, project string, serviceID string) (tags map[string]string, err error) {
+	filter := bson.M{
+		ColumnDomain:    domain,
+		ColumnProject:   project,
+		ColumnServiceID: serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var service Service
+	err = result.Decode(&service)
+	if err != nil {
+		log.Error("type conversion error", err)
+		return nil, err
+	}
+	return service.Tags, nil
+}
+
+func getService(ctx context.Context, domain string, project string, serviceID string) (*Service, error) {
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceID}): serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var svc Service
+	err = result.Decode(&svc)
+	if err != nil {
+		return nil, err
+	}
+	return &svc, nil
+}
+
+func accessible(ctx context.Context, consumerID string, providerID string) *pb.Error {
+	if len(consumerID) == 0 {
+		return nil
+	}
+
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	consumerTenant := strings.Split(domainProject, "/")
+	providerTenant := strings.Split(targetDomainProject, "/")
+
+	consumerService, err := getService(ctx, consumerTenant[0], consumerTenant[1], consumerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query consumer(%s)", err.Error())
+	}
+	if consumerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "consumer serviceID is invalid")
+	}
+
+	// 跨应用权限
+	providerService, err := getService(ctx, providerTenant[0], providerTenant[1], providerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query provider(%s)", err.Error())
+	}
+	if providerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "provider serviceID is invalid")
+	}
+	err = allowAcrossDimension(ctx, providerService, consumerService)
+	if err != nil {
+		return pb.NewError(pb.ErrPermissionDeny, err.Error())
+	}
+
+	// 黑白名单
+	rules, err := getRulesUtil(ctx, providerTenant[0], providerTenant[1], providerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query provider rules(%s)", err.Error())
+	}
+
+	if len(rules) == 0 {
+		return nil
+	}
+
+	validateTags, err := getTags(ctx, consumerTenant[0], consumerTenant[1], consumerService.ServiceInfo.ServiceId)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query consumer tags(%s)", err.Error())
+	}
+	return matchRules(rules, consumerService.ServiceInfo, validateTags)
+}
+
+func matchRules(rulesOfProvider []*Rule, consumer *pb.MicroService, tagsOfConsumer map[string]string) *pb.Error {
+	if consumer == nil {
+		return pb.NewError(pb.ErrInvalidParams, "consumer is nil")
+	}
+
+	if len(rulesOfProvider) <= 0 {
+		return nil
+	}
+	if rulesOfProvider[0].RuleInfo.RuleType == "WHITE" {
+		return patternWhiteList(rulesOfProvider, tagsOfConsumer, consumer)
+	}
+	return patternBlackList(rulesOfProvider, tagsOfConsumer, consumer)
+}
+
+func parsePattern(v reflect.Value, rule *pb.ServiceRule, tagsOfConsumer map[string]string, consumerID string) (string, *pb.Error) {
+	if strings.HasPrefix(rule.Attribute, "tag_") {
+		key := rule.Attribute[4:]
+		value := tagsOfConsumer[key]
+		if len(value) == 0 {
+			log.Info(fmt.Sprintf("can not find service[%s] tag[%s]", consumerID, key))
+		}
+		return value, nil
+	}
+	key := v.FieldByName(rule.Attribute)
+	if !key.IsValid() {
+		log.Error(fmt.Sprintf("can not find service[%s] field[%s], ruleID is %s",
+			consumerID, rule.Attribute, rule.RuleId), nil)
+		return "", pb.NewErrorf(pb.ErrInternal, "Can not find field '%s'", rule.Attribute)
+	}
+	return key.String(), nil
+
+}
+
+func patternWhiteList(rulesOfProvider []*Rule, tagsOfConsumer map[string]string, consumer *pb.MicroService) *pb.Error {
+	v := reflect.Indirect(reflect.ValueOf(consumer))
+	consumerID := consumer.ServiceId
+	for _, rule := range rulesOfProvider {
+		value, err := parsePattern(v, rule.RuleInfo, tagsOfConsumer, consumerID)
+		if err != nil {
+			return err
+		}
+		if len(value) == 0 {
+			continue
+		}
+
+		match, _ := regexp.MatchString(rule.RuleInfo.Pattern, value)
+		if match {
+			log.Info(fmt.Sprintf("consumer[%s][%s/%s/%s/%s] match white list, rule.Pattern is %s, value is %s",
+				consumerID, consumer.Environment, consumer.AppId, consumer.ServiceName, consumer.Version,
+				rule.RuleInfo.Pattern, value))
+			return nil
+		}
+	}
+	return pb.NewError(pb.ErrPermissionDeny, "Not found in white list")

Review comment:
       已经修改,感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540749701



##########
File path: datasource/mongo/ms.go
##########
@@ -1547,40 +1559,36 @@ func (ds *DataSource) GetInstances(ctx context.Context, request *pb.GetInstances
 		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
 		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version)
 
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, filter)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		log.Error(fmt.Sprintf("FindInstancesCache.Get failed %s failed", findFlag), err)
+		log.Error(fmt.Sprintf("FindInstances.Get failed %s failed", findFlag), err)
 		return &pb.GetInstancesResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
 		}, err
 	}
-	if resp == nil {
+	if services == nil {
 		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
-		log.Error("FindInstancesCache.Get failed", mes)
+		log.Error("FindInstances.Get failed", mes)
 		return &pb.GetInstancesResponse{
 			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
 		}, nil
 	}
-
-	var instances []*pb.MicroServiceInstance
-	for resp.Next(ctx) {
-		var instance Instance
-		err := resp.Decode(&instance)
-		if err != nil {
-			log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag), err)
-			return &pb.GetInstancesResponse{
-				Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
-			}, err
-		}
-		instances = append(instances, instance.InstanceInfo)
+	serviceIDs := filterServiceIDs(ctx, request.ConsumerServiceId, request.Tags, services)
+	if len(serviceIDs) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)

Review comment:
       已经修改,非常感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540749227



##########
File path: datasource/mongo/ms.go
##########
@@ -1464,44 +1469,51 @@ func (ds *DataSource) GetInstance(ctx context.Context, request *pb.GetOneInstanc
 				fmt.Sprintf("Provider[%s] does not exist.", request.ProviderServiceId)),
 		}, nil
 	}
+	findFlag := fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
+		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
+		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
+		request.ProviderInstanceId)
 
-	findFlag := func() string {
-		return fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
-			request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
-			provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
-			request.ProviderInstanceId)
-	}
-
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	findOneRes, err := client.GetMongoClient().FindOne(ctx, CollectionInstance, filter)
+	domainProject := util.ParseDomainProject(ctx)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag())
-		log.Error("FindInstances.GetWithProviderID failed", err)
+		log.Error(fmt.Sprintf("GetInstance.Get failed %s failed", findFlag), err)
 		return &pb.GetOneInstanceResponse{
-			Response: pb.CreateResponse(pb.ErrInstanceNotExists, mes.Error()),
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if services == nil {
+		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
+		log.Error("GetInstance.Get failed", mes)
+		return &pb.GetOneInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
 		}, nil
 	}
-	var instance Instance
-	err = findOneRes.Decode(&instance)
-	if err != nil {
-		log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag()), err)
+	serviceIDs := filterServiceIDs(ctx, request.ConsumerServiceId, request.Tags, services)
+	if len(serviceIDs) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)
+		log.Error("GetInstances.GetWithProviderID failed", mes)
 		return &pb.GetOneInstanceResponse{
-			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
-		}, err
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
+		}, nil
+	}
+	instances, err := findInstancesByServiceIDs(ctx, serviceIDs)
+	if len(instances) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)

Review comment:
       已经修改,非常感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540751863



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":

Review comment:
       已经修改,非常感谢

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil

Review comment:
       已经修改,非常感谢

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:

Review comment:
       已经修改,非常感谢

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {

Review comment:
       已经修改,非常感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540754256



##########
File path: datasource/mongo/ms.go
##########
@@ -1464,44 +1469,51 @@ func (ds *DataSource) GetInstance(ctx context.Context, request *pb.GetOneInstanc
 				fmt.Sprintf("Provider[%s] does not exist.", request.ProviderServiceId)),
 		}, nil
 	}
+	findFlag := fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
+		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
+		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
+		request.ProviderInstanceId)
 
-	findFlag := func() string {
-		return fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
-			request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
-			provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
-			request.ProviderInstanceId)
-	}
-
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	findOneRes, err := client.GetMongoClient().FindOne(ctx, CollectionInstance, filter)
+	domainProject := util.ParseDomainProject(ctx)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag())
-		log.Error("FindInstances.GetWithProviderID failed", err)
+		log.Error(fmt.Sprintf("GetInstance.Get failed %s failed", findFlag), err)
 		return &pb.GetOneInstanceResponse{
-			Response: pb.CreateResponse(pb.ErrInstanceNotExists, mes.Error()),
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if services == nil {
+		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
+		log.Error("GetInstance.Get failed", mes)
+		return &pb.GetOneInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
 		}, nil
 	}
-	var instance Instance
-	err = findOneRes.Decode(&instance)
-	if err != nil {
-		log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag()), err)
+	serviceIDs := filterServiceIDs(ctx, request.ConsumerServiceId, request.Tags, services)
+	if len(serviceIDs) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)
+		log.Error("GetInstances.GetWithProviderID failed", mes)
 		return &pb.GetOneInstanceResponse{
-			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
-		}, err
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
+		}, nil
+	}
+	instances, err := findInstancesByServiceIDs(ctx, serviceIDs)
+	if len(instances) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)

Review comment:
       `if services == nil || len(serviceIDs) == 0 {
   		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
   		log.Error("get instance failed", mes)
   		return &discovery.GetOneInstanceResponse{
   			Response: discovery.CreateResponse(discovery.ErrServiceNotExists, mes.Error()),
   		}, nil
   	}`




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540748306



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:
+	for _, service := range services {
+		for _, tag := range tags {
+			if _, ok := service.Tags[tag]; !ok {
+				continue loop
+			}
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func accessibleFilter(ctx context.Context, consumerID string, services []*Service) []*Service {
+	var newServices []*Service
+	for _, service := range services {
+		if err := accessible(ctx, consumerID, service.ServiceInfo.ServiceId); err != nil {
+			findFlag := fmt.Sprintf("consumer '%s' find provider %s/%s/%s", consumerID,
+				service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version)
+			log.Error(fmt.Sprintf("AccessibleFilter failed, %s", findFlag), err)
+			continue
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func filterServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+	}
+	return services, nil
+}
+
+func filterLatestServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+		if services != nil {
+			return services, nil
+		}
+	}
+	return services, nil
+}
+
+func getTags(ctx context.Context, domain string, project string, serviceID string) (tags map[string]string, err error) {
+	filter := bson.M{
+		ColumnDomain:    domain,
+		ColumnProject:   project,
+		ColumnServiceID: serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var service Service
+	err = result.Decode(&service)
+	if err != nil {
+		log.Error("type conversion error", err)
+		return nil, err
+	}
+	return service.Tags, nil
+}
+
+func getService(ctx context.Context, domain string, project string, serviceID string) (*Service, error) {
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceID}): serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var svc Service
+	err = result.Decode(&svc)
+	if err != nil {
+		return nil, err
+	}
+	return &svc, nil
+}
+
+func accessible(ctx context.Context, consumerID string, providerID string) *pb.Error {
+	if len(consumerID) == 0 {
+		return nil
+	}
+
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	consumerTenant := strings.Split(domainProject, "/")
+	providerTenant := strings.Split(targetDomainProject, "/")
+
+	consumerService, err := getService(ctx, consumerTenant[0], consumerTenant[1], consumerID)

Review comment:
       已经修改,非常感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540641351



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,363 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gt": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}

Review comment:
       这个没问题gte表示 >= ,lte表示 <=




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] tianxiaoliang commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
tianxiaoliang commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540664274



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil

Review comment:
       java可以这么写,go不可以这么写,一定要有error

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:
+	for _, service := range services {
+		for _, tag := range tags {
+			if _, ok := service.Tags[tag]; !ok {
+				continue loop
+			}
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func accessibleFilter(ctx context.Context, consumerID string, services []*Service) []*Service {
+	var newServices []*Service
+	for _, service := range services {
+		if err := accessible(ctx, consumerID, service.ServiceInfo.ServiceId); err != nil {
+			findFlag := fmt.Sprintf("consumer '%s' find provider %s/%s/%s", consumerID,
+				service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version)
+			log.Error(fmt.Sprintf("AccessibleFilter failed, %s", findFlag), err)
+			continue
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func filterServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+	}
+	return services, nil
+}
+
+func filterLatestServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+		if services != nil {
+			return services, nil
+		}
+	}
+	return services, nil
+}
+
+func getTags(ctx context.Context, domain string, project string, serviceID string) (tags map[string]string, err error) {
+	filter := bson.M{
+		ColumnDomain:    domain,
+		ColumnProject:   project,
+		ColumnServiceID: serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var service Service
+	err = result.Decode(&service)
+	if err != nil {
+		log.Error("type conversion error", err)
+		return nil, err
+	}
+	return service.Tags, nil
+}
+
+func getService(ctx context.Context, domain string, project string, serviceID string) (*Service, error) {
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceID}): serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var svc Service
+	err = result.Decode(&svc)
+	if err != nil {
+		return nil, err
+	}
+	return &svc, nil
+}
+
+func accessible(ctx context.Context, consumerID string, providerID string) *pb.Error {
+	if len(consumerID) == 0 {
+		return nil
+	}
+
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	consumerTenant := strings.Split(domainProject, "/")
+	providerTenant := strings.Split(targetDomainProject, "/")
+
+	consumerService, err := getService(ctx, consumerTenant[0], consumerTenant[1], consumerID)

Review comment:
       全有越界风险,类似问题全部检查

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:
+	for _, service := range services {
+		for _, tag := range tags {
+			if _, ok := service.Tags[tag]; !ok {
+				continue loop
+			}
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func accessibleFilter(ctx context.Context, consumerID string, services []*Service) []*Service {
+	var newServices []*Service
+	for _, service := range services {
+		if err := accessible(ctx, consumerID, service.ServiceInfo.ServiceId); err != nil {
+			findFlag := fmt.Sprintf("consumer '%s' find provider %s/%s/%s", consumerID,
+				service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version)
+			log.Error(fmt.Sprintf("AccessibleFilter failed, %s", findFlag), err)
+			continue
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func filterServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+	}
+	return services, nil
+}
+
+func filterLatestServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+		if services != nil {
+			return services, nil
+		}
+	}
+	return services, nil
+}
+
+func getTags(ctx context.Context, domain string, project string, serviceID string) (tags map[string]string, err error) {
+	filter := bson.M{
+		ColumnDomain:    domain,
+		ColumnProject:   project,
+		ColumnServiceID: serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var service Service
+	err = result.Decode(&service)
+	if err != nil {
+		log.Error("type conversion error", err)
+		return nil, err
+	}
+	return service.Tags, nil
+}
+
+func getService(ctx context.Context, domain string, project string, serviceID string) (*Service, error) {
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceID}): serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var svc Service
+	err = result.Decode(&svc)
+	if err != nil {
+		return nil, err
+	}
+	return &svc, nil
+}
+
+func accessible(ctx context.Context, consumerID string, providerID string) *pb.Error {
+	if len(consumerID) == 0 {
+		return nil
+	}
+
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	consumerTenant := strings.Split(domainProject, "/")
+	providerTenant := strings.Split(targetDomainProject, "/")
+
+	consumerService, err := getService(ctx, consumerTenant[0], consumerTenant[1], consumerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query consumer(%s)", err.Error())
+	}
+	if consumerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "consumer serviceID is invalid")
+	}
+
+	// 跨应用权限
+	providerService, err := getService(ctx, providerTenant[0], providerTenant[1], providerID)

Review comment:
       越界

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:
+	for _, service := range services {
+		for _, tag := range tags {
+			if _, ok := service.Tags[tag]; !ok {
+				continue loop
+			}
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func accessibleFilter(ctx context.Context, consumerID string, services []*Service) []*Service {
+	var newServices []*Service
+	for _, service := range services {
+		if err := accessible(ctx, consumerID, service.ServiceInfo.ServiceId); err != nil {
+			findFlag := fmt.Sprintf("consumer '%s' find provider %s/%s/%s", consumerID,
+				service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version)
+			log.Error(fmt.Sprintf("AccessibleFilter failed, %s", findFlag), err)
+			continue
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func filterServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+	}
+	return services, nil
+}
+
+func filterLatestServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+		if services != nil {
+			return services, nil
+		}
+	}
+	return services, nil
+}
+
+func getTags(ctx context.Context, domain string, project string, serviceID string) (tags map[string]string, err error) {
+	filter := bson.M{
+		ColumnDomain:    domain,
+		ColumnProject:   project,
+		ColumnServiceID: serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var service Service
+	err = result.Decode(&service)
+	if err != nil {
+		log.Error("type conversion error", err)
+		return nil, err
+	}
+	return service.Tags, nil
+}
+
+func getService(ctx context.Context, domain string, project string, serviceID string) (*Service, error) {
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceID}): serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var svc Service
+	err = result.Decode(&svc)
+	if err != nil {
+		return nil, err
+	}
+	return &svc, nil
+}
+
+func accessible(ctx context.Context, consumerID string, providerID string) *pb.Error {
+	if len(consumerID) == 0 {
+		return nil
+	}
+
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	consumerTenant := strings.Split(domainProject, "/")
+	providerTenant := strings.Split(targetDomainProject, "/")
+
+	consumerService, err := getService(ctx, consumerTenant[0], consumerTenant[1], consumerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query consumer(%s)", err.Error())
+	}
+	if consumerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "consumer serviceID is invalid")
+	}
+
+	// 跨应用权限
+	providerService, err := getService(ctx, providerTenant[0], providerTenant[1], providerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query provider(%s)", err.Error())
+	}
+	if providerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "provider serviceID is invalid")
+	}
+	err = allowAcrossDimension(ctx, providerService, consumerService)
+	if err != nil {
+		return pb.NewError(pb.ErrPermissionDeny, err.Error())
+	}
+
+	// 黑白名单
+	rules, err := getRulesUtil(ctx, providerTenant[0], providerTenant[1], providerID)

Review comment:
       越界

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:
+	for _, service := range services {
+		for _, tag := range tags {
+			if _, ok := service.Tags[tag]; !ok {
+				continue loop
+			}
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func accessibleFilter(ctx context.Context, consumerID string, services []*Service) []*Service {
+	var newServices []*Service
+	for _, service := range services {
+		if err := accessible(ctx, consumerID, service.ServiceInfo.ServiceId); err != nil {
+			findFlag := fmt.Sprintf("consumer '%s' find provider %s/%s/%s", consumerID,
+				service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version)
+			log.Error(fmt.Sprintf("AccessibleFilter failed, %s", findFlag), err)
+			continue
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func filterServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+	}
+	return services, nil
+}
+
+func filterLatestServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+		if services != nil {
+			return services, nil
+		}
+	}
+	return services, nil
+}
+
+func getTags(ctx context.Context, domain string, project string, serviceID string) (tags map[string]string, err error) {
+	filter := bson.M{
+		ColumnDomain:    domain,
+		ColumnProject:   project,
+		ColumnServiceID: serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var service Service
+	err = result.Decode(&service)
+	if err != nil {
+		log.Error("type conversion error", err)
+		return nil, err
+	}
+	return service.Tags, nil
+}
+
+func getService(ctx context.Context, domain string, project string, serviceID string) (*Service, error) {
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceID}): serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var svc Service
+	err = result.Decode(&svc)
+	if err != nil {
+		return nil, err
+	}
+	return &svc, nil
+}
+
+func accessible(ctx context.Context, consumerID string, providerID string) *pb.Error {
+	if len(consumerID) == 0 {
+		return nil
+	}
+
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	consumerTenant := strings.Split(domainProject, "/")
+	providerTenant := strings.Split(targetDomainProject, "/")
+
+	consumerService, err := getService(ctx, consumerTenant[0], consumerTenant[1], consumerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query consumer(%s)", err.Error())
+	}
+	if consumerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "consumer serviceID is invalid")
+	}
+
+	// 跨应用权限
+	providerService, err := getService(ctx, providerTenant[0], providerTenant[1], providerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query provider(%s)", err.Error())
+	}
+	if providerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "provider serviceID is invalid")
+	}
+	err = allowAcrossDimension(ctx, providerService, consumerService)
+	if err != nil {
+		return pb.NewError(pb.ErrPermissionDeny, err.Error())
+	}
+
+	// 黑白名单
+	rules, err := getRulesUtil(ctx, providerTenant[0], providerTenant[1], providerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query provider rules(%s)", err.Error())
+	}
+
+	if len(rules) == 0 {
+		return nil
+	}
+
+	validateTags, err := getTags(ctx, consumerTenant[0], consumerTenant[1], consumerService.ServiceInfo.ServiceId)

Review comment:
       越界

##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		}
+		return filterLatestServices(ctx, filter)
+	case key.Version[len(key.Version)-1:] == "+":
+		start := key.Version[:len(key.Version)-1]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start}}
+		return filterServices(ctx, filter)
+	case rangeIdx > 0:
+		start := key.Version[:rangeIdx]
+		end := key.Version[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     bson.M{"$gte": start, "$lte": end}}
+		return filterServices(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return filterServices(ctx, filter)
+	}
+}
+
+func findInstancesByServiceIDs(ctx context.Context, serviceIDs []string) ([]*pb.MicroServiceInstance, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): bson.M{"$in": serviceIDs}}, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnInstanceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	if resp == nil {
+		return nil, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			return nil, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+	return instances, nil
+}
+
+func filterServiceIDs(ctx context.Context, consumerID string, tags []string, services []*Service) []string {
+	var filterService []*Service
+	var serviceIDs []string
+	filterService = tagsFilter(services, tags)
+	filterService = accessibleFilter(ctx, consumerID, filterService)
+	for _, service := range filterService {
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return serviceIDs
+}
+
+func tagsFilter(services []*Service, tags []string) []*Service {
+	var newServices []*Service
+loop:
+	for _, service := range services {
+		for _, tag := range tags {
+			if _, ok := service.Tags[tag]; !ok {
+				continue loop
+			}
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func accessibleFilter(ctx context.Context, consumerID string, services []*Service) []*Service {
+	var newServices []*Service
+	for _, service := range services {
+		if err := accessible(ctx, consumerID, service.ServiceInfo.ServiceId); err != nil {
+			findFlag := fmt.Sprintf("consumer '%s' find provider %s/%s/%s", consumerID,
+				service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version)
+			log.Error(fmt.Sprintf("AccessibleFilter failed, %s", findFlag), err)
+			continue
+		}
+		newServices = append(newServices, service)
+	}
+	return newServices
+}
+
+func filterServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+	}
+	return services, nil
+}
+
+func filterLatestServices(ctx context.Context, filter bson.M) ([]*Service, error) {
+	resp, err := client.GetMongoClient().Find(ctx, CollectionService, filter, &options.FindOptions{
+		Sort: bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): -1}})
+	if err != nil {
+		return nil, err
+	}
+	var services []*Service
+	for resp.Next(ctx) {
+		var service Service
+		err := resp.Decode(&service)
+		if err != nil {
+			log.Error("type conversion error", err)
+			return nil, err
+		}
+		services = append(services, &service)
+		if services != nil {
+			return services, nil
+		}
+	}
+	return services, nil
+}
+
+func getTags(ctx context.Context, domain string, project string, serviceID string) (tags map[string]string, err error) {
+	filter := bson.M{
+		ColumnDomain:    domain,
+		ColumnProject:   project,
+		ColumnServiceID: serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var service Service
+	err = result.Decode(&service)
+	if err != nil {
+		log.Error("type conversion error", err)
+		return nil, err
+	}
+	return service.Tags, nil
+}
+
+func getService(ctx context.Context, domain string, project string, serviceID string) (*Service, error) {
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceID}): serviceID,
+	}
+	result, err := client.GetMongoClient().FindOne(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+	if result.Err() != nil {
+		return nil, result.Err()
+	}
+	var svc Service
+	err = result.Decode(&svc)
+	if err != nil {
+		return nil, err
+	}
+	return &svc, nil
+}
+
+func accessible(ctx context.Context, consumerID string, providerID string) *pb.Error {
+	if len(consumerID) == 0 {
+		return nil
+	}
+
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	consumerTenant := strings.Split(domainProject, "/")
+	providerTenant := strings.Split(targetDomainProject, "/")
+
+	consumerService, err := getService(ctx, consumerTenant[0], consumerTenant[1], consumerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query consumer(%s)", err.Error())
+	}
+	if consumerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "consumer serviceID is invalid")
+	}
+
+	// 跨应用权限
+	providerService, err := getService(ctx, providerTenant[0], providerTenant[1], providerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query provider(%s)", err.Error())
+	}
+	if providerService == nil {
+		return pb.NewError(pb.ErrServiceNotExists, "provider serviceID is invalid")
+	}
+	err = allowAcrossDimension(ctx, providerService, consumerService)
+	if err != nil {
+		return pb.NewError(pb.ErrPermissionDeny, err.Error())
+	}
+
+	// 黑白名单
+	rules, err := getRulesUtil(ctx, providerTenant[0], providerTenant[1], providerID)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query provider rules(%s)", err.Error())
+	}
+
+	if len(rules) == 0 {
+		return nil
+	}
+
+	validateTags, err := getTags(ctx, consumerTenant[0], consumerTenant[1], consumerService.ServiceInfo.ServiceId)
+	if err != nil {
+		return pb.NewErrorf(pb.ErrInternal, "An error occurred in query consumer tags(%s)", err.Error())
+	}
+	return matchRules(rules, consumerService.ServiceInfo, validateTags)
+}
+
+func matchRules(rulesOfProvider []*Rule, consumer *pb.MicroService, tagsOfConsumer map[string]string) *pb.Error {
+	if consumer == nil {
+		return pb.NewError(pb.ErrInvalidParams, "consumer is nil")
+	}
+
+	if len(rulesOfProvider) <= 0 {
+		return nil
+	}
+	if rulesOfProvider[0].RuleInfo.RuleType == "WHITE" {
+		return patternWhiteList(rulesOfProvider, tagsOfConsumer, consumer)
+	}
+	return patternBlackList(rulesOfProvider, tagsOfConsumer, consumer)
+}
+
+func parsePattern(v reflect.Value, rule *pb.ServiceRule, tagsOfConsumer map[string]string, consumerID string) (string, *pb.Error) {
+	if strings.HasPrefix(rule.Attribute, "tag_") {
+		key := rule.Attribute[4:]
+		value := tagsOfConsumer[key]
+		if len(value) == 0 {
+			log.Info(fmt.Sprintf("can not find service[%s] tag[%s]", consumerID, key))
+		}
+		return value, nil
+	}
+	key := v.FieldByName(rule.Attribute)
+	if !key.IsValid() {
+		log.Error(fmt.Sprintf("can not find service[%s] field[%s], ruleID is %s",
+			consumerID, rule.Attribute, rule.RuleId), nil)
+		return "", pb.NewErrorf(pb.ErrInternal, "Can not find field '%s'", rule.Attribute)
+	}
+	return key.String(), nil
+
+}
+
+func patternWhiteList(rulesOfProvider []*Rule, tagsOfConsumer map[string]string, consumer *pb.MicroService) *pb.Error {
+	v := reflect.Indirect(reflect.ValueOf(consumer))
+	consumerID := consumer.ServiceId
+	for _, rule := range rulesOfProvider {
+		value, err := parsePattern(v, rule.RuleInfo, tagsOfConsumer, consumerID)
+		if err != nil {
+			return err
+		}
+		if len(value) == 0 {
+			continue
+		}
+
+		match, _ := regexp.MatchString(rule.RuleInfo.Pattern, value)
+		if match {
+			log.Info(fmt.Sprintf("consumer[%s][%s/%s/%s/%s] match white list, rule.Pattern is %s, value is %s",
+				consumerID, consumer.Environment, consumer.AppId, consumer.ServiceName, consumer.Version,
+				rule.RuleInfo.Pattern, value))
+			return nil
+		}
+	}
+	return pb.NewError(pb.ErrPermissionDeny, "Not found in white list")

Review comment:
       小写




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540753889



##########
File path: datasource/mongo/ms.go
##########
@@ -2250,3 +2298,364 @@ func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceIn
 	instance.Version = microservice.ServiceInfo.Version
 	return nil
 }
+
+func findServices(ctx context.Context, key *pb.MicroServiceKey) ([]*Service, error) {
+	tenant := strings.Split(key.Tenant, "/")
+	rangeIdx := strings.Index(key.Version, "-")
+	switch {
+	case key.Version == "latest":
+		filter := bson.M{
+			ColumnDomain:  tenant[0],
+			ColumnProject: tenant[1],

Review comment:
       添加了相关判断




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] tianxiaoliang commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
tianxiaoliang commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540656118



##########
File path: datasource/mongo/ms.go
##########
@@ -20,20 +20,25 @@ package mongo
 import (
 	"context"
 	"fmt"
+	"reflect"
+	"regexp"
 	"strconv"
+	"strings"
 	"time"
 
+	pb "github.com/go-chassis/cari/discovery"

Review comment:
       不要用pb了,没意义

##########
File path: datasource/mongo/ms.go
##########
@@ -1464,44 +1469,51 @@ func (ds *DataSource) GetInstance(ctx context.Context, request *pb.GetOneInstanc
 				fmt.Sprintf("Provider[%s] does not exist.", request.ProviderServiceId)),
 		}, nil
 	}
+	findFlag := fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
+		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
+		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
+		request.ProviderInstanceId)
 
-	findFlag := func() string {
-		return fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
-			request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
-			provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
-			request.ProviderInstanceId)
-	}
-
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	findOneRes, err := client.GetMongoClient().FindOne(ctx, CollectionInstance, filter)
+	domainProject := util.ParseDomainProject(ctx)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag())
-		log.Error("FindInstances.GetWithProviderID failed", err)
+		log.Error(fmt.Sprintf("GetInstance.Get failed %s failed", findFlag), err)
 		return &pb.GetOneInstanceResponse{
-			Response: pb.CreateResponse(pb.ErrInstanceNotExists, mes.Error()),
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if services == nil {
+		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
+		log.Error("GetInstance.Get failed", mes)
+		return &pb.GetOneInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
 		}, nil
 	}
-	var instance Instance
-	err = findOneRes.Decode(&instance)
-	if err != nil {
-		log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag()), err)
+	serviceIDs := filterServiceIDs(ctx, request.ConsumerServiceId, request.Tags, services)
+	if len(serviceIDs) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)

Review comment:
       你这行错误和上面一模一样

##########
File path: datasource/mongo/ms.go
##########
@@ -1464,44 +1469,51 @@ func (ds *DataSource) GetInstance(ctx context.Context, request *pb.GetOneInstanc
 				fmt.Sprintf("Provider[%s] does not exist.", request.ProviderServiceId)),
 		}, nil
 	}
+	findFlag := fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
+		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
+		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
+		request.ProviderInstanceId)
 
-	findFlag := func() string {
-		return fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
-			request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
-			provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
-			request.ProviderInstanceId)
-	}
-
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	findOneRes, err := client.GetMongoClient().FindOne(ctx, CollectionInstance, filter)
+	domainProject := util.ParseDomainProject(ctx)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag())
-		log.Error("FindInstances.GetWithProviderID failed", err)
+		log.Error(fmt.Sprintf("GetInstance.Get failed %s failed", findFlag), err)
 		return &pb.GetOneInstanceResponse{
-			Response: pb.CreateResponse(pb.ErrInstanceNotExists, mes.Error()),
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if services == nil {
+		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
+		log.Error("GetInstance.Get failed", mes)
+		return &pb.GetOneInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
 		}, nil
 	}
-	var instance Instance
-	err = findOneRes.Decode(&instance)
-	if err != nil {
-		log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag()), err)
+	serviceIDs := filterServiceIDs(ctx, request.ConsumerServiceId, request.Tags, services)
+	if len(serviceIDs) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)
+		log.Error("GetInstances.GetWithProviderID failed", mes)

Review comment:
       go 的日志要开头小写,另外不要再用这种内部code来描述日志信息了,我觉得非常不合理,不是开发者,根本理解不了

##########
File path: datasource/mongo/ms.go
##########
@@ -1464,44 +1469,51 @@ func (ds *DataSource) GetInstance(ctx context.Context, request *pb.GetOneInstanc
 				fmt.Sprintf("Provider[%s] does not exist.", request.ProviderServiceId)),
 		}, nil
 	}
+	findFlag := fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
+		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
+		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
+		request.ProviderInstanceId)
 
-	findFlag := func() string {
-		return fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
-			request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
-			provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
-			request.ProviderInstanceId)
-	}
-
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	findOneRes, err := client.GetMongoClient().FindOne(ctx, CollectionInstance, filter)
+	domainProject := util.ParseDomainProject(ctx)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag())
-		log.Error("FindInstances.GetWithProviderID failed", err)
+		log.Error(fmt.Sprintf("GetInstance.Get failed %s failed", findFlag), err)
 		return &pb.GetOneInstanceResponse{
-			Response: pb.CreateResponse(pb.ErrInstanceNotExists, mes.Error()),
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if services == nil {
+		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
+		log.Error("GetInstance.Get failed", mes)
+		return &pb.GetOneInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
 		}, nil
 	}
-	var instance Instance
-	err = findOneRes.Decode(&instance)
-	if err != nil {
-		log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag()), err)
+	serviceIDs := filterServiceIDs(ctx, request.ConsumerServiceId, request.Tags, services)
+	if len(serviceIDs) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)
+		log.Error("GetInstances.GetWithProviderID failed", mes)
 		return &pb.GetOneInstanceResponse{
-			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
-		}, err
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
+		}, nil
+	}
+	instances, err := findInstancesByServiceIDs(ctx, serviceIDs)
+	if len(instances) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)

Review comment:
       一模一样的错误定义




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540749531



##########
File path: datasource/mongo/ms.go
##########
@@ -1910,14 +1922,53 @@ func registryInstance(ctx context.Context, request *pb.RegisterInstanceRequest)
 		}, err
 	}
 
-	log.Infof("register instance %s, instanceID %s, operator %s",
-		instanceFlag, insertRes.InsertedID, remoteIP)
+	log.Info(fmt.Sprintf("register instance %s, instanceID %s, operator %s",
+		instanceFlag, insertRes.InsertedID, remoteIP))
 	return &pb.RegisterInstanceResponse{
 		Response:   pb.CreateResponse(pb.ResponseSuccess, "Register service instance successfully."),
 		InstanceId: instanceID,
 	}, nil
 }
 
+func (ds *DataSource) findSharedServiceInstance(ctx context.Context, request *pb.FindInstancesRequest, provider *pb.MicroServiceKey) (*pb.FindInstancesResponse, error) {
+	var err error
+	// it means the shared micro-services must be the same env with SC.
+	provider.Environment = core.Service.Environment
+	findFlag := fmt.Sprintf("find shared provider[%s/%s/%s/%s]", provider.Environment, provider.AppId, provider.ServiceName, provider.Version)
+	services, err := findServices(ctx, provider)
+	if err != nil {
+		log.Error(fmt.Sprintf("FindInstances.Get failed %s failed", findFlag), err)

Review comment:
       已经修改,非常感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540754395



##########
File path: datasource/mongo/ms.go
##########
@@ -1464,44 +1469,51 @@ func (ds *DataSource) GetInstance(ctx context.Context, request *pb.GetOneInstanc
 				fmt.Sprintf("Provider[%s] does not exist.", request.ProviderServiceId)),
 		}, nil
 	}
+	findFlag := fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
+		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
+		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
+		request.ProviderInstanceId)
 
-	findFlag := func() string {
-		return fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
-			request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
-			provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
-			request.ProviderInstanceId)
-	}
-
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	findOneRes, err := client.GetMongoClient().FindOne(ctx, CollectionInstance, filter)
+	domainProject := util.ParseDomainProject(ctx)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag())
-		log.Error("FindInstances.GetWithProviderID failed", err)
+		log.Error(fmt.Sprintf("GetInstance.Get failed %s failed", findFlag), err)
 		return &pb.GetOneInstanceResponse{
-			Response: pb.CreateResponse(pb.ErrInstanceNotExists, mes.Error()),
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if services == nil {
+		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
+		log.Error("GetInstance.Get failed", mes)
+		return &pb.GetOneInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
 		}, nil
 	}
-	var instance Instance
-	err = findOneRes.Decode(&instance)
-	if err != nil {
-		log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag()), err)
+	serviceIDs := filterServiceIDs(ctx, request.ConsumerServiceId, request.Tags, services)
+	if len(serviceIDs) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)
+		log.Error("GetInstances.GetWithProviderID failed", mes)
 		return &pb.GetOneInstanceResponse{
-			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
-		}, err
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
+		}, nil
+	}
+	instances, err := findInstancesByServiceIDs(ctx, serviceIDs)
+	if len(instances) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)

Review comment:
       将上面的判断整合了




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540748821



##########
File path: datasource/mongo/ms.go
##########
@@ -20,20 +20,25 @@ package mongo
 import (
 	"context"
 	"fmt"
+	"reflect"
+	"regexp"
 	"strconv"
+	"strings"
 	"time"
 
+	pb "github.com/go-chassis/cari/discovery"

Review comment:
       已经修改,非常感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] tianxiaoliang merged pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
tianxiaoliang merged pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540749038



##########
File path: datasource/mongo/ms.go
##########
@@ -1464,44 +1469,51 @@ func (ds *DataSource) GetInstance(ctx context.Context, request *pb.GetOneInstanc
 				fmt.Sprintf("Provider[%s] does not exist.", request.ProviderServiceId)),
 		}, nil
 	}
+	findFlag := fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
+		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
+		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
+		request.ProviderInstanceId)
 
-	findFlag := func() string {
-		return fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
-			request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
-			provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
-			request.ProviderInstanceId)
-	}
-
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	findOneRes, err := client.GetMongoClient().FindOne(ctx, CollectionInstance, filter)
+	domainProject := util.ParseDomainProject(ctx)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag())
-		log.Error("FindInstances.GetWithProviderID failed", err)
+		log.Error(fmt.Sprintf("GetInstance.Get failed %s failed", findFlag), err)
 		return &pb.GetOneInstanceResponse{
-			Response: pb.CreateResponse(pb.ErrInstanceNotExists, mes.Error()),
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if services == nil {
+		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
+		log.Error("GetInstance.Get failed", mes)
+		return &pb.GetOneInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
 		}, nil
 	}
-	var instance Instance
-	err = findOneRes.Decode(&instance)
-	if err != nil {
-		log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag()), err)
+	serviceIDs := filterServiceIDs(ctx, request.ConsumerServiceId, request.Tags, services)
+	if len(serviceIDs) == 0 {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag)

Review comment:
       已经修改,非常感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] robotLJW commented on a change in pull request #782: [SCB-2094] Supplemenet UT of instance and problem fix

Posted by GitBox <gi...@apache.org>.
robotLJW commented on a change in pull request #782:
URL: https://github.com/apache/servicecomb-service-center/pull/782#discussion_r540749300



##########
File path: datasource/mongo/ms.go
##########
@@ -1547,40 +1559,36 @@ func (ds *DataSource) GetInstances(ctx context.Context, request *pb.GetInstances
 		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
 		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version)
 
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, filter)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		log.Error(fmt.Sprintf("FindInstancesCache.Get failed %s failed", findFlag), err)
+		log.Error(fmt.Sprintf("FindInstances.Get failed %s failed", findFlag), err)
 		return &pb.GetInstancesResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
 		}, err
 	}
-	if resp == nil {
+	if services == nil {
 		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
-		log.Error("FindInstancesCache.Get failed", mes)
+		log.Error("FindInstances.Get failed", mes)

Review comment:
       已经修改,非常感谢

##########
File path: datasource/mongo/ms.go
##########
@@ -1547,40 +1559,36 @@ func (ds *DataSource) GetInstances(ctx context.Context, request *pb.GetInstances
 		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
 		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version)
 
-	domain := util.ParseDomain(ctx)
-	project := util.ParseProject(ctx)
-	filter = bson.M{
-		ColumnDomain:  domain,
-		ColumnProject: project,
-		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
-	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, filter)
+	services, err := findServices(ctx, pb.MicroServiceToKey(domainProject, provider.ServiceInfo))
 	if err != nil {
-		log.Error(fmt.Sprintf("FindInstancesCache.Get failed %s failed", findFlag), err)
+		log.Error(fmt.Sprintf("FindInstances.Get failed %s failed", findFlag), err)

Review comment:
       已经修改,非常感谢




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org