diff --git a/.travis.yml b/.travis.yml index bd3ea077f..813fa5714 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,12 +8,12 @@ sudo: required dist: bionic # OS X 10.12 -osx_image: xcode9.2 +osx_image: xcode9.4 mono: - - 5.10.0 + - 6.0.0 -dotnet: 2.2.105 +dotnet: 3.0.100 before_install: - git fetch --unshallow # Travis always does a shallow clone, but GitVersion needs the full history including branches and tags diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..6e79d909d --- /dev/null +++ b/appveyor.yml @@ -0,0 +1 @@ +image: Visual Studio 2019 \ No newline at end of file diff --git a/build.cake b/build.cake index aabc6a0f0..5eb3d77c6 100644 --- a/build.cake +++ b/build.cake @@ -2,10 +2,9 @@ #tool "nuget:?package=GitReleaseNotes" #addin nuget:?package=Cake.Json #addin nuget:?package=Newtonsoft.Json -#tool "nuget:?package=OpenCover" #tool "nuget:?package=ReportGenerator" #tool "nuget:?package=coveralls.net&version=0.7.0" -#addin Cake.Coveralls&version=0.7.0 +#addin Cake.Coveralls&version=0.10.1 // compile var compileConfig = Argument("configuration", "Release"); @@ -119,27 +118,20 @@ Task("RunUnitTests") .IsDependentOn("Compile") .Does(() => { + var testSettings = new DotNetCoreTestSettings + { + Configuration = compileConfig, + ResultsDirectory = artifactsForUnitTestsDir, + ArgumentCustomization = args => args + .Append("--settings test/Ocelot.UnitTests/UnitTests.runsettings") + }; + + EnsureDirectoryExists(artifactsForUnitTestsDir); + DotNetCoreTest(unitTestAssemblies, testSettings); + if (IsRunningOnWindows()) { - var coverageSummaryFile = artifactsForUnitTestsDir + File("coverage.xml"); - - EnsureDirectoryExists(artifactsForUnitTestsDir); - - OpenCover(tool => - { - tool.DotNetCoreTest(unitTestAssemblies); - }, - new FilePath(coverageSummaryFile), - new OpenCoverSettings() - { - Register="user", - ArgumentCustomization=args=>args.Append(@"-oldstyle -returntargetcode -excludebyattribute:*.ExcludeFromCoverage*") - } - .WithFilter("+[Ocelot*]*") - .WithFilter("-[xunit*]*") - .WithFilter("-[Ocelot*Tests]*") - ); - + var coverageSummaryFile = GetSubDirectories(artifactsForUnitTestsDir).First().CombineWithFilePath(File("coverage.opencover.xml")); ReportGenerator(coverageSummaryFile, artifactsForUnitTestsDir); if (AppVeyor.IsRunningOnAppVeyor) @@ -171,17 +163,6 @@ Task("RunUnitTests") var whereToCheck = !AppVeyor.IsRunningOnAppVeyor ? coverallsRepo : artifactsForUnitTestsDir; throw new Exception(string.Format("Code coverage fell below the threshold of {0}%. You can find the code coverage report at {1}", minCodeCoverage, whereToCheck)); }; - - } - else - { - var settings = new DotNetCoreTestSettings - { - Configuration = compileConfig, - }; - - EnsureDirectoryExists(artifactsForUnitTestsDir); - DotNetCoreTest(unitTestAssemblies, settings); } }); diff --git a/src/Ocelot.Administration/Ocelot.Administration.csproj b/src/Ocelot.Administration/Ocelot.Administration.csproj index a4aabbd84..abf0f33fe 100644 --- a/src/Ocelot.Administration/Ocelot.Administration.csproj +++ b/src/Ocelot.Administration/Ocelot.Administration.csproj @@ -1,8 +1,6 @@  - netstandard2.0 - 2.0.0 - 2.0.0 + netcoreapp3.0 true Provides Ocelot extensions to use the administration API and IdentityService dependencies that come with it Ocelot.Administration @@ -29,10 +27,13 @@ - + all - - + + + + + diff --git a/src/Ocelot.Administration/OcelotBuilderExtensions.cs b/src/Ocelot.Administration/OcelotBuilderExtensions.cs index 207b3bcf1..da25beaa0 100644 --- a/src/Ocelot.Administration/OcelotBuilderExtensions.cs +++ b/src/Ocelot.Administration/OcelotBuilderExtensions.cs @@ -1,18 +1,18 @@ -namespace Ocelot.Administration -{ - using DependencyInjection; - using IdentityServer4.AccessTokenValidation; - using IdentityServer4.Models; - using Microsoft.AspNetCore.Builder; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.DependencyInjection.Extensions; - using Ocelot.Middleware; - using System; - using System.Collections.Generic; - using System.IdentityModel.Tokens.Jwt; - using System.Security.Cryptography.X509Certificates; +using Ocelot.DependencyInjection; +using IdentityServer4.AccessTokenValidation; +using IdentityServer4.Models; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Ocelot.Middleware; +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Cryptography.X509Certificates; +namespace Ocelot.Administration +{ public static class OcelotBuilderExtensions { public static IOcelotAdministrationBuilder AddAdministration(this IOcelotBuilder builder, string path, string secret) @@ -86,7 +86,7 @@ private static void AddIdentityServer(IIdentityServerConfiguration identityServe else { //todo - refactor so calls method? - var cert = new X509Certificate2(identityServerConfiguration.CredentialsSigningCertificateLocation, identityServerConfiguration.CredentialsSigningCertificatePassword); + var cert = new X509Certificate2(identityServerConfiguration.CredentialsSigningCertificateLocation, identityServerConfiguration.CredentialsSigningCertificatePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable); identityServerBuilder.AddSigningCredential(cert); } } diff --git a/src/Ocelot.Cache.CacheManager/Ocelot.Cache.CacheManager.csproj b/src/Ocelot.Cache.CacheManager/Ocelot.Cache.CacheManager.csproj index 7941dcab1..dab961337 100644 --- a/src/Ocelot.Cache.CacheManager/Ocelot.Cache.CacheManager.csproj +++ b/src/Ocelot.Cache.CacheManager/Ocelot.Cache.CacheManager.csproj @@ -1,8 +1,6 @@  - netstandard2.0 - 2.0.0 - 2.0.0 + netcoreapp3.0 true Provides Ocelot extensions to use CacheManager.Net Ocelot.Cache.CacheManager @@ -28,11 +26,14 @@ - + all - - - + + + + + + diff --git a/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs b/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs index 7d7f4d44f..1044b7b62 100644 --- a/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs +++ b/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs @@ -4,6 +4,7 @@ using Configuration.Repository; using global::Consul; using Logging; + using Microsoft.Extensions.Options; using Newtonsoft.Json; using Responses; using System; @@ -18,29 +19,20 @@ public class ConsulFileConfigurationRepository : IFileConfigurationRepository private readonly IOcelotLogger _logger; public ConsulFileConfigurationRepository( + IOptions fileConfiguration, Cache.IOcelotCache cache, - IInternalConfigurationRepository repo, IConsulClientFactory factory, IOcelotLoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger(); _cache = cache; - var internalConfig = repo.Get(); + var serviceDiscoveryProvider = fileConfiguration.Value.GlobalConfiguration.ServiceDiscoveryProvider; + _configurationKey = string.IsNullOrWhiteSpace(serviceDiscoveryProvider.ConfigurationKey) ? "InternalConfiguration" : + serviceDiscoveryProvider.ConfigurationKey; - _configurationKey = "InternalConfiguration"; - - string token = null; - - if (!internalConfig.IsError) - { - token = internalConfig.Data.ServiceProviderConfiguration.Token; - _configurationKey = !string.IsNullOrEmpty(internalConfig.Data.ServiceProviderConfiguration.ConfigurationKey) ? - internalConfig.Data.ServiceProviderConfiguration.ConfigurationKey : _configurationKey; - } - - var config = new ConsulRegistryConfiguration(internalConfig.Data.ServiceProviderConfiguration.Host, - internalConfig.Data.ServiceProviderConfiguration.Port, _configurationKey, token); + var config = new ConsulRegistryConfiguration(serviceDiscoveryProvider.Host, + serviceDiscoveryProvider.Port, _configurationKey, serviceDiscoveryProvider.Token); _consul = factory.Get(config); } diff --git a/src/Ocelot.Provider.Consul/Ocelot.Provider.Consul.csproj b/src/Ocelot.Provider.Consul/Ocelot.Provider.Consul.csproj index 2df87ad41..61df395be 100644 --- a/src/Ocelot.Provider.Consul/Ocelot.Provider.Consul.csproj +++ b/src/Ocelot.Provider.Consul/Ocelot.Provider.Consul.csproj @@ -1,8 +1,6 @@  - netstandard2.0 - 2.0.0 - 2.0.0 + netcoreapp3.0 true Provides Ocelot extensions to use Consul Ocelot.Provider.Consul @@ -30,8 +28,11 @@ - + all + + + diff --git a/src/Ocelot.Provider.Consul/PollingConsulServiceDiscoveryProvider.cs b/src/Ocelot.Provider.Consul/PollingConsulServiceDiscoveryProvider.cs index 15abc777c..5bace8021 100644 --- a/src/Ocelot.Provider.Consul/PollingConsulServiceDiscoveryProvider.cs +++ b/src/Ocelot.Provider.Consul/PollingConsulServiceDiscoveryProvider.cs @@ -2,16 +2,17 @@ { using Logging; using ServiceDiscovery.Providers; + using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Values; - public class PollConsul : IServiceDiscoveryProvider + public sealed class PollConsul : IServiceDiscoveryProvider, IDisposable { private readonly IOcelotLogger _logger; private readonly IServiceDiscoveryProvider _consulServiceDiscoveryProvider; - private readonly Timer _timer; + private Timer _timer; private bool _polling; private List _services; @@ -34,6 +35,12 @@ public PollConsul(int pollingInterval, IOcelotLoggerFactory factory, IServiceDis }, null, pollingInterval, pollingInterval); } + public void Dispose() + { + _timer?.Dispose(); + _timer = null; + } + public Task> Get() { return Task.FromResult(_services); diff --git a/src/Ocelot.Provider.Eureka/Ocelot.Provider.Eureka.csproj b/src/Ocelot.Provider.Eureka/Ocelot.Provider.Eureka.csproj index d25efc5ac..2254cc2a8 100644 --- a/src/Ocelot.Provider.Eureka/Ocelot.Provider.Eureka.csproj +++ b/src/Ocelot.Provider.Eureka/Ocelot.Provider.Eureka.csproj @@ -1,8 +1,6 @@  - netstandard2.0 - 2.0.0 - 2.0.0 + netcoreapp3.0 true Provides Ocelot extensions to use Eureka Ocelot.Provider.Eureka @@ -29,9 +27,12 @@ - - + + all + + + diff --git a/src/Ocelot.Provider.Eureka/OcelotBuilderExtensions.cs b/src/Ocelot.Provider.Eureka/OcelotBuilderExtensions.cs index 4a246e4fe..e141d1947 100644 --- a/src/Ocelot.Provider.Eureka/OcelotBuilderExtensions.cs +++ b/src/Ocelot.Provider.Eureka/OcelotBuilderExtensions.cs @@ -12,9 +12,7 @@ public static class OcelotBuilderExtensions { public static IOcelotBuilder AddEureka(this IOcelotBuilder builder) { - var service = builder.Services.First(x => x.ServiceType == typeof(IConfiguration)); - var configuration = (IConfiguration)service.ImplementationInstance; - builder.Services.AddDiscoveryClient(configuration); + builder.Services.AddDiscoveryClient(builder.Configuration); builder.Services.AddSingleton(EurekaProviderFactory.Get); builder.Services.AddSingleton(EurekaMiddlewareConfigurationProvider.Get); return builder; diff --git a/src/Ocelot.Provider.Kubernetes/Ocelot.Provider.Kubernetes.csproj b/src/Ocelot.Provider.Kubernetes/Ocelot.Provider.Kubernetes.csproj index 436585dad..6dba88d18 100644 --- a/src/Ocelot.Provider.Kubernetes/Ocelot.Provider.Kubernetes.csproj +++ b/src/Ocelot.Provider.Kubernetes/Ocelot.Provider.Kubernetes.csproj @@ -1,9 +1,7 @@  - netstandard2.0 - 2.0.0 - 2.0.0 + netcoreapp3.0 true Ocelot Provides Ocelot extensions to use kubernetes @@ -30,12 +28,16 @@ - - + + + + + + diff --git a/src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj b/src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj index fa15a189a..36143432b 100644 --- a/src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj +++ b/src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj @@ -1,8 +1,6 @@  - netstandard2.0 - 2.0.0 - 2.0.0 + netcoreapp3.0 true Provides Ocelot extensions to use Polly.NET Ocelot.Provider.Polly @@ -29,9 +27,12 @@ - + all - + + + + diff --git a/src/Ocelot.Provider.Rafty/Ocelot.Provider.Rafty.csproj b/src/Ocelot.Provider.Rafty/Ocelot.Provider.Rafty.csproj index f7e0996cb..e66995626 100644 --- a/src/Ocelot.Provider.Rafty/Ocelot.Provider.Rafty.csproj +++ b/src/Ocelot.Provider.Rafty/Ocelot.Provider.Rafty.csproj @@ -1,8 +1,6 @@ - + - netstandard2.0 - 2.0.0 - 2.0.0 + netcoreapp3.0 true Provides Ocelot extensions to use Rafty Ocelot.Provider.Rafty @@ -30,10 +28,13 @@ - + - + all + + + diff --git a/src/Ocelot.Tracing.Butterfly/Ocelot.Tracing.Butterfly.csproj b/src/Ocelot.Tracing.Butterfly/Ocelot.Tracing.Butterfly.csproj index c161f183a..6f2e81416 100644 --- a/src/Ocelot.Tracing.Butterfly/Ocelot.Tracing.Butterfly.csproj +++ b/src/Ocelot.Tracing.Butterfly/Ocelot.Tracing.Butterfly.csproj @@ -1,9 +1,7 @@  - netstandard2.0 - 2.0.0 - 2.0.0 + netcoreapp3.0 true This package provides methods to integrate Butterfly tracing with Ocelot. Ocelot.Tracing.Butterfly @@ -33,5 +31,8 @@ + + + diff --git a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs index 8df829351..770d7b7a6 100644 --- a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs +++ b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs @@ -14,7 +14,7 @@ public class DiskFileConfigurationRepository : IFileConfigurationRepository private static readonly object _lock = new object(); private const string ConfigurationFileName = "ocelot"; - public DiskFileConfigurationRepository(IHostingEnvironment hostingEnvironment) + public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment) { _environmentFilePath = $"{AppContext.BaseDirectory}{ConfigurationFileName}{(string.IsNullOrEmpty(hostingEnvironment.EnvironmentName) ? string.Empty : ".")}{hostingEnvironment.EnvironmentName}.json"; diff --git a/src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs b/src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs index 49e92355b..add4fe0bb 100644 --- a/src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs +++ b/src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs @@ -21,8 +21,8 @@ public FileConfigurationFluentValidator(IServiceProvider provider, ReRouteFluent .GetServices() .ToList(); - RuleFor(configuration => configuration.ReRoutes) - .SetCollectionValidator(reRouteFluentValidator); + RuleForEach(configuration => configuration.ReRoutes) + .SetValidator(reRouteFluentValidator); RuleFor(configuration => configuration.GlobalConfiguration) .SetValidator(fileGlobalConfigurationFluentValidator); diff --git a/src/Ocelot/Configuration/Validator/ReRouteFluentValidator.cs b/src/Ocelot/Configuration/Validator/ReRouteFluentValidator.cs index 724d92bbb..746c430c0 100644 --- a/src/Ocelot/Configuration/Validator/ReRouteFluentValidator.cs +++ b/src/Ocelot/Configuration/Validator/ReRouteFluentValidator.cs @@ -80,8 +80,8 @@ public ReRouteFluentValidator(IAuthenticationSchemeProvider authenticationScheme When(reRoute => string.IsNullOrEmpty(reRoute.ServiceName), () => { - RuleFor(reRoute => reRoute.DownstreamHostAndPorts) - .SetCollectionValidator(hostAndPortValidator); + RuleForEach(reRoute => reRoute.DownstreamHostAndPorts) + .SetValidator(hostAndPortValidator); }); } diff --git a/src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs b/src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs index 54137b14f..3d29ef514 100644 --- a/src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs +++ b/src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs @@ -29,12 +29,12 @@ public static IConfigurationBuilder AddOcelotBaseUrl(this IConfigurationBuilder return builder; } - public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, IHostingEnvironment env) + public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, IWebHostEnvironment env) { return builder.AddOcelot(".", env); } - public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, string folder, IHostingEnvironment env) + public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, string folder, IWebHostEnvironment env) { const string primaryConfigFile = "ocelot.json"; diff --git a/src/Ocelot/DependencyInjection/OcelotBuilder.cs b/src/Ocelot/DependencyInjection/OcelotBuilder.cs index 6733b54cd..8f120997c 100644 --- a/src/Ocelot/DependencyInjection/OcelotBuilder.cs +++ b/src/Ocelot/DependencyInjection/OcelotBuilder.cs @@ -142,7 +142,7 @@ public OcelotBuilder(IServiceCollection services, IConfiguration configurationRo .AddApplicationPart(assembly) .AddControllersAsServices() .AddAuthorization() - .AddJsonFormatters(); + .AddNewtonsoftJson(); Services.AddLogging(); Services.AddMiddlewareAnalysis(); diff --git a/src/Ocelot/DependencyInjection/ServiceCollectionExtensions.cs b/src/Ocelot/DependencyInjection/ServiceCollectionExtensions.cs index 030e99578..0d7a3bb73 100644 --- a/src/Ocelot/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Ocelot/DependencyInjection/ServiceCollectionExtensions.cs @@ -7,9 +7,9 @@ namespace Ocelot.DependencyInjection public static class ServiceCollectionExtensions { public static IOcelotBuilder AddOcelot(this IServiceCollection services) - { - var service = services.First(x => x.ServiceType == typeof(IConfiguration)); - var configuration = (IConfiguration)service.ImplementationInstance; + { + var configuration = services.BuildServiceProvider() + .GetRequiredService(); return new OcelotBuilder(services, configuration); } diff --git a/src/Ocelot/Logging/AspDotNetLogger.cs b/src/Ocelot/Logging/AspDotNetLogger.cs index 598cbdd09..35375d455 100644 --- a/src/Ocelot/Logging/AspDotNetLogger.cs +++ b/src/Ocelot/Logging/AspDotNetLogger.cs @@ -8,53 +8,83 @@ public class AspDotNetLogger : IOcelotLogger { private readonly ILogger _logger; private readonly IRequestScopedDataRepository _scopedDataRepository; + private readonly Func _func; public AspDotNetLogger(ILogger logger, IRequestScopedDataRepository scopedDataRepository) { _logger = logger; - _scopedDataRepository = scopedDataRepository; + _scopedDataRepository = scopedDataRepository; + _func = (state, exception) => + { + if (exception == null) + { + return state; + } + else + { + return $"{state}, exception: {exception}"; + } + }; } public void LogTrace(string message) - { + { var requestId = GetOcelotRequestId(); - var previousRequestId = GetOcelotPreviousRequestId(); - _logger.LogTrace("requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}", requestId, previousRequestId, message); + var previousRequestId = GetOcelotPreviousRequestId(); + + var state = $"requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}"; + + _logger.Log(LogLevel.Trace, default(EventId), state, null, _func); } public void LogDebug(string message) - { + { var requestId = GetOcelotRequestId(); - var previousRequestId = GetOcelotPreviousRequestId(); - _logger.LogDebug("requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}", requestId, previousRequestId, message); + var previousRequestId = GetOcelotPreviousRequestId(); + + var state = $"requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}"; + + _logger.Log(LogLevel.Debug, default(EventId), state, null, _func); } public void LogInformation(string message) - { + { var requestId = GetOcelotRequestId(); - var previousRequestId = GetOcelotPreviousRequestId(); - _logger.LogInformation("requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}", requestId, previousRequestId, message); + var previousRequestId = GetOcelotPreviousRequestId(); + + var state = $"requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}"; + + _logger.Log(LogLevel.Information, default(EventId), state, null, _func); } public void LogWarning(string message) { var requestId = GetOcelotRequestId(); - var previousRequestId = GetOcelotPreviousRequestId(); - _logger.LogWarning("requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}", requestId, previousRequestId, message); + var previousRequestId = GetOcelotPreviousRequestId(); + + var state = $"requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}"; + + _logger.Log(LogLevel.Warning, default(EventId), state, null, _func); } public void LogError(string message, Exception exception) { var requestId = GetOcelotRequestId(); - var previousRequestId = GetOcelotPreviousRequestId(); - _logger.LogError("requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}, exception: {exception}", requestId, previousRequestId, message, exception); + var previousRequestId = GetOcelotPreviousRequestId(); + + var state = $"requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}"; + + _logger.Log(LogLevel.Error,default(EventId), state, exception, _func); } public void LogCritical(string message, Exception exception) { var requestId = GetOcelotRequestId(); - var previousRequestId = GetOcelotPreviousRequestId(); - _logger.LogCritical("requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}, exception: {exception}", requestId, previousRequestId, message, exception); + var previousRequestId = GetOcelotPreviousRequestId(); + + var state = $"requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}"; + + _logger.Log(LogLevel.Critical, default(EventId), state, exception, _func); } private string GetOcelotRequestId() @@ -81,4 +111,4 @@ private string GetOcelotPreviousRequestId() return requestId.Data; } } -} +} diff --git a/src/Ocelot/Middleware/OcelotMiddlewareExtensions.cs b/src/Ocelot/Middleware/OcelotMiddlewareExtensions.cs index a841df5ac..42bc6b713 100644 --- a/src/Ocelot/Middleware/OcelotMiddlewareExtensions.cs +++ b/src/Ocelot/Middleware/OcelotMiddlewareExtensions.cs @@ -178,7 +178,7 @@ private static void ThrowToStopOcelotStarting(Response config) private static void ConfigureDiagnosticListener(IApplicationBuilder builder) { - var env = builder.ApplicationServices.GetService(); + var env = builder.ApplicationServices.GetService(); var listener = builder.ApplicationServices.GetService(); var diagnosticListener = builder.ApplicationServices.GetService(); diagnosticListener.SubscribeWithAdapter(listener); diff --git a/src/Ocelot/Ocelot.csproj b/src/Ocelot/Ocelot.csproj index b9d9d2cea..fb0d541ae 100644 --- a/src/Ocelot/Ocelot.csproj +++ b/src/Ocelot/Ocelot.csproj @@ -1,8 +1,6 @@  - netstandard2.0 - 2.0.0 - 2.0.0 + netcoreapp3.0 true Ocelot is an API Gateway. The project is aimed at people using .NET running a micro services / service orientated architecture that need a unified point of entry into their system. In particular I want easy integration with IdentityServer reference and bearer tokens. reference tokens. Ocelot is a bunch of middlewares in a specific order. Ocelot manipulates the HttpRequest object into a state specified by its configuration until it reaches a request builder middleware where it creates a HttpRequestMessage object which is used to make a request to a downstream service. The middleware that makes the request is the last thing in the Ocelot pipeline. It does not call the next middleware. The response from the downstream service is stored in a per request scoped repository and retrived as the requests goes back up the Ocelot pipeline. There is a piece of middleware that maps the HttpResponseMessage onto the HttpResponse object and that is returned to the client. That is basically it with a bunch of other features. Ocelot @@ -25,16 +23,20 @@ full True + - - - - - + + + NU1701 - + + all + + + + diff --git a/test/Ocelot.AcceptanceTests/ConfigurationInConsulTests.cs b/test/Ocelot.AcceptanceTests/ConfigurationInConsulTests.cs index ae7d6b0ac..e72aab335 100644 --- a/test/Ocelot.AcceptanceTests/ConfigurationInConsulTests.cs +++ b/test/Ocelot.AcceptanceTests/ConfigurationInConsulTests.cs @@ -5,6 +5,7 @@ namespace Ocelot.AcceptanceTests using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; + using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -16,9 +17,9 @@ namespace Ocelot.AcceptanceTests public class ConfigurationInConsulTests : IDisposable { - private IWebHost _builder; + private IHost _builder; private readonly Steps _steps; - private IWebHost _fakeConsulBuilder; + private IHost _fakeConsulBuilder; private FileConfiguration _config; private readonly List _consulServices; @@ -75,8 +76,10 @@ public void should_return_response_200_with_simple_url_when_using_jsonserialized private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName) { - _fakeConsulBuilder = new WebHostBuilder() - .UseUrls(url) + _fakeConsulBuilder = Host.CreateDefaultBuilder() + .ConfigureWebHost(webBuilder => + { + webBuilder.UseUrls(url) .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() @@ -103,7 +106,9 @@ private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string { var reader = new StreamReader(context.Request.Body); - var json = reader.ReadToEnd(); + // Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead. + // var json = reader.ReadToEnd(); + var json = await reader.ReadToEndAsync(); _config = JsonConvert.DeserializeObject(json); @@ -122,8 +127,8 @@ private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string await context.Response.WriteJsonAsync(_consulServices); } }); - }) - .Build(); + }); + }).Build(); _fakeConsulBuilder.Start(); } @@ -146,22 +151,24 @@ public FakeConsulGetResponse(string value) private void GivenThereIsAServiceRunningOn(string url, string basePath, int statusCode, string responseBody) { - _builder = new WebHostBuilder() - .UseUrls(url) - .UseKestrel() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() - .UseUrls(url) - .Configure(app => + _builder = Host.CreateDefaultBuilder() + .ConfigureWebHost(webBuilder => { - app.UsePathBase(basePath); - - app.Run(async context => + webBuilder.UseUrls(url) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseUrls(url) + .Configure(app => { - context.Response.StatusCode = statusCode; - await context.Response.WriteAsync(responseBody); - }); - }) + app.UsePathBase(basePath); + app.Run(async context => + { + context.Response.StatusCode = statusCode; + await context.Response.WriteAsync(responseBody); + }); + }); + }) .Build(); _builder.Start(); diff --git a/test/Ocelot.AcceptanceTests/ConsulConfigurationInConsulTests.cs b/test/Ocelot.AcceptanceTests/ConsulConfigurationInConsulTests.cs index 27f8dee8f..976bd9095 100644 --- a/test/Ocelot.AcceptanceTests/ConsulConfigurationInConsulTests.cs +++ b/test/Ocelot.AcceptanceTests/ConsulConfigurationInConsulTests.cs @@ -373,7 +373,9 @@ private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string { var reader = new StreamReader(context.Request.Body); - var json = reader.ReadToEnd(); + // Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead. + // var json = reader.ReadToEnd(); + var json = await reader.ReadToEndAsync(); _config = JsonConvert.DeserializeObject(json); diff --git a/test/Ocelot.AcceptanceTests/ConsulWebSocketTests.cs b/test/Ocelot.AcceptanceTests/ConsulWebSocketTests.cs index 8ed9b1408..7ebb47379 100644 --- a/test/Ocelot.AcceptanceTests/ConsulWebSocketTests.cs +++ b/test/Ocelot.AcceptanceTests/ConsulWebSocketTests.cs @@ -181,7 +181,13 @@ await client.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Text, } else if (result.MessageType == WebSocketMessageType.Close) { - await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); + if (client.State != WebSocketState.Closed) + { + // Last version, the client state is CloseReceived + // Valid states are: Open, CloseReceived, CloseSent + await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); + } + break; } } @@ -227,7 +233,13 @@ await client.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Text, } else if (result.MessageType == WebSocketMessageType.Close) { - await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); + if (client.State != WebSocketState.Closed) + { + // Last version, the client state is CloseReceived + // Valid states are: Open, CloseReceived, CloseSent + await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); + } + break; } } diff --git a/test/Ocelot.AcceptanceTests/ContentTests.cs b/test/Ocelot.AcceptanceTests/ContentTests.cs index 39299f74b..7a4d83650 100644 --- a/test/Ocelot.AcceptanceTests/ContentTests.cs +++ b/test/Ocelot.AcceptanceTests/ContentTests.cs @@ -55,7 +55,7 @@ public void should_not_add_content_type_or_content_length_headers() .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .And(x => ThenTheContentTypeShouldBeEmpty()) - .And(x => ThenTheContentLengthShouldBeEmpty()) + .And(x => ThenTheContentLengthShouldBeZero()) .BDDfy(); } @@ -139,9 +139,9 @@ private void ThenTheContentTypeIsIs(string expected) _contentType.ShouldBe(expected); } - private void ThenTheContentLengthShouldBeEmpty() + private void ThenTheContentLengthShouldBeZero() { - _contentLength.ShouldBeNull(); + _contentLength.ShouldBeEquivalentTo(0L); } private void ThenTheContentLengthIs(int expected) diff --git a/test/Ocelot.AcceptanceTests/GzipTests.cs b/test/Ocelot.AcceptanceTests/GzipTests.cs index bb03c9c59..51ab17236 100644 --- a/test/Ocelot.AcceptanceTests/GzipTests.cs +++ b/test/Ocelot.AcceptanceTests/GzipTests.cs @@ -73,7 +73,9 @@ private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int { using (var sr = new StreamReader(decompress)) { - text = sr.ReadToEnd(); + // Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead. + // text = sr.ReadToEnd(); + text = await sr.ReadToEndAsync(); } } diff --git a/test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj b/test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj index 762448e72..a41029d41 100644 --- a/test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj +++ b/test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj @@ -1,7 +1,7 @@  0.0.0-dev - netcoreapp2.2 + netcoreapp3.0 Ocelot.AcceptanceTests Exe Ocelot.AcceptanceTests @@ -36,36 +36,39 @@ + - - - - + + + all all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - + + + + + + + + - + - - + + - - + + + + + \ No newline at end of file diff --git a/test/Ocelot.AcceptanceTests/Steps.cs b/test/Ocelot.AcceptanceTests/Steps.cs index 6b9870bdf..5bddcd923 100644 --- a/test/Ocelot.AcceptanceTests/Steps.cs +++ b/test/Ocelot.AcceptanceTests/Steps.cs @@ -37,7 +37,7 @@ using System.Threading.Tasks; using static Ocelot.AcceptanceTests.HttpDelegatingHandlersTests; using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder; - using CookieHeaderValue = System.Net.Http.Headers.CookieHeaderValue; + using CookieHeaderValue = Microsoft.Net.Http.Headers.CookieHeaderValue; using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue; public class Steps : IDisposable @@ -338,7 +338,7 @@ public void GivenOcelotIsRunningUsingConsulToStoreConfigAndJsonSerializedCache() { x.WithMicrosoftLogging(log => { - log.AddConsole(LogLevel.Debug); + //log.AddConsole(LogLevel.Debug); }) .WithJsonSerializer() .WithHandle(typeof(InMemoryJsonHandle<>)); @@ -424,7 +424,7 @@ public void GivenOcelotIsRunningUsingJsonSerializedCache() { x.WithMicrosoftLogging(log => { - log.AddConsole(LogLevel.Debug); + //log.AddConsole(LogLevel.Debug); }) .WithJsonSerializer() .WithHandle(typeof(InMemoryJsonHandle<>)); diff --git a/test/Ocelot.AcceptanceTests/WebSocketTests.cs b/test/Ocelot.AcceptanceTests/WebSocketTests.cs index e98a1bf97..425416e2c 100644 --- a/test/Ocelot.AcceptanceTests/WebSocketTests.cs +++ b/test/Ocelot.AcceptanceTests/WebSocketTests.cs @@ -164,7 +164,13 @@ await client.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Text, } else if (result.MessageType == WebSocketMessageType.Close) { - await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); + if (client.State != WebSocketState.Closed) + { + // Last version, the client state is CloseReceived + // Valid states are: Open, CloseReceived, CloseSent + await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); + } + break; } } @@ -210,7 +216,13 @@ await client.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Text, } else if (result.MessageType == WebSocketMessageType.Close) { - await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); + if (client.State != WebSocketState.Closed) + { + // Last version, the client state is CloseReceived + // Valid states are: Open, CloseReceived, CloseSent + await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); + } + break; } } @@ -273,13 +285,13 @@ private async Task Echo(WebSocket webSocket) var result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); - while (!result.CloseStatus.HasValue) + while (!result.CloseStatus.HasValue) { await webSocket.SendAsync(new ArraySegment(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None); result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); } - + await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); } catch (Exception e) diff --git a/test/Ocelot.Benchmarks/Ocelot.Benchmarks.csproj b/test/Ocelot.Benchmarks/Ocelot.Benchmarks.csproj index 32f4f5568..48df8a929 100644 --- a/test/Ocelot.Benchmarks/Ocelot.Benchmarks.csproj +++ b/test/Ocelot.Benchmarks/Ocelot.Benchmarks.csproj @@ -2,7 +2,7 @@ 0.0.0-dev - netcoreapp2.2 + netcoreapp3.0 Ocelot.Benchmarks Exe Ocelot.Benchmarks @@ -19,8 +19,12 @@ - + all + + + + \ No newline at end of file diff --git a/test/Ocelot.IntegrationTests/AdministrationTests.cs b/test/Ocelot.IntegrationTests/AdministrationTests.cs index 5b5895cdd..b874f7879 100644 --- a/test/Ocelot.IntegrationTests/AdministrationTests.cs +++ b/test/Ocelot.IntegrationTests/AdministrationTests.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using Ocelot.Administration; using Ocelot.Cache; @@ -29,15 +30,15 @@ public class AdministrationTests : IDisposable private HttpClient _httpClient; private readonly HttpClient _httpClientTwo; private HttpResponseMessage _response; - private IWebHost _builder; - private IWebHostBuilder _webHostBuilder; + private IHost _builder; + private IHostBuilder _webHostBuilder; private string _ocelotBaseUrl; private BearerToken _token; - private IWebHostBuilder _webHostBuilderTwo; - private IWebHost _builderTwo; - private IWebHost _identityServerBuilder; - private IWebHost _fooServiceBuilder; - private IWebHost _barServiceBuilder; + private IHostBuilder _webHostBuilderTwo; + private IHost _builderTwo; + private IHost _identityServerBuilder; + private IHost _fooServiceBuilder; + private IHost _barServiceBuilder; public AdministrationTests() { @@ -220,7 +221,7 @@ public void should_get_file_configuration_edit_and_post_updated_version() UpstreamHttpMethod = new List { "get" }, UpstreamPathTemplate = "/test" } - } + }, }; var updatedConfiguration = new FileConfiguration @@ -476,56 +477,59 @@ private void GivenIHaveAToken(string url) private void GivenThereIsAnIdentityServerOn(string url, string apiName) { - _identityServerBuilder = new WebHostBuilder() - .UseUrls(url) - .UseKestrel() - .UseContentRoot(Directory.GetCurrentDirectory()) - .ConfigureServices(services => + _identityServerBuilder = Host.CreateDefaultBuilder() + .ConfigureWebHost(webBuilder => { - services.AddLogging(); - services.AddIdentityServer() - .AddDeveloperSigningCredential() + webBuilder.UseUrls(url) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .ConfigureServices(services => + { + services.AddLogging(); + services.AddIdentityServer() + .AddDeveloperSigningCredential() .AddInMemoryApiResources(new List { - new ApiResource + new ApiResource + { + Name = apiName, + Description = apiName, + Enabled = true, + DisplayName = apiName, + Scopes = new List() { - Name = apiName, - Description = apiName, - Enabled = true, - DisplayName = apiName, - Scopes = new List() - { - new Scope(apiName) - } - } + new Scope(apiName), + }, + }, }) .AddInMemoryClients(new List { - new Client - { - ClientId = apiName, - AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, - ClientSecrets = new List {new Secret("secret".Sha256())}, - AllowedScopes = new List { apiName }, - AccessTokenType = AccessTokenType.Jwt, - Enabled = true - } + new Client + { + ClientId = apiName, + AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, + ClientSecrets = new List { new Secret("secret".Sha256()) }, + AllowedScopes = new List { apiName }, + AccessTokenType = AccessTokenType.Jwt, + Enabled = true + }, }) .AddTestUsers(new List { - new TestUser - { - Username = "test", - Password = "test", - SubjectId = "1231231" - } + new TestUser + { + Username = "test", + Password = "test", + SubjectId = "1231231" + }, }); - }) - .Configure(app => - { - app.UseIdentityServer(); - }) - .Build(); + }) + .Configure(app => + { + app.UseIdentityServer(); + } + ); + }).Build(); _identityServerBuilder.Start(); @@ -540,28 +544,32 @@ private void GivenAnotherOcelotIsRunning(string baseUrl) { _httpClientTwo.BaseAddress = new Uri(baseUrl); - _webHostBuilderTwo = new WebHostBuilder() - .UseUrls(baseUrl) - .UseKestrel() - .UseContentRoot(Directory.GetCurrentDirectory()) - .ConfigureAppConfiguration((hostingContext, config) => - { - config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath); - var env = hostingContext.HostingEnvironment; - config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false); - config.AddJsonFile("ocelot.json", false, false); - config.AddEnvironmentVariables(); - }) - .ConfigureServices(x => - { - x.AddOcelot() + _webHostBuilderTwo = Host.CreateDefaultBuilder() + .ConfigureWebHost(webBuilder => + { + webBuilder.UseUrls(baseUrl) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath); + var env = hostingContext.HostingEnvironment; + config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false); + config.AddJsonFile("ocelot.json", false, false); + config.AddEnvironmentVariables(); + }) + .ConfigureServices(x => + { + x.AddMvc(option => option.EnableEndpointRouting = false); + x.AddOcelot() .AddAdministration("/administration", "secret"); - }) - .Configure(app => - { - app.UseOcelot().Wait(); - }); + }) + .Configure(app => + { + app.UseOcelot().Wait(); + }); + }); _builderTwo = _webHostBuilderTwo.Build(); @@ -654,29 +662,33 @@ private void GivenIHaveAnOcelotToken(string adminPath) private void GivenOcelotIsRunningWithIdentityServerSettings(Action configOptions) { - _webHostBuilder = new WebHostBuilder() - .UseUrls(_ocelotBaseUrl) - .UseKestrel() - .UseContentRoot(Directory.GetCurrentDirectory()) - .ConfigureAppConfiguration((hostingContext, config) => + _webHostBuilder = Host.CreateDefaultBuilder() + .ConfigureWebHost(webBuilder => { - config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath); - var env = hostingContext.HostingEnvironment; - config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) + webBuilder.UseUrls(_ocelotBaseUrl) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath); + var env = hostingContext.HostingEnvironment; + config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false); - config.AddJsonFile("ocelot.json", false, false); - config.AddEnvironmentVariables(); - }) - .ConfigureServices(x => - { - x.AddSingleton(_webHostBuilder); - x.AddOcelot() - .AddAdministration("/administration", configOptions); - }) + config.AddJsonFile("ocelot.json", false, false); + config.AddEnvironmentVariables(); + }) + .ConfigureServices(x => + { + x.AddMvc(option => option.EnableEndpointRouting = false); + x.AddSingleton(_webHostBuilder); + x.AddOcelot() + .AddAdministration("/administration", configOptions); + }) .Configure(app => { app.UseOcelot().Wait(); }); + }); _builder = _webHostBuilder.Build(); @@ -685,27 +697,31 @@ private void GivenOcelotIsRunningWithIdentityServerSettings(Action + _webHostBuilder = Host.CreateDefaultBuilder() + .ConfigureWebHost(webBuilder => { - config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath); - var env = hostingContext.HostingEnvironment; - config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) + webBuilder.UseUrls(_ocelotBaseUrl) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath); + var env = hostingContext.HostingEnvironment; + config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false); - config.AddJsonFile("ocelot.json", false, false); - config.AddEnvironmentVariables(); - }) - .ConfigureServices(x => - { - x.AddOcelot() + config.AddJsonFile("ocelot.json", false, false); + config.AddEnvironmentVariables(); + }) + .ConfigureServices(x => + { + x.AddMvc(s => s.EnableEndpointRouting = false); + x.AddOcelot() .AddAdministration("/administration", "secret"); - }) - .Configure(app => - { - app.UseOcelot().Wait(); + }) + .Configure(app => + { + app.UseOcelot().Wait(); + }); }); _builder = _webHostBuilder.Build(); @@ -715,30 +731,34 @@ private void GivenOcelotIsRunning() private void GivenOcelotIsRunningWithNoWebHostBuilder(string baseUrl) { - _webHostBuilder = new WebHostBuilder() - .UseUrls(_ocelotBaseUrl) - .UseKestrel() - .UseContentRoot(Directory.GetCurrentDirectory()) - .ConfigureAppConfiguration((hostingContext, config) => + _webHostBuilder = Host.CreateDefaultBuilder() + .ConfigureWebHost(webBuilder => { - config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath); - var env = hostingContext.HostingEnvironment; - config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) + webBuilder.UseUrls(_ocelotBaseUrl) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath); + var env = hostingContext.HostingEnvironment; + config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false); - config.AddJsonFile("ocelot.json", false, false); - config.AddEnvironmentVariables(); - }) - .ConfigureServices(x => - { - x.AddSingleton(_webHostBuilder); - x.AddOcelot() + config.AddJsonFile("ocelot.json", false, false); + config.AddEnvironmentVariables(); + }) + .ConfigureServices(x => + { + x.AddMvc(option => option.EnableEndpointRouting = false); + x.AddSingleton(_webHostBuilder); + x.AddOcelot() .AddAdministration("/administration", "secret"); - }) - .Configure(app => - { - app.UseOcelot().Wait(); - }); - + }) + .Configure(app => + { + app.UseOcelot().Wait(); + }); + }); + _builder = _webHostBuilder.Build(); _builder.Start(); @@ -797,42 +817,46 @@ public void Dispose() private void GivenThereIsAFooServiceRunningOn(string baseUrl) { - _fooServiceBuilder = new WebHostBuilder() - .UseUrls(baseUrl) - .UseKestrel() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() - .Configure(app => + _fooServiceBuilder = Host.CreateDefaultBuilder() + .ConfigureWebHost(webBuilder => { - app.UsePathBase("/foo"); - app.Run(async context => + webBuilder.UseUrls(baseUrl) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .Configure(app => { - context.Response.StatusCode = 200; - await context.Response.WriteAsync("foo"); + app.UsePathBase("/foo"); + app.Run(async context => + { + context.Response.StatusCode = 200; + await context.Response.WriteAsync("foo"); + }); }); - }) - .Build(); - + }).Build(); + _fooServiceBuilder.Start(); } private void GivenThereIsABarServiceRunningOn(string baseUrl) { - _barServiceBuilder = new WebHostBuilder() - .UseUrls(baseUrl) - .UseKestrel() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() - .Configure(app => + _barServiceBuilder = Host.CreateDefaultBuilder() + .ConfigureWebHost(webBuilder => { - app.UsePathBase("/bar"); - app.Run(async context => + webBuilder.UseUrls(baseUrl) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .Configure(app => { - context.Response.StatusCode = 200; - await context.Response.WriteAsync("bar"); + app.UsePathBase("/bar"); + app.Run(async context => + { + context.Response.StatusCode = 200; + await context.Response.WriteAsync("bar"); + }); }); - }) - .Build(); + }).Build(); _barServiceBuilder.Start(); } diff --git a/test/Ocelot.IntegrationTests/CacheManagerTests.cs b/test/Ocelot.IntegrationTests/CacheManagerTests.cs index beab8ca34..6be90f01f 100644 --- a/test/Ocelot.IntegrationTests/CacheManagerTests.cs +++ b/test/Ocelot.IntegrationTests/CacheManagerTests.cs @@ -5,6 +5,8 @@ namespace Ocelot.IntegrationTests using global::CacheManager.Core; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Ocelot.Administration; @@ -25,15 +27,10 @@ public class CacheManagerTests : IDisposable private HttpClient _httpClient; private readonly HttpClient _httpClientTwo; private HttpResponseMessage _response; - private IWebHost _builder; - private IWebHostBuilder _webHostBuilder; + private IHost _builder; + private IHostBuilder _webHostBuilder; private string _ocelotBaseUrl; private BearerToken _token; - private IWebHostBuilder _webHostBuilderTwo; - private IWebHost _builderTwo; - private IWebHost _identityServerBuilder; - private IWebHost _fooServiceBuilder; - private IWebHost _barServiceBuilder; public CacheManagerTests() { @@ -61,7 +58,7 @@ public void should_clear_region() { Host = "localhost", Port = 80, - } + }, }, DownstreamScheme = "https", DownstreamPathTemplate = "/", @@ -69,8 +66,8 @@ public void should_clear_region() UpstreamPathTemplate = "/", FileCacheOptions = new FileCacheOptions { - TtlSeconds = 10 - } + TtlSeconds = 10, + }, }, new FileReRoute() { @@ -80,7 +77,7 @@ public void should_clear_region() { Host = "localhost", Port = 80, - } + }, }, DownstreamScheme = "https", DownstreamPathTemplate = "/", @@ -88,10 +85,10 @@ public void should_clear_region() UpstreamPathTemplate = "/test", FileCacheOptions = new FileCacheOptions { - TtlSeconds = 10 - } - } - } + TtlSeconds = 10, + }, + }, + }, }; var regionToClear = "gettest"; @@ -118,7 +115,7 @@ private void GivenIHaveAnOcelotToken(string adminPath) new KeyValuePair("client_id", "admin"), new KeyValuePair("client_secret", "secret"), new KeyValuePair("scope", "admin"), - new KeyValuePair("grant_type", "client_credentials") + new KeyValuePair("grant_type", "client_credentials"), }; var content = new FormUrlEncodedContent(formData); @@ -133,16 +130,13 @@ private void GivenIHaveAnOcelotToken(string adminPath) private void GivenOcelotIsRunning() { - _webHostBuilder = new WebHostBuilder() - .UseUrls(_ocelotBaseUrl) - .UseKestrel() - .UseContentRoot(Directory.GetCurrentDirectory()) + _webHostBuilder = Host.CreateDefaultBuilder() .ConfigureAppConfiguration((hostingContext, config) => { config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath); var env = hostingContext.HostingEnvironment; config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false); + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false); config.AddJsonFile("ocelot.json", false, false); config.AddEnvironmentVariables(); }) @@ -151,20 +145,26 @@ private void GivenOcelotIsRunning() Action settings = (s) => { s.WithMicrosoftLogging(log => - { - log.AddConsole(LogLevel.Debug); - }) - .WithDictionaryHandle(); + { + //log.AddConsole(LogLevel.Debug); + }) + .WithDictionaryHandle(); }; - + x.AddMvc(option => option.EnableEndpointRouting = false); x.AddOcelot() - .AddCacheManager(settings) - .AddAdministration("/administration", "secret"); - }) + .AddCacheManager(settings) + .AddAdministration("/administration", "secret"); + }) + .ConfigureWebHost(webBuilder => + { + webBuilder.UseUrls(_ocelotBaseUrl) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) .Configure(app => { app.UseOcelot().Wait(); }); + }); _builder = _webHostBuilder.Build(); @@ -214,7 +214,7 @@ public void Dispose() Environment.SetEnvironmentVariable("OCELOT_CERTIFICATE_PASSWORD", ""); _builder?.Dispose(); _httpClient?.Dispose(); - _identityServerBuilder?.Dispose(); + //_identityServerBuilder?.Dispose(); } } } diff --git a/test/Ocelot.IntegrationTests/Ocelot.IntegrationTests.csproj b/test/Ocelot.IntegrationTests/Ocelot.IntegrationTests.csproj index 81c50e05e..f38ede57b 100644 --- a/test/Ocelot.IntegrationTests/Ocelot.IntegrationTests.csproj +++ b/test/Ocelot.IntegrationTests/Ocelot.IntegrationTests.csproj @@ -1,7 +1,7 @@  0.0.0-dev - netcoreapp2.2 + netcoreapp3.0 Ocelot.IntegrationTests Exe Ocelot.IntegrationTests @@ -29,30 +29,33 @@ + - - - - + + + all all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - + + + + + + + - + - - - + + + + + + \ No newline at end of file diff --git a/test/Ocelot.IntegrationTests/ThreadSafeHeadersTests.cs b/test/Ocelot.IntegrationTests/ThreadSafeHeadersTests.cs index 2f170229f..644d1d902 100644 --- a/test/Ocelot.IntegrationTests/ThreadSafeHeadersTests.cs +++ b/test/Ocelot.IntegrationTests/ThreadSafeHeadersTests.cs @@ -54,12 +54,12 @@ public void should_return_same_response_for_each_different_header_under_load_to_ { Host = "localhost", Port = 51879, - } + }, }, UpstreamPathTemplate = "/", UpstreamHttpMethod = new List { "Get" }, - } - } + }, + }, }; this.Given(x => GivenThereIsAConfiguration(configuration)) diff --git a/test/Ocelot.ManualTest/Ocelot.ManualTest.csproj b/test/Ocelot.ManualTest/Ocelot.ManualTest.csproj index 478d425ff..ccfdce531 100644 --- a/test/Ocelot.ManualTest/Ocelot.ManualTest.csproj +++ b/test/Ocelot.ManualTest/Ocelot.ManualTest.csproj @@ -1,7 +1,7 @@  0.0.0-dev - netcoreapp2.2 + netcoreapp3.0 true Ocelot.ManualTest Exe @@ -28,16 +28,18 @@ - - - - - - - - - + + + + + + + + all + + + \ No newline at end of file diff --git a/test/Ocelot.ManualTest/Program.cs b/test/Ocelot.ManualTest/Program.cs index 659e250a8..7d3fc969d 100644 --- a/test/Ocelot.ManualTest/Program.cs +++ b/test/Ocelot.ManualTest/Program.cs @@ -32,12 +32,12 @@ public static void Main(string[] args) }) .ConfigureServices(s => { - s.AddAuthentication() - .AddJwtBearer("TestKey", x => - { - x.Authority = "test"; - x.Audience = "test"; - }); + s.AddAuthentication(); + //.AddJwtBearer("TestKey", x => + //{ + // x.Authority = "test"; + // x.Audience = "test"; + //}); s.AddSingleton((x, t) => new FakeHandler()); s.AddOcelot() diff --git a/test/Ocelot.UnitTests/Administration/OcelotAdministrationBuilderTests.cs b/test/Ocelot.UnitTests/Administration/OcelotAdministrationBuilderTests.cs index 1eea16190..e19025d1d 100644 --- a/test/Ocelot.UnitTests/Administration/OcelotAdministrationBuilderTests.cs +++ b/test/Ocelot.UnitTests/Administration/OcelotAdministrationBuilderTests.cs @@ -2,14 +2,15 @@ namespace Ocelot.UnitTests.Administration { using IdentityServer4.AccessTokenValidation; using Microsoft.AspNetCore.Hosting; - using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Moq; using Ocelot.Administration; using Ocelot.DependencyInjection; using Shouldly; using System; using System.Collections.Generic; + using System.Reflection; using TestStack.BDDfy; using Xunit; @@ -25,9 +26,19 @@ public OcelotAdministrationBuilderTests() { _configRoot = new ConfigurationRoot(new List()); _services = new ServiceCollection(); - _services.AddSingleton(); + _services.AddSingleton(GetHostingEnvironment()); _services.AddSingleton(_configRoot); } + + private IWebHostEnvironment GetHostingEnvironment() + { + var environment = new Mock(); + environment + .Setup(e => e.ApplicationName) + .Returns(typeof(OcelotAdministrationBuilderTests).GetTypeInfo().Assembly.GetName().Name); + + return environment.Object; + } //keep [Fact] diff --git a/test/Ocelot.UnitTests/CacheManager/OcelotBuilderExtensionsTests.cs b/test/Ocelot.UnitTests/CacheManager/OcelotBuilderExtensionsTests.cs index efa5631c9..b85ee1f48 100644 --- a/test/Ocelot.UnitTests/CacheManager/OcelotBuilderExtensionsTests.cs +++ b/test/Ocelot.UnitTests/CacheManager/OcelotBuilderExtensionsTests.cs @@ -2,9 +2,10 @@ { using global::CacheManager.Core; using Microsoft.AspNetCore.Hosting; - using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting.Internal; + using Moq; using Ocelot.Cache; using Ocelot.Cache.CacheManager; using Ocelot.Configuration; @@ -14,6 +15,7 @@ using System; using System.Collections.Generic; using System.Linq; + using System.Reflection; using TestStack.BDDfy; using Xunit; @@ -30,11 +32,21 @@ public OcelotBuilderExtensionsTests() { _configRoot = new ConfigurationRoot(new List()); _services = new ServiceCollection(); - _services.AddSingleton(); + _services.AddSingleton(GetHostingEnvironment()); _services.AddSingleton(_configRoot); _maxRetries = 100; } + private IWebHostEnvironment GetHostingEnvironment() + { + var environment = new Mock(); + environment + .Setup(e => e.ApplicationName) + .Returns(typeof(OcelotBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name); + + return environment.Object; + } + [Fact] public void should_set_up_cache_manager() { diff --git a/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs b/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs index d084c2d60..b2eb06b51 100644 --- a/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs +++ b/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs @@ -15,7 +15,7 @@ namespace Ocelot.UnitTests.Configuration public class DiskFileConfigurationRepositoryTests : IDisposable { - private readonly Mock _hostingEnvironment; + private readonly Mock _hostingEnvironment; private IFileConfigurationRepository _repo; private string _environmentSpecificPath; private string _ocelotJsonPath; @@ -33,7 +33,7 @@ public DiskFileConfigurationRepositoryTests() { _semaphore = new SemaphoreSlim(1, 1); _semaphore.Wait(); - _hostingEnvironment = new Mock(); + _hostingEnvironment = new Mock(); _hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName); _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object); } diff --git a/test/Ocelot.UnitTests/Consul/ConsulFileConfigurationRepositoryTests.cs b/test/Ocelot.UnitTests/Consul/ConsulFileConfigurationRepositoryTests.cs index 8a011026f..e655f1235 100644 --- a/test/Ocelot.UnitTests/Consul/ConsulFileConfigurationRepositoryTests.cs +++ b/test/Ocelot.UnitTests/Consul/ConsulFileConfigurationRepositoryTests.cs @@ -1,6 +1,7 @@ namespace Ocelot.UnitTests.Consul { using global::Consul; + using Microsoft.Extensions.Options; using Moq; using Newtonsoft.Json; using Ocelot.Cache; @@ -23,8 +24,8 @@ public class ConsulFileConfigurationRepositoryTests { private ConsulFileConfigurationRepository _repo; + private Mock> _options; private Mock> _cache; - private Mock _internalRepo; private Mock _factory; private Mock _loggerFactory; private Mock _client; @@ -36,9 +37,9 @@ public class ConsulFileConfigurationRepositoryTests public ConsulFileConfigurationRepositoryTests() { _cache = new Mock>(); - _internalRepo = new Mock(); _loggerFactory = new Mock(); + _options = new Mock>(); _factory = new Mock(); _client = new Mock(); _kvEndpoint = new Mock(); @@ -51,11 +52,9 @@ public ConsulFileConfigurationRepositoryTests() .Setup(x => x.Get(It.IsAny())) .Returns(_client.Object); - _internalRepo - .Setup(x => x.Get()) - .Returns(new OkResponse(new InternalConfiguration(new List(), "", new ServiceProviderConfigurationBuilder().Build(), "", It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))); - - _repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object); + _options + .SetupGet(x => x.Value) + .Returns(() => _fileConfiguration); } [Fact] @@ -85,7 +84,10 @@ public void should_get_config() [Fact] public void should_get_null_config() { - this.Given(_ => GivenFetchFromConsulReturnsNull()) + var config = FakeFileConfiguration(); + + this.Given(_ => GivenIHaveAConfiguration(config)) + .Given(_ => GivenFetchFromConsulReturnsNull()) .When(_ => WhenIGetTheConfiguration()) .Then(_ => ThenTheConfigurationIsNull()) .BDDfy(); @@ -136,14 +138,8 @@ private void ThenTheConfigKeyIs(string expected) private void GivenTheConfigKeyComesFromFileConfig(string key) { - _internalRepo - .Setup(x => x.Get()) - .Returns(new OkResponse(new InternalConfiguration(new List(), "", - new ServiceProviderConfigurationBuilder().WithConfigurationKey(key).Build(), "", - new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), - new HttpHandlerOptionsBuilder().Build()))); - - _repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object); + _fileConfiguration.GlobalConfiguration.ServiceDiscoveryProvider.ConfigurationKey = key; + _repo = new ConsulFileConfigurationRepository(_options.Object, _cache.Object, _factory.Object, _loggerFactory.Object); } private void ThenTheConfigurationIsNull() @@ -221,6 +217,8 @@ private async Task WhenISetTheConfiguration() private void GivenIHaveAConfiguration(FileConfiguration config) { _fileConfiguration = config; + + _repo = new ConsulFileConfigurationRepository(_options.Object, _cache.Object, _factory.Object, _loggerFactory.Object); } private FileConfiguration FakeFileConfiguration() diff --git a/test/Ocelot.UnitTests/Consul/OcelotBuilderExtensionsTests.cs b/test/Ocelot.UnitTests/Consul/OcelotBuilderExtensionsTests.cs index 58a4f8a96..cb5fc0b5d 100644 --- a/test/Ocelot.UnitTests/Consul/OcelotBuilderExtensionsTests.cs +++ b/test/Ocelot.UnitTests/Consul/OcelotBuilderExtensionsTests.cs @@ -1,14 +1,15 @@ namespace Ocelot.UnitTests.Consul { using Microsoft.AspNetCore.Hosting; - using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Moq; using Ocelot.DependencyInjection; using Provider.Consul; using Shouldly; using System; using System.Collections.Generic; + using System.Reflection; using TestStack.BDDfy; using Xunit; @@ -24,10 +25,21 @@ public OcelotBuilderExtensionsTests() { _configRoot = new ConfigurationRoot(new List()); _services = new ServiceCollection(); - _services.AddSingleton(); + _services.AddSingleton(GetHostingEnvironment()); _services.AddSingleton(_configRoot); } + + private IWebHostEnvironment GetHostingEnvironment() + { + var environment = new Mock(); + environment + .Setup(e => e.ApplicationName) + .Returns(typeof(OcelotBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name); + + return environment.Object; + } + [Fact] public void should_set_up_consul() { diff --git a/test/Ocelot.UnitTests/Consul/PollingConsulServiceDiscoveryProviderTests.cs b/test/Ocelot.UnitTests/Consul/PollingConsulServiceDiscoveryProviderTests.cs index ab77d7d01..cc38e29c3 100644 --- a/test/Ocelot.UnitTests/Consul/PollingConsulServiceDiscoveryProviderTests.cs +++ b/test/Ocelot.UnitTests/Consul/PollingConsulServiceDiscoveryProviderTests.cs @@ -15,7 +15,6 @@ public class PollingConsulServiceDiscoveryProviderTests { private readonly int _delay; - private PollConsul _provider; private readonly List _services; private readonly Mock _factory; private readonly Mock _logger; @@ -56,27 +55,28 @@ private void ThenTheCountIs(int count) private void WhenIGetTheServices(int expected) { - _provider = new PollConsul(_delay, _factory.Object, _consulServiceDiscoveryProvider.Object); - - var result = Wait.WaitFor(3000).Until(() => + using (var provider = new PollConsul(_delay, _factory.Object, _consulServiceDiscoveryProvider.Object)) { - try + var result = Wait.WaitFor(3000).Until(() => { - _result = _provider.Get().GetAwaiter().GetResult(); - if (_result.Count == expected) + try { - return true; - } + _result = provider.Get().GetAwaiter().GetResult(); + if (_result.Count == expected) + { + return true; + } - return false; - } - catch (Exception) - { - return false; - } - }); + return false; + } + catch (Exception) + { + return false; + } + }); - result.ShouldBeTrue(); + result.ShouldBeTrue(); + } } } } diff --git a/test/Ocelot.UnitTests/Consul/ProviderFactoryTests.cs b/test/Ocelot.UnitTests/Consul/ProviderFactoryTests.cs index 5d4939d22..c51e9cd7b 100644 --- a/test/Ocelot.UnitTests/Consul/ProviderFactoryTests.cs +++ b/test/Ocelot.UnitTests/Consul/ProviderFactoryTests.cs @@ -49,7 +49,9 @@ public void should_return_PollingConsulServiceDiscoveryProvider() .Build(); var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("pollconsul", "", 1, "", "", stopsPollerFromPolling), reRoute); - provider.ShouldBeOfType(); + var pollProvider = provider as PollConsul; + pollProvider.ShouldNotBeNull(); + pollProvider.Dispose(); } } } diff --git a/test/Ocelot.UnitTests/DependencyInjection/ConfigurationBuilderExtensionsTests.cs b/test/Ocelot.UnitTests/DependencyInjection/ConfigurationBuilderExtensionsTests.cs index efb8ff9a3..1d408ba41 100644 --- a/test/Ocelot.UnitTests/DependencyInjection/ConfigurationBuilderExtensionsTests.cs +++ b/test/Ocelot.UnitTests/DependencyInjection/ConfigurationBuilderExtensionsTests.cs @@ -22,11 +22,11 @@ public class ConfigurationBuilderExtensionsTests private FileConfiguration _reRouteB; private FileConfiguration _aggregate; private FileConfiguration _envSpecific; - private Mock _hostingEnvironment; + private Mock _hostingEnvironment; public ConfigurationBuilderExtensionsTests() { - _hostingEnvironment = new Mock(); + _hostingEnvironment = new Mock(); // Clean up config files before each test var subConfigFiles = new DirectoryInfo(".").GetFiles("ocelot.*.json"); diff --git a/test/Ocelot.UnitTests/DependencyInjection/OcelotBuilderTests.cs b/test/Ocelot.UnitTests/DependencyInjection/OcelotBuilderTests.cs index 3ec06a8bf..0f1ddb605 100644 --- a/test/Ocelot.UnitTests/DependencyInjection/OcelotBuilderTests.cs +++ b/test/Ocelot.UnitTests/DependencyInjection/OcelotBuilderTests.cs @@ -1,11 +1,12 @@ namespace Ocelot.UnitTests.DependencyInjection { using Microsoft.AspNetCore.Hosting; - using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Moq; using Ocelot.Configuration.Setter; using Ocelot.DependencyInjection; + using Ocelot.Infrastructure; using Ocelot.Middleware.Multiplexer; using Ocelot.Requester; using Ocelot.UnitTests.Requester; @@ -14,7 +15,7 @@ namespace Ocelot.UnitTests.DependencyInjection using System.Collections.Generic; using System.Linq; using System.Net.Http; - using Ocelot.Infrastructure; + using System.Reflection; using TestStack.BDDfy; using Xunit; using static Ocelot.UnitTests.Middleware.UserDefinedResponseAggregatorTests; @@ -32,11 +33,21 @@ public OcelotBuilderTests() { _configRoot = new ConfigurationRoot(new List()); _services = new ServiceCollection(); - _services.AddSingleton(); + _services.AddSingleton(GetHostingEnvironment()); _services.AddSingleton(_configRoot); _maxRetries = 100; } + private IWebHostEnvironment GetHostingEnvironment() + { + var environment = new Mock(); + environment + .Setup(e => e.ApplicationName) + .Returns(typeof(OcelotBuilderTests).GetTypeInfo().Assembly.GetName().Name); + + return environment.Object; + } + [Fact] public void should_add_specific_delegating_handlers_transient() { diff --git a/test/Ocelot.UnitTests/Eureka/EurekaMiddlewareConfigurationProviderTests.cs b/test/Ocelot.UnitTests/Eureka/EurekaMiddlewareConfigurationProviderTests.cs index 3f1a6da0f..fc7f3c824 100644 --- a/test/Ocelot.UnitTests/Eureka/EurekaMiddlewareConfigurationProviderTests.cs +++ b/test/Ocelot.UnitTests/Eureka/EurekaMiddlewareConfigurationProviderTests.cs @@ -1,6 +1,6 @@ namespace Ocelot.UnitTests.Eureka { - using Microsoft.AspNetCore.Builder.Internal; + using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Moq; using Ocelot.Configuration; diff --git a/test/Ocelot.UnitTests/Kubernetes/OcelotBuilderExtensionsTests.cs b/test/Ocelot.UnitTests/Kubernetes/OcelotBuilderExtensionsTests.cs index a2cb9e94d..f858c1beb 100644 --- a/test/Ocelot.UnitTests/Kubernetes/OcelotBuilderExtensionsTests.cs +++ b/test/Ocelot.UnitTests/Kubernetes/OcelotBuilderExtensionsTests.cs @@ -1,12 +1,13 @@ using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Moq; using Ocelot.DependencyInjection; using Ocelot.Provider.Kubernetes; using Shouldly; using System; using System.Collections.Generic; +using System.Reflection; using TestStack.BDDfy; using Xunit; @@ -24,10 +25,20 @@ public OcelotBuilderExtensionsTests() { _configRoot = new ConfigurationRoot(new List()); _services = new ServiceCollection(); - _services.AddSingleton(); + _services.AddSingleton(GetHostingEnvironment()); _services.AddSingleton(_configRoot); } + private IWebHostEnvironment GetHostingEnvironment() + { + var environment = new Mock(); + environment + .Setup(e => e.ApplicationName) + .Returns(typeof(OcelotBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name); + + return environment.Object; + } + [Fact] public void should_set_up_kubernetes() { diff --git a/test/Ocelot.UnitTests/Logging/AspDotNetLoggerTests.cs b/test/Ocelot.UnitTests/Logging/AspDotNetLoggerTests.cs index 13d9f874b..c4e2d8bf8 100644 --- a/test/Ocelot.UnitTests/Logging/AspDotNetLoggerTests.cs +++ b/test/Ocelot.UnitTests/Logging/AspDotNetLoggerTests.cs @@ -10,8 +10,8 @@ namespace Ocelot.UnitTests.Logging public class AspDotNetLoggerTests { private readonly Mock> _coreLogger; + private readonly Mock _repo; private readonly AspDotNetLogger _logger; - private Mock _repo; private readonly string _b; private readonly string _a; private readonly Exception _ex; @@ -55,7 +55,7 @@ public void should_log_error() { _logger.LogError($"a message from {_a} to {_b}", _ex); - ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura, exception: System.Exception: oh no", LogLevel.Error); + ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura", LogLevel.Error, _ex); } [Fact] @@ -63,18 +63,18 @@ public void should_log_critical() { _logger.LogCritical($"a message from {_a} to {_b}", _ex); - ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura, exception: System.Exception: oh no", LogLevel.Critical); + ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura", LogLevel.Critical, _ex); } - private void ThenLevelIsLogged(string expected, LogLevel expectedLogLevel) + private void ThenLevelIsLogged(string expected, LogLevel expectedLogLevel, Exception ex = null) { _coreLogger.Verify( x => x.Log( expectedLogLevel, - It.IsAny(), - It.Is(o => o.ToString() == expected), - It.IsAny(), - It.IsAny>()), Times.Once); + default(EventId), + expected, + ex, + It.IsAny>()), Times.Once); } } } diff --git a/test/Ocelot.UnitTests/Middleware/OcelotPiplineBuilderTests.cs b/test/Ocelot.UnitTests/Middleware/OcelotPiplineBuilderTests.cs index bafc35324..21e8dd63c 100644 --- a/test/Ocelot.UnitTests/Middleware/OcelotPiplineBuilderTests.cs +++ b/test/Ocelot.UnitTests/Middleware/OcelotPiplineBuilderTests.cs @@ -4,16 +4,17 @@ namespace Ocelot.UnitTests.Middleware { using Microsoft.AspNetCore.Hosting; - using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Moq; using Ocelot.DependencyInjection; using Ocelot.Logging; using Ocelot.Middleware; using Ocelot.Middleware.Pipeline; using Shouldly; using System.Collections.Generic; + using System.Reflection; using TestStack.BDDfy; using Xunit; @@ -28,11 +29,22 @@ public OcelotPiplineBuilderTests() { _configRoot = new ConfigurationRoot(new List()); _services = new ServiceCollection(); - _services.AddSingleton(); + _services.AddSingleton(GetHostingEnvironment()); _services.AddSingleton(_configRoot); _services.AddOcelot(); } + + private IWebHostEnvironment GetHostingEnvironment() + { + var environment = new Mock(); + environment + .Setup(e => e.ApplicationName) + .Returns(typeof(OcelotPiplineBuilderTests).GetTypeInfo().Assembly.GetName().Name); + + return environment.Object; + } + [Fact] public void should_build_generic() { diff --git a/test/Ocelot.UnitTests/Ocelot.UnitTests.csproj b/test/Ocelot.UnitTests/Ocelot.UnitTests.csproj index 0809d1206..d067d869f 100644 --- a/test/Ocelot.UnitTests/Ocelot.UnitTests.csproj +++ b/test/Ocelot.UnitTests/Ocelot.UnitTests.csproj @@ -2,7 +2,7 @@ 0.0.0-dev - netcoreapp2.2 + netcoreapp3.0 Ocelot.UnitTests Ocelot.UnitTests Exe @@ -46,13 +46,13 @@ PreserveNewest - + - - - - + + + + all @@ -60,30 +60,38 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - + + + + + + + + + - - + + - - - - + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + \ No newline at end of file diff --git a/test/Ocelot.UnitTests/Rafty/OcelotAdministrationBuilderExtensionsTests.cs b/test/Ocelot.UnitTests/Rafty/OcelotAdministrationBuilderExtensionsTests.cs index feb8603c4..212d92931 100644 --- a/test/Ocelot.UnitTests/Rafty/OcelotAdministrationBuilderExtensionsTests.cs +++ b/test/Ocelot.UnitTests/Rafty/OcelotAdministrationBuilderExtensionsTests.cs @@ -1,15 +1,16 @@ namespace Ocelot.UnitTests.Rafty { using Microsoft.AspNetCore.Hosting; - using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Moq; using Ocelot.Administration; using Ocelot.DependencyInjection; using Provider.Rafty; using Shouldly; using System; using System.Collections.Generic; + using System.Reflection; using TestStack.BDDfy; using Xunit; @@ -25,10 +26,20 @@ public OcelotAdministrationBuilderExtensionsTests() { _configRoot = new ConfigurationRoot(new List()); _services = new ServiceCollection(); - _services.AddSingleton(); + _services.AddSingleton(GetHostingEnvironment()); _services.AddSingleton(_configRoot); } + private IWebHostEnvironment GetHostingEnvironment() + { + var environment = new Mock(); + environment + .Setup(e => e.ApplicationName) + .Returns(typeof(OcelotAdministrationBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name); + + return environment.Object; + } + [Fact] public void should_set_up_rafty() { diff --git a/test/Ocelot.UnitTests/RateLimit/ClientRateLimitMiddlewareTests.cs b/test/Ocelot.UnitTests/RateLimit/ClientRateLimitMiddlewareTests.cs index 1f928ff5a..2b54bbfab 100644 --- a/test/Ocelot.UnitTests/RateLimit/ClientRateLimitMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/RateLimit/ClientRateLimitMiddlewareTests.cs @@ -69,7 +69,7 @@ public void should_call_middleware_and_ratelimiting() this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute)) .When(x => x.WhenICallTheMiddlewareMultipleTime(2)) .Then(x => x.ThenresponseStatusCodeIs200()) - .When(x => x.WhenICallTheMiddlewareMultipleTime(2)) + .When(x => x.WhenICallTheMiddlewareMultipleTime(3)) .Then(x => x.ThenresponseStatusCodeIs429()) .BDDfy(); } @@ -145,8 +145,9 @@ private void ThenresponseStatusCodeIs200() internal class FakeStream : Stream { public override void Flush() - { - throw new System.NotImplementedException(); + { + //do nothing + //throw new System.NotImplementedException(); } public override int Read(byte[] buffer, int offset, int count) diff --git a/test/Ocelot.UnitTests/Request/Mapper/RequestMapperTests.cs b/test/Ocelot.UnitTests/Request/Mapper/RequestMapperTests.cs index 1727d5037..ac81a4d47 100644 --- a/test/Ocelot.UnitTests/Request/Mapper/RequestMapperTests.cs +++ b/test/Ocelot.UnitTests/Request/Mapper/RequestMapperTests.cs @@ -1,7 +1,6 @@ namespace Ocelot.UnitTests.Request.Mapper { using Microsoft.AspNetCore.Http; - using Microsoft.AspNetCore.Http.Internal; using Microsoft.Extensions.Primitives; using Ocelot.Request.Mapper; using Ocelot.Responses; @@ -19,6 +18,7 @@ public class RequestMapperTests { + private readonly HttpContext _httpContext; private readonly HttpRequest _inputRequest; private readonly RequestMapper _requestMapper; @@ -29,8 +29,8 @@ public class RequestMapperTests public RequestMapperTests() { - _inputRequest = new DefaultHttpRequest(new DefaultHttpContext()); - + _httpContext = new DefaultHttpContext(); + _inputRequest = _httpContext.Request; _requestMapper = new RequestMapper(); } diff --git a/test/Ocelot.UnitTests/UnitTests.runsettings b/test/Ocelot.UnitTests/UnitTests.runsettings new file mode 100644 index 000000000..1cba21cc9 --- /dev/null +++ b/test/Ocelot.UnitTests/UnitTests.runsettings @@ -0,0 +1,23 @@ + + + + + + + opencover + false + true + + + + + + + + + + + \ No newline at end of file diff --git a/tools/packages.config b/tools/packages.config index 1d2d15349..238f21ca0 100644 --- a/tools/packages.config +++ b/tools/packages.config @@ -1,4 +1,4 @@ - +