Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Ocelot.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down
9 changes: 9 additions & 0 deletions src/Ocelot.Common/Ocelot.Common.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
8 changes: 8 additions & 0 deletions src/Ocelot.Common/Utils/Constants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Ocelot.Common.Utils
{
public static class Constants
{
public const string ServiceFabric = "ServiceFabric";
public const string ConsulServiceDiscoveryProvider = "consul";
}
}
25 changes: 9 additions & 16 deletions src/Ocelot.Provider.Consul/Consul.cs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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<string> strings)
Expand Down
53 changes: 35 additions & 18 deletions src/Ocelot.Provider.Consul/ConsulProviderFactory.cs
Original file line number Diff line number Diff line change
@@ -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<IOcelotLoggerFactory>();
private static readonly List<PollConsul> ServiceDiscoveryProviders = new();
private static readonly object LockObject = new();

var consulFactory = provider.GetService<IConsulClientFactory>();
public static ServiceDiscoveryFinderDelegate Get = (provider, config, route) =>
{
var factory = provider.GetService<IOcelotLoggerFactory>();
var consulFactory = provider.GetService<IConsulClientFactory>();
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;
}
};
}
83 changes: 46 additions & 37 deletions src/Ocelot.Provider.Consul/PollConsul.cs
Original file line number Diff line number Diff line change
@@ -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<Service> _services;

public PollConsul(int pollingInterval, IOcelotLoggerFactory factory, IServiceDiscoveryProvider consulServiceDiscoveryProvider)
public sealed class PollConsul : IServiceDiscoveryProvider
{
_logger = factory.CreateLogger<PollConsul>();
_consulServiceDiscoveryProvider = consulServiceDiscoveryProvider;
_services = new List<Service>();
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<Service> _services;

public PollConsul(int pollingInterval, string serviceName, IOcelotLoggerFactory factory, IServiceDiscoveryProvider consulServiceDiscoveryProvider)
{
if (_polling)
_logger = factory.CreateLogger<PollConsul>();
_consulServiceDiscoveryProvider = consulServiceDiscoveryProvider;
_pollingInterval = pollingInterval;
ServiceName = serviceName;
_services = new List<Service>();

//initializing with update time = DateTime.MinValue
//polling will occur then.
_lastUpdateTime = DateTime.MinValue;
}

public string ServiceName { get; }

/// <summary>
/// Getting the services, but, if first call,
/// retrieving the services and then starting the timer.
/// </summary>
/// <returns>the service list.</returns>
public Task<List<Service>> 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<List<Service>> 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);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Ocelot.Common.Utils;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;

Expand All @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Ocelot.Errors;

using Ocelot.Configuration.File;
using Ocelot.Common.Utils;

using FluentValidation;

Expand All @@ -20,7 +21,6 @@ namespace Ocelot.Configuration.Validator
{
public class FileConfigurationFluentValidator : AbstractValidator<FileConfiguration>, IConfigurationValidator
{
private const string Servicefabric = "servicefabric";
private readonly List<ServiceDiscoveryFinderDelegate> _serviceDiscoveryFinderDelegates;

public FileConfigurationFluentValidator(IServiceProvider provider, RouteFluentValidator routeFluentValidator, FileGlobalConfigurationFluentValidator fileGlobalConfigurationFluentValidator)
Expand Down Expand Up @@ -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();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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;
}
}
}
4 changes: 4 additions & 0 deletions src/Ocelot/Ocelot.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Ocelot.Common\Ocelot.Common.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0" />
</ItemGroup>
Expand Down
20 changes: 10 additions & 10 deletions src/Ocelot/ServiceDiscovery/ServiceDiscoveryProviderFactory.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -51,7 +51,7 @@ public Response<IServiceDiscoveryProvider> Get(ServiceProviderConfiguration serv

private Response<IServiceDiscoveryProvider> 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<IServiceDiscoveryProvider>(new ServiceFabricServiceDiscoveryProvider(sfConfig));
Expand Down
Loading