in datasource/mongo/ms.go [1361:1437]
func (ds *MetadataManager) findInstance(ctx context.Context, request *discovery.FindInstancesRequest, provider *discovery.MicroServiceKey, rev string) (*discovery.FindInstancesResponse, error) {
var err error
domainProject := util.ParseDomainProject(ctx)
service := &model.Service{Service: &discovery.MicroService{Environment: request.Environment}}
if len(request.ConsumerServiceId) > 0 {
service, err = GetServiceByID(ctx, request.ConsumerServiceId)
if err != nil {
if errors.Is(err, datasource.ErrNoData) {
log.Debug(fmt.Sprintf("consumer does not exist, consumer %s find provider %s/%s/%s",
request.ConsumerServiceId, request.Environment, request.AppId, request.ServiceName))
return nil, discovery.NewError(discovery.ErrServiceNotExists,
fmt.Sprintf("Consumer[%s] does not exist.", request.ConsumerServiceId))
}
log.Error(fmt.Sprintf("get consumer failed, consumer %s find provider %s/%s/%s",
request.ConsumerServiceId, request.Environment, request.AppId, request.ServiceName), err)
return nil, discovery.NewError(discovery.ErrInternal, err.Error())
}
provider.Environment = service.Service.Environment
}
// provider is not a shared micro-service,
// only allow shared micro-service instances found request different domains.
ctx = util.SetTargetDomainProject(ctx, util.ParseDomain(ctx), util.ParseProject(ctx))
provider.Tenant = util.ParseTargetDomainProject(ctx)
findFlag := func() string {
return fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s/%s/%s/%s]",
request.ConsumerServiceId, service.Service.Environment, service.Service.AppId, service.Service.ServiceName, service.Service.Version,
provider.Environment, provider.AppId, provider.ServiceName, provider.Version)
}
services, err := filterServices(ctx, provider)
if err != nil {
log.Error(fmt.Sprintf("find instance failed %s", findFlag()), err)
return nil, discovery.NewError(discovery.ErrInternal, err.Error())
}
if len(services) == 0 {
mes := fmt.Errorf("%s failed, provider does not exist", findFlag())
log.Error("find instance failed", mes)
return nil, discovery.NewError(discovery.ErrServiceNotExists, mes.Error())
}
serviceIDs := filterServiceIDs(ctx, request.ConsumerServiceId, request.Tags, services)
inFilter := mutil.NewFilter(mutil.In(serviceIDs))
filter := mutil.NewFilter(mutil.InstanceServiceID(inFilter))
option := &options.FindOptions{Sort: bson.M{mutil.ConnectWithDot([]string{model.ColumnInstance, model.ColumnVersion}): -1}}
instances, err := dao.GetMicroServiceInstances(ctx, filter, option)
if err != nil {
log.Error(fmt.Sprintf("find instance failed %s", findFlag()), err)
return nil, discovery.NewError(discovery.ErrInternal, err.Error())
}
// add dependency queue
if len(request.ConsumerServiceId) > 0 &&
len(serviceIDs) > 0 {
provider, err = ds.reshapeProviderKey(ctx, provider, serviceIDs[0])
if err != nil {
return nil, err
}
if provider != nil {
err = AddServiceVersionRule(ctx, domainProject, service.Service, provider)
} else {
mes := fmt.Errorf("%s failed, provider does not exist", findFlag())
log.Error("add service version rule failed", mes)
return nil, discovery.NewError(discovery.ErrServiceNotExists, mes.Error())
}
if err != nil {
log.Error(fmt.Sprintf("add service version rule failed %s", findFlag()), err)
return nil, discovery.NewError(discovery.ErrInternal, err.Error())
}
}
newRev, _ := formatRevision(request.ConsumerServiceId, instances)
if rev == newRev {
instances = nil // for gRPC
}
_ = util.WithResponseRev(ctx, newRev)
return &discovery.FindInstancesResponse{
Instances: instances,
}, nil
}