Beispiel #1
0
            private void RaiseResult(ResolverResult result)
            {
                if (_listener != null)
                {
                    if (result.Addresses != null)
                    {
                        var policyName = _balancerConfiguration.LoadBalancerPolicyName switch
                        {
                            LoadBalancerName.PickFirst => "pick_first",
                            LoadBalancerName.RoundRobin => "round_robin",
                            _ => throw new InvalidOperationException("Unexpected load balancer.")
                        };

                        var serviceConfig = new ServiceConfig
                        {
                            LoadBalancingConfigs = { new LoadBalancingConfig(policyName) }
                        };

                        // DNS results change order between refreshes.
                        // Explicitly order by host to keep result order consistent.
                        var orderedAddresses = result.Addresses.OrderBy(a => a.EndPoint.Host).ToList();
                        _listener(ResolverResult.ForResult(orderedAddresses, serviceConfig, Status.DefaultSuccess));
                    }
                    else
                    {
                        _listener(ResolverResult.ForFailure(result.Status));
                    }
                }
            }
 private Schema CreateSchema()
 {
     return Schema.Create(@"
         type Query {
             a: String
             b(a: String!): String
             x: String
             y: String
             xasync: String
             yasync: String
         }
         ", c =>
     {
         c.BindResolver(() => "hello world a")
             .To("Query", "a");
         c.BindResolver(
             ctx => "hello world " + ctx.Argument<string>("a"))
             .To("Query", "b");
         c.BindResolver(
             () => ResolverResult<string>.CreateValue("hello world x"))
             .To("Query", "x");
         c.BindResolver(
             () => ResolverResult<string>.CreateError("hello world y"))
             .To("Query", "y");
         c.BindResolver(
             async () => await Task.FromResult(
                 ResolverResult<string>.CreateValue("hello world xasync")))
             .To("Query", "xasync");
         c.BindResolver(
             async () => await Task.FromResult(
                 ResolverResult<string>.CreateError("hello world yasync")))
             .To("Query", "yasync");
     });
 }
Beispiel #3
0
        protected override async Task ResolveAsync(CancellationToken cancellationToken)
        {
            if (_onRefreshAsync != null)
            {
                await _onRefreshAsync();
            }

            Listener(_result ?? ResolverResult.ForResult(Array.Empty <BalancerAddress>(), serviceConfig: null, serviceConfigStatus: null));
            _hasResolvedTcs.TrySetResult(null);
        }
        private static IResolverResult <long> GetTotalCount(
            IResolverContext context)
        {
            IConnection connection = context.Parent <IConnection>();

            if (connection.PageInfo.TotalCount.HasValue)
            {
                return(ResolverResult.CreateValue(
                           connection.PageInfo.TotalCount.Value));
            }
            return(ResolverResult.CreateError <long>(
                       "The total count was not provided by the connection."));
        }
        public static async Task <ResolverResult <THco> > TryResolveAsync <THco>(
            this HypermediaLink <THco> link)
            where THco : HypermediaClientObject
        {
            if (link.Uri == null)
            {
                return(ResolverResult.Failed <THco>());
            }

            var result = await link.Resolver.ResolveLinkAsync <THco>(link.Uri);

            return(result);
        }
        protected override XamlType GetXamlType(string xamlNamespace, string name, params XamlType[] typeArguments)
        {
            XamlType xamlType = base.GetXamlType(xamlNamespace, name, typeArguments);

            if (xamlType == null || xamlType.UnderlyingType == null)
            {
                return(xamlType);
            }

            ResolverResult resolverResult = MultiTargetingTypeResolver.Resolve(this.multiTargetingService, xamlType.UnderlyingType);

            return(MultiTargetingTypeResolver.GetXamlType(resolverResult, xamlType));
        }
Beispiel #7
0
        public static async Task <ResolverResult <TResult> > NavigateAsync <TIn, TResult>(
            this ResolverResult <TIn> resultIn,
            Func <TIn, HypermediaLink <TResult> > linkSelector)
            where TIn : HypermediaClientObject
            where TResult : HypermediaClientObject
        {
            if (!resultIn.Success)
            {
                return(ResolverResult.Failed <TResult>());
            }

            return(await linkSelector(resultIn.ResultObject).TryResolveAsync());
        }
        private Schema CreateSchema()
        {
            return(Schema.Create(@"
                type Query {
                    a: String
                    b(a: String!): String
                    x: String
                    y: String
                    z(foo: Foo): String
                    xasync: String
                    yasync: String
                }

                input Foo {
                    bar: Bar!
                }

                input Bar {
                    baz: String!
                }
                ", c =>
            {
                c.BindResolver(() => "hello world a")
                .To("Query", "a");
                c.BindResolver(
                    ctx => "hello world " + ctx.ArgumentValue <string>("a"))
                .To("Query", "b");
                c.BindResolver(
                    () => ResolverResult <string>
                    .CreateValue("hello world x"))
                .To("Query", "x");
                c.BindResolver(
                    () => ResolverResult <string>
                    .CreateError("hello world y"))
                .To("Query", "y");
                c.BindResolver(() => "hello world z")
                .To("Query", "z");
                c.BindResolver(
                    async() => await Task.FromResult(
                        ResolverResult <string>
                        .CreateValue("hello world xasync")))
                .To("Query", "xasync");
                c.BindResolver(
                    async() => await Task.FromResult(
                        ResolverResult <string>
                        .CreateError("hello world yasync")))
                .To("Query", "yasync");
            }));
        }
Beispiel #9
0
    protected override async Task ResolveAsync(CancellationToken cancellationToken)
    {
        var address = _address.Host.Replace("consul://", string.Empty);
        var _consulServiceProvider = new DiscoverProviderBuilder(_client).WithServiceName(address).WithCacheSeconds(5).Build();
        var results = await _consulServiceProvider.GetAllHealthServicesAsync();

        var balancerAddresses = new List <BalancerAddress>();

        results.ForEach(result =>
        {
            var addressArray = result.Split(":");
            var host         = addressArray[0];
            var port         = int.Parse(addressArray[1]) + 1;
            balancerAddresses.Add(new BalancerAddress(host, port));
        });
        // Pass the results back to the channel.
        Listener(ResolverResult.ForResult(balancerAddresses));
    }
        public async Task ScheduleAsync_When_TransporterPresent_RecipientResolverReturnsObject_Then_NotificationSaved()
        {
            // Arrange
            var mock           = new MockNotificationService();
            var recipient      = new Recipient();
            var content        = new NotificationContent();
            var resolverResult = new ResolverResult()
            {
                ToAddress = "*****@*****.**"
            };

            var expectedAddedNotifications = new INotificationData[]
            {
                new MockNotificationData()
            };

            mock.SetupTransporters();
            mock.MockNotificationRecipientResolver.Setup(x => x.ResolveAsync(recipient, content, mock.MockNotificationTransporter.Object.TransporterType))
            .Returns(Task.FromResult <object>(resolverResult));


            mock.MockNotificationRepository.Setup(x => x.AddAsync(It.Is <IEnumerable <CreatableNotification> >((creatables) => creatables.Count() == 1 &&
                                                                                                               creatables.FirstOrDefault(item => item.TransportType == mock.MockNotificationTransporter.Object.TransporterType &&
                                                                                                                                         item.Recipients == resolverResult &&
                                                                                                                                         item.NotificationType == content.NotificationType &&
                                                                                                                                         item.Content == content) != null)))
            .Returns(Task.FromResult <IEnumerable <INotificationData> >(expectedAddedNotifications));

            // Act
            var result = await mock.Service.ScheduleAsync(content, recipient);

            // Assert
            Assert.Single(result);
            Assert.Equal(expectedAddedNotifications, result);

            mock.MockNotificationRecipientResolver.Verify(x => x.ResolveAsync(recipient, content, mock.MockNotificationTransporter.Object.TransporterType), Times.Once);
            mock.MockNotificationRepository.Verify(x => x.AddAsync(It.IsAny <IEnumerable <CreatableNotification> >()), Times.Once);
        }
        public async Task ScheduleAndExecuteAsync_When_NotificationCreated_NotificationNotSent_Then_ScheduledReturned()
        {
            // Arrange
            var mock      = new MockNotificationService();
            var recipient = new Recipient();
            var content   = new NotificationContent();

            var resolverResult = new ResolverResult()
            {
                ToAddress = "*****@*****.**"
            };

            var expectedAddedNotifications = new INotificationData[]
            {
                new MockNotificationData()
                {
                    TransportType = mock.MockNotificationTransporter.Object.TransporterType
                }
            };

            mock.SetupTransporters();
            mock.MockNotificationRecipientResolver.Setup(x => x.ResolveAsync(recipient, content, mock.MockNotificationTransporter.Object.TransporterType))
            .Returns(Task.FromResult <object>(resolverResult));


            mock.MockNotificationRepository.Setup(x => x.AddAsync(It.Is <IEnumerable <CreatableNotification> >((creatables) => creatables.Count() == 1 &&
                                                                                                               creatables.FirstOrDefault(item => item.TransportType == mock.MockNotificationTransporter.Object.TransporterType &&
                                                                                                                                         item.Recipients == resolverResult &&
                                                                                                                                         item.NotificationType == content.NotificationType &&
                                                                                                                                         item.Content == content) != null)))
            .Returns(Task.FromResult <IEnumerable <INotificationData> >(expectedAddedNotifications));

            var expectedNextSchedule = DateTime.UtcNow.AddSeconds(60);

            mock.MockNotificationTransporter.Setup(x => x.SendAsync(expectedAddedNotifications[0].NotificationType,
                                                                    expectedAddedNotifications[0].Recipients,
                                                                    expectedAddedNotifications[0].Content))
            .Callback(() => throw new SystemException());

            // Act
            var result = await mock.Service.ScheduleAndExecuteAsync(content, recipient);

            // Assert
            Assert.Equal(NotifyStatus.Scheduled, result);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(expectedAddedNotifications[0].Id,
                                                                      NotificationState.Processing,
                                                                      0,
                                                                      null,
                                                                      null),
                                                   Times.Once);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(expectedAddedNotifications[0].Id,
                                                                      NotificationState.WaitingForRetry,
                                                                      1,
                                                                      It.IsAny <string>(),
                                                                      It.Is <DateTime>((value) => value >= expectedNextSchedule)),
                                                   Times.Once);


            mock.MockNotificationTransporter.Verify(x => x.SendAsync(expectedAddedNotifications[0].NotificationType,
                                                                     expectedAddedNotifications[0].Recipients,
                                                                     expectedAddedNotifications[0].Content),
                                                    Times.Once);
        }
Beispiel #12
0
 public void UpdateResult(ResolverResult result)
 {
     _result = result;
     Listener?.Invoke(result);
 }
Beispiel #13
0
 public void UpdateError(Status status)
 {
     UpdateResult(ResolverResult.ForFailure(status));
 }
Beispiel #14
0
 public void UpdateAddresses(List <BalancerAddress> addresses, ServiceConfig?serviceConfig = null, Status?serviceConfigStatus = null)
 {
     UpdateResult(ResolverResult.ForResult(addresses, serviceConfig, serviceConfigStatus));
 }
        private void OnResolverResult(ResolverResult result)
        {
            if (_balancer == null)
            {
                throw new InvalidOperationException($"Load balancer not configured.");
            }

            var channelStatus = result.Status;

            // https://github.com/grpc/proposal/blob/master/A21-service-config-error-handling.md
            // Additionally, only use resolved service config if not disabled.
            LoadBalancingConfig?loadBalancingConfig = null;

            if (!DisableResolverServiceConfig)
            {
                ServiceConfig?workingServiceConfig = null;
                if (result.ServiceConfig == null)
                {
                    // Step 4 and 5
                    if (result.ServiceConfigStatus == null)
                    {
                        // Step 5: Use default service config if none is provided.
                        _previousServiceConfig = DefaultServiceConfig;
                        workingServiceConfig   = DefaultServiceConfig;
                    }
                    else
                    {
                        // Step 4
                        if (_previousServiceConfig == null)
                        {
                            // Step 4.ii: If no config was provided or set previously, then treat resolution as a failure.
                            channelStatus = result.ServiceConfigStatus.GetValueOrDefault();
                        }
                        else
                        {
                            // Step 4.i: Continue using previous service config if it was set and a new one is not provided.
                            workingServiceConfig = _previousServiceConfig;
                            ConnectionManagerLog.ResolverServiceConfigFallback(Logger, result.ServiceConfigStatus.GetValueOrDefault());
                        }
                    }
                }
                else
                {
                    // Step 3: Use provided service config if it is set.
                    workingServiceConfig   = result.ServiceConfig;
                    _previousServiceConfig = result.ServiceConfig;
                }


                if (workingServiceConfig?.LoadBalancingConfigs.Count > 0)
                {
                    if (!ChildHandlerLoadBalancer.TryGetValidServiceConfigFactory(workingServiceConfig.LoadBalancingConfigs, LoadBalancerFactories, out loadBalancingConfig, out var _))
                    {
                        ConnectionManagerLog.ResolverUnsupportedLoadBalancingConfig(Logger, workingServiceConfig.LoadBalancingConfigs);
                    }
                }
            }
            else
            {
                if (result.ServiceConfig != null)
                {
                    ConnectionManagerLog.ResolverServiceConfigNotUsed(Logger);
                }
            }

            var state = new ChannelState(
                channelStatus,
                result.Addresses,
                loadBalancingConfig,
                BalancerAttributes.Empty);

            lock (_lock)
            {
                _balancer.UpdateChannelState(state);
                _resolverStartedTcs.TrySetResult(null);
            }
        }
Beispiel #16
0
        /**
         * Resolves the given query, returning a QueryResult that contains
         * everything we found while doing the resolution.
         */
        public QueryResult Execute(Domain domain, ResourceRecordType rtype, AddressClass addr_class, bool recursive)
        {
            logger.Trace("Executing query on {0} for type {1} with recursion {2}",
                         domain, rtype, recursive);

            if (zone.IsAuthorityFor(domain))
            {
                var records = zone.Query(domain, rtype, addr_class).ToList();

                // It is possible that there is a CNAME that we should be aware of - in that case, check
                // it and see if we can find one.
                if (records.Count == 0)
                {
                    var cname_records = zone.Query(domain, ResourceRecordType.CANONICAL_NAME, addr_class).ToArray();

                    if (cname_records.Length != 0)
                    {
                        logger.Trace("Authoritative for CNAMEs, re-executing");

                        // In this case, try again with the alias
                        var alias         = ((CNAMEResource)cname_records[0].Resource).Alias;
                        var alias_results = Execute(alias, rtype, addr_class, recursive);

                        // The RFC directs us to return any intermediate CNAMEs, which we do
                        alias_results.Answers.InsertRange(0, cname_records);

                        return(alias_results);
                    }
                }

                var result = new QueryResult();
                result.IsAuthority = true;
                result.FoundAnswer = true;
                result.Answers     = new List <DNSRecord>();
                result.Authority   = new List <DNSRecord>();
                result.Additional  = new List <DNSRecord>();

                result.Answers.AddRange(records);
                result.Authority.Add(zone.StartOfAuthority);
                return(result);
            }
            else
            {
                var owning_subzone = zone.FindSubZone(domain);
                if (owning_subzone != null)
                {
                    logger.Trace("Subzone {0} is authoritative", owning_subzone);

                    // We can punt on the computation to our subzone delgation
                    var subzone_nameservers             = zone.Query(owning_subzone, ResourceRecordType.NAME_SERVER, addr_class);
                    var subzone_nameserver_addr_records = subzone_nameservers
                                                          .SelectMany(ns => zone.Query(ns.Name, ResourceRecordType.HOST_ADDRESS, addr_class));
                    var subzone_nameserver_addrs = subzone_nameserver_addr_records.Select(
                        record => new IPEndPoint(((AResource)record.Resource).Address, 53)
                        ).ToArray();

                    IEnumerable <DNSRecord> response = null;
                    try
                    {
                        var info = resolver.Resolve(domain, ResourceRecordType.HOST_ADDRESS, addr_class, subzone_nameserver_addrs);
                        response = info.aliases.Concat(info.answers).ToList();
                    }
                    catch (ResolverException err)
                    {
                        logger.Trace("Could not resolve from subzone: {0}", err);
                        response = new DNSRecord[] { };
                    }

                    var result = new QueryResult();
                    result.IsAuthority = false;
                    result.FoundAnswer = response.Count() > 0;
                    result.Answers     = new List <DNSRecord>(response);
                    result.Authority   = new List <DNSRecord>(subzone_nameservers);
                    result.Additional  = new List <DNSRecord>(subzone_nameserver_addr_records);
                    return(result);
                }
                else if (recursive)
                {
                    // We'll have to go outside our zone and use the general-purpose resolver
                    ResolverResult response;
                    logger.Trace("No authoritative server is local, executing recursive resolver");

                    try
                    {
                        response = resolver.Resolve(domain, rtype, addr_class, zone.Relays);
                    }
                    catch (ResolverException err)
                    {
                        logger.Trace("Could not resolve: {0}", err);

                        response                     = new ResolverResult();
                        response.answers             = new List <DNSRecord>();
                        response.aliases             = new List <DNSRecord>();
                        response.referrals           = new List <DNSRecord>();
                        response.referral_additional = new List <DNSRecord>();
                    }

                    var result = new QueryResult();
                    result.IsAuthority = false;
                    result.FoundAnswer = response.answers.Count() > 0;
                    result.Answers     = response.aliases.Concat(response.answers).ToList();
                    result.Authority   = response.referrals.ToList();
                    result.Additional  = response.referral_additional.ToList();
                    return(result);
                }
                else
                {
                    var cached_responses = cache.Query(domain, AddressClass.INTERNET, rtype);
                    if (cached_responses.Count > 0)
                    {
                        logger.Trace("Non-recursive search found {0} cached results", cached_responses.Count);

                        var cached_result = new QueryResult();
                        cached_result.IsAuthority = false;
                        cached_result.FoundAnswer = true;
                        cached_result.Answers     = cached_responses.ToList();
                        cached_result.Additional  = new List <DNSRecord>();
                        cached_result.Authority   = new List <DNSRecord>();
                        return(cached_result);
                    }

                    // If we can't recurse, and our cache knows nothing, then punt onto the forwarder
                    logger.Trace("Executing limited-case non-recursive resolver");

                    var question = new DNSQuestion(domain, rtype, AddressClass.INTERNET);

                    foreach (var forwarder in zone.Relays)
                    {
                        try
                        {
                            var forward_result = ResolverUtils.SendQuery(forwarder, question, false);

                            // If the server doesn't like our request, then pass it to something else
                            if (forward_result.ResponseType != ResponseType.NO_ERROR &&
                                forward_result.ResponseType != ResponseType.NAME_ERROR)
                            {
                                continue;
                            }

                            var forward_return = new QueryResult();
                            forward_return.FoundAnswer = forward_result.ResponseType == ResponseType.NO_ERROR;
                            forward_return.IsAuthority = false;
                            forward_return.Answers     = forward_result.Answers.ToList();
                            forward_return.Additional  = forward_result.AdditionalRecords.ToList();
                            forward_return.Authority   = forward_result.AuthoritativeAnswers.ToList();
                            return(forward_return);
                        }
                        catch (SocketException err)
                        {
                            // We can safely punt onto the next forwarder if one bails
                            logger.Trace("Could not request from {0}: {1}", forwarder, err);
                        }
                    }

                    // We can't do anything else here, so there is no such host, as far as we knot
                    var result = new QueryResult();
                    result.FoundAnswer = false;
                    result.IsAuthority = false;
                    result.Answers     = new List <DNSRecord>();
                    result.Authority   = new List <DNSRecord>();
                    result.Additional  = new List <DNSRecord>();
                    return(result);
                }
            }
        }
        public async Task ScheduleAndExecuteAsync_When_NotificationCreated_NotificationSent_Then_SuccessfulReturned(bool isErrorsCollectionNull)
        {
            // Arrange
            var mock      = new MockNotificationService();
            var recipient = new Recipient();
            var content   = new NotificationContent();

            var resolverResult = new ResolverResult()
            {
                ToAddress = "*****@*****.**"
            };

            var expectedAddedNotifications = new INotificationData[]
            {
                new MockNotificationData()
                {
                    TransportType = mock.MockNotificationTransporter.Object.TransporterType
                }
            };

            mock.SetupTransporters();
            mock.MockNotificationRecipientResolver.Setup(x => x.ResolveAsync(recipient, content, mock.MockNotificationTransporter.Object.TransporterType))
            .Returns(Task.FromResult <object>(resolverResult));


            mock.MockNotificationRepository.Setup(x => x.AddAsync(It.Is <IEnumerable <CreatableNotification> >((creatables) => creatables.Count() == 1 &&
                                                                                                               creatables.FirstOrDefault(item => item.TransportType == mock.MockNotificationTransporter.Object.TransporterType &&
                                                                                                                                         item.Recipients == resolverResult &&
                                                                                                                                         item.NotificationType == content.NotificationType &&
                                                                                                                                         item.Content == content) != null)))
            .Returns(Task.FromResult <IEnumerable <INotificationData> >(expectedAddedNotifications));

            mock.MockNotificationTransporter.Setup(x => x.SendAsync(expectedAddedNotifications[0].NotificationType,
                                                                    expectedAddedNotifications[0].Recipients,
                                                                    expectedAddedNotifications[0].Content))
            .Returns(Task.FromResult <IEnumerable <string> >(isErrorsCollectionNull ? null : new string[0]));

            // Act
            var result = await mock.Service.ScheduleAndExecuteAsync(content, recipient);

            // Assert
            Assert.Equal(NotifyStatus.Successful, result);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(expectedAddedNotifications[0].Id,
                                                                      NotificationState.Processing,
                                                                      0,
                                                                      null,
                                                                      null),
                                                   Times.Once);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(expectedAddedNotifications[0].Id,
                                                                      NotificationState.Successful,
                                                                      0,
                                                                      null,
                                                                      null),
                                                   Times.Once);


            mock.MockNotificationTransporter.Verify(x => x.SendAsync(expectedAddedNotifications[0].NotificationType,
                                                                     expectedAddedNotifications[0].Recipients,
                                                                     expectedAddedNotifications[0].Content),
                                                    Times.Once);
        }