diff --git a/Ocelot.sln b/Ocelot.sln
index b59c188a2..ba34e163e 100644
--- a/Ocelot.sln
+++ b/Ocelot.sln
@@ -86,6 +86,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "open-tracing", "open-tracin
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OcelotOpenTracing", "samples\OcelotOpenTracing\OcelotOpenTracing.csproj", "{C9427E78-4281-4F59-A66E-17C0B66550E5}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ocelot.Common", "src\Ocelot.Common\Ocelot.Common.csproj", "{C86E258D-156D-4164-BE3D-06324CB3991A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -188,6 +190,10 @@ Global
{C9427E78-4281-4F59-A66E-17C0B66550E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9427E78-4281-4F59-A66E-17C0B66550E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9427E78-4281-4F59-A66E-17C0B66550E5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C86E258D-156D-4164-BE3D-06324CB3991A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C86E258D-156D-4164-BE3D-06324CB3991A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C86E258D-156D-4164-BE3D-06324CB3991A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C86E258D-156D-4164-BE3D-06324CB3991A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -224,6 +230,7 @@ Global
{11C622AD-8C0A-4CF4-811B-3DBB76550797} = {5CFB79B7-C9DC-45A4-9A75-625D92471702}
{731C6A8A-69ED-445C-A132-C638AA93F9C7} = {8FA0CBA0-0338-48EB-B37F-83CA5022237C}
{C9427E78-4281-4F59-A66E-17C0B66550E5} = {731C6A8A-69ED-445C-A132-C638AA93F9C7}
+ {C86E258D-156D-4164-BE3D-06324CB3991A} = {5CFB79B7-C9DC-45A4-9A75-625D92471702}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {21476EFF-778A-4F97-8A56-D1AF1CEC0C48}
diff --git a/src/Ocelot.Common/Ocelot.Common.csproj b/src/Ocelot.Common/Ocelot.Common.csproj
new file mode 100644
index 000000000..cfadb03dd
--- /dev/null
+++ b/src/Ocelot.Common/Ocelot.Common.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+
+
diff --git a/src/Ocelot.Common/Utils/Constants.cs b/src/Ocelot.Common/Utils/Constants.cs
new file mode 100644
index 000000000..28c71bab4
--- /dev/null
+++ b/src/Ocelot.Common/Utils/Constants.cs
@@ -0,0 +1,8 @@
+namespace Ocelot.Common.Utils
+{
+ public static class Constants
+ {
+ public const string ServiceFabric = "ServiceFabric";
+ public const string ConsulServiceDiscoveryProvider = "consul";
+ }
+}
diff --git a/src/Ocelot.Provider.Consul/Consul.cs b/src/Ocelot.Provider.Consul/Consul.cs
index 2e73f5271..138aac52b 100644
--- a/src/Ocelot.Provider.Consul/Consul.cs
+++ b/src/Ocelot.Provider.Consul/Consul.cs
@@ -1,16 +1,11 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-using global::Consul;
-
+using Consul;
using Ocelot.Infrastructure.Extensions;
-
using Ocelot.Logging;
-
using Ocelot.ServiceDiscovery.Providers;
-
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
using Ocelot.Values;
namespace Ocelot.Provider.Consul
@@ -71,12 +66,10 @@ private static Service BuildService(ServiceEntry serviceEntry, Node serviceNode)
private static bool IsValid(ServiceEntry serviceEntry)
{
- if (string.IsNullOrEmpty(serviceEntry.Service.Address) || serviceEntry.Service.Address.Contains("http://") || serviceEntry.Service.Address.Contains("https://") || serviceEntry.Service.Port <= 0)
- {
- return false;
- }
-
- return true;
+ return !string.IsNullOrEmpty(serviceEntry.Service.Address)
+ && !serviceEntry.Service.Address.Contains("http://")
+ && !serviceEntry.Service.Address.Contains("https://")
+ && serviceEntry.Service.Port > 0;
}
private static string GetVersionFromStrings(IEnumerable strings)
diff --git a/src/Ocelot.Provider.Consul/ConsulProviderFactory.cs b/src/Ocelot.Provider.Consul/ConsulProviderFactory.cs
index 9392f461b..4c7d406e8 100644
--- a/src/Ocelot.Provider.Consul/ConsulProviderFactory.cs
+++ b/src/Ocelot.Provider.Consul/ConsulProviderFactory.cs
@@ -1,29 +1,46 @@
-using Ocelot.Logging;
-
-using Microsoft.Extensions.DependencyInjection;
-
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.Extensions.DependencyInjection;
+using Ocelot.Logging;
using Ocelot.ServiceDiscovery;
-namespace Ocelot.Provider.Consul
+namespace Ocelot.Provider.Consul;
+
+public static class ConsulProviderFactory
{
- public static class ConsulProviderFactory
- {
- public static ServiceDiscoveryFinderDelegate Get = (provider, config, route) =>
- {
- var factory = provider.GetService();
+ private static readonly List ServiceDiscoveryProviders = new();
+ private static readonly object LockObject = new();
- var consulFactory = provider.GetService();
+ public static ServiceDiscoveryFinderDelegate Get = (provider, config, route) =>
+ {
+ var factory = provider.GetService();
+ var consulFactory = provider.GetService();
+ var consulRegistryConfiguration = new ConsulRegistryConfiguration(config.Scheme, config.Host, config.Port,
+ route.ServiceName, config.Token);
+ var consulServiceDiscoveryProvider = new Consul(consulRegistryConfiguration, factory, consulFactory);
- var consulRegistryConfiguration = new ConsulRegistryConfiguration(config.Scheme, config.Host, config.Port, route.ServiceName, config.Token);
+ if (string.Compare(config.Type, "PollConsul", StringComparison.OrdinalIgnoreCase) != 0)
+ {
+ return consulServiceDiscoveryProvider;
+ }
- var consulServiceDiscoveryProvider = new Consul(consulRegistryConfiguration, factory, consulFactory);
+ lock (LockObject)
+ {
+ var discoveryProvider = ServiceDiscoveryProviders.FirstOrDefault(x => x.ServiceName == route.ServiceName);
- if (config.Type?.ToLower() == "pollconsul")
+ if (discoveryProvider != null)
{
- return new PollConsul(config.PollingInterval, factory, consulServiceDiscoveryProvider);
+ return discoveryProvider;
}
- return consulServiceDiscoveryProvider;
- };
- }
+ discoveryProvider = new PollConsul(
+ config.PollingInterval, route.ServiceName, factory,
+ consulServiceDiscoveryProvider);
+
+ ServiceDiscoveryProviders.Add(discoveryProvider);
+
+ return discoveryProvider;
+ }
+ };
}
diff --git a/src/Ocelot.Provider.Consul/PollConsul.cs b/src/Ocelot.Provider.Consul/PollConsul.cs
index b5ac65d86..d42edbd9d 100644
--- a/src/Ocelot.Provider.Consul/PollConsul.cs
+++ b/src/Ocelot.Provider.Consul/PollConsul.cs
@@ -1,53 +1,62 @@
using Ocelot.Logging;
using Ocelot.ServiceDiscovery.Providers;
-using Ocelot.Values;
using System;
using System.Collections.Generic;
-using System.Threading;
+using System.Linq;
using System.Threading.Tasks;
+using Ocelot.Values;
-namespace Ocelot.Provider.Consul;
-
-public sealed class PollConsul : IServiceDiscoveryProvider, IDisposable
+namespace Ocelot.Provider.Consul
{
- private readonly IOcelotLogger _logger;
- private readonly IServiceDiscoveryProvider _consulServiceDiscoveryProvider;
- private Timer _timer;
- private bool _polling;
- private List _services;
-
- public PollConsul(int pollingInterval, IOcelotLoggerFactory factory, IServiceDiscoveryProvider consulServiceDiscoveryProvider)
+ public sealed class PollConsul : IServiceDiscoveryProvider
{
- _logger = factory.CreateLogger();
- _consulServiceDiscoveryProvider = consulServiceDiscoveryProvider;
- _services = new List();
+ private readonly IOcelotLogger _logger;
+ private readonly IServiceDiscoveryProvider _consulServiceDiscoveryProvider;
- _timer = new Timer(async x =>
+ private readonly int _pollingInterval;
+ private DateTime _lastUpdateTime;
+ private readonly object _lockObject = new();
+
+ private List _services;
+
+ public PollConsul(int pollingInterval, string serviceName, IOcelotLoggerFactory factory, IServiceDiscoveryProvider consulServiceDiscoveryProvider)
{
- if (_polling)
+ _logger = factory.CreateLogger();
+ _consulServiceDiscoveryProvider = consulServiceDiscoveryProvider;
+ _pollingInterval = pollingInterval;
+ ServiceName = serviceName;
+ _services = new List();
+
+ //initializing with update time = DateTime.MinValue
+ //polling will occur then.
+ _lastUpdateTime = DateTime.MinValue;
+ }
+
+ public string ServiceName { get; }
+
+ ///
+ /// Getting the services, but, if first call,
+ /// retrieving the services and then starting the timer.
+ ///
+ /// the service list.
+ public Task> Get()
+ {
+ lock (_lockObject)
{
- return;
- }
+ var refreshTime = _lastUpdateTime.AddMilliseconds(_pollingInterval);
- _polling = true;
- await Poll();
- _polling = false;
- }, null, pollingInterval, pollingInterval);
- }
-
- public void Dispose()
- {
- _timer?.Dispose();
- _timer = null;
- }
+ //checking if any services available
+ if (refreshTime >= DateTime.UtcNow && _services.Any())
+ {
+ return Task.FromResult(_services);
+ }
- public Task> Get()
- {
- return Task.FromResult(_services);
- }
+ _logger.LogInformation($"Retrieving new client information for service: {ServiceName}");
+ _services = _consulServiceDiscoveryProvider.Get().Result;
+ _lastUpdateTime = DateTime.UtcNow;
- private async Task Poll()
- {
- _services = await _consulServiceDiscoveryProvider.Get();
+ return Task.FromResult(_services);
+ }
+ }
}
}
diff --git a/src/Ocelot/Configuration/Creator/ServiceProviderConfigurationCreator.cs b/src/Ocelot/Configuration/Creator/ServiceProviderConfigurationCreator.cs
index ee6c9a7ae..9ebdb1f80 100644
--- a/src/Ocelot/Configuration/Creator/ServiceProviderConfigurationCreator.cs
+++ b/src/Ocelot/Configuration/Creator/ServiceProviderConfigurationCreator.cs
@@ -1,3 +1,4 @@
+using Ocelot.Common.Utils;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
@@ -12,7 +13,7 @@ public ServiceProviderConfiguration Create(FileGlobalConfiguration globalConfigu
var host = globalConfiguration?.ServiceDiscoveryProvider?.Host ?? "localhost";
var type = !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Type)
? globalConfiguration?.ServiceDiscoveryProvider?.Type
- : "consul";
+ : Constants.ConsulServiceDiscoveryProvider;
var pollingInterval = globalConfiguration?.ServiceDiscoveryProvider?.PollingInterval ?? 0;
var k8snamespace = globalConfiguration?.ServiceDiscoveryProvider?.Namespace ?? string.Empty;
diff --git a/src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs b/src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs
index 1d900c59a..1ec920eef 100644
--- a/src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs
+++ b/src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs
@@ -7,6 +7,7 @@
using Ocelot.Errors;
using Ocelot.Configuration.File;
+using Ocelot.Common.Utils;
using FluentValidation;
@@ -20,7 +21,6 @@ namespace Ocelot.Configuration.Validator
{
public class FileConfigurationFluentValidator : AbstractValidator, IConfigurationValidator
{
- private const string Servicefabric = "servicefabric";
private readonly List _serviceDiscoveryFinderDelegates;
public FileConfigurationFluentValidator(IServiceProvider provider, RouteFluentValidator routeFluentValidator, FileGlobalConfigurationFluentValidator fileGlobalConfigurationFluentValidator)
@@ -71,14 +71,14 @@ public FileConfigurationFluentValidator(IServiceProvider provider, RouteFluentVa
private bool HaveServiceDiscoveryProviderRegistered(FileRoute route, FileServiceDiscoveryProvider serviceDiscoveryProvider)
{
return string.IsNullOrEmpty(route.ServiceName) ||
- serviceDiscoveryProvider?.Type?.ToLower() == Servicefabric ||
+ serviceDiscoveryProvider?.Type?.ToLower() == Constants.ServiceFabric.ToLower() ||
_serviceDiscoveryFinderDelegates.Any();
}
private bool HaveServiceDiscoveryProviderRegistered(FileServiceDiscoveryProvider serviceDiscoveryProvider)
{
return serviceDiscoveryProvider == null ||
- serviceDiscoveryProvider?.Type?.ToLower() == Servicefabric ||
+ serviceDiscoveryProvider?.Type?.ToLower() == Constants.ServiceFabric.ToLower() ||
string.IsNullOrEmpty(serviceDiscoveryProvider.Type) || _serviceDiscoveryFinderDelegates.Any();
}
diff --git a/src/Ocelot/DownstreamUrlCreator/Middleware/DownstreamUrlCreatorMiddleware.cs b/src/Ocelot/DownstreamUrlCreator/Middleware/DownstreamUrlCreatorMiddleware.cs
index 4db8f5d96..814556476 100644
--- a/src/Ocelot/DownstreamUrlCreator/Middleware/DownstreamUrlCreatorMiddleware.cs
+++ b/src/Ocelot/DownstreamUrlCreator/Middleware/DownstreamUrlCreatorMiddleware.cs
@@ -1,16 +1,16 @@
-using System;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-
-using Ocelot.Configuration;
-
-using Ocelot.DownstreamRouteFinder.UrlMatcher;
-
-using Ocelot.Logging;
-
-using Microsoft.AspNetCore.Http;
-
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+using Ocelot.Configuration;
+
+using Ocelot.DownstreamRouteFinder.UrlMatcher;
+
+using Ocelot.Logging;
+
+using Microsoft.AspNetCore.Http;
+using Ocelot.Common.Utils;
using Ocelot.Middleware;
using Ocelot.Request.Middleware;
@@ -150,7 +150,7 @@ private static bool ContainsQueryString(DownstreamPath dsPath)
private static bool ServiceFabricRequest(IInternalConfiguration config, DownstreamRoute downstreamRoute)
{
- return config.ServiceProviderConfiguration.Type?.ToLower() == "servicefabric" && downstreamRoute.UseServiceDiscovery;
+ return config.ServiceProviderConfiguration.Type?.ToLower() == Constants.ServiceFabric.ToLower() && downstreamRoute.UseServiceDiscovery;
}
}
}
diff --git a/src/Ocelot/Ocelot.csproj b/src/Ocelot/Ocelot.csproj
index 29063e93d..3b9db17c2 100644
--- a/src/Ocelot/Ocelot.csproj
+++ b/src/Ocelot/Ocelot.csproj
@@ -36,6 +36,10 @@
all
+
+
+
+
diff --git a/src/Ocelot/ServiceDiscovery/ServiceDiscoveryProviderFactory.cs b/src/Ocelot/ServiceDiscovery/ServiceDiscoveryProviderFactory.cs
index ed04c3532..a46f056f7 100644
--- a/src/Ocelot/ServiceDiscovery/ServiceDiscoveryProviderFactory.cs
+++ b/src/Ocelot/ServiceDiscovery/ServiceDiscoveryProviderFactory.cs
@@ -1,12 +1,12 @@
-using System;
-using System.Collections.Generic;
-
-using Ocelot.ServiceDiscovery.Configuration;
-
-using Ocelot.Logging;
-
-using Microsoft.Extensions.DependencyInjection;
-
+using System;
+using System.Collections.Generic;
+
+using Ocelot.ServiceDiscovery.Configuration;
+
+using Ocelot.Logging;
+
+using Microsoft.Extensions.DependencyInjection;
+using Ocelot.Common.Utils;
using Ocelot.Configuration;
using Ocelot.ServiceDiscovery.Providers;
@@ -51,7 +51,7 @@ public Response Get(ServiceProviderConfiguration serv
private Response GetServiceDiscoveryProvider(ServiceProviderConfiguration config, DownstreamRoute route)
{
- if (config.Type?.ToLower() == "servicefabric")
+ if (config.Type?.ToLower() == Constants.ServiceFabric.ToLower())
{
var sfConfig = new ServiceFabricConfiguration(config.Host, config.Port, route.ServiceName);
return new OkResponse(new ServiceFabricServiceDiscoveryProvider(sfConfig));
diff --git a/test/Ocelot.UnitTests/Consul/ConsulFileConfigurationRepositoryTests.cs b/test/Ocelot.UnitTests/Consul/ConsulFileConfigurationRepositoryTests.cs
index 9d4d29bad..85235e9e4 100644
--- a/test/Ocelot.UnitTests/Consul/ConsulFileConfigurationRepositoryTests.cs
+++ b/test/Ocelot.UnitTests/Consul/ConsulFileConfigurationRepositoryTests.cs
@@ -1,19 +1,19 @@
-using global::Consul;
-using Microsoft.Extensions.Options;
-using Moq;
-using Newtonsoft.Json;
-using Ocelot.Cache;
-using Ocelot.Configuration.File;
-using Ocelot.Logging;
-using Ocelot.Provider.Consul;
-using Ocelot.Responses;
-using Shouldly;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using TestStack.BDDfy;
+using global::Consul;
+using Microsoft.Extensions.Options;
+using Moq;
+using Newtonsoft.Json;
+using Ocelot.Cache;
+using Ocelot.Configuration.File;
+using Ocelot.Logging;
+using Ocelot.Provider.Consul;
+using Ocelot.Responses;
+using Shouldly;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Consul
diff --git a/test/Ocelot.UnitTests/Consul/PollingConsulServiceDiscoveryProviderTests.cs b/test/Ocelot.UnitTests/Consul/PollingConsulServiceDiscoveryProviderTests.cs
index b3780fd21..8eaf2d028 100644
--- a/test/Ocelot.UnitTests/Consul/PollingConsulServiceDiscoveryProviderTests.cs
+++ b/test/Ocelot.UnitTests/Consul/PollingConsulServiceDiscoveryProviderTests.cs
@@ -42,6 +42,17 @@ public void should_return_service_from_consul()
.BDDfy();
}
+ [Fact]
+ public void should_return_service_from_consul_without_delay()
+ {
+ var service = new Service(string.Empty, new ServiceHostAndPort(string.Empty, 0), string.Empty, string.Empty, new List());
+
+ this.Given(x => GivenConsulReturns(service))
+ .When(x => WhenIGetTheServicesWithoutDelay(1))
+ .Then(x => ThenTheCountIs(1))
+ .BDDfy();
+ }
+
private void GivenConsulReturns(Service service)
{
_services.Add(service);
@@ -55,28 +66,38 @@ private void ThenTheCountIs(int count)
private void WhenIGetTheServices(int expected)
{
- using (var provider = new PollConsul(_delay, _factory.Object, _consulServiceDiscoveryProvider.Object))
+ var provider = new PollConsul(_delay, "test", _factory.Object, _consulServiceDiscoveryProvider.Object);
+ var result = Wait.WaitFor(3000).Until(() =>
{
- var result = Wait.WaitFor(3000).Until(() =>
+ try
+ {
+ _result = provider.Get().GetAwaiter().GetResult();
+ return _result.Count == expected;
+ }
+ catch (Exception)
{
- try
- {
- _result = provider.Get().GetAwaiter().GetResult();
- if (_result.Count == expected)
- {
- return true;
- }
+ return false;
+ }
+ });
- return false;
- }
- catch (Exception)
- {
- return false;
- }
- });
+ result.ShouldBeTrue();
+ }
- result.ShouldBeTrue();
+ private void WhenIGetTheServicesWithoutDelay(int expected)
+ {
+ var provider = new PollConsul(_delay, "test2", _factory.Object, _consulServiceDiscoveryProvider.Object);
+ bool result;
+ try
+ {
+ _result = provider.Get().GetAwaiter().GetResult();
+ result = _result.Count == expected;
+ }
+ catch (Exception)
+ {
+ result = false;
}
+
+ result.ShouldBeTrue();
}
}
}
diff --git a/test/Ocelot.UnitTests/Consul/ProviderFactoryTests.cs b/test/Ocelot.UnitTests/Consul/ProviderFactoryTests.cs
index 7b3085c53..f4265b5b7 100644
--- a/test/Ocelot.UnitTests/Consul/ProviderFactoryTests.cs
+++ b/test/Ocelot.UnitTests/Consul/ProviderFactoryTests.cs
@@ -1,56 +1,117 @@
-using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Linq;
+using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Logging;
using Ocelot.Provider.Consul;
+using Ocelot.ServiceDiscovery.Providers;
using Shouldly;
-using System;
-using Xunit;
-
-namespace Ocelot.UnitTests.Consul
-{
- public class ProviderFactoryTests
- {
- private readonly IServiceProvider _provider;
-
- public ProviderFactoryTests()
- {
- var services = new ServiceCollection();
- var loggerFactory = new Mock();
- var logger = new Mock();
- loggerFactory.Setup(x => x.CreateLogger()).Returns(logger.Object);
- loggerFactory.Setup(x => x.CreateLogger()).Returns(logger.Object);
- var consulFactory = new Mock();
- services.AddSingleton(consulFactory.Object);
- services.AddSingleton(loggerFactory.Object);
- _provider = services.BuildServiceProvider();
- }
-
- [Fact]
- public void should_return_ConsulServiceDiscoveryProvider()
- {
- var route = new DownstreamRouteBuilder()
- .WithServiceName(string.Empty)
- .Build();
-
- var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration(string.Empty, string.Empty, string.Empty, 1, string.Empty, string.Empty, 1), route);
- provider.ShouldBeOfType();
- }
-
- [Fact]
- public void should_return_PollingConsulServiceDiscoveryProvider()
- {
- var stopsPollerFromPolling = 10000;
-
- var route = new DownstreamRouteBuilder()
- .WithServiceName(string.Empty)
- .Build();
-
- var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("pollconsul", "http", string.Empty, 1, string.Empty, string.Empty, stopsPollerFromPolling), route);
- var pollProvider = provider as PollConsul;
- pollProvider.ShouldNotBeNull();
- pollProvider.Dispose();
- }
- }
+using Xunit;
+
+namespace Ocelot.UnitTests.Consul;
+
+public class ProviderFactoryTests
+{
+ private readonly IServiceProvider _provider;
+
+ public ProviderFactoryTests()
+ {
+ var services = new ServiceCollection();
+ var loggerFactory = new Mock();
+ var logger = new Mock();
+ loggerFactory.Setup(x => x.CreateLogger()).Returns(logger.Object);
+ loggerFactory.Setup(x => x.CreateLogger()).Returns(logger.Object);
+ var consulFactory = new Mock();
+ services.AddSingleton(consulFactory.Object);
+ services.AddSingleton(loggerFactory.Object);
+ _provider = services.BuildServiceProvider();
+ }
+
+ [Fact]
+ public void should_return_ConsulServiceDiscoveryProvider()
+ {
+ var route = new DownstreamRouteBuilder()
+ .WithServiceName(string.Empty)
+ .Build();
+
+ var provider = ConsulProviderFactory.Get(_provider,
+ new ServiceProviderConfiguration(string.Empty, string.Empty, string.Empty, 1, string.Empty, string.Empty,
+ 1), route);
+ provider.ShouldBeOfType();
+ }
+
+ [Fact]
+ public void should_return_PollingConsulServiceDiscoveryProvider()
+ {
+ var provider = DummyPollingConsulServiceFactory(string.Empty);
+ var pollProvider = provider as PollConsul;
+ pollProvider.ShouldNotBeNull();
+ }
+
+ [Fact]
+ public void should_return_SameProviderForGivenServiceName()
+ {
+ var provider = DummyPollingConsulServiceFactory("test");
+ var provider2 = DummyPollingConsulServiceFactory("test");
+
+ provider.ShouldBeEquivalentTo(provider2);
+
+ var pollProvider = provider as PollConsul;
+ pollProvider.ShouldNotBeNull();
+
+ var pollProvider2 = provider2 as PollConsul;
+ pollProvider2.ShouldNotBeNull();
+
+ pollProvider.ServiceName.ShouldBeEquivalentTo(pollProvider2.ServiceName);
+ }
+
+ [Theory]
+ [InlineData(new object[] { new[] { "service1", "service2", "service3", "service4" } })]
+ public void should_return_ProviderAccordingToServiceName(string[] serviceNames)
+ {
+ var providersList = serviceNames.Select(DummyPollingConsulServiceFactory).ToList();
+
+ foreach (var serviceName in serviceNames)
+ {
+ var currentProvider = DummyPollingConsulServiceFactory(serviceName);
+ providersList.ShouldContain(currentProvider);
+ }
+
+ var convertedProvidersList = providersList.Select(x => x as PollConsul).ToList();
+
+ foreach (var convertedProvider in convertedProvidersList)
+ {
+ convertedProvider.ShouldNotBeNull();
+ }
+
+ foreach (var serviceName in serviceNames)
+ {
+ var cProvider = DummyPollingConsulServiceFactory(serviceName);
+ var convertedCProvider = cProvider as PollConsul;
+
+ convertedCProvider.ShouldNotBeNull();
+
+ var matchingProviders = convertedProvidersList.Where(x => x.ServiceName == convertedCProvider.ServiceName)
+ .ToList();
+ matchingProviders.ShouldHaveSingleItem();
+
+ matchingProviders.First().ShouldNotBeNull();
+ matchingProviders.First().ServiceName.ShouldBeEquivalentTo(convertedCProvider.ServiceName);
+ }
+ }
+
+ private IServiceDiscoveryProvider DummyPollingConsulServiceFactory(string serviceName)
+ {
+ var stopsFromPolling = 10000;
+
+ var route = new DownstreamRouteBuilder()
+ .WithServiceName(serviceName)
+ .Build();
+
+ return ConsulProviderFactory.Get(_provider,
+ new ServiceProviderConfiguration("pollconsul", "http", string.Empty, 1, string.Empty, string.Empty,
+ stopsFromPolling), route);
+ }
}