Ejemplo n.º 1
0
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            try
            {
                IAsyncPolicy policy;

                if (_qoSProvider.CircuitBreaker.Policies.Length == 1)
                {
                    policy = _qoSProvider.CircuitBreaker.Policies[0];
                }
                else
                {
                    policy = Policy.WrapAsync(_qoSProvider.CircuitBreaker.Policies);
                }

                return(await policy.ExecuteAsync(() => base.SendAsync(request, cancellationToken)));
            }
            catch (BrokenCircuitException ex)
            {
                _logger.LogError($"Reached to allowed number of exceptions. Circuit is open", ex);
                throw;
            }
            catch (HttpRequestException ex)
            {
                _logger.LogError($"Error in CircuitBreakingDelegatingHandler.SendAync", ex);
                throw;
            }
        }
        public async Task Invoke(HttpContext context)
        {
            var upstreamUrlPath = context.Request.Path.ToString();

            //todo make this getting config its own middleware one day?
            var configuration = await _configProvider.Get();

            if (configuration.IsError)
            {
                _logger.LogError($"{MiddlewareName} setting pipeline errors. IOcelotConfigurationProvider returned {configuration.Errors.ToErrorString()}");
                SetPipelineError(configuration.Errors);
            }

            SetServiceProviderConfigurationForThisRequest(configuration.Data.ServiceProviderConfiguration);

            _logger.LogDebug("upstream url path is {upstreamUrlPath}", upstreamUrlPath);

            var downstreamRoute = _downstreamRouteFinder.FindDownstreamRoute(upstreamUrlPath, context.Request.Method, configuration.Data);

            if (downstreamRoute.IsError)
            {
                _logger.LogError($"{MiddlewareName} setting pipeline errors. IDownstreamRouteFinder returned {downstreamRoute.Errors.ToErrorString()}");

                SetPipelineError(downstreamRoute.Errors);
                return;
            }

            _logger.LogDebug("downstream template is {downstreamRoute.Data.ReRoute.DownstreamPath}", downstreamRoute.Data.ReRoute.DownstreamPathTemplate);

            SetDownstreamRouteForThisRequest(downstreamRoute.Data);

            await _next.Invoke(context);
        }
Ejemplo n.º 3
0
        public async Task Invoke(HttpContext context)
        {
            _logger.TraceMiddlewareEntry();

            if (IsAuthenticatedRoute(DownstreamRoute.ReRoute))
            {
                _logger.LogDebug($"{context.Request.Path} is an authenticated route. {MiddlwareName} checking if client is authenticated");

                var authenticationHandler = _authHandlerFactory.Get(_app, DownstreamRoute.ReRoute.AuthenticationOptions);

                if (authenticationHandler.IsError)
                {
                    _logger.LogError($"Error getting authentication handler for {context.Request.Path}. {authenticationHandler.Errors.ToErrorString()}");
                    SetPipelineError(authenticationHandler.Errors);
                    _logger.TraceMiddlewareCompleted();
                    return;
                }

                await authenticationHandler.Data.Handler.Handle(context);


                if (context.User.Identity.IsAuthenticated)
                {
                    _logger.LogDebug($"Client has been authenticated for {context.Request.Path}");

                    _logger.TraceInvokeNext();
                    await _next.Invoke(context);

                    _logger.TraceInvokeNextCompleted();
                    _logger.TraceMiddlewareCompleted();
                }
                else
                {
                    var error = new List <Error>
                    {
                        new UnauthenticatedError(
                            $"Request for authenticated route {context.Request.Path} by {context.User.Identity.Name} was unauthenticated")
                    };

                    _logger.LogError($"Client has NOT been authenticated for {context.Request.Path} and pipeline error set. {error.ToErrorString()}");
                    SetPipelineError(error);

                    _logger.TraceMiddlewareCompleted();
                    return;
                }
            }
            else
            {
                _logger.LogTrace($"No authentication needed for {context.Request.Path}");

                _logger.TraceInvokeNext();
                await _next.Invoke(context);

                _logger.TraceInvokeNextCompleted();
                _logger.TraceMiddlewareCompleted();
            }
        }
Ejemplo n.º 4
0
        public async Task <List <Service> > Get()
        {
            // 如果Consul有问题会导致网关异常
            //var queryResult = await _consul.Health.Service(_config.KeyOfServiceInConsul, string.Empty, true);
            if (_config.KeyOfServiceInConsul == string.Empty)
            {
                return(new List <Service>());
            }
            QueryResult <ServiceEntry[]> queryResult = new QueryResult <ServiceEntry[]>();

            try
            {
                queryResult = await _consul.Health.Service(_config.KeyOfServiceInConsul, string.Empty, true);
            }
            catch (Exception ex)
            {
                _logger.LogError($"_consul.Health.Service异常{_config.KeyOfServiceInConsul}", ex);
                return(await GetServiceFromCache(_config.KeyOfServiceInConsul));
            }

            var services = new List <Service>();

            foreach (var serviceEntry in queryResult.Response)
            {
                if (IsValid(serviceEntry))
                {
                    try
                    {
                        var nodes = await _consul.Catalog.Nodes();

                        if (nodes.Response == null)
                        {
                            services.Add(BuildService(serviceEntry, null));
                        }
                        else
                        {
                            var serviceNode = nodes.Response.FirstOrDefault(n => n.Address == serviceEntry.Service.Address);
                            services.Add(BuildService(serviceEntry, serviceNode));
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"_consul.Catalog.Nodes异常{serviceEntry.Service}", ex);
                        return(await GetServiceFromCache(_config.KeyOfServiceInConsul));
                    }
                }
                else
                {
                    _logger.LogWarning($"Unable to use service Address: {serviceEntry.Service.Address} and Port: {serviceEntry.Service.Port} as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0");
                }
            }

            await ServiceToCache(_config.KeyOfServiceInConsul, services);

            return(services.ToList());
        }
Ejemplo n.º 5
0
        public PollyQoSProvider(ReRoute reRoute, IOcelotLoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger <PollyQoSProvider>();

            _timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(reRoute.QosOptionsOptions.TimeoutValue), reRoute.QosOptionsOptions.TimeoutStrategy);

            _circuitBreakerPolicy = Policy
                                    .Handle <HttpRequestException>()
                                    .Or <TimeoutRejectedException>()
                                    .Or <TimeoutException>()
                                    .CircuitBreakerAsync(
                exceptionsAllowedBeforeBreaking: reRoute.QosOptionsOptions.ExceptionsAllowedBeforeBreaking,
                durationOfBreak: TimeSpan.FromMilliseconds(reRoute.QosOptionsOptions.DurationOfBreak),
                onBreak: (ex, breakDelay) =>
            {
                _logger.LogError(
                    ".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex);
            },
                onReset: () =>
            {
                _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again.");
            },
                onHalfOpen: () =>
            {
                _logger.LogDebug(".Breaker logging: Half-open; next call is a trial.");
            }
                );

            _circuitBreaker = new CircuitBreaker(_circuitBreakerPolicy, _timeoutPolicy);
        }
Ejemplo n.º 6
0
        public async Task Invoke(DownstreamContext context)
        {
            if (IsAuthenticatedRoute(context.DownstreamReRoute))
            {
                _logger.LogDebug($"{context.HttpContext.Request.Path} is an authenticated route. {MiddlewareName} checking if client is authenticated");

                var result = await context.HttpContext.AuthenticateAsync(context.DownstreamReRoute.AuthenticationOptions.AuthenticationProviderKey);

                context.HttpContext.User = result.Principal;

                if (context.HttpContext.User.Identity.IsAuthenticated)
                {
                    _logger.LogDebug($"Client has been authenticated for {context.HttpContext.Request.Path}");
                    await _next.Invoke(context);
                }
                else
                {
                    var error = new List <Error>
                    {
                        new UnauthenticatedError(
                            $"Request for authenticated route {context.HttpContext.Request.Path} by {context.HttpContext.User.Identity.Name} was unauthenticated")
                    };

                    _logger.LogError($"Client has NOT been authenticated for {context.HttpContext.Request.Path} and pipeline error set. {error.ToErrorString()}");

                    SetPipelineError(context, error);
                }
            }
            else
            {
                _logger.LogTrace($"No authentication needed for {context.HttpContext.Request.Path}");

                await _next.Invoke(context);
            }
        }
Ejemplo n.º 7
0
        public async Task <IActionResult> Command()
        {
            try
            {
                using (var reader = new StreamReader(HttpContext.Request.Body))
                {
                    var json = await reader.ReadToEndAsync();

                    var command = JsonConvert.DeserializeObject <ICommand>(json, _jsonSerialiserSettings);

                    _logger.LogDebug($"{_baseSchemeUrlAndPort}/command called, my state is {_node.State.GetType().FullName}");

                    var commandResponse = await _node.Accept(command);

                    json = JsonConvert.SerializeObject(commandResponse, _jsonSerialiserSettings);

                    return(StatusCode(200, json));
                }
            }
            catch (Exception e)
            {
                _logger.LogError($"THERE WAS A PROBLEM ON NODE {_node.State.CurrentState.Id}", e);
                throw;
            }
        }
        public async Task Invoke(HttpContext context)
        {
            _logger.TraceMiddlewareEntry();

            var upstreamUrlPath = context.Request.Path.ToString().SetLastCharacterAs('/');

            _logger.LogDebug("upstream url path is {upstreamUrlPath}", upstreamUrlPath);

            var downstreamRoute = await _downstreamRouteFinder.FindDownstreamRoute(upstreamUrlPath, context.Request.Method);

            if (downstreamRoute.IsError)
            {
                _logger.LogError($"{MiddlwareName} setting pipeline errors. IDownstreamRouteFinder returned {downstreamRoute.Errors.ToErrorString()}");

                SetPipelineError(downstreamRoute.Errors);

                _logger.TraceMiddlewareCompleted();
                return;
            }

            _logger.LogDebug("downstream template is {downstreamRoute.Data.ReRoute.DownstreamPath}", downstreamRoute.Data.ReRoute.DownstreamPathTemplate);

            SetDownstreamRouteForThisRequest(downstreamRoute.Data);

            _logger.TraceInvokeNext();

            await _next.Invoke(context);

            _logger.TraceInvokeNextCompleted();
            _logger.TraceMiddlewareCompleted();
        }
Ejemplo n.º 9
0
        private IClusterClient ConnectClient(string serviceName, IClusterClient client)
        {
            int attempt = 0;

            while (true)
            {
                try
                {
                    client.Connect().Wait();
                    _logger.LogDebug($"Connection {serviceName} Sucess...");
                    return(client);
                }
                catch (Exception ex)
                {
                    _logger.LogError($"Connection {serviceName} Faile...", ex);
                    attempt++;
                    if (attempt <= this._options.InitializeAttemptsBeforeFailing)
                    {
                        _logger.LogDebug($"Attempt {attempt} of " + this._options.InitializeAttemptsBeforeFailing + " failed to initialize the Orleans client.");
                        Task.Delay(TimeSpan.FromSeconds(4)).Wait();
                        continue;
                    }
                    throw new OrleansConnectionFailedException($"Connection {serviceName} Faile...");
                }
            }
        }
        /// <summary>
        ///  Used: https://stackoverflow.com/a/40256772
        /// </summary>
        /// <returns></returns>
        public async Task Discover(IEnumerable <string> serviceNames)
        {
            if (!_options.ResolveClientsOnStartup)
            {
                return;
            }

            try
            {
                foreach (var serviceName in serviceNames?.Distinct())
                {
                    _logger.LogInformation($"Resolving service: '{serviceName}'.");

                    var serviceNameUri = ServiceFabricUriBuilder.Build(serviceName);
                    var partitions     = await _fabricClient.QueryManager.GetPartitionListAsync(serviceNameUri);

                    foreach (var partition in partitions)
                    {
                        _logger.LogInformation($"Discovered service partition: '{partition.PartitionInformation.Kind}':'{partition.PartitionInformation.Id}'");
                        var key = partition.PartitionInformation.Kind switch
                        {
                            ServicePartitionKind.Singleton => ServicePartitionKey.Singleton,
                            _ => throw new ArgumentOutOfRangeException($"Partitionkind: '{partition.PartitionInformation.Kind}' unknown."),
                        };
                        try
                        {
                            var resolved = await _servicePartitionResolver.ResolveAsync(serviceNameUri, key, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CancellationToken.None);

                            foreach (var endpoint in resolved.Endpoints)
                            {
                                _logger.LogInformation($"Discovered service endpoint: '{endpoint.Address}'");
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError($"Could not resolve service: '{serviceNameUri}'.", ex);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message, ex);
            }
        }
 protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
 {
     try
     {
         return(await Policy
                .WrapAsync(_qoSProvider.CircuitBreaker.CircuitBreakerPolicy, _qoSProvider.CircuitBreaker.TimeoutPolicy)
                .ExecuteAsync(() => base.SendAsync(request, cancellationToken)));
     }
     catch (BrokenCircuitException ex)
     {
         _logger.LogError($"Reached to allowed number of exceptions. Circuit is open", ex);
         throw;
     }
     catch (HttpRequestException ex)
     {
         _logger.LogError($"Error in CircuitBreakingDelegatingHandler.SendAync", ex);
         throw;
     }
 }
Ejemplo n.º 12
0
        public HeaderTransformations Create(FileReRoute fileReRoute)
        {
            var upstream = new List <HeaderFindAndReplace>();

            foreach (var input in fileReRoute.UpstreamHeaderTransform)
            {
                var hAndr = Map(input);
                if (!hAndr.IsError)
                {
                    upstream.Add(hAndr.Data);
                }
                else
                {
                    _logger.LogError($"Unable to add UpstreamHeaderTransform {input.Key}: {input.Value}");
                }
            }

            var downstream             = new List <HeaderFindAndReplace>();
            var addHeadersToDownstream = new List <AddHeader>();

            foreach (var input in fileReRoute.DownstreamHeaderTransform)
            {
                if (input.Value.Contains(","))
                {
                    var hAndr = Map(input);
                    if (!hAndr.IsError)
                    {
                        downstream.Add(hAndr.Data);
                    }
                    else
                    {
                        _logger.LogError($"Unable to add DownstreamHeaderTransform {input.Key}: {input.Value}");
                    }
                }
                else
                {
                    addHeadersToDownstream.Add(new AddHeader(input.Key, input.Value));
                }
            }

            return(new HeaderTransformations(upstream, downstream, addHeadersToDownstream));
        }
Ejemplo n.º 13
0
        public async Task Invoke(DownstreamContext context)
        {
            await _next.Invoke(context);

            if (context.IsError)
            {
                var errors = context.Errors;
                _logger.LogError($"{errors.Count} pipeline errors found in {MiddlewareName}. Setting error response status code");

                foreach (var error in errors)
                {
                    _logger.LogError(error.Message);
                }

                SetErrorResponse(context.HttpContext, errors);
            }
            else
            {
                _logger.LogDebug("no pipeline errors, setting and returning completed response");
                await _responder.SetResponseOnHttpContext(context.HttpContext, context.DownstreamResponse);
            }
        }
Ejemplo n.º 14
0
 private IClusterClient ConnectClient(string serviceName, IClusterClient client)
 {
     try
     {
         client.Connect(RetryFilter).Wait();
         _logger.LogDebug($"Connection {serviceName} Sucess...");
         return(client);
     }
     catch (Exception ex)
     {
         _logger.LogError($"Connection {serviceName} Faile...", ex);
         throw new OrleansConnectionFailedException($"Connection {serviceName} Faile...");
     }
 }
Ejemplo n.º 15
0
        public async Task Invoke(DownstreamContext context)
        {
            var upstreamUrlPath = context.HttpContext.Request.Path.ToString();

            var upstreamHost = context.HttpContext.Request.Headers["Host"];

            var configuration = await _configProvider.Get();

            if (configuration.IsError)
            {
                _logger.LogError($"{MiddlewareName} setting pipeline errors. IOcelotConfigurationProvider returned {configuration.Errors.ToErrorString()}");
                SetPipelineError(context, configuration.Errors);
                return;
            }

            context.ServiceProviderConfiguration = configuration.Data.ServiceProviderConfiguration;

            _logger.LogDebug("upstream url path is {upstreamUrlPath}", upstreamUrlPath);

            var downstreamRoute = _downstreamRouteFinder.FindDownstreamRoute(upstreamUrlPath, context.HttpContext.Request.Method, configuration.Data, upstreamHost);

            if (downstreamRoute.IsError)
            {
                _logger.LogError($"{MiddlewareName} setting pipeline errors. IDownstreamRouteFinder returned {downstreamRoute.Errors.ToErrorString()}");

                SetPipelineError(context, downstreamRoute.Errors);
                return;
            }

            //todo - put this back in
            // _logger.LogDebug("downstream template is {downstreamRoute.Data.ReRoute.DownstreamPath}", downstreamRoute.Data.ReRoute.DownstreamReRoute.DownstreamPathTemplate);

            context.TemplatePlaceholderNameAndValues = downstreamRoute.Data.TemplatePlaceholderNameAndValues;

            await _multiplexer.Multiplex(context, downstreamRoute.Data.ReRoute, _next);
        }
Ejemplo n.º 16
0
        public async Task <Response <OrleansResponseMessage> > Invoke(GrainReference grain, GrainRouteValues route)
        {
            ObjectMethodExecutor executor;

            object[] parameters;
            try
            {
                string key = $"{route.SiloName}.{route.GrainName}.{route.GrainMethodName}";
                executor = _cachedExecutors.GetOrAdd(key, (_key) =>
                {
                    ObjectMethodExecutor _executor = ObjectMethodExecutor.Create(route.GrainMethod, grain.GrainType.GetTypeInfo());
                    return(_executor);
                });
                parameters = GetParameters(executor, route);
            }
            catch (Exception ex)
            {
                _logger.LogError($"Binding parameter failed", ex);
                return(new ErrorResponse <OrleansResponseMessage>(new UnknownError(ex.Message)));
            }
            try
            {
                return(await this.Invoke(executor, grain, parameters));
            }
            catch (Exception ex)
            {
                _logger.LogError($"Request {grain.GrainType.Name} Orleans failed,", ex);
                if (ex.InnerException != null && ex.InnerException is Orleans.Runtime.OrleansMessageRejectionException)
                {
                    await Task.Delay(1);

                    return(await this.Invoke(executor, grain, parameters));
                }
                throw ex;
            }
        }
Ejemplo n.º 17
0
        public async Task Invoke(HttpContext context)
        {
            await _next.Invoke(context);

            if (PipelineError)
            {
                var errors = PipelineErrors;
                _logger.LogError($"{PipelineErrors.Count} pipeline errors found in {MiddlewareName}. Setting error response status code");
                SetErrorResponse(context, errors);
            }
            else
            {
                _logger.LogDebug("no pipeline errors, setting and returning completed response");
                await _responder.SetResponseOnHttpContext(context, HttpResponseMessage);
            }
        }
        public async Task <List <Service> > Get()
        {
            var serviceNameUri = ServiceFabricUriBuilder.Build(_servicename);
            var services       = new List <Service>();

            try
            {
                var service = await _servicePartitionResolver.ResolveAsync(serviceNameUri, ServicePartitionKey.Singleton, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CancellationToken.None);

                services.Add(BuildService(service));
            }
            catch (Exception ex)
            {
                _logger.LogError($"Could not resolve service: '{serviceNameUri}'.", ex);
            }

            return(services);
        }
Ejemplo n.º 19
0
        public async Task <List <Service> > Get()
        {
            var queryResult = await _consul.Health.Service(_consulConfig.KeyOfServiceInConsul, string.Empty, true);

            var services = new List <Service>();

            foreach (var serviceEntry in queryResult.Response)
            {
                if (IsValid(serviceEntry))
                {
                    services.Add(BuildService(serviceEntry));
                }
                else
                {
                    _logger.LogError($"Unable to use service Address: {serviceEntry.Service.Address} and Port: {serviceEntry.Service.Port} as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0");
                }
            }

            return(services.ToList());
        }
Ejemplo n.º 20
0
        public void Add(List <AddHeader> addHeaders, HttpResponseMessage response)
        {
            foreach (var add in addHeaders)
            {
                if (add.Value.StartsWith('{') && add.Value.EndsWith('}'))
                {
                    var value = _placeholders.Get(add.Value);

                    if (value.IsError)
                    {
                        _logger.LogError($"Unable to add header to response {add.Key}: {add.Value}");
                        continue;
                    }

                    response.Headers.TryAddWithoutValidation(add.Key, value.Data);
                }
                else
                {
                    response.Headers.TryAddWithoutValidation(add.Key, add.Value);
                }
            }
        }
        public async Task <Response <OrleansResponseMessage> > Invoke(GrainReference grain, GrainRouteValues route)
        {
            try
            {
                string key      = $"{route.SiloName}.{route.GrainName}.{route.GrainMethodName}";
                var    executor = _cachedExecutors.GetOrAdd(key, (_key) =>
                {
                    ObjectMethodExecutor _executor = ObjectMethodExecutor.Create(route.GrainMethod, grain.GrainType.GetTypeInfo());
                    return(_executor);
                });

                var parameters = GetParameters(executor, route);
                var result     = await this.ExecuteAsync(executor, grain, parameters);

                var message = new OrleansResponseMessage(new OrleansContent(result, this._jsonSerializer), HttpStatusCode.OK);
                return(new OkResponse <OrleansResponseMessage>(message));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message, ex);
                return(new ErrorResponse <OrleansResponseMessage>(new UnknownError(ex.Message)));
            }
        }
Ejemplo n.º 22
0
        public async Task Invoke(HttpContext context)
        {
            try
            {
                await TrySetGlobalRequestId(context);

                _logger.LogDebug("ocelot pipeline started");

                await _next.Invoke(context);
            }
            catch (Exception e)
            {
                _logger.LogDebug("error calling middleware");

                var message = CreateMessage(context, e);

                _logger.LogError(message, e);

                SetInternalServerErrorOnResponse(context);
            }

            _logger.LogDebug("ocelot pipeline finished");
        }