mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-08-04 14:38:30 +08:00
Merge branch 'develop' into feature/#238-statefull
This commit is contained in:
@ -63,4 +63,3 @@ namespace Ocelot.Authentication.Middleware
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,8 @@ namespace Ocelot.Authorisation
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return new OkResponse<bool>(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +123,6 @@ namespace Ocelot.Cache.Middleware
|
||||
|
||||
var contentHeaders = response?.Content?.Headers.ToDictionary(v => v.Key, v => v.Value);
|
||||
|
||||
|
||||
var cached = new CachedResponse(statusCode, headers, body, contentHeaders);
|
||||
return cached;
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ using Ocelot.Configuration.File;
|
||||
|
||||
namespace Ocelot.Cache
|
||||
{
|
||||
|
||||
public class RegionCreator : IRegionCreator
|
||||
{
|
||||
public string Create(FileReRoute reRoute)
|
||||
@ -21,4 +20,4 @@ namespace Ocelot.Cache
|
||||
return region;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ namespace Ocelot.Cache
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public List<string> Value {get;private set;}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ namespace Ocelot.Claims.Middleware
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
|
@ -215,7 +215,6 @@ namespace Ocelot.Configuration.Builder
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public DownstreamReRoute Build()
|
||||
{
|
||||
return new DownstreamReRoute(
|
||||
|
@ -35,7 +35,6 @@ namespace Ocelot.Configuration.Creator
|
||||
private readonly IHeaderFindAndReplaceCreator _headerFAndRCreator;
|
||||
private readonly IDownstreamAddressesCreator _downstreamAddressesCreator;
|
||||
|
||||
|
||||
public FileOcelotConfigurationCreator(
|
||||
IOptions<FileConfiguration> options,
|
||||
IConfigurationValidator configurationValidator,
|
||||
|
@ -67,7 +67,6 @@ namespace Ocelot.Configuration.Creator
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private bool IsPlaceHolder(string upstreamTemplate, int i)
|
||||
{
|
||||
return upstreamTemplate[i] == '{';
|
||||
|
@ -7,6 +7,7 @@
|
||||
Host = host;
|
||||
Port = port;
|
||||
}
|
||||
|
||||
public string Host { get; private set; }
|
||||
public int Port { get; private set; }
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ namespace Ocelot.Configuration.File
|
||||
}
|
||||
|
||||
public List<FileReRoute> ReRoutes { get; set; }
|
||||
|
||||
// Seperate field for aggregates because this let's you re-use ReRoutes in multiple Aggregates
|
||||
public List<FileAggregateReRoute> Aggregates { get;set; }
|
||||
public FileGlobalConfiguration GlobalConfiguration { get; set; }
|
||||
|
@ -1,5 +1,4 @@
|
||||
|
||||
namespace Ocelot.Configuration.File
|
||||
namespace Ocelot.Configuration.File
|
||||
{
|
||||
public class FileGlobalConfiguration
|
||||
{
|
||||
|
@ -34,6 +34,4 @@ namespace Ocelot.Configuration.File
|
||||
/// </summary>
|
||||
public int HttpStatusCode { get; set; } = 429;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Ocelot.Configuration.File
|
||||
{
|
||||
|
||||
public class FileRateLimitRule
|
||||
{
|
||||
public FileRateLimitRule()
|
||||
@ -27,6 +26,7 @@ namespace Ocelot.Configuration.File
|
||||
public string Period { get; set; }
|
||||
|
||||
public double PeriodTimespan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of requests that a client can make in a defined period
|
||||
/// </summary>
|
||||
@ -38,6 +38,7 @@ namespace Ocelot.Configuration.File
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.Append(
|
||||
$"{nameof(Period)}:{Period},{nameof(PeriodTimespan)}:{PeriodTimespan:F},{nameof(Limit)}:{Limit},{nameof(ClientWhitelist)}:[");
|
||||
|
@ -14,8 +14,7 @@ namespace Ocelot.Configuration
|
||||
DurationOfBreak = durationofBreak;
|
||||
TimeoutValue = timeoutValue;
|
||||
TimeoutStrategy = timeoutStrategy;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int ExceptionsAllowedBeforeBreaking { get; private set; }
|
||||
|
||||
@ -24,6 +23,5 @@ namespace Ocelot.Configuration
|
||||
public int TimeoutValue { get; private set; }
|
||||
|
||||
public TimeoutStrategy TimeoutStrategy { get; private set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,10 @@ namespace Ocelot.Configuration
|
||||
public string Period { get; private set; }
|
||||
|
||||
public double PeriodTimespan { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of requests that a client can make in a defined period
|
||||
/// </summary>
|
||||
public long Limit { get; private set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,12 +9,12 @@ namespace Ocelot.Configuration
|
||||
IsCached = isCached;
|
||||
IsQos = isQos;
|
||||
EnableRateLimiting = isEnableRateLimiting;
|
||||
|
||||
}
|
||||
|
||||
public bool IsAuthenticated { get; private set; }
|
||||
public bool IsAuthorised { get; private set; }
|
||||
public bool IsCached { get; private set; }
|
||||
public bool IsQos { get; private set; }
|
||||
public bool EnableRateLimiting { get; private set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,6 @@ namespace Ocelot.Configuration.Repository
|
||||
_polling = true;
|
||||
await Poll();
|
||||
_polling = false;
|
||||
|
||||
}, null, 0, 1000);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ using Ocelot.ServiceDiscovery;
|
||||
|
||||
namespace Ocelot.Configuration.Repository
|
||||
{
|
||||
|
||||
public class ConsulFileConfigurationRepository : IFileConfigurationRepository
|
||||
{
|
||||
private readonly ConsulClient _consul;
|
||||
|
@ -1,16 +1,16 @@
|
||||
namespace Ocelot.Configuration
|
||||
{
|
||||
public class ServiceProviderConfiguration
|
||||
{
|
||||
public ServiceProviderConfiguration(string type, string host, int port)
|
||||
{
|
||||
Host = host;
|
||||
Port = port;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
public string Host { get; private set; }
|
||||
public int Port { get; private set; }
|
||||
public string Type { get; private set; }
|
||||
}
|
||||
}
|
||||
namespace Ocelot.Configuration
|
||||
{
|
||||
public class ServiceProviderConfiguration
|
||||
{
|
||||
public ServiceProviderConfiguration(string type, string host, int port)
|
||||
{
|
||||
Host = host;
|
||||
Port = port;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
public string Host { get; private set; }
|
||||
public int Port { get; private set; }
|
||||
public string Type { get; private set; }
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ namespace Ocelot.Configuration.Setter
|
||||
private readonly IOcelotConfigurationCreator _configCreator;
|
||||
private readonly IFileConfigurationRepository _repo;
|
||||
|
||||
public FileConfigurationSetter(IOcelotConfigurationRepository configRepo,
|
||||
public FileConfigurationSetter(IOcelotConfigurationRepository configRepo,
|
||||
IOcelotConfigurationCreator configCreator, IFileConfigurationRepository repo)
|
||||
{
|
||||
_configRepo = configRepo;
|
||||
@ -39,4 +39,4 @@ namespace Ocelot.Configuration.Setter
|
||||
return new ErrorResponse(config.Errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ namespace Ocelot.Configuration.Validator
|
||||
{
|
||||
public FileValidationFailedError(string message) : base(message, OcelotErrorCode.FileValidationFailedError)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ namespace Ocelot.Configuration.Validator
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var schemes = await _authenticationSchemeProvider.GetAllSchemesAsync();
|
||||
|
||||
var supportedSchemes = schemes.Select(scheme => scheme.Name).ToList();
|
||||
|
@ -125,7 +125,7 @@ namespace Ocelot.DependencyInjection
|
||||
|
||||
// see this for why we register this as singleton http://stackoverflow.com/questions/37371264/invalidoperationexception-unable-to-resolve-service-for-type-microsoft-aspnetc
|
||||
// could maybe use a scoped data repository
|
||||
_services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
_services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
_services.TryAddSingleton<IRequestScopedDataRepository, HttpDataRepository>();
|
||||
_services.AddMemoryCache();
|
||||
_services.TryAddSingleton<OcelotDiagnosticListener>();
|
||||
@ -153,7 +153,6 @@ namespace Ocelot.DependencyInjection
|
||||
|
||||
// We add this here so that we can always inject something into the factory for IoC..
|
||||
_services.AddSingleton<IServiceTracer, FakeServiceTracer>();
|
||||
|
||||
}
|
||||
|
||||
public IOcelotAdministrationBuilder AddAdministration(string path, string secret)
|
||||
@ -264,8 +263,7 @@ namespace Ocelot.DependencyInjection
|
||||
|
||||
var urlFinder = new BaseUrlFinder(_configurationRoot);
|
||||
var baseSchemeUrlAndPort = urlFinder.Find();
|
||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
||||
|
||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
||||
|
||||
_services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
|
||||
.AddIdentityServerAuthentication(o =>
|
||||
|
@ -11,7 +11,8 @@ namespace Ocelot.DownstreamRouteFinder
|
||||
TemplatePlaceholderNameAndValues = templatePlaceholderNameAndValues;
|
||||
ReRoute = reRoute;
|
||||
}
|
||||
|
||||
public List<PlaceholderNameAndValue> TemplatePlaceholderNameAndValues { get; private set; }
|
||||
public ReRoute ReRoute { get; private set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
|
||||
private readonly IOcelotConfigurationProvider _configProvider;
|
||||
private readonly IMultiplexer _multiplexer;
|
||||
|
||||
|
||||
public DownstreamRouteFinderMiddleware(OcelotRequestDelegate next,
|
||||
IOcelotLoggerFactory loggerFactory,
|
||||
IDownstreamRouteFinder downstreamRouteFinder,
|
||||
@ -60,8 +59,8 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
|
||||
return;
|
||||
}
|
||||
|
||||
//todo - put this back in
|
||||
// _logger.LogDebug("downstream template is {downstreamRoute.Data.ReRoute.DownstreamPath}", downstreamRoute.Data.ReRoute.DownstreamReRoute.DownstreamPathTemplate);
|
||||
// todo - put this back in
|
||||
//// _logger.LogDebug("downstream template is {downstreamRoute.Data.ReRoute.DownstreamPath}", downstreamRoute.Data.ReRoute.DownstreamReRoute.DownstreamPathTemplate);
|
||||
|
||||
context.TemplatePlaceholderNameAndValues = downstreamRoute.Data.TemplatePlaceholderNameAndValues;
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Responses;
|
||||
|
||||
namespace Ocelot.DownstreamRouteFinder.UrlMatcher
|
||||
{
|
||||
public interface IPlaceholderNameAndValueFinder
|
||||
{
|
||||
Response<List<PlaceholderNameAndValue>> Find(string path, string pathTemplate);
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Responses;
|
||||
|
||||
namespace Ocelot.DownstreamRouteFinder.UrlMatcher
|
||||
{
|
||||
public interface IPlaceholderNameAndValueFinder
|
||||
{
|
||||
Response<List<PlaceholderNameAndValue>> Find(string path, string pathTemplate);
|
||||
}
|
||||
}
|
@ -1,13 +1,14 @@
|
||||
namespace Ocelot.DownstreamRouteFinder.UrlMatcher
|
||||
{
|
||||
public class PlaceholderNameAndValue
|
||||
{
|
||||
public PlaceholderNameAndValue(string name, string value)
|
||||
{
|
||||
Name = name;
|
||||
Value = value;
|
||||
}
|
||||
public string Name {get;private set;}
|
||||
public string Value {get;private set;}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.DownstreamRouteFinder.UrlMatcher
|
||||
{
|
||||
public class PlaceholderNameAndValue
|
||||
{
|
||||
public PlaceholderNameAndValue(string name, string value)
|
||||
{
|
||||
Name = name;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Name {get;private set;}
|
||||
public string Value {get;private set;}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ namespace Ocelot.DownstreamRouteFinder.UrlMatcher
|
||||
{
|
||||
Match = match;
|
||||
}
|
||||
|
||||
public bool Match {get;private set;}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ namespace Ocelot.DownstreamRouteFinder.UrlMatcher
|
||||
|
||||
counterForTemplate = endOfPlaceholder;
|
||||
}
|
||||
|
||||
counterForPath++;
|
||||
}
|
||||
|
||||
@ -90,6 +91,7 @@ namespace Ocelot.DownstreamRouteFinder.UrlMatcher
|
||||
|
||||
return variableName;
|
||||
}
|
||||
|
||||
private int GetNextCounterPosition(string urlTemplate, int counterForTemplate, char delimiter)
|
||||
{
|
||||
var closingPlaceHolderPositionOnTemplate = urlTemplate.IndexOf(delimiter, counterForTemplate);
|
||||
@ -111,4 +113,4 @@ namespace Ocelot.DownstreamRouteFinder.UrlMatcher
|
||||
return character == '{';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
|
||||
namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
|
||||
{
|
||||
public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer
|
||||
{
|
||||
public Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
|
||||
{
|
||||
var downstreamPath = new StringBuilder();
|
||||
|
||||
downstreamPath.Append(downstreamPathTemplate.Value);
|
||||
|
||||
foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues)
|
||||
{
|
||||
downstreamPath.Replace(placeholderVariableAndValue.Name, placeholderVariableAndValue.Value);
|
||||
}
|
||||
|
||||
return new OkResponse<DownstreamPath>(new DownstreamPath(downstreamPath.ToString()));
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
|
||||
namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
|
||||
{
|
||||
public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer
|
||||
{
|
||||
public Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
|
||||
{
|
||||
var downstreamPath = new StringBuilder();
|
||||
|
||||
downstreamPath.Append(downstreamPathTemplate.Value);
|
||||
|
||||
foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues)
|
||||
{
|
||||
downstreamPath.Replace(placeholderVariableAndValue.Name, placeholderVariableAndValue.Value);
|
||||
}
|
||||
|
||||
return new OkResponse<DownstreamPath>(new DownstreamPath(downstreamPath.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
|
||||
namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
|
||||
{
|
||||
public interface IDownstreamPathPlaceholderReplacer
|
||||
{
|
||||
Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues);
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
|
||||
namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
|
||||
{
|
||||
public interface IDownstreamPathPlaceholderReplacer
|
||||
{
|
||||
Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues);
|
||||
}
|
||||
}
|
@ -100,6 +100,7 @@ namespace Ocelot.Errors.Middleware
|
||||
message =
|
||||
$"{message}, inner exception message {e.InnerException.Message}, inner exception stack {e.InnerException.StackTrace}";
|
||||
}
|
||||
|
||||
return $"{message} RequestId: {context.HttpContext.TraceIdentifier}";
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace Ocelot.Headers
|
||||
return $"{downstreamUrl}/";
|
||||
});
|
||||
}
|
||||
|
||||
public Response Replace(HttpResponseMessage response, List<HeaderFindAndReplace> fAndRs, HttpRequestMessage httpRequestMessage)
|
||||
{
|
||||
foreach (var f in fAndRs)
|
||||
@ -54,4 +55,4 @@ namespace Ocelot.Headers
|
||||
return new OkResponse();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,6 @@
|
||||
return new OkResponse<string>(value);
|
||||
}
|
||||
|
||||
|
||||
public Response<List<string>> GetValuesByClaimType(IEnumerable<Claim> claims, string claimType)
|
||||
{
|
||||
List<string> values = new List<string>();
|
||||
@ -47,7 +46,6 @@
|
||||
return new OkResponse<List<string>>(values);
|
||||
}
|
||||
|
||||
|
||||
private Response<string> GetValue(IEnumerable<Claim> claims, string key)
|
||||
{
|
||||
var claim = claims.FirstOrDefault(c => c.Type == key);
|
||||
|
@ -9,6 +9,7 @@ namespace Ocelot.LoadBalancer.LoadBalancers
|
||||
HostAndPort = hostAndPort;
|
||||
Connections = connections;
|
||||
}
|
||||
|
||||
public ServiceHostAndPort HostAndPort { get; private set; }
|
||||
public int Connections { get; private set; }
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ namespace Ocelot.LoadBalancer.LoadBalancers
|
||||
_services = services;
|
||||
}
|
||||
|
||||
|
||||
public async Task<Response<ServiceHostAndPort>> Lease()
|
||||
{
|
||||
var services = await _services.Invoke();
|
||||
|
@ -6,6 +6,7 @@ namespace Ocelot.Logging
|
||||
{
|
||||
IOcelotLogger CreateLogger<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thin wrapper around the DotNet core logging framework, used to allow the scopedDataRepository to be injected giving access to the Ocelot RequestId
|
||||
/// </summary>
|
||||
|
@ -22,8 +22,6 @@ namespace Ocelot.Middleware
|
||||
public HttpRequestMessage DownstreamRequest { get; set; }
|
||||
public HttpResponseMessage DownstreamResponse { get; set; }
|
||||
public List<Error> Errors { get;set; }
|
||||
//public string RequestId {get;set;}
|
||||
//public string PreviousRequestId {get;set;}
|
||||
public bool IsError => Errors.Count > 0;
|
||||
}
|
||||
}
|
||||
|
@ -59,9 +59,11 @@
|
||||
|
||||
var firstDelegate = pipelineBuilder.Build();
|
||||
|
||||
//inject first delegate into first piece of asp.net middleware..maybe not like this
|
||||
//then because we are updating the http context in ocelot it comes out correct for
|
||||
//rest of asp.net..
|
||||
/*
|
||||
inject first delegate into first piece of asp.net middleware..maybe not like this
|
||||
then because we are updating the http context in ocelot it comes out correct for
|
||||
rest of asp.net..
|
||||
*/
|
||||
|
||||
builder.Use(async (context, task) =>
|
||||
{
|
||||
|
@ -37,7 +37,6 @@
|
||||
/// <summary>
|
||||
/// This allows the user to implement there own query string manipulation logic
|
||||
/// </summary>
|
||||
public Func<DownstreamContext, Func<Task>, Task> PreQueryStringBuilderMiddleware { get; set; }
|
||||
|
||||
public Func<DownstreamContext, Func<Task>, Task> PreQueryStringBuilderMiddleware { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||
<Authors>Tom Pallister</Authors>
|
||||
<CodeAnalysisRuleSet>..\..\codeanalysis.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>full</DebugType>
|
||||
@ -35,6 +36,9 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.0" />
|
||||
<PackageReference Include="CacheManager.Core" Version="1.1.1" />
|
||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="1.1.1" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
|
||||
namespace Ocelot.Raft
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method|AttributeTargets.Property)]
|
||||
public class ExcludeFromCoverageAttribute : Attribute{}
|
||||
using System;
|
||||
|
||||
namespace Ocelot.Raft
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method|AttributeTargets.Property)]
|
||||
public class ExcludeFromCoverageAttribute : Attribute{}
|
||||
}
|
@ -8,8 +8,8 @@ namespace Ocelot.Raft
|
||||
public FakeCommand(string value)
|
||||
{
|
||||
this.Value = value;
|
||||
|
||||
}
|
||||
|
||||
public string Value { get; private set; }
|
||||
}
|
||||
}
|
||||
|
@ -27,16 +27,19 @@ namespace Ocelot.Raft
|
||||
_finder = finder;
|
||||
_options = options;
|
||||
_peers = new List<IPeer>();
|
||||
|
||||
//todo - sort out async nonsense..
|
||||
var config = _provider.Get().GetAwaiter().GetResult();
|
||||
foreach (var item in _options.Value.Peers)
|
||||
{
|
||||
var httpClient = new HttpClient();
|
||||
|
||||
//todo what if this errors?
|
||||
var httpPeer = new HttpPeer(item.HostAndPort, httpClient, _finder, config.Data, _identityServerConfig);
|
||||
_peers.Add(httpPeer);
|
||||
}
|
||||
}
|
||||
|
||||
public List<IPeer> Get()
|
||||
{
|
||||
return _peers;
|
||||
|
@ -28,7 +28,7 @@ namespace Ocelot.Raft
|
||||
{
|
||||
_identityServerConfiguration = identityServerConfiguration;
|
||||
_config = config;
|
||||
Id = hostAndPort;
|
||||
Id = hostAndPort;
|
||||
_hostAndPort = hostAndPort;
|
||||
_httpClient = httpClient;
|
||||
_jsonSerializerSettings = new JsonSerializerSettings() {
|
||||
@ -68,6 +68,7 @@ namespace Ocelot.Raft
|
||||
{
|
||||
SetToken();
|
||||
}
|
||||
|
||||
var json = JsonConvert.SerializeObject(appendEntries, _jsonSerializerSettings);
|
||||
var content = new StringContent(json);
|
||||
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
|
||||
@ -88,12 +89,14 @@ namespace Ocelot.Raft
|
||||
}
|
||||
}
|
||||
|
||||
public Response<T> Request<T>(T command) where T : ICommand
|
||||
public Response<T> Request<T>(T command)
|
||||
where T : ICommand
|
||||
{
|
||||
if(_token == null)
|
||||
{
|
||||
SetToken();
|
||||
}
|
||||
|
||||
var json = JsonConvert.SerializeObject(command, _jsonSerializerSettings);
|
||||
var content = new StringContent(json);
|
||||
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
|
||||
|
@ -19,7 +19,7 @@ namespace Ocelot.Raft
|
||||
//todo - handle an error
|
||||
//hack it to just cast as at the moment we know this is the only command :P
|
||||
var hack = (UpdateFileConfiguration)log.CommandData;
|
||||
_setter.Set(hack.Configuration).GetAwaiter().GetResult();;
|
||||
_setter.Set(hack.Configuration).GetAwaiter().GetResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ namespace Ocelot.Raft
|
||||
FileStream fs = File.Create(_path);
|
||||
fs.Dispose();
|
||||
}
|
||||
|
||||
using(var connection = new SqliteConnection($"Data Source={_path};"))
|
||||
{
|
||||
connection.Open();
|
||||
@ -59,6 +60,7 @@ namespace Ocelot.Raft
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -88,6 +90,7 @@ namespace Ocelot.Raft
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -113,6 +116,7 @@ namespace Ocelot.Raft
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -129,6 +133,7 @@ namespace Ocelot.Raft
|
||||
TypeNameHandling = TypeNameHandling.All
|
||||
};
|
||||
var data = JsonConvert.SerializeObject(log, jsonSerializerSettings);
|
||||
|
||||
//todo - sql injection dont copy this..
|
||||
var sql = $"insert into logs (data) values ('{data}')";
|
||||
using(var command = new SqliteCommand(sql, connection))
|
||||
@ -153,6 +158,7 @@ namespace Ocelot.Raft
|
||||
using(var connection = new SqliteConnection($"Data Source={_path};"))
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
//todo - sql injection dont copy this..
|
||||
var sql = $"select data from logs where id = {index};";
|
||||
using(var command = new SqliteCommand(sql, connection))
|
||||
@ -183,6 +189,7 @@ namespace Ocelot.Raft
|
||||
using(var connection = new SqliteConnection($"Data Source={_path};"))
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
//todo - sql injection dont copy this..
|
||||
var sql = $"select data from logs where id = {index}";
|
||||
using(var command = new SqliteCommand(sql, connection))
|
||||
@ -207,6 +214,7 @@ namespace Ocelot.Raft
|
||||
using(var connection = new SqliteConnection($"Data Source={_path};"))
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
//todo - sql injection dont copy this..
|
||||
var sql = $"select id, data from logs where id >= {index}";
|
||||
using(var command = new SqliteCommand(sql, connection))
|
||||
@ -222,15 +230,13 @@ namespace Ocelot.Raft
|
||||
};
|
||||
var log = JsonConvert.DeserializeObject<LogEntry>(data, jsonSerializerSettings);
|
||||
logsToReturn.Add((id, log));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return logsToReturn;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public long GetTermAtIndex(int index)
|
||||
@ -241,6 +247,7 @@ namespace Ocelot.Raft
|
||||
using(var connection = new SqliteConnection($"Data Source={_path};"))
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
//todo - sql injection dont copy this..
|
||||
var sql = $"select data from logs where id = {index}";
|
||||
using(var command = new SqliteCommand(sql, connection))
|
||||
@ -256,9 +263,11 @@ namespace Ocelot.Raft
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove(int indexOfCommand)
|
||||
{
|
||||
lock(_lock)
|
||||
@ -266,6 +275,7 @@ namespace Ocelot.Raft
|
||||
using(var connection = new SqliteConnection($"Data Source={_path};"))
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
//todo - sql injection dont copy this..
|
||||
var deleteSql = $"delete from logs where id >= {indexOfCommand};";
|
||||
using(var deleteCommand = new SqliteCommand(deleteSql, connection))
|
||||
@ -276,4 +286,4 @@ namespace Ocelot.Raft
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Ocelot.RateLimit
|
||||
{
|
||||
|
||||
public class ClientRateLimitProcessor
|
||||
{
|
||||
private readonly IRateLimitCounterHandler _counterHandler;
|
||||
@ -24,7 +23,6 @@ namespace Ocelot.RateLimit
|
||||
return _core.ProcessRequest(requestIdentity, option);
|
||||
}
|
||||
|
||||
|
||||
public int RetryAfterFrom(DateTime timestamp, RateLimitRule rule)
|
||||
{
|
||||
return _core.RetryAfterFrom(timestamp, rule);
|
||||
@ -39,7 +37,5 @@ namespace Ocelot.RateLimit
|
||||
{
|
||||
return _core.ConvertToTimeSpan(timeSpan);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ namespace Ocelot.RateLimit
|
||||
{
|
||||
return JsonConvert.DeserializeObject<RateLimitCounter>(stored);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ namespace Ocelot.RateLimit.Middleware
|
||||
public async Task Invoke(DownstreamContext context)
|
||||
{
|
||||
var options = context.DownstreamReRoute.RateLimitOptions;
|
||||
|
||||
// check if rate limiting is enabled
|
||||
if (!context.DownstreamReRoute.EnableEndpointEndpointRateLimiting)
|
||||
{
|
||||
@ -38,6 +39,7 @@ namespace Ocelot.RateLimit.Middleware
|
||||
await _next.Invoke(context);
|
||||
return;
|
||||
}
|
||||
|
||||
// compute identity from request
|
||||
var identity = SetIdentity(context.HttpContext, options);
|
||||
|
||||
@ -65,13 +67,14 @@ namespace Ocelot.RateLimit.Middleware
|
||||
LogBlockedRequest(context.HttpContext, identity, counter, rule, context.DownstreamReRoute);
|
||||
|
||||
var retrystring = retryAfter.ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
|
||||
// break execution
|
||||
await ReturnQuotaExceededResponse(context.HttpContext, options, retrystring);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//set X-Rate-Limit headers for the longest period
|
||||
if (!options.DisableRateLimitHeaders)
|
||||
{
|
||||
@ -103,6 +106,7 @@ namespace Ocelot.RateLimit.Middleware
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -134,8 +138,5 @@ namespace Ocelot.RateLimit.Middleware
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ namespace Ocelot.RateLimit
|
||||
{
|
||||
// increment request count
|
||||
var totalRequests = entry.Value.TotalRequests + 1;
|
||||
|
||||
// deep copy
|
||||
counter = new RateLimitCounter(entry.Value.Timestamp, totalRequests);
|
||||
}
|
||||
@ -62,6 +63,7 @@ namespace Ocelot.RateLimit
|
||||
var expirationTime = ConvertToTimeSpan(rule.Period);
|
||||
_counterHandler.Set(counterId, counter, expirationTime);
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
@ -69,6 +71,7 @@ namespace Ocelot.RateLimit
|
||||
{
|
||||
var counterId = ComputeCounterKey(requestIdentity, option);
|
||||
var rule = option.RateLimitRule;
|
||||
|
||||
// stores: id (string) - timestamp (datetime) - total_requests (long)
|
||||
_counterHandler.Set(counterId, counter, expirationTime);
|
||||
}
|
||||
@ -92,7 +95,6 @@ namespace Ocelot.RateLimit
|
||||
rule.Period,
|
||||
rule.Limit.ToString(),
|
||||
(DateTime.UtcNow + ConvertToTimeSpan(rule.Period)).ToUniversalTime().ToString("o", DateTimeFormatInfo.InvariantInfo));
|
||||
|
||||
}
|
||||
|
||||
return headers;
|
||||
@ -141,7 +143,6 @@ namespace Ocelot.RateLimit
|
||||
default:
|
||||
throw new FormatException($"{timeSpan} can't be converted to TimeSpan, unknown type {type}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,4 +92,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ namespace Ocelot.RequestId.Middleware
|
||||
private readonly IOcelotLogger _logger;
|
||||
private readonly IRequestScopedDataRepository _requestScopedDataRepository;
|
||||
|
||||
|
||||
public ReRouteRequestIdMiddleware(OcelotRequestDelegate next,
|
||||
IOcelotLoggerFactory loggerFactory,
|
||||
IRequestScopedDataRepository requestScopedDataRepository)
|
||||
|
@ -55,7 +55,6 @@ namespace Ocelot.Requester
|
||||
{
|
||||
_cacheHandlers.Set(cacheKey, httpClient, TimeSpan.FromHours(24));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private IHttpClient GetHttpClient(string cacheKey, IHttpClientBuilder builder, DownstreamContext request)
|
||||
|
6
src/Ocelot/Requester/ITracingHandler.cs
Normal file
6
src/Ocelot/Requester/ITracingHandler.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace Ocelot.Requester
|
||||
{
|
||||
public interface ITracingHandler
|
||||
{
|
||||
}
|
||||
}
|
@ -41,6 +41,7 @@ namespace Ocelot.Requester
|
||||
{
|
||||
connectionQueue.TryDequeue(out client);
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
|
@ -8,10 +8,6 @@ using Butterfly.OpenTracing;
|
||||
|
||||
namespace Ocelot.Requester
|
||||
{
|
||||
public interface ITracingHandler
|
||||
{
|
||||
}
|
||||
|
||||
public class OcelotHttpTracingHandler : DelegatingHandler, ITracingHandler
|
||||
{
|
||||
private readonly IServiceTracer _tracer;
|
||||
@ -35,7 +31,7 @@ namespace Ocelot.Requester
|
||||
{
|
||||
request.Headers.Remove(prefix_spanId);
|
||||
request.Headers.TryAddWithoutValidation(prefix_spanId, span.SpanContext.SpanId);
|
||||
};
|
||||
}
|
||||
|
||||
span.Tags.Client().Component("HttpClient")
|
||||
.HttpMethod(request.Method.Method)
|
||||
@ -51,7 +47,7 @@ namespace Ocelot.Requester
|
||||
if (!c.Contains(k))
|
||||
{
|
||||
c.Add(k, v);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
span.Log(LogField.CreateNew().ClientSend());
|
||||
|
@ -50,7 +50,6 @@ namespace Ocelot.Responder
|
||||
httpContext.Response.StatusCode = (int)response.StatusCode;
|
||||
|
||||
return Task.CompletedTask;
|
||||
|
||||
}, context);
|
||||
|
||||
using (Stream stream = new MemoryStream(content))
|
||||
|
@ -29,7 +29,6 @@ namespace Ocelot.Responder.Middleware
|
||||
_responder = responder;
|
||||
_codeMapper = codeMapper;
|
||||
_logger = loggerFactory.CreateLogger<ResponderMiddleware>();
|
||||
|
||||
}
|
||||
|
||||
public async Task Invoke(DownstreamContext context)
|
||||
|
@ -8,8 +8,9 @@ namespace Ocelot.Responses
|
||||
public ErrorResponse(Error error) : base(new List<Error>{error})
|
||||
{
|
||||
}
|
||||
|
||||
public ErrorResponse(List<Error> errors) : base(errors)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,16 +3,18 @@ using Ocelot.Errors;
|
||||
|
||||
namespace Ocelot.Responses
|
||||
{
|
||||
#pragma warning disable SA1649 // File name must match first type name
|
||||
public class ErrorResponse<T> : Response<T>
|
||||
#pragma warning restore SA1649 // File name must match first type name
|
||||
{
|
||||
public ErrorResponse(Error error)
|
||||
: base(new List<Error> {error})
|
||||
{
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
public ErrorResponse(List<Error> errors)
|
||||
: base(errors)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
namespace Ocelot.Responses
|
||||
{
|
||||
#pragma warning disable SA1649 // File name must match first type name
|
||||
public class OkResponse<T> : Response<T>
|
||||
#pragma warning restore SA1649 // File name must match first type name
|
||||
{
|
||||
public OkResponse(T data) : base(data)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ using Ocelot.Errors;
|
||||
|
||||
namespace Ocelot.Responses
|
||||
{
|
||||
#pragma warning disable SA1649 // File name must match first type name
|
||||
public abstract class Response<T> : Response
|
||||
#pragma warning restore SA1649 // File name must match first type name
|
||||
{
|
||||
protected Response(T data)
|
||||
{
|
||||
@ -14,7 +16,6 @@ namespace Ocelot.Responses
|
||||
{
|
||||
}
|
||||
|
||||
public T Data { get; private set; }
|
||||
|
||||
public T Data { get; private set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ namespace Ocelot.ServiceDiscovery
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
public IServiceDiscoveryProvider Get(ServiceProviderConfiguration serviceConfig, DownstreamReRoute reRoute)
|
||||
public IServiceDiscoveryProvider Get(ServiceProviderConfiguration serviceConfig, DownstreamReRoute reRoute)
|
||||
{
|
||||
if (reRoute.UseServiceDiscovery)
|
||||
{
|
||||
|
@ -16,6 +16,7 @@ namespace Ocelot.Values
|
||||
Version = version;
|
||||
Tags = tags;
|
||||
}
|
||||
|
||||
public string Id { get; private set; }
|
||||
|
||||
public string Name { get; private set; }
|
||||
|
Reference in New Issue
Block a user