mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-20 08:02:50 +08:00
Merge branch 'release/13.8.0'
This commit is contained in:
commit
fbd9c01a42
@ -8,12 +8,12 @@ sudo: required
|
|||||||
dist: bionic
|
dist: bionic
|
||||||
|
|
||||||
# OS X 10.12
|
# OS X 10.12
|
||||||
osx_image: xcode9.2
|
osx_image: xcode9.4
|
||||||
|
|
||||||
mono:
|
mono:
|
||||||
- 5.10.0
|
- 6.0.0
|
||||||
|
|
||||||
dotnet: 2.2.105
|
dotnet: 3.0.100
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- git fetch --unshallow # Travis always does a shallow clone, but GitVersion needs the full history including branches and tags
|
- git fetch --unshallow # Travis always does a shallow clone, but GitVersion needs the full history including branches and tags
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#This is the base image used for any ran images
|
#This is the base image used for any ran images
|
||||||
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ EXPOSE 80
|
|||||||
#It can also be used to run other CLI commands on the project, such as packing/deploying nuget packages. Some examples:
|
#It can also be used to run other CLI commands on the project, such as packing/deploying nuget packages. Some examples:
|
||||||
#Run tests: docker build --target builder -t ocelot-build . && docker run ocelot-build test --logger:trx;LogFileName=results.trx
|
#Run tests: docker build --target builder -t ocelot-build . && docker run ocelot-build test --logger:trx;LogFileName=results.trx
|
||||||
#Run benchmarks: docker build --target builder --build-arg build_configuration=Release -t ocelot-build . && docker run ocelot-build run -c Release --project test/Ocelot.Benchmarks/Ocelot.Benchmarks.csproj
|
#Run benchmarks: docker build --target builder --build-arg build_configuration=Release -t ocelot-build . && docker run ocelot-build run -c Release --project test/Ocelot.Benchmarks/Ocelot.Benchmarks.csproj
|
||||||
FROM microsoft/dotnet:2.1.502-sdk AS builder
|
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS builder
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
#First we add only the project files so that we can cache nuget packages with dotnet restore
|
#First we add only the project files so that we can cache nuget packages with dotnet restore
|
||||||
COPY Ocelot.sln Ocelot.sln
|
COPY Ocelot.sln Ocelot.sln
|
||||||
|
1
appveyor.yml
Normal file
1
appveyor.yml
Normal file
@ -0,0 +1 @@
|
|||||||
|
image: Visual Studio 2019
|
52
build.cake
52
build.cake
@ -1,11 +1,10 @@
|
|||||||
#tool "nuget:?package=GitVersion.CommandLine"
|
#tool "nuget:?package=GitVersion.CommandLine"
|
||||||
#tool "nuget:?package=GitReleaseNotes"
|
#tool "nuget:?package=GitReleaseNotes"
|
||||||
#addin nuget:?package=Cake.Json
|
#addin nuget:?package=Cake.Json
|
||||||
#addin nuget:?package=Newtonsoft.Json&version=9.0.1
|
#addin nuget:?package=Newtonsoft.Json
|
||||||
#tool "nuget:?package=OpenCover"
|
|
||||||
#tool "nuget:?package=ReportGenerator"
|
#tool "nuget:?package=ReportGenerator"
|
||||||
#tool "nuget:?package=coveralls.net&version=0.7.0"
|
#tool "nuget:?package=coveralls.net&version=0.7.0"
|
||||||
#addin Cake.Coveralls&version=0.7.0
|
#addin Cake.Coveralls&version=0.10.1
|
||||||
|
|
||||||
// compile
|
// compile
|
||||||
var compileConfig = Argument("configuration", "Release");
|
var compileConfig = Argument("configuration", "Release");
|
||||||
@ -119,27 +118,20 @@ Task("RunUnitTests")
|
|||||||
.IsDependentOn("Compile")
|
.IsDependentOn("Compile")
|
||||||
.Does(() =>
|
.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())
|
if (IsRunningOnWindows())
|
||||||
{
|
{
|
||||||
var coverageSummaryFile = artifactsForUnitTestsDir + File("coverage.xml");
|
var coverageSummaryFile = GetSubDirectories(artifactsForUnitTestsDir).First().CombineWithFilePath(File("coverage.opencover.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]*")
|
|
||||||
);
|
|
||||||
|
|
||||||
ReportGenerator(coverageSummaryFile, artifactsForUnitTestsDir);
|
ReportGenerator(coverageSummaryFile, artifactsForUnitTestsDir);
|
||||||
|
|
||||||
if (AppVeyor.IsRunningOnAppVeyor)
|
if (AppVeyor.IsRunningOnAppVeyor)
|
||||||
@ -171,17 +163,6 @@ Task("RunUnitTests")
|
|||||||
var whereToCheck = !AppVeyor.IsRunningOnAppVeyor ? coverallsRepo : artifactsForUnitTestsDir;
|
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));
|
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);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -363,8 +344,7 @@ Task("DownloadGitHubReleaseArtifacts")
|
|||||||
Information("Release url " + releaseUrl);
|
Information("Release url " + releaseUrl);
|
||||||
|
|
||||||
var assets_url = Newtonsoft.Json.Linq.JObject.Parse(GetResource(releaseUrl))
|
var assets_url = Newtonsoft.Json.Linq.JObject.Parse(GetResource(releaseUrl))
|
||||||
.GetValue("assets_url")
|
.Value<string>("assets_url");
|
||||||
.Value<string>();
|
|
||||||
|
|
||||||
Information("Assets url " + assets_url);
|
Information("Assets url " + assets_url);
|
||||||
|
|
||||||
@ -372,7 +352,7 @@ Task("DownloadGitHubReleaseArtifacts")
|
|||||||
|
|
||||||
Information("Assets " + assets_url);
|
Information("Assets " + assets_url);
|
||||||
|
|
||||||
foreach(var asset in Newtonsoft.Json.JsonConvert.DeserializeObject<JArray>(assets))
|
foreach(var asset in Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JArray>(assets))
|
||||||
{
|
{
|
||||||
Information("In the loop..");
|
Information("In the loop..");
|
||||||
|
|
||||||
|
@ -2,22 +2,25 @@ Claims Transformation
|
|||||||
=====================
|
=====================
|
||||||
|
|
||||||
Ocelot allows the user to access claims and transform them into headers, query string
|
Ocelot allows the user to access claims and transform them into headers, query string
|
||||||
parameters and other claims. This is only available once a user has been authenticated.
|
parameters, other claims and change downstream paths. This is only available once a user
|
||||||
|
has been authenticated.
|
||||||
|
|
||||||
After the user is authenticated we run the claims to claims transformation middleware.
|
After the user is authenticated we run the claims to claims transformation middleware.
|
||||||
This allows the user to transform claims before the authorisation middleware is called.
|
This allows the user to transform claims before the authorisation middleware is called.
|
||||||
After the user is authorised first we call the claims to headers middleware and Finally
|
After the user is authorised first we call the claims to headers middleware, then
|
||||||
the claims to query string parameters middleware.
|
the claims to query string parameters middleware, and Finally the claims to downstream path
|
||||||
|
middleware.
|
||||||
|
|
||||||
The syntax for performing the transforms is the same for each process. In the ReRoute
|
The syntax for performing the transforms is the same for each process. In the ReRoute
|
||||||
configuration a json dictionary is added with a specific name either AddClaimsToRequest,
|
configuration a json dictionary is added with a specific name either AddClaimsToRequest,
|
||||||
AddHeadersToRequest, AddQueriesToRequest.
|
AddHeadersToRequest, AddQueriesToRequest, or ChangeDownstreamPathTemplate.
|
||||||
|
|
||||||
Note: I'm not a hotshot programmer so have no idea if this syntax is good...
|
Note: I'm not a hotshot programmer so have no idea if this syntax is good...
|
||||||
|
|
||||||
Within this dictionary the entries specify how Ocelot should transform things!
|
Within this dictionary the entries specify how Ocelot should transform things!
|
||||||
The key to the dictionary is going to become the key of either a claim, header
|
The key to the dictionary is going to become the key of either a claim, header
|
||||||
or query parameter.
|
or query parameter. In the case of ChangeDownstreamPathTemplate, the key must be
|
||||||
|
also specified in the DownstreamPathTemplate, in order to do the transformation.
|
||||||
|
|
||||||
The value of the entry is parsed to logic that will perform the transform. First of
|
The value of the entry is parsed to logic that will perform the transform. First of
|
||||||
all a dictionary accessor is specified e.g. Claims[CustomerId]. This means we want
|
all a dictionary accessor is specified e.g. Claims[CustomerId]. This means we want
|
||||||
@ -69,4 +72,25 @@ Below is an example configuration that will transforms claims to query string pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
This shows a transform where Ocelot looks at the users LocationId claim and add it as
|
This shows a transform where Ocelot looks at the users LocationId claim and add it as
|
||||||
a query string parameter to be forwarded onto the downstream service.
|
a query string parameter to be forwarded onto the downstream service.
|
||||||
|
|
||||||
|
Claims to Downstream Path Transformation
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Below is an example configuration that will transform claims to downstream path custom placeholders
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
"UpstreamPathTemplate": "/api/users/me/{everything}",
|
||||||
|
"DownstreamPathTemplate": "/api/users/{userId}/{everything}",
|
||||||
|
"ChangeDownstreamPathTemplate": {
|
||||||
|
"userId": "Claims[sub] > value[1] > |",
|
||||||
|
}
|
||||||
|
|
||||||
|
This shows a transform where Ocelot looks at the users userId claim and substitutes the value
|
||||||
|
to the "{userId}" placeholder specified in the DownstreamPathTemplate. Take into account that the
|
||||||
|
key specified in the ChangeDownstreamPathTemplate must be the same than the placeholder specified in
|
||||||
|
the DownstreamPathTemplate.
|
||||||
|
|
||||||
|
Note: if a key specified in the ChangeDownstreamPathTemplate does not exist as a placeholder in DownstreamPathTemplate
|
||||||
|
it will fail at runtime returning an error in the response.
|
@ -25,7 +25,7 @@ If you have services deployed in kubernetes you will normally use the naming ser
|
|||||||
You can replicate a Permissive. Using RBAC role bindings.
|
You can replicate a Permissive. Using RBAC role bindings.
|
||||||
`Permissive RBAC Permissions <https://kubernetes.io/docs/reference/access-authn-authz/rbac/#permissive-rbac-permissions>`_, k8s api server and token will read from pod .
|
`Permissive RBAC Permissions <https://kubernetes.io/docs/reference/access-authn-authz/rbac/#permissive-rbac-permissions>`_, k8s api server and token will read from pod .
|
||||||
|
|
||||||
.. code-block::json
|
.. code-block::bash
|
||||||
kubectl create clusterrolebinding permissive-binding --clusterrole=cluster-admin --user=admin --user=kubelet --group=system:serviceaccounts
|
kubectl create clusterrolebinding permissive-binding --clusterrole=cluster-admin --user=admin --user=kubelet --group=system:serviceaccounts
|
||||||
|
|
||||||
The following example shows how to set up a ReRoute that will work in kubernetes. The most important thing is the ServiceName which is made up of the
|
The following example shows how to set up a ReRoute that will work in kubernetes. The most important thing is the ServiceName which is made up of the
|
||||||
@ -54,6 +54,7 @@ kubernetes service name. We also need to set up the ServiceDiscoveryProvider in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Service deployment in Namespace Dev , ServiceDiscoveryProvider type is kube, you also can set pollkube ServiceDiscoveryProvider type.
|
Service deployment in Namespace Dev , ServiceDiscoveryProvider type is kube, you also can set pollkube ServiceDiscoveryProvider type.
|
||||||
Note: Host、 Port and Token are no longer in use。
|
Note: Host、 Port and Token are no longer in use。
|
||||||
|
|
||||||
@ -74,3 +75,21 @@ The polling interval is in milliseconds and tells Ocelot how often to call kuber
|
|||||||
|
|
||||||
Please note there are tradeoffs here. If you poll kubernetes it is possible Ocelot will not know if a service is down depending on your polling interval and you might get more errors than if you get the latest services per request. This really depends on how volatile your services are. I doubt it will matter for most people and polling may give a tiny performance improvement over calling kubernetes per request.
|
Please note there are tradeoffs here. If you poll kubernetes it is possible Ocelot will not know if a service is down depending on your polling interval and you might get more errors than if you get the latest services per request. This really depends on how volatile your services are. I doubt it will matter for most people and polling may give a tiny performance improvement over calling kubernetes per request.
|
||||||
There is no way for Ocelot to work these out for you.
|
There is no way for Ocelot to work these out for you.
|
||||||
|
|
||||||
|
If your downstream service resides in a different namespace you can override the global setting at the ReRoute level by specifying a ServiceNamespace
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"ReRoutes": [
|
||||||
|
{
|
||||||
|
"DownstreamPathTemplate": "/api/values",
|
||||||
|
"DownstreamScheme": "http",
|
||||||
|
"UpstreamPathTemplate": "/values",
|
||||||
|
"ServiceName": "downstreamservice",
|
||||||
|
"ServiceNamespace": "downstream-namespace",
|
||||||
|
"UpstreamHttpMethod": [ "Get" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
@ -46,7 +46,7 @@ The following shows how to set up multiple downstream services for a ReRoute usi
|
|||||||
Service Discovery
|
Service Discovery
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
The following shows how to set up a ReRoute using service discovery then select the LeadConnection load balancer.
|
The following shows how to set up a ReRoute using service discovery then select the LeastConnection load balancer.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ In your ocelot.json set the following in the GlobalConfiguration section. This w
|
|||||||
"RequestIdKey": "OcRequestId"
|
"RequestIdKey": "OcRequestId"
|
||||||
}
|
}
|
||||||
|
|
||||||
I reccomend using the GlobalConfiguration unless you really need it to be ReRoute specific.
|
I recommend using the GlobalConfiguration unless you really need it to be ReRoute specific.
|
||||||
|
|
||||||
*ReRoute*
|
*ReRoute*
|
||||||
|
|
||||||
|
@ -15,11 +15,11 @@ it reaches a request builder middleware where it creates a HttpRequestMessage ob
|
|||||||
used to make a request to a downstream service. The middleware that makes the request 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 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
|
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
|
and retrieved 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 maps the HttpResponseMessage onto the HttpResponse object and that is returned to the client.
|
||||||
That is basically it with a bunch of other features.
|
That is basically it with a bunch of other features.
|
||||||
|
|
||||||
The following are configuration that you use when deploying Ocelot.
|
The following are configurations that you use when deploying Ocelot.
|
||||||
|
|
||||||
Basic Implementation
|
Basic Implementation
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -42,6 +42,9 @@ AddOcelot() (adds ocelot services), UseOcelot().Wait() (sets up all the Ocelot m
|
|||||||
|
|
||||||
.. code-block:: csharp
|
.. code-block:: csharp
|
||||||
|
|
||||||
|
using Ocelot.DependencyInjection;
|
||||||
|
using Ocelot.Middleware;
|
||||||
|
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
|
||||||
<NETStandardImplicitPackageVersion>2.0.0</NETStandardImplicitPackageVersion>
|
|
||||||
<NoPackageAnalysis>true</NoPackageAnalysis>
|
<NoPackageAnalysis>true</NoPackageAnalysis>
|
||||||
<Description>Provides Ocelot extensions to use the administration API and IdentityService dependencies that come with it</Description>
|
<Description>Provides Ocelot extensions to use the administration API and IdentityService dependencies that come with it</Description>
|
||||||
<AssemblyTitle>Ocelot.Administration</AssemblyTitle>
|
<AssemblyTitle>Ocelot.Administration</AssemblyTitle>
|
||||||
@ -29,10 +27,13 @@
|
|||||||
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
|
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
|
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
|
||||||
<PackageReference Include="IdentityServer4" Version="2.4.0" />
|
<PackageReference Include="IdentityServer4" Version="3.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
namespace Ocelot.Administration
|
using Ocelot.DependencyInjection;
|
||||||
{
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using DependencyInjection;
|
using IdentityServer4.Models;
|
||||||
using IdentityServer4.AccessTokenValidation;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using IdentityServer4.Models;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Ocelot.Middleware;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using System;
|
||||||
using Ocelot.Middleware;
|
using System.Collections.Generic;
|
||||||
using System;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using System.Collections.Generic;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
|
||||||
using System.Security.Cryptography.X509Certificates;
|
|
||||||
|
|
||||||
|
namespace Ocelot.Administration
|
||||||
|
{
|
||||||
public static class OcelotBuilderExtensions
|
public static class OcelotBuilderExtensions
|
||||||
{
|
{
|
||||||
public static IOcelotAdministrationBuilder AddAdministration(this IOcelotBuilder builder, string path, string secret)
|
public static IOcelotAdministrationBuilder AddAdministration(this IOcelotBuilder builder, string path, string secret)
|
||||||
@ -86,7 +86,7 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
//todo - refactor so calls method?
|
//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);
|
identityServerBuilder.AddSigningCredential(cert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
|
||||||
<NETStandardImplicitPackageVersion>2.0.0</NETStandardImplicitPackageVersion>
|
|
||||||
<NoPackageAnalysis>true</NoPackageAnalysis>
|
<NoPackageAnalysis>true</NoPackageAnalysis>
|
||||||
<Description>Provides Ocelot extensions to use CacheManager.Net</Description>
|
<Description>Provides Ocelot extensions to use CacheManager.Net</Description>
|
||||||
<AssemblyTitle>Ocelot.Cache.CacheManager</AssemblyTitle>
|
<AssemblyTitle>Ocelot.Cache.CacheManager</AssemblyTitle>
|
||||||
@ -28,11 +26,14 @@
|
|||||||
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
|
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="CacheManager.Core" Version="1.2.0" />
|
<PackageReference Include="CacheManager.Core" Version="2.0.0-beta-1629" />
|
||||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="1.2.0" />
|
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="2.0.0-beta-1629" />
|
||||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.2.0" />
|
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="2.0.0-beta-1629" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
public async Task<List<Service>> Get()
|
public async Task<List<Service>> Get()
|
||||||
{
|
{
|
||||||
var queryResult = await _consul.Health.Service(_config.KeyOfServiceInConsul, string.Empty, false);
|
var queryResult = await _consul.Health.Service(_config.KeyOfServiceInConsul, string.Empty, true);
|
||||||
|
|
||||||
var services = new List<Service>();
|
var services = new List<Service>();
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using Configuration.Repository;
|
using Configuration.Repository;
|
||||||
using global::Consul;
|
using global::Consul;
|
||||||
using Logging;
|
using Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Responses;
|
using Responses;
|
||||||
using System;
|
using System;
|
||||||
@ -18,29 +19,20 @@
|
|||||||
private readonly IOcelotLogger _logger;
|
private readonly IOcelotLogger _logger;
|
||||||
|
|
||||||
public ConsulFileConfigurationRepository(
|
public ConsulFileConfigurationRepository(
|
||||||
|
IOptions<FileConfiguration> fileConfiguration,
|
||||||
Cache.IOcelotCache<FileConfiguration> cache,
|
Cache.IOcelotCache<FileConfiguration> cache,
|
||||||
IInternalConfigurationRepository repo,
|
|
||||||
IConsulClientFactory factory,
|
IConsulClientFactory factory,
|
||||||
IOcelotLoggerFactory loggerFactory)
|
IOcelotLoggerFactory loggerFactory)
|
||||||
{
|
{
|
||||||
_logger = loggerFactory.CreateLogger<ConsulFileConfigurationRepository>();
|
_logger = loggerFactory.CreateLogger<ConsulFileConfigurationRepository>();
|
||||||
_cache = cache;
|
_cache = cache;
|
||||||
|
|
||||||
var internalConfig = repo.Get();
|
var serviceDiscoveryProvider = fileConfiguration.Value.GlobalConfiguration.ServiceDiscoveryProvider;
|
||||||
|
_configurationKey = string.IsNullOrWhiteSpace(serviceDiscoveryProvider.ConfigurationKey) ? "InternalConfiguration" :
|
||||||
|
serviceDiscoveryProvider.ConfigurationKey;
|
||||||
|
|
||||||
_configurationKey = "InternalConfiguration";
|
var config = new ConsulRegistryConfiguration(serviceDiscoveryProvider.Host,
|
||||||
|
serviceDiscoveryProvider.Port, _configurationKey, serviceDiscoveryProvider.Token);
|
||||||
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);
|
|
||||||
|
|
||||||
_consul = factory.Get(config);
|
_consul = factory.Get(config);
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,13 @@
|
|||||||
|
|
||||||
public static class ConsulProviderFactory
|
public static class ConsulProviderFactory
|
||||||
{
|
{
|
||||||
public static ServiceDiscoveryFinderDelegate Get = (provider, config, name) =>
|
public static ServiceDiscoveryFinderDelegate Get = (provider, config, reRoute) =>
|
||||||
{
|
{
|
||||||
var factory = provider.GetService<IOcelotLoggerFactory>();
|
var factory = provider.GetService<IOcelotLoggerFactory>();
|
||||||
|
|
||||||
var consulFactory = provider.GetService<IConsulClientFactory>();
|
var consulFactory = provider.GetService<IConsulClientFactory>();
|
||||||
|
|
||||||
var consulRegistryConfiguration = new ConsulRegistryConfiguration(config.Host, config.Port, name, config.Token);
|
var consulRegistryConfiguration = new ConsulRegistryConfiguration(config.Host, config.Port, reRoute.ServiceName, config.Token);
|
||||||
|
|
||||||
var consulServiceDiscoveryProvider = new Consul(consulRegistryConfiguration, factory, consulFactory);
|
var consulServiceDiscoveryProvider = new Consul(consulRegistryConfiguration, factory, consulFactory);
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
|
||||||
<NETStandardImplicitPackageVersion>2.0.0</NETStandardImplicitPackageVersion>
|
|
||||||
<NoPackageAnalysis>true</NoPackageAnalysis>
|
<NoPackageAnalysis>true</NoPackageAnalysis>
|
||||||
<Description>Provides Ocelot extensions to use Consul</Description>
|
<Description>Provides Ocelot extensions to use Consul</Description>
|
||||||
<AssemblyTitle>Ocelot.Provider.Consul</AssemblyTitle>
|
<AssemblyTitle>Ocelot.Provider.Consul</AssemblyTitle>
|
||||||
@ -30,8 +28,11 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Consul" Version="0.7.2.6" />
|
<PackageReference Include="Consul" Version="0.7.2.6" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -2,16 +2,17 @@
|
|||||||
{
|
{
|
||||||
using Logging;
|
using Logging;
|
||||||
using ServiceDiscovery.Providers;
|
using ServiceDiscovery.Providers;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Values;
|
using Values;
|
||||||
|
|
||||||
public class PollConsul : IServiceDiscoveryProvider
|
public sealed class PollConsul : IServiceDiscoveryProvider, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IOcelotLogger _logger;
|
private readonly IOcelotLogger _logger;
|
||||||
private readonly IServiceDiscoveryProvider _consulServiceDiscoveryProvider;
|
private readonly IServiceDiscoveryProvider _consulServiceDiscoveryProvider;
|
||||||
private readonly Timer _timer;
|
private Timer _timer;
|
||||||
private bool _polling;
|
private bool _polling;
|
||||||
private List<Service> _services;
|
private List<Service> _services;
|
||||||
|
|
||||||
@ -34,6 +35,12 @@
|
|||||||
}, null, pollingInterval, pollingInterval);
|
}, null, pollingInterval, pollingInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_timer?.Dispose();
|
||||||
|
_timer = null;
|
||||||
|
}
|
||||||
|
|
||||||
public Task<List<Service>> Get()
|
public Task<List<Service>> Get()
|
||||||
{
|
{
|
||||||
return Task.FromResult(_services);
|
return Task.FromResult(_services);
|
||||||
|
@ -6,13 +6,13 @@
|
|||||||
|
|
||||||
public static class EurekaProviderFactory
|
public static class EurekaProviderFactory
|
||||||
{
|
{
|
||||||
public static ServiceDiscoveryFinderDelegate Get = (provider, config, name) =>
|
public static ServiceDiscoveryFinderDelegate Get = (provider, config, reRoute) =>
|
||||||
{
|
{
|
||||||
var client = provider.GetService<IDiscoveryClient>();
|
var client = provider.GetService<IDiscoveryClient>();
|
||||||
|
|
||||||
if (config.Type?.ToLower() == "eureka" && client != null)
|
if (config.Type?.ToLower() == "eureka" && client != null)
|
||||||
{
|
{
|
||||||
return new Eureka(name, client);
|
return new Eureka(reRoute.ServiceName, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
|
||||||
<NETStandardImplicitPackageVersion>2.0.0</NETStandardImplicitPackageVersion>
|
|
||||||
<NoPackageAnalysis>true</NoPackageAnalysis>
|
<NoPackageAnalysis>true</NoPackageAnalysis>
|
||||||
<Description>Provides Ocelot extensions to use Eureka</Description>
|
<Description>Provides Ocelot extensions to use Eureka</Description>
|
||||||
<AssemblyTitle>Ocelot.Provider.Eureka</AssemblyTitle>
|
<AssemblyTitle>Ocelot.Provider.Eureka</AssemblyTitle>
|
||||||
@ -29,9 +27,12 @@
|
|||||||
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
|
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Steeltoe.Discovery.ClientCore" Version="2.2.0" />
|
<PackageReference Include="Steeltoe.Discovery.ClientCore" Version="2.3.0" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -12,9 +12,7 @@
|
|||||||
{
|
{
|
||||||
public static IOcelotBuilder AddEureka(this IOcelotBuilder builder)
|
public static IOcelotBuilder AddEureka(this IOcelotBuilder builder)
|
||||||
{
|
{
|
||||||
var service = builder.Services.First(x => x.ServiceType == typeof(IConfiguration));
|
builder.Services.AddDiscoveryClient(builder.Configuration);
|
||||||
var configuration = (IConfiguration)service.ImplementationInstance;
|
|
||||||
builder.Services.AddDiscoveryClient(configuration);
|
|
||||||
builder.Services.AddSingleton<ServiceDiscoveryFinderDelegate>(EurekaProviderFactory.Get);
|
builder.Services.AddSingleton<ServiceDiscoveryFinderDelegate>(EurekaProviderFactory.Get);
|
||||||
builder.Services.AddSingleton<OcelotMiddlewareConfigurationDelegate>(EurekaMiddlewareConfigurationProvider.Get);
|
builder.Services.AddSingleton<OcelotMiddlewareConfigurationDelegate>(EurekaMiddlewareConfigurationProvider.Get);
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -25,8 +25,7 @@ namespace Ocelot.Provider.Kubernetes
|
|||||||
|
|
||||||
public async Task<List<Service>> Get()
|
public async Task<List<Service>> Get()
|
||||||
{
|
{
|
||||||
var service = await kubeApi.ServicesV1()
|
var service = await kubeApi.ServicesV1().Get(kubeRegistryConfiguration.KeyOfServiceInK8s, kubeRegistryConfiguration.KubeNamespace);
|
||||||
.Get(kubeRegistryConfiguration.KeyOfServiceInK8s, kubeRegistryConfiguration.KubeNamespace);
|
|
||||||
var services = new List<Service>();
|
var services = new List<Service>();
|
||||||
if (IsValid(service))
|
if (IsValid(service))
|
||||||
{
|
{
|
||||||
|
@ -3,24 +3,25 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using Ocelot.Logging;
|
using Ocelot.Logging;
|
||||||
using Ocelot.ServiceDiscovery;
|
using Ocelot.ServiceDiscovery;
|
||||||
using System;
|
using System;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
|
||||||
namespace Ocelot.Provider.Kubernetes
|
namespace Ocelot.Provider.Kubernetes
|
||||||
{
|
{
|
||||||
public static class KubernetesProviderFactory
|
public static class KubernetesProviderFactory
|
||||||
{
|
{
|
||||||
public static ServiceDiscoveryFinderDelegate Get = (provider, config, name) =>
|
public static ServiceDiscoveryFinderDelegate Get = (provider, config, reRoute) =>
|
||||||
{
|
{
|
||||||
var factory = provider.GetService<IOcelotLoggerFactory>();
|
var factory = provider.GetService<IOcelotLoggerFactory>();
|
||||||
return GetkubeProvider(provider, config, name, factory);
|
return GetkubeProvider(provider, config, reRoute, factory);
|
||||||
};
|
};
|
||||||
|
|
||||||
private static ServiceDiscovery.Providers.IServiceDiscoveryProvider GetkubeProvider(IServiceProvider provider, Configuration.ServiceProviderConfiguration config, string name, IOcelotLoggerFactory factory)
|
private static ServiceDiscovery.Providers.IServiceDiscoveryProvider GetkubeProvider(IServiceProvider provider, Configuration.ServiceProviderConfiguration config, DownstreamReRoute reRoute, IOcelotLoggerFactory factory)
|
||||||
{
|
{
|
||||||
var kubeClient = provider.GetService<IKubeApiClient>();
|
var kubeClient = provider.GetService<IKubeApiClient>();
|
||||||
var k8sRegistryConfiguration = new KubeRegistryConfiguration()
|
var k8sRegistryConfiguration = new KubeRegistryConfiguration()
|
||||||
{
|
{
|
||||||
KeyOfServiceInK8s = name,
|
KeyOfServiceInK8s = reRoute.ServiceName,
|
||||||
KubeNamespace = config.Namespace,
|
KubeNamespace = string.IsNullOrEmpty(reRoute.ServiceNamespace) ? config.Namespace : reRoute.ServiceNamespace
|
||||||
};
|
};
|
||||||
|
|
||||||
var k8sServiceDiscoveryProvider = new Kube(k8sRegistryConfiguration, factory, kubeClient);
|
var k8sServiceDiscoveryProvider = new Kube(k8sRegistryConfiguration, factory, kubeClient);
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
|
||||||
<NETStandardImplicitPackageVersion>2.0.0</NETStandardImplicitPackageVersion>
|
|
||||||
<NoPackageAnalysis>true</NoPackageAnalysis>
|
<NoPackageAnalysis>true</NoPackageAnalysis>
|
||||||
<Product>Ocelot</Product>
|
<Product>Ocelot</Product>
|
||||||
<Description>Provides Ocelot extensions to use kubernetes</Description>
|
<Description>Provides Ocelot extensions to use kubernetes</Description>
|
||||||
@ -30,12 +28,16 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="KubeClient" Version="2.2.12" />
|
<PackageReference Include="KubeClient" Version="2.3.4" />
|
||||||
<PackageReference Include="KubeClient.Extensions.DependencyInjection" Version="2.2.12" />
|
<PackageReference Include="KubeClient.Extensions.DependencyInjection" Version="2.3.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
|
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
|
||||||
<NETStandardImplicitPackageVersion>2.0.0</NETStandardImplicitPackageVersion>
|
|
||||||
<NoPackageAnalysis>true</NoPackageAnalysis>
|
<NoPackageAnalysis>true</NoPackageAnalysis>
|
||||||
<Description>Provides Ocelot extensions to use Polly.NET</Description>
|
<Description>Provides Ocelot extensions to use Polly.NET</Description>
|
||||||
<AssemblyTitle>Ocelot.Provider.Polly</AssemblyTitle>
|
<AssemblyTitle>Ocelot.Provider.Polly</AssemblyTitle>
|
||||||
@ -29,9 +27,12 @@
|
|||||||
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
|
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Polly" Version="7.1.0" />
|
<PackageReference Include="Polly" Version="7.1.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
|
||||||
<NETStandardImplicitPackageVersion>2.0.0</NETStandardImplicitPackageVersion>
|
|
||||||
<NoPackageAnalysis>true</NoPackageAnalysis>
|
<NoPackageAnalysis>true</NoPackageAnalysis>
|
||||||
<Description>Provides Ocelot extensions to use Rafty</Description>
|
<Description>Provides Ocelot extensions to use Rafty</Description>
|
||||||
<AssemblyTitle>Ocelot.Provider.Rafty</AssemblyTitle>
|
<AssemblyTitle>Ocelot.Provider.Rafty</AssemblyTitle>
|
||||||
@ -30,10 +28,13 @@
|
|||||||
<ProjectReference Include="..\Ocelot.Administration\Ocelot.Administration.csproj" />
|
<ProjectReference Include="..\Ocelot.Administration\Ocelot.Administration.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Data.SQLite" Version="2.2.4" />
|
<PackageReference Include="Microsoft.Data.SQLite" Version="3.0.0" />
|
||||||
<PackageReference Include="Rafty" Version="0.4.4" />
|
<PackageReference Include="Rafty" Version="0.4.4" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
|
||||||
<NETStandardImplicitPackageVersion>2.0.0</NETStandardImplicitPackageVersion>
|
|
||||||
<NoPackageAnalysis>true</NoPackageAnalysis>
|
<NoPackageAnalysis>true</NoPackageAnalysis>
|
||||||
<Description>This package provides methods to integrate Butterfly tracing with Ocelot.</Description>
|
<Description>This package provides methods to integrate Butterfly tracing with Ocelot.</Description>
|
||||||
<AssemblyTitle>Ocelot.Tracing.Butterfly</AssemblyTitle>
|
<AssemblyTitle>Ocelot.Tracing.Butterfly</AssemblyTitle>
|
||||||
@ -33,5 +31,8 @@
|
|||||||
<PackageReference Include="Butterfly.Client" Version="0.0.8" />
|
<PackageReference Include="Butterfly.Client" Version="0.0.8" />
|
||||||
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
|
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
public async Task Invoke(DownstreamContext context)
|
public async Task Invoke(DownstreamContext context)
|
||||||
{
|
{
|
||||||
if (IsAuthenticatedRoute(context.DownstreamReRoute))
|
if (!IsOptionsHttpMethod(context) && IsAuthenticatedRoute(context.DownstreamReRoute))
|
||||||
{
|
{
|
||||||
Logger.LogInformation("route is authenticated scopes must be checked");
|
Logger.LogInformation("route is authenticated scopes must be checked");
|
||||||
|
|
||||||
@ -52,7 +52,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsAuthorisedRoute(context.DownstreamReRoute))
|
if (!IsOptionsHttpMethod(context) && IsAuthorisedRoute(context.DownstreamReRoute))
|
||||||
{
|
{
|
||||||
Logger.LogInformation("route is authorised");
|
Logger.LogInformation("route is authorised");
|
||||||
|
|
||||||
@ -98,6 +98,11 @@
|
|||||||
private static bool IsAuthorisedRoute(DownstreamReRoute reRoute)
|
private static bool IsAuthorisedRoute(DownstreamReRoute reRoute)
|
||||||
{
|
{
|
||||||
return reRoute.IsAuthorised;
|
return reRoute.IsAuthorised;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsOptionsHttpMethod(DownstreamContext context)
|
||||||
|
{
|
||||||
|
return context.HttpContext.Request.Method.ToUpper() == "OPTIONS";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ namespace Ocelot.Configuration.Builder
|
|||||||
private Dictionary<string, string> _routeClaimRequirement;
|
private Dictionary<string, string> _routeClaimRequirement;
|
||||||
private bool _isAuthorised;
|
private bool _isAuthorised;
|
||||||
private List<ClaimToThing> _claimToQueries;
|
private List<ClaimToThing> _claimToQueries;
|
||||||
|
private List<ClaimToThing> _claimToDownstreamPath;
|
||||||
private string _requestIdHeaderKey;
|
private string _requestIdHeaderKey;
|
||||||
private bool _isCached;
|
private bool _isCached;
|
||||||
private CacheOptions _fileCacheOptions;
|
private CacheOptions _fileCacheOptions;
|
||||||
@ -30,6 +31,7 @@ namespace Ocelot.Configuration.Builder
|
|||||||
private RateLimitOptions _rateLimitOptions;
|
private RateLimitOptions _rateLimitOptions;
|
||||||
private bool _useServiceDiscovery;
|
private bool _useServiceDiscovery;
|
||||||
private string _serviceName;
|
private string _serviceName;
|
||||||
|
private string _serviceNamespace;
|
||||||
private List<HeaderFindAndReplace> _upstreamHeaderFindAndReplace;
|
private List<HeaderFindAndReplace> _upstreamHeaderFindAndReplace;
|
||||||
private List<HeaderFindAndReplace> _downstreamHeaderFindAndReplace;
|
private List<HeaderFindAndReplace> _downstreamHeaderFindAndReplace;
|
||||||
private readonly List<DownstreamHostAndPort> _downstreamAddresses;
|
private readonly List<DownstreamHostAndPort> _downstreamAddresses;
|
||||||
@ -126,6 +128,12 @@ namespace Ocelot.Configuration.Builder
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DownstreamReRouteBuilder WithClaimsToDownstreamPath(List<ClaimToThing> input)
|
||||||
|
{
|
||||||
|
_claimToDownstreamPath = input;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public DownstreamReRouteBuilder WithIsCached(bool input)
|
public DownstreamReRouteBuilder WithIsCached(bool input)
|
||||||
{
|
{
|
||||||
_isCached = input;
|
_isCached = input;
|
||||||
@ -186,6 +194,12 @@ namespace Ocelot.Configuration.Builder
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DownstreamReRouteBuilder WithServiceNamespace(string serviceNamespace)
|
||||||
|
{
|
||||||
|
_serviceNamespace = serviceNamespace;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public DownstreamReRouteBuilder WithUpstreamHeaderFindAndReplace(List<HeaderFindAndReplace> upstreamHeaderFindAndReplace)
|
public DownstreamReRouteBuilder WithUpstreamHeaderFindAndReplace(List<HeaderFindAndReplace> upstreamHeaderFindAndReplace)
|
||||||
{
|
{
|
||||||
_upstreamHeaderFindAndReplace = upstreamHeaderFindAndReplace;
|
_upstreamHeaderFindAndReplace = upstreamHeaderFindAndReplace;
|
||||||
@ -243,6 +257,7 @@ namespace Ocelot.Configuration.Builder
|
|||||||
_downstreamHeaderFindAndReplace,
|
_downstreamHeaderFindAndReplace,
|
||||||
_downstreamAddresses,
|
_downstreamAddresses,
|
||||||
_serviceName,
|
_serviceName,
|
||||||
|
_serviceNamespace,
|
||||||
_httpHandlerOptions,
|
_httpHandlerOptions,
|
||||||
_useServiceDiscovery,
|
_useServiceDiscovery,
|
||||||
_enableRateLimiting,
|
_enableRateLimiting,
|
||||||
@ -257,6 +272,7 @@ namespace Ocelot.Configuration.Builder
|
|||||||
_claimToQueries,
|
_claimToQueries,
|
||||||
_claimsToHeaders,
|
_claimsToHeaders,
|
||||||
_claimToClaims,
|
_claimToClaims,
|
||||||
|
_claimToDownstreamPath,
|
||||||
_isAuthenticated,
|
_isAuthenticated,
|
||||||
_isAuthorised,
|
_isAuthorised,
|
||||||
_authenticationOptions,
|
_authenticationOptions,
|
||||||
|
@ -86,6 +86,8 @@ namespace Ocelot.Configuration.Creator
|
|||||||
|
|
||||||
var claimsToQueries = _claimsToThingCreator.Create(fileReRoute.AddQueriesToRequest);
|
var claimsToQueries = _claimsToThingCreator.Create(fileReRoute.AddQueriesToRequest);
|
||||||
|
|
||||||
|
var claimsToDownstreamPath = _claimsToThingCreator.Create(fileReRoute.ChangeDownstreamPathTemplate);
|
||||||
|
|
||||||
var qosOptions = _qosOptionsCreator.Create(fileReRoute.QoSOptions, fileReRoute.UpstreamPathTemplate, fileReRoute.UpstreamHttpMethod);
|
var qosOptions = _qosOptionsCreator.Create(fileReRoute.QoSOptions, fileReRoute.UpstreamPathTemplate, fileReRoute.UpstreamHttpMethod);
|
||||||
|
|
||||||
var rateLimitOption = _rateLimitOptionsCreator.Create(fileReRoute.RateLimitOptions, globalConfiguration);
|
var rateLimitOption = _rateLimitOptionsCreator.Create(fileReRoute.RateLimitOptions, globalConfiguration);
|
||||||
@ -114,6 +116,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
.WithRouteClaimsRequirement(fileReRoute.RouteClaimsRequirement)
|
.WithRouteClaimsRequirement(fileReRoute.RouteClaimsRequirement)
|
||||||
.WithIsAuthorised(fileReRouteOptions.IsAuthorised)
|
.WithIsAuthorised(fileReRouteOptions.IsAuthorised)
|
||||||
.WithClaimsToQueries(claimsToQueries)
|
.WithClaimsToQueries(claimsToQueries)
|
||||||
|
.WithClaimsToDownstreamPath(claimsToDownstreamPath)
|
||||||
.WithRequestIdKey(requestIdKey)
|
.WithRequestIdKey(requestIdKey)
|
||||||
.WithIsCached(fileReRouteOptions.IsCached)
|
.WithIsCached(fileReRouteOptions.IsCached)
|
||||||
.WithCacheOptions(new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds, region))
|
.WithCacheOptions(new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds, region))
|
||||||
@ -126,6 +129,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
.WithRateLimitOptions(rateLimitOption)
|
.WithRateLimitOptions(rateLimitOption)
|
||||||
.WithHttpHandlerOptions(httpHandlerOptions)
|
.WithHttpHandlerOptions(httpHandlerOptions)
|
||||||
.WithServiceName(fileReRoute.ServiceName)
|
.WithServiceName(fileReRoute.ServiceName)
|
||||||
|
.WithServiceNamespace(fileReRoute.ServiceNamespace)
|
||||||
.WithUseServiceDiscovery(fileReRouteOptions.UseServiceDiscovery)
|
.WithUseServiceDiscovery(fileReRouteOptions.UseServiceDiscovery)
|
||||||
.WithUpstreamHeaderFindAndReplace(hAndRs.Upstream)
|
.WithUpstreamHeaderFindAndReplace(hAndRs.Upstream)
|
||||||
.WithDownstreamHeaderFindAndReplace(hAndRs.Downstream)
|
.WithDownstreamHeaderFindAndReplace(hAndRs.Downstream)
|
||||||
|
@ -13,6 +13,7 @@ namespace Ocelot.Configuration
|
|||||||
List<HeaderFindAndReplace> downstreamHeadersFindAndReplace,
|
List<HeaderFindAndReplace> downstreamHeadersFindAndReplace,
|
||||||
List<DownstreamHostAndPort> downstreamAddresses,
|
List<DownstreamHostAndPort> downstreamAddresses,
|
||||||
string serviceName,
|
string serviceName,
|
||||||
|
string serviceNamespace,
|
||||||
HttpHandlerOptions httpHandlerOptions,
|
HttpHandlerOptions httpHandlerOptions,
|
||||||
bool useServiceDiscovery,
|
bool useServiceDiscovery,
|
||||||
bool enableEndpointEndpointRateLimiting,
|
bool enableEndpointEndpointRateLimiting,
|
||||||
@ -27,6 +28,7 @@ namespace Ocelot.Configuration
|
|||||||
List<ClaimToThing> claimsToQueries,
|
List<ClaimToThing> claimsToQueries,
|
||||||
List<ClaimToThing> claimsToHeaders,
|
List<ClaimToThing> claimsToHeaders,
|
||||||
List<ClaimToThing> claimsToClaims,
|
List<ClaimToThing> claimsToClaims,
|
||||||
|
List<ClaimToThing> claimsToPath,
|
||||||
bool isAuthenticated,
|
bool isAuthenticated,
|
||||||
bool isAuthorised,
|
bool isAuthorised,
|
||||||
AuthenticationOptions authenticationOptions,
|
AuthenticationOptions authenticationOptions,
|
||||||
@ -47,6 +49,7 @@ namespace Ocelot.Configuration
|
|||||||
DownstreamHeadersFindAndReplace = downstreamHeadersFindAndReplace ?? new List<HeaderFindAndReplace>();
|
DownstreamHeadersFindAndReplace = downstreamHeadersFindAndReplace ?? new List<HeaderFindAndReplace>();
|
||||||
DownstreamAddresses = downstreamAddresses ?? new List<DownstreamHostAndPort>();
|
DownstreamAddresses = downstreamAddresses ?? new List<DownstreamHostAndPort>();
|
||||||
ServiceName = serviceName;
|
ServiceName = serviceName;
|
||||||
|
ServiceNamespace = serviceNamespace;
|
||||||
HttpHandlerOptions = httpHandlerOptions;
|
HttpHandlerOptions = httpHandlerOptions;
|
||||||
UseServiceDiscovery = useServiceDiscovery;
|
UseServiceDiscovery = useServiceDiscovery;
|
||||||
EnableEndpointEndpointRateLimiting = enableEndpointEndpointRateLimiting;
|
EnableEndpointEndpointRateLimiting = enableEndpointEndpointRateLimiting;
|
||||||
@ -61,6 +64,7 @@ namespace Ocelot.Configuration
|
|||||||
ClaimsToQueries = claimsToQueries ?? new List<ClaimToThing>();
|
ClaimsToQueries = claimsToQueries ?? new List<ClaimToThing>();
|
||||||
ClaimsToHeaders = claimsToHeaders ?? new List<ClaimToThing>();
|
ClaimsToHeaders = claimsToHeaders ?? new List<ClaimToThing>();
|
||||||
ClaimsToClaims = claimsToClaims ?? new List<ClaimToThing>();
|
ClaimsToClaims = claimsToClaims ?? new List<ClaimToThing>();
|
||||||
|
ClaimsToPath = claimsToPath ?? new List<ClaimToThing>();
|
||||||
IsAuthenticated = isAuthenticated;
|
IsAuthenticated = isAuthenticated;
|
||||||
IsAuthorised = isAuthorised;
|
IsAuthorised = isAuthorised;
|
||||||
AuthenticationOptions = authenticationOptions;
|
AuthenticationOptions = authenticationOptions;
|
||||||
@ -76,6 +80,7 @@ namespace Ocelot.Configuration
|
|||||||
public List<HeaderFindAndReplace> DownstreamHeadersFindAndReplace { get; }
|
public List<HeaderFindAndReplace> DownstreamHeadersFindAndReplace { get; }
|
||||||
public List<DownstreamHostAndPort> DownstreamAddresses { get; }
|
public List<DownstreamHostAndPort> DownstreamAddresses { get; }
|
||||||
public string ServiceName { get; }
|
public string ServiceName { get; }
|
||||||
|
public string ServiceNamespace { get; }
|
||||||
public HttpHandlerOptions HttpHandlerOptions { get; }
|
public HttpHandlerOptions HttpHandlerOptions { get; }
|
||||||
public bool UseServiceDiscovery { get; }
|
public bool UseServiceDiscovery { get; }
|
||||||
public bool EnableEndpointEndpointRateLimiting { get; }
|
public bool EnableEndpointEndpointRateLimiting { get; }
|
||||||
@ -90,6 +95,7 @@ namespace Ocelot.Configuration
|
|||||||
public List<ClaimToThing> ClaimsToQueries { get; }
|
public List<ClaimToThing> ClaimsToQueries { get; }
|
||||||
public List<ClaimToThing> ClaimsToHeaders { get; }
|
public List<ClaimToThing> ClaimsToHeaders { get; }
|
||||||
public List<ClaimToThing> ClaimsToClaims { get; }
|
public List<ClaimToThing> ClaimsToClaims { get; }
|
||||||
|
public List<ClaimToThing> ClaimsToPath { get; }
|
||||||
public bool IsAuthenticated { get; }
|
public bool IsAuthenticated { get; }
|
||||||
public bool IsAuthorised { get; }
|
public bool IsAuthorised { get; }
|
||||||
public AuthenticationOptions AuthenticationOptions { get; }
|
public AuthenticationOptions AuthenticationOptions { get; }
|
||||||
|
@ -11,6 +11,7 @@ namespace Ocelot.Configuration.File
|
|||||||
AddClaimsToRequest = new Dictionary<string, string>();
|
AddClaimsToRequest = new Dictionary<string, string>();
|
||||||
RouteClaimsRequirement = new Dictionary<string, string>();
|
RouteClaimsRequirement = new Dictionary<string, string>();
|
||||||
AddQueriesToRequest = new Dictionary<string, string>();
|
AddQueriesToRequest = new Dictionary<string, string>();
|
||||||
|
ChangeDownstreamPathTemplate = new Dictionary<string, string>();
|
||||||
DownstreamHeaderTransform = new Dictionary<string, string>();
|
DownstreamHeaderTransform = new Dictionary<string, string>();
|
||||||
FileCacheOptions = new FileCacheOptions();
|
FileCacheOptions = new FileCacheOptions();
|
||||||
QoSOptions = new FileQoSOptions();
|
QoSOptions = new FileQoSOptions();
|
||||||
@ -34,10 +35,12 @@ namespace Ocelot.Configuration.File
|
|||||||
public Dictionary<string, string> AddClaimsToRequest { get; set; }
|
public Dictionary<string, string> AddClaimsToRequest { get; set; }
|
||||||
public Dictionary<string, string> RouteClaimsRequirement { get; set; }
|
public Dictionary<string, string> RouteClaimsRequirement { get; set; }
|
||||||
public Dictionary<string, string> AddQueriesToRequest { get; set; }
|
public Dictionary<string, string> AddQueriesToRequest { get; set; }
|
||||||
|
public Dictionary<string, string> ChangeDownstreamPathTemplate { get; set; }
|
||||||
public string RequestIdKey { get; set; }
|
public string RequestIdKey { get; set; }
|
||||||
public FileCacheOptions FileCacheOptions { get; set; }
|
public FileCacheOptions FileCacheOptions { get; set; }
|
||||||
public bool ReRouteIsCaseSensitive { get; set; }
|
public bool ReRouteIsCaseSensitive { get; set; }
|
||||||
public string ServiceName { get; set; }
|
public string ServiceName { get; set; }
|
||||||
|
public string ServiceNamespace { get; set; }
|
||||||
public string DownstreamScheme { get; set; }
|
public string DownstreamScheme { get; set; }
|
||||||
public FileQoSOptions QoSOptions { get; set; }
|
public FileQoSOptions QoSOptions { get; set; }
|
||||||
public FileLoadBalancerOptions LoadBalancerOptions { get; set; }
|
public FileLoadBalancerOptions LoadBalancerOptions { get; set; }
|
||||||
|
@ -14,7 +14,7 @@ namespace Ocelot.Configuration.Repository
|
|||||||
private static readonly object _lock = new object();
|
private static readonly object _lock = new object();
|
||||||
private const string ConfigurationFileName = "ocelot";
|
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";
|
_environmentFilePath = $"{AppContext.BaseDirectory}{ConfigurationFileName}{(string.IsNullOrEmpty(hostingEnvironment.EnvironmentName) ? string.Empty : ".")}{hostingEnvironment.EnvironmentName}.json";
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
.GetServices<ServiceDiscoveryFinderDelegate>()
|
.GetServices<ServiceDiscoveryFinderDelegate>()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
RuleFor(configuration => configuration.ReRoutes)
|
RuleForEach(configuration => configuration.ReRoutes)
|
||||||
.SetCollectionValidator(reRouteFluentValidator);
|
.SetValidator(reRouteFluentValidator);
|
||||||
|
|
||||||
RuleFor(configuration => configuration.GlobalConfiguration)
|
RuleFor(configuration => configuration.GlobalConfiguration)
|
||||||
.SetValidator(fileGlobalConfigurationFluentValidator);
|
.SetValidator(fileGlobalConfigurationFluentValidator);
|
||||||
|
@ -80,8 +80,8 @@
|
|||||||
|
|
||||||
When(reRoute => string.IsNullOrEmpty(reRoute.ServiceName), () =>
|
When(reRoute => string.IsNullOrEmpty(reRoute.ServiceName), () =>
|
||||||
{
|
{
|
||||||
RuleFor(reRoute => reRoute.DownstreamHostAndPorts)
|
RuleForEach(reRoute => reRoute.DownstreamHostAndPorts)
|
||||||
.SetCollectionValidator(hostAndPortValidator);
|
.SetValidator(hostAndPortValidator);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,18 +29,18 @@ namespace Ocelot.DependencyInjection
|
|||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, IHostingEnvironment env)
|
public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, IWebHostEnvironment env)
|
||||||
{
|
{
|
||||||
return builder.AddOcelot(".", 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";
|
const string primaryConfigFile = "ocelot.json";
|
||||||
|
|
||||||
const string globalConfigFile = "ocelot.global.json";
|
const string globalConfigFile = "ocelot.global.json";
|
||||||
|
|
||||||
const string subConfigPattern = @"^ocelot\.[a-zA-Z0-9]+\.json$";
|
const string subConfigPattern = @"^ocelot\.(.*?)\.json$";
|
||||||
|
|
||||||
string excludeConfigName = env?.EnvironmentName != null ? $"ocelot.{env.EnvironmentName}.json" : string.Empty;
|
string excludeConfigName = env?.EnvironmentName != null ? $"ocelot.{env.EnvironmentName}.json" : string.Empty;
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Ocelot.Middleware.Multiplexer;
|
using Ocelot.Middleware.Multiplexer;
|
||||||
|
using System;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
|
||||||
namespace Ocelot.DependencyInjection
|
namespace Ocelot.DependencyInjection
|
||||||
@ -13,6 +14,8 @@ namespace Ocelot.DependencyInjection
|
|||||||
|
|
||||||
IMvcCoreBuilder MvcCoreBuilder { get; }
|
IMvcCoreBuilder MvcCoreBuilder { get; }
|
||||||
|
|
||||||
|
IOcelotBuilder AddDelegatingHandler(Type type, bool global = false);
|
||||||
|
|
||||||
IOcelotBuilder AddDelegatingHandler<T>(bool global = false)
|
IOcelotBuilder AddDelegatingHandler<T>(bool global = false)
|
||||||
where T : DelegatingHandler;
|
where T : DelegatingHandler;
|
||||||
|
|
||||||
@ -21,5 +24,7 @@ namespace Ocelot.DependencyInjection
|
|||||||
|
|
||||||
IOcelotBuilder AddTransientDefinedAggregator<T>()
|
IOcelotBuilder AddTransientDefinedAggregator<T>()
|
||||||
where T : class, IDefinedAggregator;
|
where T : class, IDefinedAggregator;
|
||||||
|
|
||||||
|
IOcelotBuilder AddConfigPlaceholders();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ namespace Ocelot.DependencyInjection
|
|||||||
using Ocelot.Logging;
|
using Ocelot.Logging;
|
||||||
using Ocelot.Middleware;
|
using Ocelot.Middleware;
|
||||||
using Ocelot.Middleware.Multiplexer;
|
using Ocelot.Middleware.Multiplexer;
|
||||||
|
using Ocelot.PathManipulation;
|
||||||
using Ocelot.QueryStrings;
|
using Ocelot.QueryStrings;
|
||||||
using Ocelot.RateLimit;
|
using Ocelot.RateLimit;
|
||||||
using Ocelot.Request.Creator;
|
using Ocelot.Request.Creator;
|
||||||
@ -35,6 +36,8 @@ namespace Ocelot.DependencyInjection
|
|||||||
using Ocelot.Security;
|
using Ocelot.Security;
|
||||||
using Ocelot.Security.IPSecurity;
|
using Ocelot.Security.IPSecurity;
|
||||||
using Ocelot.ServiceDiscovery;
|
using Ocelot.ServiceDiscovery;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
@ -91,6 +94,7 @@ namespace Ocelot.DependencyInjection
|
|||||||
Services.TryAddSingleton<IAddClaimsToRequest, AddClaimsToRequest>();
|
Services.TryAddSingleton<IAddClaimsToRequest, AddClaimsToRequest>();
|
||||||
Services.TryAddSingleton<IAddHeadersToRequest, AddHeadersToRequest>();
|
Services.TryAddSingleton<IAddHeadersToRequest, AddHeadersToRequest>();
|
||||||
Services.TryAddSingleton<IAddQueriesToRequest, AddQueriesToRequest>();
|
Services.TryAddSingleton<IAddQueriesToRequest, AddQueriesToRequest>();
|
||||||
|
Services.TryAddSingleton<IChangeDownstreamPathTemplate, ChangeDownstreamPathTemplate>();
|
||||||
Services.TryAddSingleton<IClaimsParser, ClaimsParser>();
|
Services.TryAddSingleton<IClaimsParser, ClaimsParser>();
|
||||||
Services.TryAddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
|
Services.TryAddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
|
||||||
Services.TryAddSingleton<IPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>();
|
Services.TryAddSingleton<IPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>();
|
||||||
@ -138,7 +142,7 @@ namespace Ocelot.DependencyInjection
|
|||||||
.AddApplicationPart(assembly)
|
.AddApplicationPart(assembly)
|
||||||
.AddControllersAsServices()
|
.AddControllersAsServices()
|
||||||
.AddAuthorization()
|
.AddAuthorization()
|
||||||
.AddJsonFormatters();
|
.AddNewtonsoftJson();
|
||||||
|
|
||||||
Services.AddLogging();
|
Services.AddLogging();
|
||||||
Services.AddMiddlewareAnalysis();
|
Services.AddMiddlewareAnalysis();
|
||||||
@ -165,6 +169,28 @@ namespace Ocelot.DependencyInjection
|
|||||||
Services.TryAddSingleton<ISecurityPolicy, IPSecurityPolicy>();
|
Services.TryAddSingleton<ISecurityPolicy, IPSecurityPolicy>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IOcelotBuilder AddDelegatingHandler(Type delegateType, bool global = false)
|
||||||
|
{
|
||||||
|
if (!typeof(DelegatingHandler).IsAssignableFrom(delegateType)) throw new ArgumentOutOfRangeException(nameof(delegateType), delegateType.Name, "It is not a delegatin handler");
|
||||||
|
|
||||||
|
if (global)
|
||||||
|
{
|
||||||
|
Services.AddTransient(delegateType);
|
||||||
|
Services.AddTransient<GlobalDelegatingHandler>(s =>
|
||||||
|
{
|
||||||
|
|
||||||
|
var service = s.GetService(delegateType) as DelegatingHandler;
|
||||||
|
return new GlobalDelegatingHandler(service);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Services.AddTransient(typeof(DelegatingHandler), delegateType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public IOcelotBuilder AddDelegatingHandler<THandler>(bool global = false)
|
public IOcelotBuilder AddDelegatingHandler<THandler>(bool global = false)
|
||||||
where THandler : DelegatingHandler
|
where THandler : DelegatingHandler
|
||||||
{
|
{
|
||||||
@ -184,5 +210,39 @@ namespace Ocelot.DependencyInjection
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IOcelotBuilder AddConfigPlaceholders()
|
||||||
|
{
|
||||||
|
// see: https://greatrexpectations.com/2018/10/25/decorators-in-net-core-with-dependency-injection
|
||||||
|
var wrappedDescriptor = Services.First(x => x.ServiceType == typeof(IPlaceholders));
|
||||||
|
|
||||||
|
var objectFactory = ActivatorUtilities.CreateFactory(
|
||||||
|
typeof(ConfigAwarePlaceholders),
|
||||||
|
new[] { typeof(IPlaceholders) });
|
||||||
|
|
||||||
|
Services.Replace(ServiceDescriptor.Describe(
|
||||||
|
typeof(IPlaceholders),
|
||||||
|
s => (IPlaceholders) objectFactory(s,
|
||||||
|
new[] {CreateInstance(s, wrappedDescriptor)}),
|
||||||
|
wrappedDescriptor.Lifetime
|
||||||
|
));
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object CreateInstance(IServiceProvider services, ServiceDescriptor descriptor)
|
||||||
|
{
|
||||||
|
if (descriptor.ImplementationInstance != null)
|
||||||
|
{
|
||||||
|
return descriptor.ImplementationInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (descriptor.ImplementationFactory != null)
|
||||||
|
{
|
||||||
|
return descriptor.ImplementationFactory(services);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ActivatorUtilities.GetServiceOrCreateInstance(services, descriptor.ImplementationType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,9 @@ namespace Ocelot.DependencyInjection
|
|||||||
public static class ServiceCollectionExtensions
|
public static class ServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
public static IOcelotBuilder AddOcelot(this IServiceCollection services)
|
public static IOcelotBuilder AddOcelot(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
var service = services.First(x => x.ServiceType == typeof(IConfiguration));
|
var configuration = services.BuildServiceProvider()
|
||||||
var configuration = (IConfiguration)service.ImplementationInstance;
|
.GetRequiredService<IConfiguration>();
|
||||||
return new OcelotBuilder(services, configuration);
|
return new OcelotBuilder(services, configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||||
|
using Ocelot.Infrastructure;
|
||||||
|
using Ocelot.Infrastructure.Claims.Parser;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
using Ocelot.Values;
|
||||||
|
|
||||||
|
namespace Ocelot.PathManipulation
|
||||||
|
{
|
||||||
|
public class ChangeDownstreamPathTemplate : IChangeDownstreamPathTemplate
|
||||||
|
{
|
||||||
|
private readonly IClaimsParser _claimsParser;
|
||||||
|
|
||||||
|
public ChangeDownstreamPathTemplate(IClaimsParser claimsParser)
|
||||||
|
{
|
||||||
|
_claimsParser = claimsParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response ChangeDownstreamPath(List<ClaimToThing> claimsToThings, IEnumerable<Claim> claims,
|
||||||
|
DownstreamPathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> placeholders)
|
||||||
|
{
|
||||||
|
foreach (var config in claimsToThings)
|
||||||
|
{
|
||||||
|
var value = _claimsParser.GetValue(claims, config.NewKey, config.Delimiter, config.Index);
|
||||||
|
|
||||||
|
if (value.IsError)
|
||||||
|
{
|
||||||
|
return new ErrorResponse(value.Errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
var placeholderName = $"{{{config.ExistingKey}}}";
|
||||||
|
|
||||||
|
if (!downstreamPathTemplate.Value.Contains(placeholderName))
|
||||||
|
{
|
||||||
|
return new ErrorResponse(new CouldNotFindPlaceholderError(placeholderName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (placeholders.Any(ph => ph.Name == placeholderName))
|
||||||
|
{
|
||||||
|
placeholders.RemoveAll(ph => ph.Name == placeholderName);
|
||||||
|
}
|
||||||
|
|
||||||
|
placeholders.Add(new PlaceholderNameAndValue(placeholderName, value.Data));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OkResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||||
|
using Ocelot.Request.Middleware;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
using Ocelot.Values;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Ocelot.PathManipulation
|
||||||
|
{
|
||||||
|
public interface IChangeDownstreamPathTemplate
|
||||||
|
{
|
||||||
|
Response ChangeDownstreamPath(List<ClaimToThing> claimsToThings, IEnumerable<Claim> claims,
|
||||||
|
DownstreamPathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> placeholders);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
using Ocelot.Logging;
|
||||||
|
using Ocelot.Middleware;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ocelot.PathManipulation.Middleware
|
||||||
|
{
|
||||||
|
public class ClaimsToDownstreamPathMiddleware : OcelotMiddleware
|
||||||
|
{
|
||||||
|
private readonly OcelotRequestDelegate _next;
|
||||||
|
private readonly IChangeDownstreamPathTemplate _changeDownstreamPathTemplate;
|
||||||
|
|
||||||
|
public ClaimsToDownstreamPathMiddleware(OcelotRequestDelegate next,
|
||||||
|
IOcelotLoggerFactory loggerFactory,
|
||||||
|
IChangeDownstreamPathTemplate changeDownstreamPathTemplate)
|
||||||
|
: base(loggerFactory.CreateLogger<ClaimsToDownstreamPathMiddleware>())
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
_changeDownstreamPathTemplate = changeDownstreamPathTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Invoke(DownstreamContext context)
|
||||||
|
{
|
||||||
|
if (context.DownstreamReRoute.ClaimsToPath.Any())
|
||||||
|
{
|
||||||
|
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamPathTemplate.Value} has instructions to convert claims to path");
|
||||||
|
var response = _changeDownstreamPathTemplate.ChangeDownstreamPath(context.DownstreamReRoute.ClaimsToPath, context.HttpContext.User.Claims,
|
||||||
|
context.DownstreamReRoute.DownstreamPathTemplate, context.TemplatePlaceholderNameAndValues);
|
||||||
|
|
||||||
|
if (response.IsError)
|
||||||
|
{
|
||||||
|
Logger.LogWarning("there was an error setting queries on context, setting pipeline error");
|
||||||
|
|
||||||
|
SetPipelineError(context, response.Errors);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await _next.Invoke(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
using Ocelot.Middleware.Pipeline;
|
||||||
|
|
||||||
|
namespace Ocelot.PathManipulation.Middleware
|
||||||
|
{
|
||||||
|
public static class ClaimsToDownstreamPathMiddlewareExtensions
|
||||||
|
{
|
||||||
|
public static IOcelotPipelineBuilder UseClaimsToDownstreamPathMiddleware(this IOcelotPipelineBuilder builder)
|
||||||
|
{
|
||||||
|
return builder.UseMiddleware<ClaimsToDownstreamPathMiddleware>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
namespace Ocelot.Infrastructure.Claims.Parser
|
namespace Ocelot.Infrastructure.Claims.Parser
|
||||||
{
|
{
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using Responses;
|
using Responses;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
var splits = claimResponse.Data.Split(delimiter.ToCharArray());
|
var splits = claimResponse.Data.Split(delimiter.ToCharArray());
|
||||||
|
|
||||||
if (splits.Length < index || index < 0)
|
if (splits.Length <= index || index < 0)
|
||||||
{
|
{
|
||||||
return new ErrorResponse<string>(new CannotFindClaimError($"Cannot find claim for key: {key}, delimiter: {delimiter}, index: {index}"));
|
return new ErrorResponse<string>(new CannotFindClaimError($"Cannot find claim for key: {key}, delimiter: {delimiter}, index: {index}"));
|
||||||
}
|
}
|
||||||
@ -55,4 +55,4 @@
|
|||||||
return new ErrorResponse<string>(new CannotFindClaimError($"Cannot find claim for key: {key}"));
|
return new ErrorResponse<string>(new CannotFindClaimError($"Cannot find claim for key: {key}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
61
src/Ocelot/Infrastructure/ConfigAwarePlaceholders.cs
Normal file
61
src/Ocelot/Infrastructure/ConfigAwarePlaceholders.cs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
namespace Ocelot.Infrastructure
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Request.Middleware;
|
||||||
|
using Responses;
|
||||||
|
|
||||||
|
public class ConfigAwarePlaceholders : IPlaceholders
|
||||||
|
{
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
private readonly IPlaceholders _placeholders;
|
||||||
|
|
||||||
|
public ConfigAwarePlaceholders(IConfiguration configuration, IPlaceholders placeholders)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
_placeholders = placeholders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response<string> Get(string key)
|
||||||
|
{
|
||||||
|
var placeholderResponse = _placeholders.Get(key);
|
||||||
|
|
||||||
|
if (!placeholderResponse.IsError)
|
||||||
|
{
|
||||||
|
return placeholderResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetFromConfig(CleanKey(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response<string> Get(string key, DownstreamRequest request)
|
||||||
|
{
|
||||||
|
var placeholderResponse = _placeholders.Get(key, request);
|
||||||
|
|
||||||
|
if (!placeholderResponse.IsError)
|
||||||
|
{
|
||||||
|
return placeholderResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetFromConfig(CleanKey(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response Add(string key, Func<Response<string>> func)
|
||||||
|
=> _placeholders.Add(key, func);
|
||||||
|
|
||||||
|
public Response Remove(string key)
|
||||||
|
=> _placeholders.Remove(key);
|
||||||
|
|
||||||
|
private string CleanKey(string key)
|
||||||
|
=> Regex.Replace(key, @"[{}]", string.Empty, RegexOptions.None);
|
||||||
|
|
||||||
|
private Response<string> GetFromConfig(string key)
|
||||||
|
{
|
||||||
|
var valueFromConfig = _configuration[key];
|
||||||
|
return valueFromConfig == null
|
||||||
|
? (Response<string>) new ErrorResponse<string>(new CouldNotFindPlaceholderError(key))
|
||||||
|
: new OkResponse<string>(valueFromConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,53 +8,83 @@ namespace Ocelot.Logging
|
|||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IRequestScopedDataRepository _scopedDataRepository;
|
private readonly IRequestScopedDataRepository _scopedDataRepository;
|
||||||
|
private readonly Func<string, Exception, string> _func;
|
||||||
|
|
||||||
public AspDotNetLogger(ILogger logger, IRequestScopedDataRepository scopedDataRepository)
|
public AspDotNetLogger(ILogger logger, IRequestScopedDataRepository scopedDataRepository)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_scopedDataRepository = scopedDataRepository;
|
_scopedDataRepository = scopedDataRepository;
|
||||||
|
_func = (state, exception) =>
|
||||||
|
{
|
||||||
|
if (exception == null)
|
||||||
|
{
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $"{state}, exception: {exception}";
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LogTrace(string message)
|
public void LogTrace(string message)
|
||||||
{
|
{
|
||||||
var requestId = GetOcelotRequestId();
|
var requestId = GetOcelotRequestId();
|
||||||
var previousRequestId = GetOcelotPreviousRequestId();
|
var previousRequestId = GetOcelotPreviousRequestId();
|
||||||
_logger.LogTrace("requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}", requestId, previousRequestId, message);
|
|
||||||
|
var state = $"requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}";
|
||||||
|
|
||||||
|
_logger.Log(LogLevel.Trace, default(EventId), state, null, _func);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LogDebug(string message)
|
public void LogDebug(string message)
|
||||||
{
|
{
|
||||||
var requestId = GetOcelotRequestId();
|
var requestId = GetOcelotRequestId();
|
||||||
var previousRequestId = GetOcelotPreviousRequestId();
|
var previousRequestId = GetOcelotPreviousRequestId();
|
||||||
_logger.LogDebug("requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}", requestId, previousRequestId, message);
|
|
||||||
|
var state = $"requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}";
|
||||||
|
|
||||||
|
_logger.Log(LogLevel.Debug, default(EventId), state, null, _func);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LogInformation(string message)
|
public void LogInformation(string message)
|
||||||
{
|
{
|
||||||
var requestId = GetOcelotRequestId();
|
var requestId = GetOcelotRequestId();
|
||||||
var previousRequestId = GetOcelotPreviousRequestId();
|
var previousRequestId = GetOcelotPreviousRequestId();
|
||||||
_logger.LogInformation("requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}", requestId, previousRequestId, message);
|
|
||||||
|
var state = $"requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}";
|
||||||
|
|
||||||
|
_logger.Log(LogLevel.Information, default(EventId), state, null, _func);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LogWarning(string message)
|
public void LogWarning(string message)
|
||||||
{
|
{
|
||||||
var requestId = GetOcelotRequestId();
|
var requestId = GetOcelotRequestId();
|
||||||
var previousRequestId = GetOcelotPreviousRequestId();
|
var previousRequestId = GetOcelotPreviousRequestId();
|
||||||
_logger.LogWarning("requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}", requestId, previousRequestId, message);
|
|
||||||
|
var state = $"requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}";
|
||||||
|
|
||||||
|
_logger.Log(LogLevel.Warning, default(EventId), state, null, _func);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LogError(string message, Exception exception)
|
public void LogError(string message, Exception exception)
|
||||||
{
|
{
|
||||||
var requestId = GetOcelotRequestId();
|
var requestId = GetOcelotRequestId();
|
||||||
var previousRequestId = GetOcelotPreviousRequestId();
|
var previousRequestId = GetOcelotPreviousRequestId();
|
||||||
_logger.LogError("requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}, exception: {exception}", requestId, previousRequestId, message, exception);
|
|
||||||
|
var state = $"requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}";
|
||||||
|
|
||||||
|
_logger.Log(LogLevel.Error,default(EventId), state, exception, _func);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LogCritical(string message, Exception exception)
|
public void LogCritical(string message, Exception exception)
|
||||||
{
|
{
|
||||||
var requestId = GetOcelotRequestId();
|
var requestId = GetOcelotRequestId();
|
||||||
var previousRequestId = GetOcelotPreviousRequestId();
|
var previousRequestId = GetOcelotPreviousRequestId();
|
||||||
_logger.LogCritical("requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}, exception: {exception}", requestId, previousRequestId, message, exception);
|
|
||||||
|
var state = $"requestId: {requestId}, previousRequestId: {previousRequestId}, message: {message}";
|
||||||
|
|
||||||
|
_logger.Log(LogLevel.Critical, default(EventId), state, exception, _func);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetOcelotRequestId()
|
private string GetOcelotRequestId()
|
||||||
@ -81,4 +111,4 @@ namespace Ocelot.Logging
|
|||||||
return requestId.Data;
|
return requestId.Data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@
|
|||||||
|
|
||||||
private static void ConfigureDiagnosticListener(IApplicationBuilder builder)
|
private static void ConfigureDiagnosticListener(IApplicationBuilder builder)
|
||||||
{
|
{
|
||||||
var env = builder.ApplicationServices.GetService<IHostingEnvironment>();
|
var env = builder.ApplicationServices.GetService<IWebHostEnvironment>();
|
||||||
var listener = builder.ApplicationServices.GetService<OcelotDiagnosticListener>();
|
var listener = builder.ApplicationServices.GetService<OcelotDiagnosticListener>();
|
||||||
var diagnosticListener = builder.ApplicationServices.GetService<DiagnosticListener>();
|
var diagnosticListener = builder.ApplicationServices.GetService<DiagnosticListener>();
|
||||||
diagnosticListener.SubscribeWithAdapter(listener);
|
diagnosticListener.SubscribeWithAdapter(listener);
|
||||||
|
@ -79,12 +79,12 @@ namespace Ocelot.Middleware.Pipeline
|
|||||||
var diagnosticListener = (DiagnosticListener)app.ApplicationServices.GetService(typeof(DiagnosticListener));
|
var diagnosticListener = (DiagnosticListener)app.ApplicationServices.GetService(typeof(DiagnosticListener));
|
||||||
var middlewareName = ocelotDelegate.Target.GetType().Name;
|
var middlewareName = ocelotDelegate.Target.GetType().Name;
|
||||||
|
|
||||||
OcelotRequestDelegate wrapped = context =>
|
OcelotRequestDelegate wrapped = async context =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Write(diagnosticListener, "Ocelot.MiddlewareStarted", middlewareName, context);
|
Write(diagnosticListener, "Ocelot.MiddlewareStarted", middlewareName, context);
|
||||||
return ocelotDelegate(context);
|
await ocelotDelegate(context);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@ using Ocelot.DownstreamUrlCreator.Middleware;
|
|||||||
using Ocelot.Errors.Middleware;
|
using Ocelot.Errors.Middleware;
|
||||||
using Ocelot.Headers.Middleware;
|
using Ocelot.Headers.Middleware;
|
||||||
using Ocelot.LoadBalancer.Middleware;
|
using Ocelot.LoadBalancer.Middleware;
|
||||||
|
using Ocelot.PathManipulation.Middleware;
|
||||||
using Ocelot.QueryStrings.Middleware;
|
using Ocelot.QueryStrings.Middleware;
|
||||||
using Ocelot.RateLimit.Middleware;
|
using Ocelot.RateLimit.Middleware;
|
||||||
using Ocelot.Request.Middleware;
|
using Ocelot.Request.Middleware;
|
||||||
@ -118,6 +119,8 @@ namespace Ocelot.Middleware.Pipeline
|
|||||||
// Now we can run any claims to query string transformation middleware
|
// Now we can run any claims to query string transformation middleware
|
||||||
builder.UseClaimsToQueryStringMiddleware();
|
builder.UseClaimsToQueryStringMiddleware();
|
||||||
|
|
||||||
|
builder.UseClaimsToDownstreamPathMiddleware();
|
||||||
|
|
||||||
// Get the load balancer for this request
|
// Get the load balancer for this request
|
||||||
builder.UseLoadBalancingMiddleware();
|
builder.UseLoadBalancingMiddleware();
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
|
||||||
<NETStandardImplicitPackageVersion>2.0.0</NETStandardImplicitPackageVersion>
|
|
||||||
<NoPackageAnalysis>true</NoPackageAnalysis>
|
<NoPackageAnalysis>true</NoPackageAnalysis>
|
||||||
<Description>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.</Description>
|
<Description>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.</Description>
|
||||||
<AssemblyTitle>Ocelot</AssemblyTitle>
|
<AssemblyTitle>Ocelot</AssemblyTitle>
|
||||||
@ -25,16 +23,20 @@
|
|||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<DebugSymbols>True</DebugSymbols>
|
<DebugSymbols>True</DebugSymbols>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentValidation" Version="8.4.0" />
|
<PackageReference Include="FluentValidation" Version="8.5.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.DiagnosticAdapter" Version="3.0.0">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="2.2.0" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.DiagnosticAdapter" Version="2.2.0">
|
|
||||||
<NoWarn>NU1701</NoWarn>
|
<NoWarn>NU1701</NoWarn>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
|
||||||
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -4,5 +4,5 @@ namespace Ocelot.ServiceDiscovery
|
|||||||
using Providers;
|
using Providers;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
public delegate IServiceDiscoveryProvider ServiceDiscoveryFinderDelegate(IServiceProvider provider, ServiceProviderConfiguration config, string key);
|
public delegate IServiceDiscoveryProvider ServiceDiscoveryFinderDelegate(IServiceProvider provider, ServiceProviderConfiguration config, DownstreamReRoute reRoute);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ namespace Ocelot.ServiceDiscovery
|
|||||||
{
|
{
|
||||||
if (reRoute.UseServiceDiscovery)
|
if (reRoute.UseServiceDiscovery)
|
||||||
{
|
{
|
||||||
return GetServiceDiscoveryProvider(serviceConfig, reRoute.ServiceName);
|
return GetServiceDiscoveryProvider(serviceConfig, reRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
var services = new List<Service>();
|
var services = new List<Service>();
|
||||||
@ -42,17 +42,17 @@ namespace Ocelot.ServiceDiscovery
|
|||||||
return new OkResponse<IServiceDiscoveryProvider>(new ConfigurationServiceProvider(services));
|
return new OkResponse<IServiceDiscoveryProvider>(new ConfigurationServiceProvider(services));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response<IServiceDiscoveryProvider> GetServiceDiscoveryProvider(ServiceProviderConfiguration config, string key)
|
private Response<IServiceDiscoveryProvider> GetServiceDiscoveryProvider(ServiceProviderConfiguration config, DownstreamReRoute reRoute)
|
||||||
{
|
{
|
||||||
if (config.Type?.ToLower() == "servicefabric")
|
if (config.Type?.ToLower() == "servicefabric")
|
||||||
{
|
{
|
||||||
var sfConfig = new ServiceFabricConfiguration(config.Host, config.Port, key);
|
var sfConfig = new ServiceFabricConfiguration(config.Host, config.Port, reRoute.ServiceName);
|
||||||
return new OkResponse<IServiceDiscoveryProvider>(new ServiceFabricServiceDiscoveryProvider(sfConfig));
|
return new OkResponse<IServiceDiscoveryProvider>(new ServiceFabricServiceDiscoveryProvider(sfConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_delegates != null)
|
if (_delegates != null)
|
||||||
{
|
{
|
||||||
var provider = _delegates?.Invoke(_provider, config, key);
|
var provider = _delegates?.Invoke(_provider, config, reRoute);
|
||||||
|
|
||||||
if (provider.GetType().Name.ToLower() == config.Type.ToLower())
|
if (provider.GetType().Name.ToLower() == config.Type.ToLower())
|
||||||
{
|
{
|
||||||
|
@ -47,6 +47,15 @@ namespace Ocelot.WebSockets.Middleware
|
|||||||
await destination.CloseOutputAsync(WebSocketCloseStatus.EndpointUnavailable, null, cancellationToken);
|
await destination.CloseOutputAsync(WebSocketCloseStatus.EndpointUnavailable, null, cancellationToken);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
catch (WebSocketException e)
|
||||||
|
{
|
||||||
|
if (e.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely)
|
||||||
|
{
|
||||||
|
await destination.CloseOutputAsync(WebSocketCloseStatus.EndpointUnavailable, null, cancellationToken);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
if (result.MessageType == WebSocketMessageType.Close)
|
if (result.MessageType == WebSocketMessageType.Close)
|
||||||
{
|
{
|
||||||
|
201
test/Ocelot.AcceptanceTests/ClaimsToDownstreamPathTests.cs
Normal file
201
test/Ocelot.AcceptanceTests/ClaimsToDownstreamPathTests.cs
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
using IdentityServer4.AccessTokenValidation;
|
||||||
|
using IdentityServer4.Models;
|
||||||
|
using IdentityServer4.Test;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Shouldly;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
|
||||||
|
public class ClaimsToDownstreamPathTests : IDisposable
|
||||||
|
{
|
||||||
|
private IWebHost _servicebuilder;
|
||||||
|
private IWebHost _identityServerBuilder;
|
||||||
|
private readonly Steps _steps;
|
||||||
|
private Action<IdentityServerAuthenticationOptions> _options;
|
||||||
|
private string _identityServerRootUrl = "http://localhost:57888";
|
||||||
|
private string _downstreamFinalPath;
|
||||||
|
|
||||||
|
public ClaimsToDownstreamPathTests()
|
||||||
|
{
|
||||||
|
_steps = new Steps();
|
||||||
|
_options = o =>
|
||||||
|
{
|
||||||
|
o.Authority = _identityServerRootUrl;
|
||||||
|
o.ApiName = "api";
|
||||||
|
o.RequireHttpsMetadata = false;
|
||||||
|
o.SupportedTokens = SupportedTokens.Both;
|
||||||
|
o.ApiSecret = "secret";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_200_and_change_downstream_path()
|
||||||
|
{
|
||||||
|
var user = new TestUser()
|
||||||
|
{
|
||||||
|
Username = "test",
|
||||||
|
Password = "test",
|
||||||
|
SubjectId = "registered|1231231",
|
||||||
|
};
|
||||||
|
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/users/{userId}",
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = 57876,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
UpstreamPathTemplate = "/users",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test",
|
||||||
|
AllowedScopes = new List<string>
|
||||||
|
{
|
||||||
|
"openid", "offline_access", "api",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ChangeDownstreamPathTemplate =
|
||||||
|
{
|
||||||
|
{"userId", "Claims[sub] > value[1] > |"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:57888", "api", AccessTokenType.Jwt, user))
|
||||||
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:57876", 200))
|
||||||
|
.And(x => _steps.GivenIHaveAToken("http://localhost:57888"))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/users"))
|
||||||
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
|
.And(x => _steps.ThenTheResponseBodyShouldBe("UserId: 1231231"))
|
||||||
|
.And(x => _downstreamFinalPath.ShouldBe("/users/1231231"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode)
|
||||||
|
{
|
||||||
|
_servicebuilder = new WebHostBuilder()
|
||||||
|
.UseUrls(url)
|
||||||
|
.UseKestrel()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseIISIntegration()
|
||||||
|
.UseUrls(url)
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
_downstreamFinalPath = context.Request.Path.Value;
|
||||||
|
|
||||||
|
string userId = _downstreamFinalPath.Replace("/users/", string.Empty);
|
||||||
|
|
||||||
|
var responseBody = $"UserId: {userId}";
|
||||||
|
context.Response.StatusCode = statusCode;
|
||||||
|
await context.Response.WriteAsync(responseBody);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_servicebuilder.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenThereIsAnIdentityServerOn(string url, string apiName, AccessTokenType tokenType, TestUser user)
|
||||||
|
{
|
||||||
|
_identityServerBuilder = new WebHostBuilder()
|
||||||
|
.UseUrls(url)
|
||||||
|
.UseKestrel()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseIISIntegration()
|
||||||
|
.UseUrls(url)
|
||||||
|
.ConfigureServices(services =>
|
||||||
|
{
|
||||||
|
services.AddLogging();
|
||||||
|
services.AddIdentityServer()
|
||||||
|
.AddDeveloperSigningCredential()
|
||||||
|
.AddInMemoryApiResources(new List<ApiResource>
|
||||||
|
{
|
||||||
|
new ApiResource
|
||||||
|
{
|
||||||
|
Name = apiName,
|
||||||
|
Description = "My API",
|
||||||
|
Enabled = true,
|
||||||
|
DisplayName = "test",
|
||||||
|
Scopes = new List<Scope>()
|
||||||
|
{
|
||||||
|
new Scope("api"),
|
||||||
|
new Scope("openid"),
|
||||||
|
new Scope("offline_access")
|
||||||
|
},
|
||||||
|
ApiSecrets = new List<Secret>()
|
||||||
|
{
|
||||||
|
new Secret
|
||||||
|
{
|
||||||
|
Value = "secret".Sha256()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
UserClaims = new List<string>()
|
||||||
|
{
|
||||||
|
"CustomerId", "LocationId", "UserType", "UserId"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.AddInMemoryClients(new List<Client>
|
||||||
|
{
|
||||||
|
new Client
|
||||||
|
{
|
||||||
|
ClientId = "client",
|
||||||
|
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
|
||||||
|
ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
|
||||||
|
AllowedScopes = new List<string> { apiName, "openid", "offline_access" },
|
||||||
|
AccessTokenType = tokenType,
|
||||||
|
Enabled = true,
|
||||||
|
RequireClientSecret = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.AddTestUsers(new List<TestUser>
|
||||||
|
{
|
||||||
|
user
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.UseIdentityServer();
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_identityServerBuilder.Start();
|
||||||
|
|
||||||
|
_steps.VerifyIdentiryServerStarted(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_servicebuilder?.Dispose();
|
||||||
|
_steps.Dispose();
|
||||||
|
_identityServerBuilder?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -16,9 +17,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
public class ConfigurationInConsulTests : IDisposable
|
public class ConfigurationInConsulTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
private IHost _builder;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private IWebHost _fakeConsulBuilder;
|
private IHost _fakeConsulBuilder;
|
||||||
private FileConfiguration _config;
|
private FileConfiguration _config;
|
||||||
private readonly List<ServiceEntry> _consulServices;
|
private readonly List<ServiceEntry> _consulServices;
|
||||||
|
|
||||||
@ -75,8 +76,10 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName)
|
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName)
|
||||||
{
|
{
|
||||||
_fakeConsulBuilder = new WebHostBuilder()
|
_fakeConsulBuilder = Host.CreateDefaultBuilder()
|
||||||
.UseUrls(url)
|
.ConfigureWebHost(webBuilder =>
|
||||||
|
{
|
||||||
|
webBuilder.UseUrls(url)
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.UseIISIntegration()
|
.UseIISIntegration()
|
||||||
@ -103,7 +106,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
var reader = new StreamReader(context.Request.Body);
|
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<FileConfiguration>(json);
|
_config = JsonConvert.DeserializeObject<FileConfiguration>(json);
|
||||||
|
|
||||||
@ -122,8 +127,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteJsonAsync(_consulServices);
|
await context.Response.WriteJsonAsync(_consulServices);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
.Build();
|
}).Build();
|
||||||
|
|
||||||
_fakeConsulBuilder.Start();
|
_fakeConsulBuilder.Start();
|
||||||
}
|
}
|
||||||
@ -146,22 +151,24 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, string basePath, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string url, string basePath, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_builder = Host.CreateDefaultBuilder()
|
||||||
.UseUrls(url)
|
.ConfigureWebHost(webBuilder =>
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
{
|
||||||
app.UsePathBase(basePath);
|
webBuilder.UseUrls(url)
|
||||||
|
.UseKestrel()
|
||||||
app.Run(async context =>
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseIISIntegration()
|
||||||
|
.UseUrls(url)
|
||||||
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = statusCode;
|
app.UsePathBase(basePath);
|
||||||
await context.Response.WriteAsync(responseBody);
|
app.Run(async context =>
|
||||||
});
|
{
|
||||||
})
|
context.Response.StatusCode = statusCode;
|
||||||
|
await context.Response.WriteAsync(responseBody);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_builder.Start();
|
_builder.Start();
|
||||||
|
@ -373,7 +373,9 @@
|
|||||||
{
|
{
|
||||||
var reader = new StreamReader(context.Request.Body);
|
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<FileConfiguration>(json);
|
_config = JsonConvert.DeserializeObject<FileConfiguration>(json);
|
||||||
|
|
||||||
|
@ -181,7 +181,13 @@
|
|||||||
}
|
}
|
||||||
else if (result.MessageType == WebSocketMessageType.Close)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,7 +233,13 @@
|
|||||||
}
|
}
|
||||||
else if (result.MessageType == WebSocketMessageType.Close)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
||||||
.And(x => ThenTheContentTypeShouldBeEmpty())
|
.And(x => ThenTheContentTypeShouldBeEmpty())
|
||||||
.And(x => ThenTheContentLengthShouldBeEmpty())
|
.And(x => ThenTheContentLengthShouldBeZero())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,9 +139,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_contentType.ShouldBe(expected);
|
_contentType.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheContentLengthShouldBeEmpty()
|
private void ThenTheContentLengthShouldBeZero()
|
||||||
{
|
{
|
||||||
_contentLength.ShouldBeNull();
|
_contentLength.ShouldBeEquivalentTo(0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheContentLengthIs(int expected)
|
private void ThenTheContentLengthIs(int expected)
|
||||||
|
@ -73,7 +73,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
using (var sr = new StreamReader(decompress))
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<AssemblyName>Ocelot.AcceptanceTests</AssemblyName>
|
<AssemblyName>Ocelot.AcceptanceTests</AssemblyName>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<PackageId>Ocelot.AcceptanceTests</PackageId>
|
<PackageId>Ocelot.AcceptanceTests</PackageId>
|
||||||
@ -36,36 +36,39 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.4" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||||
<PackageReference Include="Shouldly" Version="3.0.2" />
|
<PackageReference Include="Shouldly" Version="4.0.0-beta0002" />
|
||||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
|
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
|
||||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
|
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
|
||||||
<PackageReference Include="IdentityServer4" Version="2.4.0" />
|
<PackageReference Include="IdentityServer4" Version="3.0.1" />
|
||||||
<PackageReference Include="Consul" Version="0.7.2.6" />
|
<PackageReference Include="Consul" Version="0.7.2.6" />
|
||||||
<PackageReference Include="Rafty" Version="0.4.4" />
|
<PackageReference Include="Rafty" Version="0.4.4" />
|
||||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.2.0" />
|
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="2.0.0-beta-1629" />
|
||||||
<PackageReference Include="CacheManager.Serialization.Json" Version="1.2.0" />
|
<PackageReference Include="CacheManager.Serialization.Json" Version="2.0.0-beta-1629" />
|
||||||
<PackageReference Include="Pivotal.Discovery.ClientCore" Version="2.2.0" />
|
<PackageReference Include="Pivotal.Discovery.ClientCore" Version="2.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -37,7 +37,7 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using static Ocelot.AcceptanceTests.HttpDelegatingHandlersTests;
|
using static Ocelot.AcceptanceTests.HttpDelegatingHandlersTests;
|
||||||
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
|
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;
|
using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue;
|
||||||
|
|
||||||
public class Steps : IDisposable
|
public class Steps : IDisposable
|
||||||
@ -338,7 +338,7 @@
|
|||||||
{
|
{
|
||||||
x.WithMicrosoftLogging(log =>
|
x.WithMicrosoftLogging(log =>
|
||||||
{
|
{
|
||||||
log.AddConsole(LogLevel.Debug);
|
//log.AddConsole(LogLevel.Debug);
|
||||||
})
|
})
|
||||||
.WithJsonSerializer()
|
.WithJsonSerializer()
|
||||||
.WithHandle(typeof(InMemoryJsonHandle<>));
|
.WithHandle(typeof(InMemoryJsonHandle<>));
|
||||||
@ -424,7 +424,7 @@
|
|||||||
{
|
{
|
||||||
x.WithMicrosoftLogging(log =>
|
x.WithMicrosoftLogging(log =>
|
||||||
{
|
{
|
||||||
log.AddConsole(LogLevel.Debug);
|
//log.AddConsole(LogLevel.Debug);
|
||||||
})
|
})
|
||||||
.WithJsonSerializer()
|
.WithJsonSerializer()
|
||||||
.WithHandle(typeof(InMemoryJsonHandle<>));
|
.WithHandle(typeof(InMemoryJsonHandle<>));
|
||||||
|
@ -164,7 +164,13 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
else if (result.MessageType == WebSocketMessageType.Close)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +216,13 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
else if (result.MessageType == WebSocketMessageType.Close)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,13 +285,13 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||||
|
|
||||||
while (!result.CloseStatus.HasValue)
|
while (!result.CloseStatus.HasValue)
|
||||||
{
|
{
|
||||||
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
|
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
|
||||||
|
|
||||||
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
|
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<AssemblyName>Ocelot.Benchmarks</AssemblyName>
|
<AssemblyName>Ocelot.Benchmarks</AssemblyName>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<PackageId>Ocelot.Benchmarks</PackageId>
|
<PackageId>Ocelot.Benchmarks</PackageId>
|
||||||
@ -19,8 +19,12 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BenchmarkDotNet" Version="0.11.5" />
|
<PackageReference Include="BenchmarkDotNet" Version="0.11.5" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Hosting;
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ocelot.Administration;
|
using Ocelot.Administration;
|
||||||
using Ocelot.Cache;
|
using Ocelot.Cache;
|
||||||
@ -29,15 +30,15 @@ namespace Ocelot.IntegrationTests
|
|||||||
private HttpClient _httpClient;
|
private HttpClient _httpClient;
|
||||||
private readonly HttpClient _httpClientTwo;
|
private readonly HttpClient _httpClientTwo;
|
||||||
private HttpResponseMessage _response;
|
private HttpResponseMessage _response;
|
||||||
private IWebHost _builder;
|
private IHost _builder;
|
||||||
private IWebHostBuilder _webHostBuilder;
|
private IHostBuilder _webHostBuilder;
|
||||||
private string _ocelotBaseUrl;
|
private string _ocelotBaseUrl;
|
||||||
private BearerToken _token;
|
private BearerToken _token;
|
||||||
private IWebHostBuilder _webHostBuilderTwo;
|
private IHostBuilder _webHostBuilderTwo;
|
||||||
private IWebHost _builderTwo;
|
private IHost _builderTwo;
|
||||||
private IWebHost _identityServerBuilder;
|
private IHost _identityServerBuilder;
|
||||||
private IWebHost _fooServiceBuilder;
|
private IHost _fooServiceBuilder;
|
||||||
private IWebHost _barServiceBuilder;
|
private IHost _barServiceBuilder;
|
||||||
|
|
||||||
public AdministrationTests()
|
public AdministrationTests()
|
||||||
{
|
{
|
||||||
@ -220,7 +221,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
UpstreamHttpMethod = new List<string> { "get" },
|
UpstreamHttpMethod = new List<string> { "get" },
|
||||||
UpstreamPathTemplate = "/test"
|
UpstreamPathTemplate = "/test"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var updatedConfiguration = new FileConfiguration
|
var updatedConfiguration = new FileConfiguration
|
||||||
@ -476,56 +477,59 @@ namespace Ocelot.IntegrationTests
|
|||||||
|
|
||||||
private void GivenThereIsAnIdentityServerOn(string url, string apiName)
|
private void GivenThereIsAnIdentityServerOn(string url, string apiName)
|
||||||
{
|
{
|
||||||
_identityServerBuilder = new WebHostBuilder()
|
_identityServerBuilder = Host.CreateDefaultBuilder()
|
||||||
.UseUrls(url)
|
.ConfigureWebHost(webBuilder =>
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.ConfigureServices(services =>
|
|
||||||
{
|
{
|
||||||
services.AddLogging();
|
webBuilder.UseUrls(url)
|
||||||
services.AddIdentityServer()
|
.UseKestrel()
|
||||||
.AddDeveloperSigningCredential()
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.ConfigureServices(services =>
|
||||||
|
{
|
||||||
|
services.AddLogging();
|
||||||
|
services.AddIdentityServer()
|
||||||
|
.AddDeveloperSigningCredential()
|
||||||
.AddInMemoryApiResources(new List<ApiResource>
|
.AddInMemoryApiResources(new List<ApiResource>
|
||||||
{
|
{
|
||||||
new ApiResource
|
new ApiResource
|
||||||
|
{
|
||||||
|
Name = apiName,
|
||||||
|
Description = apiName,
|
||||||
|
Enabled = true,
|
||||||
|
DisplayName = apiName,
|
||||||
|
Scopes = new List<Scope>()
|
||||||
{
|
{
|
||||||
Name = apiName,
|
new Scope(apiName),
|
||||||
Description = apiName,
|
},
|
||||||
Enabled = true,
|
},
|
||||||
DisplayName = apiName,
|
|
||||||
Scopes = new List<Scope>()
|
|
||||||
{
|
|
||||||
new Scope(apiName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.AddInMemoryClients(new List<Client>
|
.AddInMemoryClients(new List<Client>
|
||||||
{
|
{
|
||||||
new Client
|
new Client
|
||||||
{
|
{
|
||||||
ClientId = apiName,
|
ClientId = apiName,
|
||||||
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
|
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
|
||||||
ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
|
ClientSecrets = new List<Secret> { new Secret("secret".Sha256()) },
|
||||||
AllowedScopes = new List<string> { apiName },
|
AllowedScopes = new List<string> { apiName },
|
||||||
AccessTokenType = AccessTokenType.Jwt,
|
AccessTokenType = AccessTokenType.Jwt,
|
||||||
Enabled = true
|
Enabled = true
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.AddTestUsers(new List<TestUser>
|
.AddTestUsers(new List<TestUser>
|
||||||
{
|
{
|
||||||
new TestUser
|
new TestUser
|
||||||
{
|
{
|
||||||
Username = "test",
|
Username = "test",
|
||||||
Password = "test",
|
Password = "test",
|
||||||
SubjectId = "1231231"
|
SubjectId = "1231231"
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.UseIdentityServer();
|
app.UseIdentityServer();
|
||||||
})
|
}
|
||||||
.Build();
|
);
|
||||||
|
}).Build();
|
||||||
|
|
||||||
_identityServerBuilder.Start();
|
_identityServerBuilder.Start();
|
||||||
|
|
||||||
@ -540,28 +544,32 @@ namespace Ocelot.IntegrationTests
|
|||||||
{
|
{
|
||||||
_httpClientTwo.BaseAddress = new Uri(baseUrl);
|
_httpClientTwo.BaseAddress = new Uri(baseUrl);
|
||||||
|
|
||||||
_webHostBuilderTwo = new WebHostBuilder()
|
_webHostBuilderTwo = Host.CreateDefaultBuilder()
|
||||||
.UseUrls(baseUrl)
|
.ConfigureWebHost(webBuilder =>
|
||||||
.UseKestrel()
|
{
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
webBuilder.UseUrls(baseUrl)
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
.UseKestrel()
|
||||||
{
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||||
var env = hostingContext.HostingEnvironment;
|
{
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("ocelot.json", false, false);
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
config.AddEnvironmentVariables();
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
})
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
.ConfigureServices(x =>
|
config.AddEnvironmentVariables();
|
||||||
{
|
})
|
||||||
x.AddOcelot()
|
.ConfigureServices(x =>
|
||||||
|
{
|
||||||
|
x.AddMvc(option => option.EnableEndpointRouting = false);
|
||||||
|
x.AddOcelot()
|
||||||
.AddAdministration("/administration", "secret");
|
.AddAdministration("/administration", "secret");
|
||||||
})
|
})
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.UseOcelot().Wait();
|
app.UseOcelot().Wait();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
_builderTwo = _webHostBuilderTwo.Build();
|
_builderTwo = _webHostBuilderTwo.Build();
|
||||||
|
|
||||||
@ -654,29 +662,33 @@ namespace Ocelot.IntegrationTests
|
|||||||
|
|
||||||
private void GivenOcelotIsRunningWithIdentityServerSettings(Action<IdentityServerAuthenticationOptions> configOptions)
|
private void GivenOcelotIsRunningWithIdentityServerSettings(Action<IdentityServerAuthenticationOptions> configOptions)
|
||||||
{
|
{
|
||||||
_webHostBuilder = new WebHostBuilder()
|
_webHostBuilder = Host.CreateDefaultBuilder()
|
||||||
.UseUrls(_ocelotBaseUrl)
|
.ConfigureWebHost(webBuilder =>
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
webBuilder.UseUrls(_ocelotBaseUrl)
|
||||||
var env = hostingContext.HostingEnvironment;
|
.UseKestrel()
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
.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);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json", false, false);
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x =>
|
.ConfigureServices(x =>
|
||||||
{
|
{
|
||||||
x.AddSingleton(_webHostBuilder);
|
x.AddMvc(option => option.EnableEndpointRouting = false);
|
||||||
x.AddOcelot()
|
x.AddSingleton(_webHostBuilder);
|
||||||
.AddAdministration("/administration", configOptions);
|
x.AddOcelot()
|
||||||
})
|
.AddAdministration("/administration", configOptions);
|
||||||
|
})
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.UseOcelot().Wait();
|
app.UseOcelot().Wait();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
_builder = _webHostBuilder.Build();
|
_builder = _webHostBuilder.Build();
|
||||||
|
|
||||||
@ -685,27 +697,31 @@ namespace Ocelot.IntegrationTests
|
|||||||
|
|
||||||
private void GivenOcelotIsRunning()
|
private void GivenOcelotIsRunning()
|
||||||
{
|
{
|
||||||
_webHostBuilder = new WebHostBuilder()
|
_webHostBuilder = Host.CreateDefaultBuilder()
|
||||||
.UseUrls(_ocelotBaseUrl)
|
.ConfigureWebHost(webBuilder =>
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
webBuilder.UseUrls(_ocelotBaseUrl)
|
||||||
var env = hostingContext.HostingEnvironment;
|
.UseKestrel()
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
.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);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json", false, false);
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x =>
|
.ConfigureServices(x =>
|
||||||
{
|
{
|
||||||
x.AddOcelot()
|
x.AddMvc(s => s.EnableEndpointRouting = false);
|
||||||
|
x.AddOcelot()
|
||||||
.AddAdministration("/administration", "secret");
|
.AddAdministration("/administration", "secret");
|
||||||
})
|
})
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.UseOcelot().Wait();
|
app.UseOcelot().Wait();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
_builder = _webHostBuilder.Build();
|
_builder = _webHostBuilder.Build();
|
||||||
@ -715,30 +731,34 @@ namespace Ocelot.IntegrationTests
|
|||||||
|
|
||||||
private void GivenOcelotIsRunningWithNoWebHostBuilder(string baseUrl)
|
private void GivenOcelotIsRunningWithNoWebHostBuilder(string baseUrl)
|
||||||
{
|
{
|
||||||
_webHostBuilder = new WebHostBuilder()
|
_webHostBuilder = Host.CreateDefaultBuilder()
|
||||||
.UseUrls(_ocelotBaseUrl)
|
.ConfigureWebHost(webBuilder =>
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
webBuilder.UseUrls(_ocelotBaseUrl)
|
||||||
var env = hostingContext.HostingEnvironment;
|
.UseKestrel()
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
.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);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json", false, false);
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x =>
|
.ConfigureServices(x =>
|
||||||
{
|
{
|
||||||
x.AddSingleton(_webHostBuilder);
|
x.AddMvc(option => option.EnableEndpointRouting = false);
|
||||||
x.AddOcelot()
|
x.AddSingleton(_webHostBuilder);
|
||||||
|
x.AddOcelot()
|
||||||
.AddAdministration("/administration", "secret");
|
.AddAdministration("/administration", "secret");
|
||||||
})
|
})
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.UseOcelot().Wait();
|
app.UseOcelot().Wait();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
_builder = _webHostBuilder.Build();
|
_builder = _webHostBuilder.Build();
|
||||||
|
|
||||||
_builder.Start();
|
_builder.Start();
|
||||||
@ -797,42 +817,46 @@ namespace Ocelot.IntegrationTests
|
|||||||
|
|
||||||
private void GivenThereIsAFooServiceRunningOn(string baseUrl)
|
private void GivenThereIsAFooServiceRunningOn(string baseUrl)
|
||||||
{
|
{
|
||||||
_fooServiceBuilder = new WebHostBuilder()
|
_fooServiceBuilder = Host.CreateDefaultBuilder()
|
||||||
.UseUrls(baseUrl)
|
.ConfigureWebHost(webBuilder =>
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
{
|
||||||
app.UsePathBase("/foo");
|
webBuilder.UseUrls(baseUrl)
|
||||||
app.Run(async context =>
|
.UseKestrel()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseIISIntegration()
|
||||||
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = 200;
|
app.UsePathBase("/foo");
|
||||||
await context.Response.WriteAsync("foo");
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = 200;
|
||||||
|
await context.Response.WriteAsync("foo");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})
|
}).Build();
|
||||||
.Build();
|
|
||||||
|
|
||||||
_fooServiceBuilder.Start();
|
_fooServiceBuilder.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsABarServiceRunningOn(string baseUrl)
|
private void GivenThereIsABarServiceRunningOn(string baseUrl)
|
||||||
{
|
{
|
||||||
_barServiceBuilder = new WebHostBuilder()
|
_barServiceBuilder = Host.CreateDefaultBuilder()
|
||||||
.UseUrls(baseUrl)
|
.ConfigureWebHost(webBuilder =>
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
{
|
||||||
app.UsePathBase("/bar");
|
webBuilder.UseUrls(baseUrl)
|
||||||
app.Run(async context =>
|
.UseKestrel()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseIISIntegration()
|
||||||
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = 200;
|
app.UsePathBase("/bar");
|
||||||
await context.Response.WriteAsync("bar");
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = 200;
|
||||||
|
await context.Response.WriteAsync("bar");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})
|
}).Build();
|
||||||
.Build();
|
|
||||||
|
|
||||||
_barServiceBuilder.Start();
|
_barServiceBuilder.Start();
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ namespace Ocelot.IntegrationTests
|
|||||||
using global::CacheManager.Core;
|
using global::CacheManager.Core;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ocelot.Administration;
|
using Ocelot.Administration;
|
||||||
@ -25,15 +27,10 @@ namespace Ocelot.IntegrationTests
|
|||||||
private HttpClient _httpClient;
|
private HttpClient _httpClient;
|
||||||
private readonly HttpClient _httpClientTwo;
|
private readonly HttpClient _httpClientTwo;
|
||||||
private HttpResponseMessage _response;
|
private HttpResponseMessage _response;
|
||||||
private IWebHost _builder;
|
private IHost _builder;
|
||||||
private IWebHostBuilder _webHostBuilder;
|
private IHostBuilder _webHostBuilder;
|
||||||
private string _ocelotBaseUrl;
|
private string _ocelotBaseUrl;
|
||||||
private BearerToken _token;
|
private BearerToken _token;
|
||||||
private IWebHostBuilder _webHostBuilderTwo;
|
|
||||||
private IWebHost _builderTwo;
|
|
||||||
private IWebHost _identityServerBuilder;
|
|
||||||
private IWebHost _fooServiceBuilder;
|
|
||||||
private IWebHost _barServiceBuilder;
|
|
||||||
|
|
||||||
public CacheManagerTests()
|
public CacheManagerTests()
|
||||||
{
|
{
|
||||||
@ -61,7 +58,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 80,
|
Port = 80,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
DownstreamScheme = "https",
|
DownstreamScheme = "https",
|
||||||
DownstreamPathTemplate = "/",
|
DownstreamPathTemplate = "/",
|
||||||
@ -69,8 +66,8 @@ namespace Ocelot.IntegrationTests
|
|||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
FileCacheOptions = new FileCacheOptions
|
FileCacheOptions = new FileCacheOptions
|
||||||
{
|
{
|
||||||
TtlSeconds = 10
|
TtlSeconds = 10,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
new FileReRoute()
|
new FileReRoute()
|
||||||
{
|
{
|
||||||
@ -80,7 +77,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 80,
|
Port = 80,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
DownstreamScheme = "https",
|
DownstreamScheme = "https",
|
||||||
DownstreamPathTemplate = "/",
|
DownstreamPathTemplate = "/",
|
||||||
@ -88,10 +85,10 @@ namespace Ocelot.IntegrationTests
|
|||||||
UpstreamPathTemplate = "/test",
|
UpstreamPathTemplate = "/test",
|
||||||
FileCacheOptions = new FileCacheOptions
|
FileCacheOptions = new FileCacheOptions
|
||||||
{
|
{
|
||||||
TtlSeconds = 10
|
TtlSeconds = 10,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var regionToClear = "gettest";
|
var regionToClear = "gettest";
|
||||||
@ -118,7 +115,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
new KeyValuePair<string, string>("client_id", "admin"),
|
new KeyValuePair<string, string>("client_id", "admin"),
|
||||||
new KeyValuePair<string, string>("client_secret", "secret"),
|
new KeyValuePair<string, string>("client_secret", "secret"),
|
||||||
new KeyValuePair<string, string>("scope", "admin"),
|
new KeyValuePair<string, string>("scope", "admin"),
|
||||||
new KeyValuePair<string, string>("grant_type", "client_credentials")
|
new KeyValuePair<string, string>("grant_type", "client_credentials"),
|
||||||
};
|
};
|
||||||
var content = new FormUrlEncodedContent(formData);
|
var content = new FormUrlEncodedContent(formData);
|
||||||
|
|
||||||
@ -133,16 +130,13 @@ namespace Ocelot.IntegrationTests
|
|||||||
|
|
||||||
private void GivenOcelotIsRunning()
|
private void GivenOcelotIsRunning()
|
||||||
{
|
{
|
||||||
_webHostBuilder = new WebHostBuilder()
|
_webHostBuilder = Host.CreateDefaultBuilder()
|
||||||
.UseUrls(_ocelotBaseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
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.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
@ -151,20 +145,26 @@ namespace Ocelot.IntegrationTests
|
|||||||
Action<ConfigurationBuilderCachePart> settings = (s) =>
|
Action<ConfigurationBuilderCachePart> settings = (s) =>
|
||||||
{
|
{
|
||||||
s.WithMicrosoftLogging(log =>
|
s.WithMicrosoftLogging(log =>
|
||||||
{
|
{
|
||||||
log.AddConsole(LogLevel.Debug);
|
//log.AddConsole(LogLevel.Debug);
|
||||||
})
|
})
|
||||||
.WithDictionaryHandle();
|
.WithDictionaryHandle();
|
||||||
};
|
};
|
||||||
|
x.AddMvc(option => option.EnableEndpointRouting = false);
|
||||||
x.AddOcelot()
|
x.AddOcelot()
|
||||||
.AddCacheManager(settings)
|
.AddCacheManager(settings)
|
||||||
.AddAdministration("/administration", "secret");
|
.AddAdministration("/administration", "secret");
|
||||||
})
|
})
|
||||||
|
.ConfigureWebHost(webBuilder =>
|
||||||
|
{
|
||||||
|
webBuilder.UseUrls(_ocelotBaseUrl)
|
||||||
|
.UseKestrel()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.UseOcelot().Wait();
|
app.UseOcelot().Wait();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
_builder = _webHostBuilder.Build();
|
_builder = _webHostBuilder.Build();
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
Environment.SetEnvironmentVariable("OCELOT_CERTIFICATE_PASSWORD", "");
|
Environment.SetEnvironmentVariable("OCELOT_CERTIFICATE_PASSWORD", "");
|
||||||
_builder?.Dispose();
|
_builder?.Dispose();
|
||||||
_httpClient?.Dispose();
|
_httpClient?.Dispose();
|
||||||
_identityServerBuilder?.Dispose();
|
//_identityServerBuilder?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<AssemblyName>Ocelot.IntegrationTests</AssemblyName>
|
<AssemblyName>Ocelot.IntegrationTests</AssemblyName>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<PackageId>Ocelot.IntegrationTests</PackageId>
|
<PackageId>Ocelot.IntegrationTests</PackageId>
|
||||||
@ -29,30 +29,33 @@
|
|||||||
<ProjectReference Include="..\..\src\Ocelot.Provider.Polly\Ocelot.Provider.Polly.csproj" />
|
<ProjectReference Include="..\..\src\Ocelot.Provider.Polly\Ocelot.Provider.Polly.csproj" />
|
||||||
<ProjectReference Include="..\..\src\Ocelot.Provider.Rafty\Ocelot.Provider.Rafty.csproj" />
|
<ProjectReference Include="..\..\src\Ocelot.Provider.Rafty\Ocelot.Provider.Rafty.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
<PackageReference Include="Microsoft.Data.SQLite" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Data.SQLite" Version="2.2.4" />
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.4" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
<PackageReference Include="Shouldly" Version="3.0.2" />
|
<PackageReference Include="Shouldly" Version="4.0.0-beta0002" />
|
||||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||||
<PackageReference Include="Microsoft.Data.SQLite" Version="2.2.4" />
|
<PackageReference Include="Microsoft.Data.SQLite" Version="3.0.0" />
|
||||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
|
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
|
||||||
<PackageReference Include="IdentityServer4" Version="2.4.0" />
|
<PackageReference Include="IdentityServer4" Version="3.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -54,12 +54,12 @@ namespace Ocelot.IntegrationTests
|
|||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51879,
|
Port = 51879,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => GivenThereIsAConfiguration(configuration))
|
this.Given(x => GivenThereIsAConfiguration(configuration))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<AssemblyName>Ocelot.ManualTest</AssemblyName>
|
<AssemblyName>Ocelot.ManualTest</AssemblyName>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
@ -28,16 +28,18 @@
|
|||||||
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
|
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.4" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -32,12 +32,12 @@ namespace Ocelot.ManualTest
|
|||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
{
|
{
|
||||||
s.AddAuthentication()
|
s.AddAuthentication();
|
||||||
.AddJwtBearer("TestKey", x =>
|
//.AddJwtBearer("TestKey", x =>
|
||||||
{
|
//{
|
||||||
x.Authority = "test";
|
// x.Authority = "test";
|
||||||
x.Audience = "test";
|
// x.Audience = "test";
|
||||||
});
|
//});
|
||||||
|
|
||||||
s.AddSingleton<QosDelegatingHandlerDelegate>((x, t) => new FakeHandler());
|
s.AddSingleton<QosDelegatingHandlerDelegate>((x, t) => new FakeHandler());
|
||||||
s.AddOcelot()
|
s.AddOcelot()
|
||||||
|
@ -2,14 +2,15 @@ namespace Ocelot.UnitTests.Administration
|
|||||||
{
|
{
|
||||||
using IdentityServer4.AccessTokenValidation;
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting.Internal;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Moq;
|
||||||
using Ocelot.Administration;
|
using Ocelot.Administration;
|
||||||
using Ocelot.DependencyInjection;
|
using Ocelot.DependencyInjection;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@ -25,9 +26,19 @@ namespace Ocelot.UnitTests.Administration
|
|||||||
{
|
{
|
||||||
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
||||||
_services = new ServiceCollection();
|
_services = new ServiceCollection();
|
||||||
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
|
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
|
||||||
_services.AddSingleton(_configRoot);
|
_services.AddSingleton(_configRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IWebHostEnvironment GetHostingEnvironment()
|
||||||
|
{
|
||||||
|
var environment = new Mock<IWebHostEnvironment>();
|
||||||
|
environment
|
||||||
|
.Setup(e => e.ApplicationName)
|
||||||
|
.Returns(typeof(OcelotAdministrationBuilderTests).GetTypeInfo().Assembly.GetName().Name);
|
||||||
|
|
||||||
|
return environment.Object;
|
||||||
|
}
|
||||||
|
|
||||||
//keep
|
//keep
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
{
|
{
|
||||||
using global::CacheManager.Core;
|
using global::CacheManager.Core;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting.Internal;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting.Internal;
|
||||||
|
using Moq;
|
||||||
using Ocelot.Cache;
|
using Ocelot.Cache;
|
||||||
using Ocelot.Cache.CacheManager;
|
using Ocelot.Cache.CacheManager;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
@ -14,6 +15,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@ -30,11 +32,21 @@
|
|||||||
{
|
{
|
||||||
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
||||||
_services = new ServiceCollection();
|
_services = new ServiceCollection();
|
||||||
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
|
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
|
||||||
_services.AddSingleton(_configRoot);
|
_services.AddSingleton(_configRoot);
|
||||||
_maxRetries = 100;
|
_maxRetries = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IWebHostEnvironment GetHostingEnvironment()
|
||||||
|
{
|
||||||
|
var environment = new Mock<IWebHostEnvironment>();
|
||||||
|
environment
|
||||||
|
.Setup(e => e.ApplicationName)
|
||||||
|
.Returns(typeof(OcelotBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name);
|
||||||
|
|
||||||
|
return environment.Object;
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_set_up_cache_manager()
|
public void should_set_up_cache_manager()
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
public class DiskFileConfigurationRepositoryTests : IDisposable
|
public class DiskFileConfigurationRepositoryTests : IDisposable
|
||||||
{
|
{
|
||||||
private readonly Mock<IHostingEnvironment> _hostingEnvironment;
|
private readonly Mock<IWebHostEnvironment> _hostingEnvironment;
|
||||||
private IFileConfigurationRepository _repo;
|
private IFileConfigurationRepository _repo;
|
||||||
private string _environmentSpecificPath;
|
private string _environmentSpecificPath;
|
||||||
private string _ocelotJsonPath;
|
private string _ocelotJsonPath;
|
||||||
@ -33,7 +33,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
_semaphore = new SemaphoreSlim(1, 1);
|
_semaphore = new SemaphoreSlim(1, 1);
|
||||||
_semaphore.Wait();
|
_semaphore.Wait();
|
||||||
_hostingEnvironment = new Mock<IHostingEnvironment>();
|
_hostingEnvironment = new Mock<IWebHostEnvironment>();
|
||||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||||
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
|
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
namespace Ocelot.UnitTests.Consul
|
namespace Ocelot.UnitTests.Consul
|
||||||
{
|
{
|
||||||
using global::Consul;
|
using global::Consul;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ocelot.Cache;
|
using Ocelot.Cache;
|
||||||
@ -23,8 +24,8 @@
|
|||||||
public class ConsulFileConfigurationRepositoryTests
|
public class ConsulFileConfigurationRepositoryTests
|
||||||
{
|
{
|
||||||
private ConsulFileConfigurationRepository _repo;
|
private ConsulFileConfigurationRepository _repo;
|
||||||
|
private Mock<IOptions<FileConfiguration>> _options;
|
||||||
private Mock<IOcelotCache<FileConfiguration>> _cache;
|
private Mock<IOcelotCache<FileConfiguration>> _cache;
|
||||||
private Mock<IInternalConfigurationRepository> _internalRepo;
|
|
||||||
private Mock<IConsulClientFactory> _factory;
|
private Mock<IConsulClientFactory> _factory;
|
||||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||||
private Mock<IConsulClient> _client;
|
private Mock<IConsulClient> _client;
|
||||||
@ -36,9 +37,9 @@
|
|||||||
public ConsulFileConfigurationRepositoryTests()
|
public ConsulFileConfigurationRepositoryTests()
|
||||||
{
|
{
|
||||||
_cache = new Mock<IOcelotCache<FileConfiguration>>();
|
_cache = new Mock<IOcelotCache<FileConfiguration>>();
|
||||||
_internalRepo = new Mock<IInternalConfigurationRepository>();
|
|
||||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||||
|
|
||||||
|
_options = new Mock<IOptions<FileConfiguration>>();
|
||||||
_factory = new Mock<IConsulClientFactory>();
|
_factory = new Mock<IConsulClientFactory>();
|
||||||
_client = new Mock<IConsulClient>();
|
_client = new Mock<IConsulClient>();
|
||||||
_kvEndpoint = new Mock<IKVEndpoint>();
|
_kvEndpoint = new Mock<IKVEndpoint>();
|
||||||
@ -51,11 +52,9 @@
|
|||||||
.Setup(x => x.Get(It.IsAny<ConsulRegistryConfiguration>()))
|
.Setup(x => x.Get(It.IsAny<ConsulRegistryConfiguration>()))
|
||||||
.Returns(_client.Object);
|
.Returns(_client.Object);
|
||||||
|
|
||||||
_internalRepo
|
_options
|
||||||
.Setup(x => x.Get())
|
.SetupGet(x => x.Value)
|
||||||
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "", new ServiceProviderConfigurationBuilder().Build(), "", It.IsAny<LoadBalancerOptions>(), It.IsAny<string>(), It.IsAny<QoSOptions>(), It.IsAny<HttpHandlerOptions>())));
|
.Returns(() => _fileConfiguration);
|
||||||
|
|
||||||
_repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -85,7 +84,10 @@
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_get_null_config()
|
public void should_get_null_config()
|
||||||
{
|
{
|
||||||
this.Given(_ => GivenFetchFromConsulReturnsNull())
|
var config = FakeFileConfiguration();
|
||||||
|
|
||||||
|
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||||
|
.Given(_ => GivenFetchFromConsulReturnsNull())
|
||||||
.When(_ => WhenIGetTheConfiguration())
|
.When(_ => WhenIGetTheConfiguration())
|
||||||
.Then(_ => ThenTheConfigurationIsNull())
|
.Then(_ => ThenTheConfigurationIsNull())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -136,14 +138,8 @@
|
|||||||
|
|
||||||
private void GivenTheConfigKeyComesFromFileConfig(string key)
|
private void GivenTheConfigKeyComesFromFileConfig(string key)
|
||||||
{
|
{
|
||||||
_internalRepo
|
_fileConfiguration.GlobalConfiguration.ServiceDiscoveryProvider.ConfigurationKey = key;
|
||||||
.Setup(x => x.Get())
|
_repo = new ConsulFileConfigurationRepository(_options.Object, _cache.Object, _factory.Object, _loggerFactory.Object);
|
||||||
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "",
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheConfigurationIsNull()
|
private void ThenTheConfigurationIsNull()
|
||||||
@ -221,6 +217,8 @@
|
|||||||
private void GivenIHaveAConfiguration(FileConfiguration config)
|
private void GivenIHaveAConfiguration(FileConfiguration config)
|
||||||
{
|
{
|
||||||
_fileConfiguration = config;
|
_fileConfiguration = config;
|
||||||
|
|
||||||
|
_repo = new ConsulFileConfigurationRepository(_options.Object, _cache.Object, _factory.Object, _loggerFactory.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FileConfiguration FakeFileConfiguration()
|
private FileConfiguration FakeFileConfiguration()
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
namespace Ocelot.UnitTests.Consul
|
namespace Ocelot.UnitTests.Consul
|
||||||
{
|
{
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting.Internal;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Moq;
|
||||||
using Ocelot.DependencyInjection;
|
using Ocelot.DependencyInjection;
|
||||||
using Provider.Consul;
|
using Provider.Consul;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@ -24,10 +25,21 @@
|
|||||||
{
|
{
|
||||||
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
||||||
_services = new ServiceCollection();
|
_services = new ServiceCollection();
|
||||||
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
|
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
|
||||||
_services.AddSingleton(_configRoot);
|
_services.AddSingleton(_configRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private IWebHostEnvironment GetHostingEnvironment()
|
||||||
|
{
|
||||||
|
var environment = new Mock<IWebHostEnvironment>();
|
||||||
|
environment
|
||||||
|
.Setup(e => e.ApplicationName)
|
||||||
|
.Returns(typeof(OcelotBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name);
|
||||||
|
|
||||||
|
return environment.Object;
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_set_up_consul()
|
public void should_set_up_consul()
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
public class PollingConsulServiceDiscoveryProviderTests
|
public class PollingConsulServiceDiscoveryProviderTests
|
||||||
{
|
{
|
||||||
private readonly int _delay;
|
private readonly int _delay;
|
||||||
private PollConsul _provider;
|
|
||||||
private readonly List<Service> _services;
|
private readonly List<Service> _services;
|
||||||
private readonly Mock<IOcelotLoggerFactory> _factory;
|
private readonly Mock<IOcelotLoggerFactory> _factory;
|
||||||
private readonly Mock<IOcelotLogger> _logger;
|
private readonly Mock<IOcelotLogger> _logger;
|
||||||
@ -56,27 +55,28 @@
|
|||||||
|
|
||||||
private void WhenIGetTheServices(int expected)
|
private void WhenIGetTheServices(int expected)
|
||||||
{
|
{
|
||||||
_provider = new PollConsul(_delay, _factory.Object, _consulServiceDiscoveryProvider.Object);
|
using (var provider = new PollConsul(_delay, _factory.Object, _consulServiceDiscoveryProvider.Object))
|
||||||
|
|
||||||
var result = Wait.WaitFor(3000).Until(() =>
|
|
||||||
{
|
{
|
||||||
try
|
var result = Wait.WaitFor(3000).Until(() =>
|
||||||
{
|
{
|
||||||
_result = _provider.Get().GetAwaiter().GetResult();
|
try
|
||||||
if (_result.Count == expected)
|
|
||||||
{
|
{
|
||||||
return true;
|
_result = provider.Get().GetAwaiter().GetResult();
|
||||||
|
if (_result.Count == expected)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return false;
|
result.ShouldBeTrue();
|
||||||
}
|
}
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
result.ShouldBeTrue();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace Ocelot.UnitTests.Consul
|
using Ocelot.Configuration.Builder;
|
||||||
|
|
||||||
|
namespace Ocelot.UnitTests.Consul
|
||||||
{
|
{
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Moq;
|
using Moq;
|
||||||
@ -29,7 +31,11 @@
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_ConsulServiceDiscoveryProvider()
|
public void should_return_ConsulServiceDiscoveryProvider()
|
||||||
{
|
{
|
||||||
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("", "", 1, "", "", 1), "");
|
var reRoute = new DownstreamReRouteBuilder()
|
||||||
|
.WithServiceName("")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("", "", 1, "", "", 1), reRoute);
|
||||||
provider.ShouldBeOfType<Consul>();
|
provider.ShouldBeOfType<Consul>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,8 +43,15 @@
|
|||||||
public void should_return_PollingConsulServiceDiscoveryProvider()
|
public void should_return_PollingConsulServiceDiscoveryProvider()
|
||||||
{
|
{
|
||||||
var stopsPollerFromPolling = 10000;
|
var stopsPollerFromPolling = 10000;
|
||||||
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("pollconsul", "", 1, "", "", stopsPollerFromPolling), "");
|
|
||||||
provider.ShouldBeOfType<PollConsul>();
|
var reRoute = new DownstreamReRouteBuilder()
|
||||||
|
.WithServiceName("")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("pollconsul", "", 1, "", "", stopsPollerFromPolling), reRoute);
|
||||||
|
var pollProvider = provider as PollConsul;
|
||||||
|
pollProvider.ShouldNotBeNull();
|
||||||
|
pollProvider.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,11 @@
|
|||||||
private FileConfiguration _reRouteB;
|
private FileConfiguration _reRouteB;
|
||||||
private FileConfiguration _aggregate;
|
private FileConfiguration _aggregate;
|
||||||
private FileConfiguration _envSpecific;
|
private FileConfiguration _envSpecific;
|
||||||
private Mock<IHostingEnvironment> _hostingEnvironment;
|
private Mock<IWebHostEnvironment> _hostingEnvironment;
|
||||||
|
|
||||||
public ConfigurationBuilderExtensionsTests()
|
public ConfigurationBuilderExtensionsTests()
|
||||||
{
|
{
|
||||||
_hostingEnvironment = new Mock<IHostingEnvironment>();
|
_hostingEnvironment = new Mock<IWebHostEnvironment>();
|
||||||
// Clean up config files before each test
|
// Clean up config files before each test
|
||||||
var subConfigFiles = new DirectoryInfo(".").GetFiles("ocelot.*.json");
|
var subConfigFiles = new DirectoryInfo(".").GetFiles("ocelot.*.json");
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
namespace Ocelot.UnitTests.DependencyInjection
|
namespace Ocelot.UnitTests.DependencyInjection
|
||||||
{
|
{
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting.Internal;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Moq;
|
||||||
using Ocelot.Configuration.Setter;
|
using Ocelot.Configuration.Setter;
|
||||||
using Ocelot.DependencyInjection;
|
using Ocelot.DependencyInjection;
|
||||||
|
using Ocelot.Infrastructure;
|
||||||
using Ocelot.Middleware.Multiplexer;
|
using Ocelot.Middleware.Multiplexer;
|
||||||
using Ocelot.Requester;
|
using Ocelot.Requester;
|
||||||
using Ocelot.UnitTests.Requester;
|
using Ocelot.UnitTests.Requester;
|
||||||
@ -14,6 +15,7 @@ namespace Ocelot.UnitTests.DependencyInjection
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Reflection;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using static Ocelot.UnitTests.Middleware.UserDefinedResponseAggregatorTests;
|
using static Ocelot.UnitTests.Middleware.UserDefinedResponseAggregatorTests;
|
||||||
@ -31,11 +33,21 @@ namespace Ocelot.UnitTests.DependencyInjection
|
|||||||
{
|
{
|
||||||
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
||||||
_services = new ServiceCollection();
|
_services = new ServiceCollection();
|
||||||
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
|
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
|
||||||
_services.AddSingleton(_configRoot);
|
_services.AddSingleton(_configRoot);
|
||||||
_maxRetries = 100;
|
_maxRetries = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IWebHostEnvironment GetHostingEnvironment()
|
||||||
|
{
|
||||||
|
var environment = new Mock<IWebHostEnvironment>();
|
||||||
|
environment
|
||||||
|
.Setup(e => e.ApplicationName)
|
||||||
|
.Returns(typeof(OcelotBuilderTests).GetTypeInfo().Assembly.GetName().Name);
|
||||||
|
|
||||||
|
return environment.Object;
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_add_specific_delegating_handlers_transient()
|
public void should_add_specific_delegating_handlers_transient()
|
||||||
{
|
{
|
||||||
@ -47,6 +59,17 @@ namespace Ocelot.UnitTests.DependencyInjection
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_add_type_specific_delegating_handlers_transient()
|
||||||
|
{
|
||||||
|
this.Given(x => WhenISetUpOcelotServices())
|
||||||
|
.When(x => AddTypeSpecificTransientDelegatingHandler(typeof(FakeDelegatingHandler)))
|
||||||
|
.And(x => AddTypeSpecificTransientDelegatingHandler(typeof(FakeDelegatingHandlerTwo)))
|
||||||
|
.Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||||
|
.And(x => ThenTheSpecificHandlersAreTransient())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_add_global_delegating_handlers_transient()
|
public void should_add_global_delegating_handlers_transient()
|
||||||
{
|
{
|
||||||
@ -58,6 +81,17 @@ namespace Ocelot.UnitTests.DependencyInjection
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_add_global_type_delegating_handlers_transient()
|
||||||
|
{
|
||||||
|
this.Given(x => WhenISetUpOcelotServices())
|
||||||
|
.When(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandler>())
|
||||||
|
.And(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandlerTwo>())
|
||||||
|
.Then(x => ThenTheProviderIsRegisteredAndReturnsHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||||
|
.And(x => ThenTheGlobalHandlersAreTransient())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_set_up_services()
|
public void should_set_up_services()
|
||||||
{
|
{
|
||||||
@ -114,6 +148,16 @@ namespace Ocelot.UnitTests.DependencyInjection
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_replace_iplaceholder()
|
||||||
|
{
|
||||||
|
this.Given(x => x.WhenISetUpOcelotServices())
|
||||||
|
.When(x => AddConfigPlaceholders())
|
||||||
|
.Then(x => ThenAnExceptionIsntThrown())
|
||||||
|
.And(x => ThenTheIPlaceholderInstanceIsReplaced())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
private void AddSingletonDefinedAggregator<T>()
|
private void AddSingletonDefinedAggregator<T>()
|
||||||
where T : class, IDefinedAggregator
|
where T : class, IDefinedAggregator
|
||||||
{
|
{
|
||||||
@ -126,6 +170,11 @@ namespace Ocelot.UnitTests.DependencyInjection
|
|||||||
_ocelotBuilder.AddTransientDefinedAggregator<T>();
|
_ocelotBuilder.AddTransientDefinedAggregator<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddConfigPlaceholders()
|
||||||
|
{
|
||||||
|
_ocelotBuilder.AddConfigPlaceholders();
|
||||||
|
}
|
||||||
|
|
||||||
private void ThenTheSpecificHandlersAreTransient()
|
private void ThenTheSpecificHandlersAreTransient()
|
||||||
{
|
{
|
||||||
var handlers = _serviceProvider.GetServices<DelegatingHandler>().ToList();
|
var handlers = _serviceProvider.GetServices<DelegatingHandler>().ToList();
|
||||||
@ -156,6 +205,16 @@ namespace Ocelot.UnitTests.DependencyInjection
|
|||||||
_ocelotBuilder.AddDelegatingHandler<T>();
|
_ocelotBuilder.AddDelegatingHandler<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddTypeTransientGlobalDelegatingHandler(Type type)
|
||||||
|
{
|
||||||
|
_ocelotBuilder.AddDelegatingHandler(type, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddTypeSpecificTransientDelegatingHandler(Type type)
|
||||||
|
{
|
||||||
|
_ocelotBuilder.AddDelegatingHandler(type);
|
||||||
|
}
|
||||||
|
|
||||||
private void ThenTheProviderIsRegisteredAndReturnsHandlers<TOne, TWo>()
|
private void ThenTheProviderIsRegisteredAndReturnsHandlers<TOne, TWo>()
|
||||||
{
|
{
|
||||||
_serviceProvider = _services.BuildServiceProvider();
|
_serviceProvider = _services.BuildServiceProvider();
|
||||||
@ -203,6 +262,13 @@ namespace Ocelot.UnitTests.DependencyInjection
|
|||||||
_ocelotBuilder.ShouldBeOfType<OcelotBuilder>();
|
_ocelotBuilder.ShouldBeOfType<OcelotBuilder>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ThenTheIPlaceholderInstanceIsReplaced()
|
||||||
|
{
|
||||||
|
_serviceProvider = _services.BuildServiceProvider();
|
||||||
|
var placeholders = _serviceProvider.GetService<IPlaceholders>();
|
||||||
|
placeholders.ShouldBeOfType<ConfigAwarePlaceholders>();
|
||||||
|
}
|
||||||
|
|
||||||
private void WhenISetUpOcelotServices()
|
private void WhenISetUpOcelotServices()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -0,0 +1,196 @@
|
|||||||
|
using Moq;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||||
|
using Ocelot.Errors;
|
||||||
|
using Ocelot.Infrastructure;
|
||||||
|
using Ocelot.Infrastructure.Claims.Parser;
|
||||||
|
using Ocelot.PathManipulation;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
using Ocelot.UnitTests.Responder;
|
||||||
|
using Ocelot.Values;
|
||||||
|
using Shouldly;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Ocelot.UnitTests.DownstreamPathManipulation
|
||||||
|
{
|
||||||
|
public class ChangeDownstreamPathTemplateTests
|
||||||
|
{
|
||||||
|
private readonly ChangeDownstreamPathTemplate _changeDownstreamPath;
|
||||||
|
private DownstreamPathTemplate _downstreamPathTemplate;
|
||||||
|
private readonly Mock<IClaimsParser> _parser;
|
||||||
|
private List<ClaimToThing> _configuration;
|
||||||
|
private List<Claim> _claims;
|
||||||
|
private Response _result;
|
||||||
|
private Response<string> _claimValue;
|
||||||
|
private List<PlaceholderNameAndValue> _placeholderValues;
|
||||||
|
|
||||||
|
public ChangeDownstreamPathTemplateTests()
|
||||||
|
{
|
||||||
|
_parser = new Mock<IClaimsParser>();
|
||||||
|
_changeDownstreamPath = new ChangeDownstreamPathTemplate(_parser.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_change_downstream_path_request()
|
||||||
|
{
|
||||||
|
var claims = new List<Claim>
|
||||||
|
{
|
||||||
|
new Claim("test", "data"),
|
||||||
|
};
|
||||||
|
var placeHolderValues = new List<PlaceholderNameAndValue>();
|
||||||
|
this.Given(
|
||||||
|
x => x.GivenAClaimToThing(new List<ClaimToThing>
|
||||||
|
{
|
||||||
|
new ClaimToThing("path-key", "", "", 0),
|
||||||
|
}))
|
||||||
|
.And(x => x.GivenClaims(claims))
|
||||||
|
.And(x => x.GivenDownstreamPathTemplate("/api/test/{path-key}"))
|
||||||
|
.And(x => x.GivenPlaceholderNameAndValues(placeHolderValues))
|
||||||
|
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||||
|
.When(x => x.WhenIChangeDownstreamPath())
|
||||||
|
.Then(x => x.ThenTheResultIsSuccess())
|
||||||
|
.And(x => x.ThenClaimDataIsContainedInPlaceHolder("{path-key}", "value"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_replace_existing_placeholder_value()
|
||||||
|
{
|
||||||
|
var claims = new List<Claim>
|
||||||
|
{
|
||||||
|
new Claim("test", "data"),
|
||||||
|
};
|
||||||
|
var placeHolderValues = new List<PlaceholderNameAndValue>
|
||||||
|
{
|
||||||
|
new PlaceholderNameAndValue ("{path-key}", "old_value"),
|
||||||
|
};
|
||||||
|
this.Given(
|
||||||
|
x => x.GivenAClaimToThing(new List<ClaimToThing>
|
||||||
|
{
|
||||||
|
new ClaimToThing("path-key", "", "", 0),
|
||||||
|
}))
|
||||||
|
.And(x => x.GivenClaims(claims))
|
||||||
|
.And(x => x.GivenDownstreamPathTemplate("/api/test/{path-key}"))
|
||||||
|
.And(x => x.GivenPlaceholderNameAndValues(placeHolderValues))
|
||||||
|
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||||
|
.When(x => x.WhenIChangeDownstreamPath())
|
||||||
|
.Then(x => x.ThenTheResultIsSuccess())
|
||||||
|
.And(x => x.ThenClaimDataIsContainedInPlaceHolder("{path-key}", "value"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_error_when_no_placeholder_in_downstream_path()
|
||||||
|
{
|
||||||
|
var claims = new List<Claim>
|
||||||
|
{
|
||||||
|
new Claim("test", "data"),
|
||||||
|
};
|
||||||
|
var placeHolderValues = new List<PlaceholderNameAndValue>();
|
||||||
|
this.Given(
|
||||||
|
x => x.GivenAClaimToThing(new List<ClaimToThing>
|
||||||
|
{
|
||||||
|
new ClaimToThing("path-key", "", "", 0),
|
||||||
|
}))
|
||||||
|
.And(x => x.GivenClaims(claims))
|
||||||
|
.And(x => x.GivenDownstreamPathTemplate("/api/test"))
|
||||||
|
.And(x => x.GivenPlaceholderNameAndValues(placeHolderValues))
|
||||||
|
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||||
|
.When(x => x.WhenIChangeDownstreamPath())
|
||||||
|
.Then(x => x.ThenTheResultIsCouldNotFindPlaceholderError())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
private void should_return_error_when_claim_parser_returns_error()
|
||||||
|
{
|
||||||
|
var claims = new List<Claim>
|
||||||
|
{
|
||||||
|
new Claim("test", "data"),
|
||||||
|
};
|
||||||
|
var placeHolderValues = new List<PlaceholderNameAndValue>();
|
||||||
|
this.Given(
|
||||||
|
x => x.GivenAClaimToThing(new List<ClaimToThing>
|
||||||
|
{
|
||||||
|
new ClaimToThing("path-key", "", "", 0),
|
||||||
|
}))
|
||||||
|
.And(x => x.GivenClaims(claims))
|
||||||
|
.And(x => x.GivenDownstreamPathTemplate("/api/test/{path-key}"))
|
||||||
|
.And(x => x.GivenPlaceholderNameAndValues(placeHolderValues))
|
||||||
|
.And(x => x.GivenTheClaimParserReturns(new ErrorResponse<string>(new List<Error>
|
||||||
|
{
|
||||||
|
new AnyError(),
|
||||||
|
})))
|
||||||
|
.When(x => x.WhenIChangeDownstreamPath())
|
||||||
|
.Then(x => x.ThenTheResultIsError())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenAClaimToThing(List<ClaimToThing> configuration)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenClaims(List<Claim> claims)
|
||||||
|
{
|
||||||
|
_claims = claims;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenDownstreamPathTemplate(string template)
|
||||||
|
{
|
||||||
|
_downstreamPathTemplate = new DownstreamPathTemplate(template);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenPlaceholderNameAndValues(List<PlaceholderNameAndValue> placeholders)
|
||||||
|
{
|
||||||
|
_placeholderValues = placeholders;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheClaimParserReturns(Response<string> claimValue)
|
||||||
|
{
|
||||||
|
_claimValue = claimValue;
|
||||||
|
_parser
|
||||||
|
.Setup(
|
||||||
|
x =>
|
||||||
|
x.GetValue(It.IsAny<IEnumerable<Claim>>(),
|
||||||
|
It.IsAny<string>(),
|
||||||
|
It.IsAny<string>(),
|
||||||
|
It.IsAny<int>()))
|
||||||
|
.Returns(_claimValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenIChangeDownstreamPath()
|
||||||
|
{
|
||||||
|
_result = _changeDownstreamPath.ChangeDownstreamPath(_configuration, _claims,
|
||||||
|
_downstreamPathTemplate, _placeholderValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheResultIsSuccess()
|
||||||
|
{
|
||||||
|
_result.IsError.ShouldBe(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheResultIsCouldNotFindPlaceholderError()
|
||||||
|
{
|
||||||
|
_result.IsError.ShouldBe(true);
|
||||||
|
_result.Errors.Count.ShouldBe(1);
|
||||||
|
_result.Errors.First().ShouldBeOfType<CouldNotFindPlaceholderError>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheResultIsError()
|
||||||
|
{
|
||||||
|
_result.IsError.ShouldBe(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenClaimDataIsContainedInPlaceHolder(string name, string value)
|
||||||
|
{
|
||||||
|
var placeHolder = _placeholderValues.FirstOrDefault(ph => ph.Name == name && ph.Value == value);
|
||||||
|
placeHolder.ShouldNotBeNull();
|
||||||
|
_placeholderValues.Count.ShouldBe(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Moq;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.Configuration.Builder;
|
||||||
|
using Ocelot.DownstreamRouteFinder;
|
||||||
|
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||||
|
using Ocelot.Logging;
|
||||||
|
using Ocelot.Middleware;
|
||||||
|
using Ocelot.PathManipulation;
|
||||||
|
using Ocelot.PathManipulation.Middleware;
|
||||||
|
using Ocelot.Request.Middleware;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
using Ocelot.Values;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Ocelot.UnitTests.DownstreamPathManipulation
|
||||||
|
{
|
||||||
|
public class ClaimsToDownstreamPathMiddlewareTests
|
||||||
|
{
|
||||||
|
private readonly Mock<IChangeDownstreamPathTemplate> _changePath;
|
||||||
|
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||||
|
private Mock<IOcelotLogger> _logger;
|
||||||
|
private ClaimsToDownstreamPathMiddleware _middleware;
|
||||||
|
private DownstreamContext _downstreamContext;
|
||||||
|
private OcelotRequestDelegate _next;
|
||||||
|
|
||||||
|
public ClaimsToDownstreamPathMiddlewareTests()
|
||||||
|
{
|
||||||
|
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
|
||||||
|
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||||
|
_logger = new Mock<IOcelotLogger>();
|
||||||
|
_loggerFactory.Setup(x => x.CreateLogger<ClaimsToDownstreamPathMiddleware>()).Returns(_logger.Object);
|
||||||
|
_next = context => Task.CompletedTask;
|
||||||
|
_changePath = new Mock<IChangeDownstreamPathTemplate>();
|
||||||
|
_downstreamContext.DownstreamRequest = new DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "http://test.com"));
|
||||||
|
_middleware = new ClaimsToDownstreamPathMiddleware(_next, _loggerFactory.Object, _changePath.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_call_add_queries_correctly()
|
||||||
|
{
|
||||||
|
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||||
|
new ReRouteBuilder()
|
||||||
|
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||||
|
.WithDownstreamPathTemplate("any old string")
|
||||||
|
.WithClaimsToDownstreamPath(new List<ClaimToThing>
|
||||||
|
{
|
||||||
|
new ClaimToThing("UserId", "Subject", "", 0),
|
||||||
|
})
|
||||||
|
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||||
|
.Build())
|
||||||
|
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||||
|
.Build());
|
||||||
|
|
||||||
|
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||||
|
.And(x => x.GivenTheChangeDownstreamPathReturnsOk())
|
||||||
|
.When(x => x.WhenICallTheMiddleware())
|
||||||
|
.Then(x => x.ThenChangeDownstreamPathIsCalledCorrectly())
|
||||||
|
.BDDfy();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenICallTheMiddleware()
|
||||||
|
{
|
||||||
|
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheChangeDownstreamPathReturnsOk()
|
||||||
|
{
|
||||||
|
_changePath
|
||||||
|
.Setup(x => x.ChangeDownstreamPath(
|
||||||
|
It.IsAny<List<ClaimToThing>>(),
|
||||||
|
It.IsAny<IEnumerable<Claim>>(),
|
||||||
|
It.IsAny<DownstreamPathTemplate>(),
|
||||||
|
It.IsAny<List<PlaceholderNameAndValue>>()))
|
||||||
|
.Returns(new OkResponse());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenChangeDownstreamPathIsCalledCorrectly()
|
||||||
|
{
|
||||||
|
_changePath
|
||||||
|
.Verify(x => x.ChangeDownstreamPath(
|
||||||
|
It.IsAny<List<ClaimToThing>>(),
|
||||||
|
It.IsAny<IEnumerable<Claim>>(),
|
||||||
|
_downstreamContext.DownstreamReRoute.DownstreamPathTemplate,
|
||||||
|
_downstreamContext.TemplatePlaceholderNameAndValues), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||||
|
{
|
||||||
|
_downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
|
||||||
|
_downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
namespace Ocelot.UnitTests.Eureka
|
namespace Ocelot.UnitTests.Eureka
|
||||||
{
|
{
|
||||||
using Microsoft.AspNetCore.Builder.Internal;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
|
@ -27,7 +27,10 @@
|
|||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
services.AddSingleton<IDiscoveryClient>(client.Object);
|
services.AddSingleton<IDiscoveryClient>(client.Object);
|
||||||
var sp = services.BuildServiceProvider();
|
var sp = services.BuildServiceProvider();
|
||||||
var provider = EurekaProviderFactory.Get(sp, config, null);
|
var reRoute = new DownstreamReRouteBuilder()
|
||||||
|
.WithServiceName("")
|
||||||
|
.Build();
|
||||||
|
var provider = EurekaProviderFactory.Get(sp, config, reRoute);
|
||||||
provider.ShouldBeOfType<Eureka>();
|
provider.ShouldBeOfType<Eureka>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
namespace Ocelot.UnitTests.Infrastructure
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using Moq;
|
||||||
|
using Ocelot.Infrastructure;
|
||||||
|
using Responses;
|
||||||
|
using Shouldly;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
public class ConfigAwarePlaceholdersTests
|
||||||
|
{
|
||||||
|
private readonly IPlaceholders _placeholders;
|
||||||
|
private readonly Mock<IPlaceholders> _basePlaceholders;
|
||||||
|
|
||||||
|
public ConfigAwarePlaceholdersTests()
|
||||||
|
{
|
||||||
|
var configurationBuilder = new ConfigurationBuilder();
|
||||||
|
configurationBuilder.AddJsonFile("appsettings.json");
|
||||||
|
var configuration = configurationBuilder.Build();
|
||||||
|
|
||||||
|
_basePlaceholders = new Mock<IPlaceholders>();
|
||||||
|
_placeholders = new ConfigAwarePlaceholders(configuration, _basePlaceholders.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_value_from_underlying_placeholders()
|
||||||
|
{
|
||||||
|
var baseUrl = "http://www.bbc.co.uk";
|
||||||
|
const string key = "{BaseUrl}";
|
||||||
|
|
||||||
|
_basePlaceholders.Setup(x => x.Get(key)).Returns(new OkResponse<string>(baseUrl));
|
||||||
|
var result = _placeholders.Get(key);
|
||||||
|
result.Data.ShouldBe(baseUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_value_from_config_with_same_name_as_placeholder_if_underlying_placeholder_not_found()
|
||||||
|
{
|
||||||
|
const string expected = "http://foo-bar.co.uk";
|
||||||
|
var baseUrl = "http://www.bbc.co.uk";
|
||||||
|
const string key = "{BaseUrl}";
|
||||||
|
|
||||||
|
_basePlaceholders.Setup(x => x.Get(key)).Returns(new ErrorResponse<string>(new FakeError()));
|
||||||
|
var result = _placeholders.Get(key);
|
||||||
|
result.Data.ShouldBe(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("{TestConfig}")]
|
||||||
|
[InlineData("{TestConfigNested:Child}")]
|
||||||
|
public void should_return_value_from_config(string key)
|
||||||
|
{
|
||||||
|
const string expected = "foo";
|
||||||
|
|
||||||
|
_basePlaceholders.Setup(x => x.Get(key)).Returns(new ErrorResponse<string>(new FakeError()));
|
||||||
|
var result = _placeholders.Get(key);
|
||||||
|
result.Data.ShouldBe(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_call_underyling_when_added()
|
||||||
|
{
|
||||||
|
const string key = "{Test}";
|
||||||
|
Func<Response<string>> func = () => new OkResponse<string>("test)");
|
||||||
|
_placeholders.Add(key, func);
|
||||||
|
_basePlaceholders.Verify(p => p.Add(key, func), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_call_underyling_when_removed()
|
||||||
|
{
|
||||||
|
const string key = "{Test}";
|
||||||
|
_placeholders.Remove(key);
|
||||||
|
_basePlaceholders.Verify(p => p.Remove(key), Times.Once);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,13 @@
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting.Internal;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Moq;
|
||||||
using Ocelot.DependencyInjection;
|
using Ocelot.DependencyInjection;
|
||||||
using Ocelot.Provider.Kubernetes;
|
using Ocelot.Provider.Kubernetes;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@ -24,10 +25,20 @@ namespace Ocelot.UnitTests.Kubernetes
|
|||||||
{
|
{
|
||||||
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
||||||
_services = new ServiceCollection();
|
_services = new ServiceCollection();
|
||||||
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
|
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
|
||||||
_services.AddSingleton(_configRoot);
|
_services.AddSingleton(_configRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IWebHostEnvironment GetHostingEnvironment()
|
||||||
|
{
|
||||||
|
var environment = new Mock<IWebHostEnvironment>();
|
||||||
|
environment
|
||||||
|
.Setup(e => e.ApplicationName)
|
||||||
|
.Returns(typeof(OcelotBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name);
|
||||||
|
|
||||||
|
return environment.Object;
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_set_up_kubernetes()
|
public void should_set_up_kubernetes()
|
||||||
{
|
{
|
||||||
|
@ -10,8 +10,8 @@ namespace Ocelot.UnitTests.Logging
|
|||||||
public class AspDotNetLoggerTests
|
public class AspDotNetLoggerTests
|
||||||
{
|
{
|
||||||
private readonly Mock<ILogger<object>> _coreLogger;
|
private readonly Mock<ILogger<object>> _coreLogger;
|
||||||
|
private readonly Mock<IRequestScopedDataRepository> _repo;
|
||||||
private readonly AspDotNetLogger _logger;
|
private readonly AspDotNetLogger _logger;
|
||||||
private Mock<IRequestScopedDataRepository> _repo;
|
|
||||||
private readonly string _b;
|
private readonly string _b;
|
||||||
private readonly string _a;
|
private readonly string _a;
|
||||||
private readonly Exception _ex;
|
private readonly Exception _ex;
|
||||||
@ -55,7 +55,7 @@ namespace Ocelot.UnitTests.Logging
|
|||||||
{
|
{
|
||||||
_logger.LogError($"a message from {_a} to {_b}", _ex);
|
_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]
|
[Fact]
|
||||||
@ -63,18 +63,18 @@ namespace Ocelot.UnitTests.Logging
|
|||||||
{
|
{
|
||||||
_logger.LogCritical($"a message from {_a} to {_b}", _ex);
|
_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(
|
_coreLogger.Verify(
|
||||||
x => x.Log(
|
x => x.Log(
|
||||||
expectedLogLevel,
|
expectedLogLevel,
|
||||||
It.IsAny<EventId>(),
|
default(EventId),
|
||||||
It.Is<object>(o => o.ToString() == expected),
|
expected,
|
||||||
It.IsAny<Exception>(),
|
ex,
|
||||||
It.IsAny<Func<object, Exception, string>>()), Times.Once);
|
It.IsAny<Func<string, Exception, string>>()), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,17 @@ using System.Threading.Tasks;
|
|||||||
namespace Ocelot.UnitTests.Middleware
|
namespace Ocelot.UnitTests.Middleware
|
||||||
{
|
{
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting.Internal;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Moq;
|
||||||
using Ocelot.DependencyInjection;
|
using Ocelot.DependencyInjection;
|
||||||
using Ocelot.Logging;
|
using Ocelot.Logging;
|
||||||
using Ocelot.Middleware;
|
using Ocelot.Middleware;
|
||||||
using Ocelot.Middleware.Pipeline;
|
using Ocelot.Middleware.Pipeline;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@ -28,11 +29,22 @@ namespace Ocelot.UnitTests.Middleware
|
|||||||
{
|
{
|
||||||
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
||||||
_services = new ServiceCollection();
|
_services = new ServiceCollection();
|
||||||
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
|
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
|
||||||
_services.AddSingleton<IConfiguration>(_configRoot);
|
_services.AddSingleton<IConfiguration>(_configRoot);
|
||||||
_services.AddOcelot();
|
_services.AddOcelot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private IWebHostEnvironment GetHostingEnvironment()
|
||||||
|
{
|
||||||
|
var environment = new Mock<IWebHostEnvironment>();
|
||||||
|
environment
|
||||||
|
.Setup(e => e.ApplicationName)
|
||||||
|
.Returns(typeof(OcelotPiplineBuilderTests).GetTypeInfo().Assembly.GetName().Name);
|
||||||
|
|
||||||
|
return environment.Object;
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_build_generic()
|
public void should_build_generic()
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<AssemblyName>Ocelot.UnitTests</AssemblyName>
|
<AssemblyName>Ocelot.UnitTests</AssemblyName>
|
||||||
<PackageId>Ocelot.UnitTests</PackageId>
|
<PackageId>Ocelot.UnitTests</PackageId>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
@ -46,13 +46,13 @@
|
|||||||
<None Update="idsrv3test.pfx">
|
<None Update="idsrv3test.pfx">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
||||||
@ -60,30 +60,38 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.4" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
|
||||||
<PackageReference Include="Moq" Version="4.10.1" />
|
<PackageReference Include="Moq" Version="4.13.0" />
|
||||||
<PackageReference Include="Shouldly" Version="3.0.2" />
|
<PackageReference Include="Shouldly" Version="4.0.0-beta0002" />
|
||||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
|
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
|
||||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
|
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
|
||||||
<PackageReference Include="IdentityServer4" Version="2.4.0" />
|
<PackageReference Include="IdentityServer4" Version="3.0.1" />
|
||||||
<PackageReference Include="Pivotal.Discovery.ClientCore" Version="2.2.0" />
|
<PackageReference Include="Pivotal.Discovery.ClientCore" Version="2.2.0" />
|
||||||
<PackageReference Include="Consul" Version="0.7.2.6" />
|
<PackageReference Include="Consul" Version="0.7.2.6" />
|
||||||
<PackageReference Include="CacheManager.Core" Version="1.2.0" />
|
<PackageReference Include="CacheManager.Core" Version="2.0.0-beta-1629" />
|
||||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="1.2.0" />
|
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="2.0.0-beta-1629" />
|
||||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.2.0" />
|
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="2.0.0-beta-1629" />
|
||||||
<PackageReference Include="Polly" Version="7.1.0" />
|
<PackageReference Include="Polly" Version="7.1.1" />
|
||||||
<PackageReference Include="Rafty" Version="0.4.4" />
|
<PackageReference Include="Rafty" Version="0.4.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="WebSockets\" />
|
<Folder Include="WebSockets\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
|
||||||
|
<PackageReference Include="coverlet.collector" Version="1.1.0">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -1,15 +1,16 @@
|
|||||||
namespace Ocelot.UnitTests.Rafty
|
namespace Ocelot.UnitTests.Rafty
|
||||||
{
|
{
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting.Internal;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Moq;
|
||||||
using Ocelot.Administration;
|
using Ocelot.Administration;
|
||||||
using Ocelot.DependencyInjection;
|
using Ocelot.DependencyInjection;
|
||||||
using Provider.Rafty;
|
using Provider.Rafty;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@ -25,10 +26,20 @@
|
|||||||
{
|
{
|
||||||
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
||||||
_services = new ServiceCollection();
|
_services = new ServiceCollection();
|
||||||
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
|
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
|
||||||
_services.AddSingleton(_configRoot);
|
_services.AddSingleton(_configRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IWebHostEnvironment GetHostingEnvironment()
|
||||||
|
{
|
||||||
|
var environment = new Mock<IWebHostEnvironment>();
|
||||||
|
environment
|
||||||
|
.Setup(e => e.ApplicationName)
|
||||||
|
.Returns(typeof(OcelotAdministrationBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name);
|
||||||
|
|
||||||
|
return environment.Object;
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_set_up_rafty()
|
public void should_set_up_rafty()
|
||||||
{
|
{
|
||||||
|
@ -69,7 +69,7 @@ namespace Ocelot.UnitTests.RateLimit
|
|||||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||||
.When(x => x.WhenICallTheMiddlewareMultipleTime(2))
|
.When(x => x.WhenICallTheMiddlewareMultipleTime(2))
|
||||||
.Then(x => x.ThenresponseStatusCodeIs200())
|
.Then(x => x.ThenresponseStatusCodeIs200())
|
||||||
.When(x => x.WhenICallTheMiddlewareMultipleTime(2))
|
.When(x => x.WhenICallTheMiddlewareMultipleTime(3))
|
||||||
.Then(x => x.ThenresponseStatusCodeIs429())
|
.Then(x => x.ThenresponseStatusCodeIs429())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
@ -145,8 +145,9 @@ namespace Ocelot.UnitTests.RateLimit
|
|||||||
internal class FakeStream : Stream
|
internal class FakeStream : Stream
|
||||||
{
|
{
|
||||||
public override void Flush()
|
public override void Flush()
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//do nothing
|
||||||
|
//throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Read(byte[] buffer, int offset, int count)
|
public override int Read(byte[] buffer, int offset, int count)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
namespace Ocelot.UnitTests.Request.Mapper
|
namespace Ocelot.UnitTests.Request.Mapper
|
||||||
{
|
{
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Internal;
|
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using Ocelot.Request.Mapper;
|
using Ocelot.Request.Mapper;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
@ -19,6 +18,7 @@
|
|||||||
|
|
||||||
public class RequestMapperTests
|
public class RequestMapperTests
|
||||||
{
|
{
|
||||||
|
private readonly HttpContext _httpContext;
|
||||||
private readonly HttpRequest _inputRequest;
|
private readonly HttpRequest _inputRequest;
|
||||||
|
|
||||||
private readonly RequestMapper _requestMapper;
|
private readonly RequestMapper _requestMapper;
|
||||||
@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
public RequestMapperTests()
|
public RequestMapperTests()
|
||||||
{
|
{
|
||||||
_inputRequest = new DefaultHttpRequest(new DefaultHttpContext());
|
_httpContext = new DefaultHttpContext();
|
||||||
|
_inputRequest = _httpContext.Request;
|
||||||
_requestMapper = new RequestMapper();
|
_requestMapper = new RequestMapper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
test/Ocelot.UnitTests/UnitTests.runsettings
Normal file
23
test/Ocelot.UnitTests/UnitTests.runsettings
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<RunSettings>
|
||||||
|
<DataCollectionRunSettings>
|
||||||
|
<DataCollectors>
|
||||||
|
<DataCollector friendlyName="XPlat code coverage">
|
||||||
|
<Configuration>
|
||||||
|
<Format>opencover</Format>
|
||||||
|
<SingleHit>false</SingleHit>
|
||||||
|
<UseSourceLink>true</UseSourceLink>
|
||||||
|
</Configuration>
|
||||||
|
</DataCollector>
|
||||||
|
</DataCollectors>
|
||||||
|
</DataCollectionRunSettings>
|
||||||
|
<!-- This is a workaround for an issue with Coverlet.Collector > 1.0.0 (see https://github.com/microsoft/vstest/issues/2205)-->
|
||||||
|
<InProcDataCollectionRunSettings>
|
||||||
|
<InProcDataCollectors>
|
||||||
|
<InProcDataCollector assemblyQualifiedName="Coverlet.Collector.DataCollection.CoverletInProcDataCollector, coverlet.collector, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null"
|
||||||
|
friendlyName="XPlat Code Coverage"
|
||||||
|
enabled="True"
|
||||||
|
codebase="coverlet.collector.dll" />
|
||||||
|
</InProcDataCollectors>
|
||||||
|
</InProcDataCollectionRunSettings>
|
||||||
|
</RunSettings>
|
@ -20,5 +20,10 @@
|
|||||||
"port": 5000,
|
"port": 5000,
|
||||||
"hostName": "localhost"
|
"hostName": "localhost"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"BaseUrl": "http://foo-bar.co.uk",
|
||||||
|
"TestConfig": "foo",
|
||||||
|
"TestConfigNested":{
|
||||||
|
"Child": "foo"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Cake" version="0.25.0" />
|
<package id="Cake" version="0.35.0" />
|
||||||
</packages>
|
</packages>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user