Feature/steeltoe (#324)

* #262 - Integrated Steeltoe Service Discovery with Ocelot for review.

* messing around

* seems to be working with eureka

* acceptance test passing with external lib references

* #262 support for netflix eureka service discovery thanks to pivotal

* #262 fixed warnings
This commit is contained in:
Tom Pallister
2018-04-20 21:28:49 +01:00
committed by GitHub
parent a5f3e0fa75
commit 4f061f2b74
18 changed files with 665 additions and 72 deletions

View File

@ -21,7 +21,7 @@ namespace Ocelot.DependencyInjection
IOcelotBuilder AddSingletonDelegatingHandler<T>(bool global = false)
where T : DelegatingHandler;
IOcelotBuilder AddTransientDelegatingHandler<T>(bool global = false)
where T : DelegatingHandler;

View File

@ -45,6 +45,8 @@ namespace Ocelot.DependencyInjection
using Ocelot.Infrastructure.Consul;
using Butterfly.Client.Tracing;
using Ocelot.Middleware.Multiplexer;
using Pivotal.Discovery.Client;
using ServiceDiscovery.Providers;
public class OcelotBuilder : IOcelotBuilder
{
@ -112,6 +114,17 @@ namespace Ocelot.DependencyInjection
_services.TryAddSingleton<IDownstreamAddressesCreator, DownstreamAddressesCreator>();
_services.TryAddSingleton<IDelegatingHandlerHandlerFactory, DelegatingHandlerHandlerFactory>();
if (UsingEurekaServiceDiscoveryProvider(configurationRoot))
{
_services.AddDiscoveryClient(configurationRoot);
}
else
{
_services.TryAddSingleton<IDiscoveryClient, FakeEurekaDiscoveryClient>();
}
_services.TryAddSingleton<IHttpRequester, HttpClientHttpRequester>();
// 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>();
@ -346,5 +359,13 @@ namespace Ocelot.DependencyInjection
}
};
}
private static bool UsingEurekaServiceDiscoveryProvider(IConfiguration configurationRoot)
{
var type = configurationRoot.GetValue<string>("GlobalConfiguration:ServiceDiscoveryProvider:Type",
string.Empty);
return type.ToLower() == "eureka";
}
}
}

View File

@ -17,6 +17,7 @@
using Rafty.Concensus;
using Rafty.Infrastructure;
using Ocelot.Middleware.Pipeline;
using Pivotal.Discovery.Client;
public static class OcelotMiddlewareExtensions
{
@ -38,6 +39,11 @@
SetUpRafty(builder);
}
if (UsingEurekaServiceDiscoveryProvider(configuration))
{
builder.UseDiscoveryClient();
}
ConfigureDiagnosticListener(builder);
var pipelineBuilder = new OcelotPipelineBuilder(builder.ApplicationServices);
@ -63,6 +69,11 @@
return builder;
}
private static bool UsingEurekaServiceDiscoveryProvider(IInternalConfiguration configuration)
{
return configuration?.ServiceProviderConfiguration != null && configuration.ServiceProviderConfiguration.Type?.ToLower() == "eureka";
}
private static bool UsingRafty(IApplicationBuilder builder)
{
var possible = builder.ApplicationServices.GetService(typeof(INode)) as INode;

View File

@ -46,6 +46,7 @@
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.1.2" />
<PackageReference Include="Consul" Version="0.7.2.4" />
<PackageReference Include="Polly" Version="5.8.0" />
<PackageReference Include="Pivotal.Discovery.Client" Version="1.1.0" />
<PackageReference Include="IdentityServer4" Version="2.1.3" />
<PackageReference Include="Rafty" Version="0.4.2" />
</ItemGroup>

View File

@ -0,0 +1,34 @@
namespace Ocelot.ServiceDiscovery.Providers
{
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Pivotal.Discovery.Client;
using Values;
public class EurekaServiceDiscoveryProvider : IServiceDiscoveryProvider
{
private readonly IDiscoveryClient _client;
private readonly string _serviceName;
public EurekaServiceDiscoveryProvider(string serviceName, IDiscoveryClient client)
{
_client = client;
_serviceName = serviceName;
}
public Task<List<Service>> Get()
{
var services = new List<Service>();
var instances = _client.GetInstances(_serviceName);
if (instances != null && instances.Any())
{
services.AddRange(instances.Select(i => new Service(i.ServiceId, new ServiceHostAndPort(i.Host, i.Port), "", "", new List<string>())));
}
return Task.FromResult(services);
}
}
}

View File

@ -0,0 +1,27 @@
namespace Ocelot.ServiceDiscovery.Providers
{
using System.Collections.Generic;
using System.Threading.Tasks;
using Pivotal.Discovery.Client;
public class FakeEurekaDiscoveryClient : IDiscoveryClient
{
public IServiceInstance GetLocalServiceInstance()
{
throw new System.NotImplementedException();
}
public IList<IServiceInstance> GetInstances(string serviceId)
{
throw new System.NotImplementedException();
}
public Task ShutdownAsync()
{
throw new System.NotImplementedException();
}
public string Description { get; }
public IList<string> Services { get; }
}
}

View File

@ -8,15 +8,19 @@ using Ocelot.Values;
namespace Ocelot.ServiceDiscovery
{
using Pivotal.Discovery.Client;
public class ServiceDiscoveryProviderFactory : IServiceDiscoveryProviderFactory
{
private readonly IOcelotLoggerFactory _factory;
private readonly IConsulClientFactory _clientFactory;
private readonly IConsulClientFactory _consulFactory;
private readonly IDiscoveryClient _eurekaClient;
public ServiceDiscoveryProviderFactory(IOcelotLoggerFactory factory, IConsulClientFactory clientFactory)
public ServiceDiscoveryProviderFactory(IOcelotLoggerFactory factory, IConsulClientFactory consulFactory, IDiscoveryClient eurekaClient)
{
_factory = factory;
_clientFactory = clientFactory;
_consulFactory = consulFactory;
_eurekaClient = eurekaClient;
}
public IServiceDiscoveryProvider Get(ServiceProviderConfiguration serviceConfig, DownstreamReRoute reRoute)
@ -40,14 +44,19 @@ namespace Ocelot.ServiceDiscovery
private IServiceDiscoveryProvider GetServiceDiscoveryProvider(ServiceProviderConfiguration serviceConfig, string serviceName)
{
if (serviceConfig.Type == "ServiceFabric")
if (serviceConfig.Type?.ToLower() == "servicefabric")
{
var config = new ServiceFabricConfiguration(serviceConfig.Host, serviceConfig.Port, serviceName);
return new ServiceFabricServiceDiscoveryProvider(config);
}
if (serviceConfig.Type?.ToLower() == "eureka")
{
return new EurekaServiceDiscoveryProvider(serviceName, _eurekaClient);
}
var consulRegistryConfiguration = new ConsulRegistryConfiguration(serviceConfig.Host, serviceConfig.Port, serviceName, serviceConfig.Token);
return new ConsulServiceDiscoveryProvider(consulRegistryConfiguration, _factory, _clientFactory);
return new ConsulServiceDiscoveryProvider(consulRegistryConfiguration, _factory, _consulFactory);
}
}
}