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:
[email protected]


Reply via email to