mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:22:50 +08:00
* #441 added a test for this change * #441 bit of tidying up and fixing of erros
This commit is contained in:
parent
2832cb1bf4
commit
a87bc92c60
@ -61,7 +61,7 @@
|
|||||||
|
|
||||||
downstreamRoute = new OkResponse<DownstreamRoute>(new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute));
|
downstreamRoute = new OkResponse<DownstreamRoute>(new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute));
|
||||||
|
|
||||||
_cache.AddOrUpdate(loadBalancerKey, downstreamRoute, (x, y) => downstreamRoute);
|
_cache.AddOrUpdate(loadBalancerKey, downstreamRoute, (x, y) => downstreamRoute);
|
||||||
|
|
||||||
return downstreamRoute;
|
return downstreamRoute;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ namespace Ocelot.LoadBalancer.LoadBalancers
|
|||||||
public async Task<Response<ServiceHostAndPort>> Lease(DownstreamContext downstreamContext)
|
public async Task<Response<ServiceHostAndPort>> Lease(DownstreamContext downstreamContext)
|
||||||
{
|
{
|
||||||
var services = await _services();
|
var services = await _services();
|
||||||
//todo first or default could be null..
|
|
||||||
if (services == null || services.Count == 0)
|
if (services == null || services.Count == 0)
|
||||||
{
|
{
|
||||||
return new ErrorResponse<ServiceHostAndPort>(new ServicesAreEmptyError("There were no services in NoLoadBalancer"));
|
return new ErrorResponse<ServiceHostAndPort>(new ServicesAreEmptyError("There were no services in NoLoadBalancer"));
|
||||||
|
@ -99,6 +99,7 @@ namespace Ocelot.Raft
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_sempaphore.Release();
|
_sempaphore.Release();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -120,6 +121,7 @@ namespace Ocelot.Raft
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_sempaphore.Release();
|
_sempaphore.Release();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -135,6 +137,7 @@ namespace Ocelot.Raft
|
|||||||
TypeNameHandling = TypeNameHandling.All
|
TypeNameHandling = TypeNameHandling.All
|
||||||
};
|
};
|
||||||
var data = JsonConvert.SerializeObject(log, jsonSerializerSettings);
|
var data = JsonConvert.SerializeObject(log, jsonSerializerSettings);
|
||||||
|
|
||||||
//todo - sql injection dont copy this..
|
//todo - sql injection dont copy this..
|
||||||
var sql = $"insert into logs (data) values ('{data}')";
|
var sql = $"insert into logs (data) values ('{data}')";
|
||||||
_logger.LogInformation($"id: {_nodeId.Id}, sql: {sql}");
|
_logger.LogInformation($"id: {_nodeId.Id}, sql: {sql}");
|
||||||
@ -162,6 +165,7 @@ namespace Ocelot.Raft
|
|||||||
using (var connection = new SqliteConnection($"Data Source={_path};"))
|
using (var connection = new SqliteConnection($"Data Source={_path};"))
|
||||||
{
|
{
|
||||||
connection.Open();
|
connection.Open();
|
||||||
|
|
||||||
//todo - sql injection dont copy this..
|
//todo - sql injection dont copy this..
|
||||||
var sql = $"select data from logs where id = {index};";
|
var sql = $"select data from logs where id = {index};";
|
||||||
_logger.LogInformation($"id: {_nodeId.Id} sql: {sql}");
|
_logger.LogInformation($"id: {_nodeId.Id} sql: {sql}");
|
||||||
@ -188,6 +192,7 @@ namespace Ocelot.Raft
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_sempaphore.Release();
|
_sempaphore.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,6 +202,7 @@ namespace Ocelot.Raft
|
|||||||
using (var connection = new SqliteConnection($"Data Source={_path};"))
|
using (var connection = new SqliteConnection($"Data Source={_path};"))
|
||||||
{
|
{
|
||||||
connection.Open();
|
connection.Open();
|
||||||
|
|
||||||
//todo - sql injection dont copy this..
|
//todo - sql injection dont copy this..
|
||||||
var sql = $"select data from logs where id = {index};";
|
var sql = $"select data from logs where id = {index};";
|
||||||
using (var command = new SqliteCommand(sql, connection))
|
using (var command = new SqliteCommand(sql, connection))
|
||||||
@ -227,6 +233,7 @@ namespace Ocelot.Raft
|
|||||||
using (var connection = new SqliteConnection($"Data Source={_path};"))
|
using (var connection = new SqliteConnection($"Data Source={_path};"))
|
||||||
{
|
{
|
||||||
connection.Open();
|
connection.Open();
|
||||||
|
|
||||||
//todo - sql injection dont copy this..
|
//todo - sql injection dont copy this..
|
||||||
var sql = $"select data from logs where id = {index}";
|
var sql = $"select data from logs where id = {index}";
|
||||||
using (var command = new SqliteCommand(sql, connection))
|
using (var command = new SqliteCommand(sql, connection))
|
||||||
@ -251,6 +258,7 @@ namespace Ocelot.Raft
|
|||||||
using (var connection = new SqliteConnection($"Data Source={_path};"))
|
using (var connection = new SqliteConnection($"Data Source={_path};"))
|
||||||
{
|
{
|
||||||
connection.Open();
|
connection.Open();
|
||||||
|
|
||||||
//todo - sql injection dont copy this..
|
//todo - sql injection dont copy this..
|
||||||
var sql = $"select id, data from logs where id >= {index}";
|
var sql = $"select id, data from logs where id >= {index}";
|
||||||
using (var command = new SqliteCommand(sql, connection))
|
using (var command = new SqliteCommand(sql, connection))
|
||||||
@ -267,10 +275,10 @@ namespace Ocelot.Raft
|
|||||||
};
|
};
|
||||||
var log = JsonConvert.DeserializeObject<LogEntry>(data, jsonSerializerSettings);
|
var log = JsonConvert.DeserializeObject<LogEntry>(data, jsonSerializerSettings);
|
||||||
logsToReturn.Add((id, log));
|
logsToReturn.Add((id, log));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_sempaphore.Release();
|
_sempaphore.Release();
|
||||||
return logsToReturn;
|
return logsToReturn;
|
||||||
}
|
}
|
||||||
@ -283,6 +291,7 @@ namespace Ocelot.Raft
|
|||||||
using (var connection = new SqliteConnection($"Data Source={_path};"))
|
using (var connection = new SqliteConnection($"Data Source={_path};"))
|
||||||
{
|
{
|
||||||
connection.Open();
|
connection.Open();
|
||||||
|
|
||||||
//todo - sql injection dont copy this..
|
//todo - sql injection dont copy this..
|
||||||
var sql = $"select data from logs where id = {index}";
|
var sql = $"select data from logs where id = {index}";
|
||||||
using (var command = new SqliteCommand(sql, connection))
|
using (var command = new SqliteCommand(sql, connection))
|
||||||
@ -299,15 +308,18 @@ namespace Ocelot.Raft
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_sempaphore.Release();
|
_sempaphore.Release();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Remove(int indexOfCommand)
|
public async Task Remove(int indexOfCommand)
|
||||||
{
|
{
|
||||||
_sempaphore.Wait();
|
_sempaphore.Wait();
|
||||||
using (var connection = new SqliteConnection($"Data Source={_path};"))
|
using (var connection = new SqliteConnection($"Data Source={_path};"))
|
||||||
{
|
{
|
||||||
connection.Open();
|
connection.Open();
|
||||||
|
|
||||||
//todo - sql injection dont copy this..
|
//todo - sql injection dont copy this..
|
||||||
var deleteSql = $"delete from logs where id >= {indexOfCommand};";
|
var deleteSql = $"delete from logs where id >= {indexOfCommand};";
|
||||||
_logger.LogInformation($"id: {_nodeId.Id} Remove {deleteSql}");
|
_logger.LogInformation($"id: {_nodeId.Id} Remove {deleteSql}");
|
||||||
@ -316,6 +328,7 @@ namespace Ocelot.Raft
|
|||||||
var result = await deleteCommand.ExecuteNonQueryAsync();
|
var result = await deleteCommand.ExecuteNonQueryAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_sempaphore.Release();
|
_sempaphore.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,10 @@
|
|||||||
using System;
|
namespace Ocelot.Requester
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Ocelot.Requester
|
|
||||||
{
|
{
|
||||||
|
using System;
|
||||||
|
|
||||||
public interface IHttpClientCache
|
public interface IHttpClientCache
|
||||||
{
|
{
|
||||||
bool Exists(string id);
|
|
||||||
IHttpClient Get(string id);
|
IHttpClient Get(string id);
|
||||||
void Remove(string id);
|
|
||||||
void Set(string id, IHttpClient handler, TimeSpan expirationTime);
|
void Set(string id, IHttpClient handler, TimeSpan expirationTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
using Microsoft.Extensions.Caching.Memory;
|
namespace Ocelot.Requester
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Ocelot.Requester
|
|
||||||
{
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
public class MemoryHttpClientCache : IHttpClientCache
|
public class MemoryHttpClientCache : IHttpClientCache
|
||||||
{
|
{
|
||||||
private readonly ConcurrentDictionary<string, ConcurrentQueue<IHttpClient>> _httpClientsCache = new ConcurrentDictionary<string, ConcurrentQueue<IHttpClient>>();
|
private readonly ConcurrentDictionary<string, ConcurrentQueue<IHttpClient>> _httpClientsCache;
|
||||||
|
|
||||||
|
public MemoryHttpClientCache()
|
||||||
|
{
|
||||||
|
_httpClientsCache = new ConcurrentDictionary<string, ConcurrentQueue<IHttpClient>>();
|
||||||
|
}
|
||||||
|
|
||||||
public void Set(string id, IHttpClient client, TimeSpan expirationTime)
|
public void Set(string id, IHttpClient client, TimeSpan expirationTime)
|
||||||
{
|
{
|
||||||
ConcurrentQueue<IHttpClient> connectionQueue;
|
if (_httpClientsCache.TryGetValue(id, out var connectionQueue))
|
||||||
if (_httpClientsCache.TryGetValue(id, out connectionQueue))
|
|
||||||
{
|
{
|
||||||
connectionQueue.Enqueue(client);
|
connectionQueue.Enqueue(client);
|
||||||
}
|
}
|
||||||
@ -27,28 +26,15 @@ namespace Ocelot.Requester
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Exists(string id)
|
|
||||||
{
|
|
||||||
ConcurrentQueue<IHttpClient> connectionQueue;
|
|
||||||
return _httpClientsCache.TryGetValue(id, out connectionQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IHttpClient Get(string id)
|
public IHttpClient Get(string id)
|
||||||
{
|
{
|
||||||
IHttpClient client= null;
|
IHttpClient client= null;
|
||||||
ConcurrentQueue<IHttpClient> connectionQueue;
|
if (_httpClientsCache.TryGetValue(id, out var connectionQueue))
|
||||||
if (_httpClientsCache.TryGetValue(id, out connectionQueue))
|
|
||||||
{
|
{
|
||||||
connectionQueue.TryDequeue(out client);
|
connectionQueue.TryDequeue(out client);
|
||||||
}
|
}
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(string id)
|
|
||||||
{
|
|
||||||
ConcurrentQueue<IHttpClient> connectionQueue;
|
|
||||||
_httpClientsCache.TryRemove(id, out connectionQueue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,6 @@ namespace Ocelot.UnitTests.Middleware
|
|||||||
services.AddDiscoveryClient(new DiscoveryOptions
|
services.AddDiscoveryClient(new DiscoveryOptions
|
||||||
{
|
{
|
||||||
ClientType = DiscoveryClientType.EUREKA,
|
ClientType = DiscoveryClientType.EUREKA,
|
||||||
//options can not be null
|
|
||||||
ClientOptions = new EurekaClientOptions()
|
ClientOptions = new EurekaClientOptions()
|
||||||
{
|
{
|
||||||
ShouldFetchRegistry = false,
|
ShouldFetchRegistry = false,
|
||||||
|
@ -23,15 +23,18 @@ namespace Ocelot.UnitTests.Requester
|
|||||||
{
|
{
|
||||||
public class HttpClientBuilderTests : IDisposable
|
public class HttpClientBuilderTests : IDisposable
|
||||||
{
|
{
|
||||||
private readonly HttpClientBuilder _builder;
|
private HttpClientBuilder _builder;
|
||||||
private readonly Mock<IDelegatingHandlerHandlerFactory> _factory;
|
private readonly Mock<IDelegatingHandlerHandlerFactory> _factory;
|
||||||
private IHttpClient _httpClient;
|
private IHttpClient _httpClient;
|
||||||
private HttpResponseMessage _response;
|
private HttpResponseMessage _response;
|
||||||
private DownstreamContext _context;
|
private DownstreamContext _context;
|
||||||
private readonly Mock<IHttpClientCache> _cacheHandlers;
|
private readonly Mock<IHttpClientCache> _cacheHandlers;
|
||||||
private Mock<IOcelotLogger> _logger;
|
private readonly Mock<IOcelotLogger> _logger;
|
||||||
private int _count;
|
private int _count;
|
||||||
private IWebHost _host;
|
private IWebHost _host;
|
||||||
|
private IHttpClient _againHttpClient;
|
||||||
|
private IHttpClient _firstHttpClient;
|
||||||
|
private MemoryHttpClientCache _realCache;
|
||||||
|
|
||||||
public HttpClientBuilderTests()
|
public HttpClientBuilderTests()
|
||||||
{
|
{
|
||||||
@ -61,6 +64,47 @@ namespace Ocelot.UnitTests.Requester
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_get_from_cache()
|
||||||
|
{
|
||||||
|
var qosOptions = new QoSOptionsBuilder()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var reRoute = new DownstreamReRouteBuilder()
|
||||||
|
.WithQosOptions(qosOptions)
|
||||||
|
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
|
||||||
|
.WithLoadBalancerKey("")
|
||||||
|
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
this.Given(x => GivenARealCache())
|
||||||
|
.And(x => GivenTheFactoryReturns())
|
||||||
|
.And(x => GivenARequest(reRoute))
|
||||||
|
.And(x => WhenIBuildTheFirstTime())
|
||||||
|
.And(x => WhenISave())
|
||||||
|
.And(x => WhenIBuildAgain())
|
||||||
|
.And(x => WhenISave())
|
||||||
|
.When(x => WhenIBuildAgain())
|
||||||
|
.Then(x => ThenTheHttpClientIsFromTheCache())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenARealCache()
|
||||||
|
{
|
||||||
|
_realCache = new MemoryHttpClientCache();
|
||||||
|
_builder = new HttpClientBuilder(_factory.Object, _realCache, _logger.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheHttpClientIsFromTheCache()
|
||||||
|
{
|
||||||
|
_againHttpClient.ShouldBe(_firstHttpClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenISave()
|
||||||
|
{
|
||||||
|
_builder.Save();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_log_if_ignoring_ssl_errors()
|
public void should_log_if_ignoring_ssl_errors()
|
||||||
{
|
{
|
||||||
@ -302,6 +346,17 @@ namespace Ocelot.UnitTests.Requester
|
|||||||
_httpClient = _builder.Create(_context);
|
_httpClient = _builder.Create(_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void WhenIBuildTheFirstTime()
|
||||||
|
{
|
||||||
|
_firstHttpClient = _builder.Create(_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenIBuildAgain()
|
||||||
|
{
|
||||||
|
_builder = new HttpClientBuilder(_factory.Object, _realCache, _logger.Object);
|
||||||
|
_againHttpClient = _builder.Create(_context);
|
||||||
|
}
|
||||||
|
|
||||||
private void ThenTheHttpClientShouldNotBeNull()
|
private void ThenTheHttpClientShouldNotBeNull()
|
||||||
{
|
{
|
||||||
_httpClient.ShouldNotBeNull();
|
_httpClient.ShouldNotBeNull();
|
||||||
|
@ -1,33 +1,24 @@
|
|||||||
using System;
|
namespace Ocelot.UnitTests.ServiceDiscovery
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using Consul;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Moq;
|
|
||||||
using Ocelot.Infrastructure.Consul;
|
|
||||||
using Ocelot.Logging;
|
|
||||||
using Ocelot.ServiceDiscovery.Configuration;
|
|
||||||
using Ocelot.ServiceDiscovery.Providers;
|
|
||||||
using Ocelot.Values;
|
|
||||||
using Xunit;
|
|
||||||
using TestStack.BDDfy;
|
|
||||||
using Shouldly;
|
|
||||||
using static Ocelot.Infrastructure.Wait;
|
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.ServiceDiscovery
|
|
||||||
{
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Moq;
|
||||||
|
using Ocelot.Logging;
|
||||||
|
using Ocelot.ServiceDiscovery.Providers;
|
||||||
|
using Ocelot.Values;
|
||||||
|
using Xunit;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Shouldly;
|
||||||
|
using static Ocelot.Infrastructure.Wait;
|
||||||
|
|
||||||
public class PollingConsulServiceDiscoveryProviderTests
|
public class PollingConsulServiceDiscoveryProviderTests
|
||||||
{
|
{
|
||||||
private readonly int _delay;
|
private readonly int _delay;
|
||||||
private PollingConsulServiceDiscoveryProvider _provider;
|
private PollingConsulServiceDiscoveryProvider _provider;
|
||||||
private readonly string _serviceName;
|
private readonly List<Service> _services;
|
||||||
private List<Service> _services;
|
|
||||||
private readonly Mock<IOcelotLoggerFactory> _factory;
|
private readonly Mock<IOcelotLoggerFactory> _factory;
|
||||||
private readonly Mock<IOcelotLogger> _logger;
|
private readonly Mock<IOcelotLogger> _logger;
|
||||||
private Mock<IServiceDiscoveryProvider> _consulServiceDiscoveryProvider;
|
private readonly Mock<IServiceDiscoveryProvider> _consulServiceDiscoveryProvider;
|
||||||
private List<Service> _result;
|
private List<Service> _result;
|
||||||
|
|
||||||
public PollingConsulServiceDiscoveryProviderTests()
|
public PollingConsulServiceDiscoveryProviderTests()
|
||||||
@ -64,7 +55,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
|
|||||||
|
|
||||||
private void WhenIGetTheServices(int expected)
|
private void WhenIGetTheServices(int expected)
|
||||||
{
|
{
|
||||||
_provider = new PollingConsulServiceDiscoveryProvider(_delay, _serviceName, _factory.Object, _consulServiceDiscoveryProvider.Object);
|
_provider = new PollingConsulServiceDiscoveryProvider(_delay, "", _factory.Object, _consulServiceDiscoveryProvider.Object);
|
||||||
|
|
||||||
var result = WaitFor(3000).Until(() => {
|
var result = WaitFor(3000).Until(() => {
|
||||||
try
|
try
|
||||||
|
Loading…
x
Reference in New Issue
Block a user