mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:22:50 +08:00
Feature/merge configuration files (#316)
* #296 renamed configuration.json to ocelot.json in preparation * removed things we dont need for tests * another file we dont need * removed some async we dont need * refactoring to consolidate configuration code * removed another pointless abstraction * #296 started writing merge code * #296 coming up with ideas for this config merging * #296 still hacking this idea around * #296 will now do a crappy merge on the configuration * #296 change so tests pass on windows
This commit is contained in:
parent
3607c0867e
commit
aa55fe34cb
2
.gitignore
vendored
2
.gitignore
vendored
@ -243,7 +243,7 @@ tools/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
# Ocelot acceptance test config
|
# Ocelot acceptance test config
|
||||||
test/Ocelot.AcceptanceTests/configuration.json
|
test/Ocelot.AcceptanceTests/ocelot.json
|
||||||
|
|
||||||
# Read the docstates
|
# Read the docstates
|
||||||
_build/
|
_build/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
Configuration
|
Configuration
|
||||||
============
|
============
|
||||||
|
|
||||||
An example configuration can be found `here <https://github.com/TomPallister/Ocelot/blob/develop/test/Ocelot.ManualTest/configuration.json>`_.
|
An example configuration can be found `here <https://github.com/TomPallister/Ocelot/blob/develop/test/Ocelot.ManualTest/ocelot.json>`_.
|
||||||
There are two sections to the configuration. An array of ReRoutes and a GlobalConfiguration.
|
There are two sections to the configuration. An array of ReRoutes and a GlobalConfiguration.
|
||||||
The ReRoutes are the objects that tell Ocelot how to treat an upstream request. The Global
|
The ReRoutes are the objects that tell Ocelot how to treat an upstream request. The Global
|
||||||
configuration is a bit hacky and allows overrides of ReRoute specific settings. It's useful
|
configuration is a bit hacky and allows overrides of ReRoute specific settings. It's useful
|
||||||
@ -69,22 +69,6 @@ Here is an example ReRoute configuration, You don't need to set all of these thi
|
|||||||
|
|
||||||
More information on how to use these options is below..
|
More information on how to use these options is below..
|
||||||
|
|
||||||
Follow Redirects / Use CookieContainer
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Use HttpHandlerOptions in ReRoute configuration to set up HttpHandler behavior:
|
|
||||||
|
|
||||||
1. AllowAutoRedirect is a value that indicates whether the request should follow redirection responses. Set it true if the request should automatically
|
|
||||||
follow redirection responses from the Downstream resource; otherwise false. The default value is false.
|
|
||||||
2. UseCookieContainer is a value that indicates whether the handler uses the CookieContainer
|
|
||||||
property to store server cookies and uses these cookies when sending requests. The default value is false. Please note
|
|
||||||
that if you are using the CookieContainer Ocelot caches the HttpClient for each downstream service. This means that all requests
|
|
||||||
to that DownstreamService will share the same cookies. `Issue 274 <https://github.com/ThreeMammals/Ocelot/issues/274>`_ was created because a user
|
|
||||||
noticed that the cookies were being shared. I tried to think of a nice way to handle this but I think it is impossible. If you don't cache the clients
|
|
||||||
that means each request gets a new client and therefore a new cookie container. If you clear the cookies from the cached client container you get race conditions due to inflight
|
|
||||||
requests. This would also mean that subsequent requests dont use the cookies from the previous response! All in all not a great situation. I would avoid setting
|
|
||||||
UseCookieContainer to true unless you have a really really good reason. Just look at your response headers and forward the cookies back with your next request!
|
|
||||||
|
|
||||||
Multiple environments
|
Multiple environments
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@ -99,15 +83,40 @@ to you
|
|||||||
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
|
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
|
||||||
.AddJsonFile("appsettings.json", true, true)
|
.AddJsonFile("appsettings.json", true, true)
|
||||||
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
|
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
|
||||||
.AddJsonFile("configuration.json")
|
.AddJsonFile("ocelot.json")
|
||||||
.AddJsonFile($"configuration.{hostingContext.HostingEnvironment.EnvironmentName}.json")
|
.AddJsonFile($"configuration.{hostingContext.HostingEnvironment.EnvironmentName}.json")
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
|
|
||||||
Ocelot should now use the environment specific configuration and fall back to configuration.json if there isnt one.
|
Ocelot will now use the environment specific configuration and fall back to ocelot.json if there isnt one.
|
||||||
|
|
||||||
You also need to set the corresponding environment variable which is ASPNETCORE_ENVIRONMENT. More info on this can be found in the `asp.net core docs <https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments>`_.
|
You also need to set the corresponding environment variable which is ASPNETCORE_ENVIRONMENT. More info on this can be found in the `asp.net core docs <https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments>`_.
|
||||||
|
|
||||||
|
Merging configuration files
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This feature was requested in `Issue 296 <https://github.com/ThreeMammals/Ocelot/issues/296>`_ and allows users to have multiple configuration files to make managing large configurations easier.
|
||||||
|
|
||||||
|
Instead of adding the configuration directly e.g. AddJsonFile("ocelot.json") you can call AddOcelot() like below.
|
||||||
|
|
||||||
|
.. code-block:: csharp
|
||||||
|
|
||||||
|
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||||
|
{
|
||||||
|
config
|
||||||
|
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
|
||||||
|
.AddJsonFile("appsettings.json", true, true)
|
||||||
|
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
|
||||||
|
.AddOcelot()
|
||||||
|
.AddEnvironmentVariables();
|
||||||
|
})
|
||||||
|
|
||||||
|
In this scenario Ocelot will look for any files that match the pattern ocleot.*.json and then merge these together. If you want to set the GlobalConfiguration property you must have a file called ocelot.global.json.
|
||||||
|
|
||||||
|
The way Ocelot merges the files is basically load them, loop over them, add any ReRoutes, add any AggregateReRoutes and if the file is called ocelot.global.json add the GlobalConfiguration aswell as any ReRoutes or AggregateReRoutes. Ocelot will then save the merged configuration to a file called ocelot.json and this will be used as the source of truth while ocelot is running.
|
||||||
|
|
||||||
|
At the moment there is no validation at this stage it only happens when Ocelot validates the final merged configuration. This is something to be aware of when you are investigating problems. I would advise always checking what is in ocelot.json if you have any problems.
|
||||||
|
|
||||||
Store configuration in consul
|
Store configuration in consul
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@ -119,7 +128,7 @@ If you add the following when you register your services Ocelot will attempt to
|
|||||||
.AddOcelot()
|
.AddOcelot()
|
||||||
.AddStoreOcelotConfigurationInConsul();
|
.AddStoreOcelotConfigurationInConsul();
|
||||||
|
|
||||||
You also need to add the following to your configuration.json. This is how Ocelot
|
You also need to add the following to your ocelot.json. This is how Ocelot
|
||||||
finds your Consul agent and interacts to load and store the configuration from Consul.
|
finds your Consul agent and interacts to load and store the configuration from Consul.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
@ -135,3 +144,19 @@ I decided to create this feature after working on the raft consensus algorithm a
|
|||||||
I guess it means if you want to use Ocelot to its fullest you take on Consul as a dependency for now.
|
I guess it means if you want to use Ocelot to its fullest you take on Consul as a dependency for now.
|
||||||
|
|
||||||
This feature has a 3 second ttl cache before making a new request to your local consul agent.
|
This feature has a 3 second ttl cache before making a new request to your local consul agent.
|
||||||
|
|
||||||
|
Follow Redirects / Use CookieContainer
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Use HttpHandlerOptions in ReRoute configuration to set up HttpHandler behavior:
|
||||||
|
|
||||||
|
1. AllowAutoRedirect is a value that indicates whether the request should follow redirection responses. Set it true if the request should automatically
|
||||||
|
follow redirection responses from the Downstream resource; otherwise false. The default value is false.
|
||||||
|
2. UseCookieContainer is a value that indicates whether the handler uses the CookieContainer
|
||||||
|
property to store server cookies and uses these cookies when sending requests. The default value is false. Please note
|
||||||
|
that if you are using the CookieContainer Ocelot caches the HttpClient for each downstream service. This means that all requests
|
||||||
|
to that DownstreamService will share the same cookies. `Issue 274 <https://github.com/ThreeMammals/Ocelot/issues/274>`_ was created because a user
|
||||||
|
noticed that the cookies were being shared. I tried to think of a nice way to handle this but I think it is impossible. If you don't cache the clients
|
||||||
|
that means each request gets a new client and therefore a new cookie container. If you clear the cookies from the cached client container you get race conditions due to inflight
|
||||||
|
requests. This would also mean that subsequent requests dont use the cookies from the previous response! All in all not a great situation. I would avoid setting
|
||||||
|
UseCookieContainer to true unless you have a really really good reason. Just look at your response headers and forward the cookies back with your next request!
|
||||||
|
@ -40,7 +40,7 @@ Or transient as below...
|
|||||||
.AddTransientDelegatingHandler<FakeHandlerTwo>()
|
.AddTransientDelegatingHandler<FakeHandlerTwo>()
|
||||||
|
|
||||||
Both of these Add methods have a default parameter called global which is set to false. If it is false then the intent of
|
Both of these Add methods have a default parameter called global which is set to false. If it is false then the intent of
|
||||||
the DelegatingHandler is to be applied to specific ReRoutes via configuration.json (more on that later). If it is set to true
|
the DelegatingHandler is to be applied to specific ReRoutes via ocelot.json (more on that later). If it is set to true
|
||||||
then it becomes a global handler and will be applied to all ReRoutes.
|
then it becomes a global handler and will be applied to all ReRoutes.
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
@ -58,7 +58,7 @@ Or transient as below...
|
|||||||
.AddTransientDelegatingHandler<FakeHandler>(true)
|
.AddTransientDelegatingHandler<FakeHandler>(true)
|
||||||
|
|
||||||
Finally if you want ReRoute specific DelegatingHandlers or to order your specific and / or global (more on this later) DelegatingHandlers
|
Finally if you want ReRoute specific DelegatingHandlers or to order your specific and / or global (more on this later) DelegatingHandlers
|
||||||
then you must add the following json to the specific ReRoute in configuration.json. The names in the array must match the class names of your
|
then you must add the following json to the specific ReRoute in ocelot.json. The names in the array must match the class names of your
|
||||||
DelegatingHandlers for Ocelot to match them together.
|
DelegatingHandlers for Ocelot to match them together.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
@ -70,8 +70,8 @@ DelegatingHandlers for Ocelot to match them together.
|
|||||||
|
|
||||||
You can have as many DelegatingHandlers as you want and they are run in the following order:
|
You can have as many DelegatingHandlers as you want and they are run in the following order:
|
||||||
|
|
||||||
1. Any globals that are left in the order they were added to services and are not in the DelegatingHandlers array from configuration.json.
|
1. Any globals that are left in the order they were added to services and are not in the DelegatingHandlers array from ocelot.json.
|
||||||
2. Any non global DelegatingHandlers plus any globals that were in the DelegatingHandlers array from configuration.json ordered as they are in the DelegatingHandlers array.
|
2. Any non global DelegatingHandlers plus any globals that were in the DelegatingHandlers array from ocelot.json ordered as they are in the DelegatingHandlers array.
|
||||||
3. Tracing DelegatingHandler if enabled (see tracing docs).
|
3. Tracing DelegatingHandler if enabled (see tracing docs).
|
||||||
4. QoS DelegatingHandler if enabled (see QoS docs).
|
4. QoS DelegatingHandler if enabled (see QoS docs).
|
||||||
5. The HttpClient sends the HttpRequestMessage.
|
5. The HttpClient sends the HttpRequestMessage.
|
||||||
|
@ -8,7 +8,7 @@ Add to Request
|
|||||||
|
|
||||||
This feature was requestes in `GitHub #313 <https://github.com/ThreeMammals/Ocelot/issues/313>`_.
|
This feature was requestes in `GitHub #313 <https://github.com/ThreeMammals/Ocelot/issues/313>`_.
|
||||||
|
|
||||||
If you want to add a header to your upstream request please add the following to a ReRoute in your configuration.json:
|
If you want to add a header to your upstream request please add the following to a ReRoute in your ocelot.json:
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ Add to Response
|
|||||||
|
|
||||||
This feature was requested in `GitHub #280 <https://github.com/TomPallister/Ocelot/issues/280>`_.
|
This feature was requested in `GitHub #280 <https://github.com/TomPallister/Ocelot/issues/280>`_.
|
||||||
|
|
||||||
If you want to add a header to your downstream response please add the following to a ReRoute in configuration.json.
|
If you want to add a header to your downstream response please add the following to a ReRoute in ocelot.json..
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ The key is "Test" and the value is "http://www.bbc.co.uk/, http://ocelot.com/".
|
|||||||
Pre Downstream Request
|
Pre Downstream Request
|
||||||
^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Add the following to a ReRoute in configuration.json in order to replace http://www.bbc.co.uk/ with http://ocelot.com/. This header will be changed before the request downstream and will be sent to the downstream server.
|
Add the following to a ReRoute in ocelot.json in order to replace http://www.bbc.co.uk/ with http://ocelot.com/. This header will be changed before the request downstream and will be sent to the downstream server.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ Add the following to a ReRoute in configuration.json in order to replace http://
|
|||||||
Post Downstream Request
|
Post Downstream Request
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Add the following to a ReRoute in configuration.json in order to replace http://www.bbc.co.uk/ with http://ocelot.com/. This transformation will take place after Ocelot has received the response from the downstream service.
|
Add the following to a ReRoute in ocelot.json in order to replace http://www.bbc.co.uk/ with http://ocelot.com/. This transformation will take place after Ocelot has received the response from the downstream service.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ You must choose in your configuration which load balancer to use.
|
|||||||
Configuration
|
Configuration
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
The following shows how to set up multiple downstream services for a ReRoute using configuration.json and then select the LeadConnection load balancer. This is the simplest way to get load balancing set up.
|
The following shows how to set up multiple downstream services for a ReRoute using ocelot.json and then select the LeadConnection load balancer. This is the simplest way to get load balancing set up.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ Period - This value specifies the period, such as 1s, 5m, 1h,1d and so on.
|
|||||||
PeriodTimespan - This value specifies that we can retry after a certain number of seconds.
|
PeriodTimespan - This value specifies that we can retry after a certain number of seconds.
|
||||||
Limit - This value specifies the maximum number of requests that a client can make in a defined period.
|
Limit - This value specifies the maximum number of requests that a client can make in a defined period.
|
||||||
|
|
||||||
You can also set the following in the GlobalConfiguration part of configuration.json
|
You can also set the following in the GlobalConfiguration part of ocelot.json
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ architecture with Ocelot.
|
|||||||
|
|
||||||
This feature was requested as part of `Issue 79 <https://github.com/TomPallister/Ocelot/pull/79>`_ and further improvements were made as part of `Issue 298 <https://github.com/TomPallister/Ocelot/issue/298>`_.
|
This feature was requested as part of `Issue 79 <https://github.com/TomPallister/Ocelot/pull/79>`_ and further improvements were made as part of `Issue 298 <https://github.com/TomPallister/Ocelot/issue/298>`_.
|
||||||
|
|
||||||
In order to set this up you must do something like the following in your configuration.json. Here we have specified two normal ReRoutes and each one has a Key property.
|
In order to set this up you must do something like the following in your ocelot.json. Here we have specified two normal ReRoutes and each one has a Key property.
|
||||||
We then specify an Aggregate that composes the two ReRoutes using their keys in the ReRouteKeys list and says then we have the UpstreamPathTemplate which works like a normal ReRoute.
|
We then specify an Aggregate that composes the two ReRoutes using their keys in the ReRouteKeys list and says then we have the UpstreamPathTemplate which works like a normal ReRoute.
|
||||||
Obviously you cannot have duplicate UpstreamPathTemplates between ReRoutes and Aggregates. You can use all of Ocelot's normal ReRoute options apart from RequestIdKey (explained in gotchas below).
|
Obviously you cannot have duplicate UpstreamPathTemplates between ReRoutes and Aggregates. You can use all of Ocelot's normal ReRoute options apart from RequestIdKey (explained in gotchas below).
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ Advanced register your own Aggregators
|
|||||||
Ocelot started with just the basic request aggregation and since then we have added a more advanced method that let's the user take in the responses from the
|
Ocelot started with just the basic request aggregation and since then we have added a more advanced method that let's the user take in the responses from the
|
||||||
downstream services and then aggregate them into a response object.
|
downstream services and then aggregate them into a response object.
|
||||||
|
|
||||||
The configuration.json setup is pretty much the same as the basic aggregation approach apart from you need to add an Aggregator property like below.
|
The ocelot.json setup is pretty much the same as the basic aggregation approach apart from you need to add an Aggregator property like below.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ In order to use the reques tid feature you have two options.
|
|||||||
|
|
||||||
*Global*
|
*Global*
|
||||||
|
|
||||||
In your configuration.json set the following in the GlobalConfiguration section. This will be used for all requests into Ocelot.
|
In your ocelot.json set the following in the GlobalConfiguration section. This will be used for all requests into Ocelot.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ I reccomend using the GlobalConfiguration unless you really need it to be ReRout
|
|||||||
|
|
||||||
*ReRoute*
|
*ReRoute*
|
||||||
|
|
||||||
If you want to override this for a specific ReRoute add the following to configuration.json for the specific ReRoute.
|
If you want to override this for a specific ReRoute add the following to ocelot.json for the specific ReRoute.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
|
@ -145,9 +145,9 @@ Priority
|
|||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
In `Issue 270 <https://github.com/TomPallister/Ocelot/pull/270>`_ I finally decided to expose the ReRoute priority in
|
In `Issue 270 <https://github.com/TomPallister/Ocelot/pull/270>`_ I finally decided to expose the ReRoute priority in
|
||||||
configuration.json. This means you can decide in what order you want your ReRoutes to match the Upstream HttpRequest.
|
ocelot.json. This means you can decide in what order you want your ReRoutes to match the Upstream HttpRequest.
|
||||||
|
|
||||||
In order to get this working add the following to a ReRoute in configuration.json, 0 is just an example value here but will explain below.
|
In order to get this working add the following to a ReRoute in ocelot.json, 0 is just an example value here but will explain below.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ In your ConfigureServices method
|
|||||||
option.Service = "Ocelot";
|
option.Service = "Ocelot";
|
||||||
});
|
});
|
||||||
|
|
||||||
Then in your configuration.json add the following to the ReRoute you want to trace..
|
Then in your ocelot.json add the following to the ReRoute you want to trace..
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ In your Configure method you need to tell your application to use WebSockets.
|
|||||||
app.UseOcelot().Wait();
|
app.UseOcelot().Wait();
|
||||||
})
|
})
|
||||||
|
|
||||||
Then in your configuration.json add the following to proxy a ReRoute using websockets.
|
Then in your ocelot.json add the following to proxy a ReRoute using websockets.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ All versions can be found `here <https://www.nuget.org/packages/Ocelot/>`_.
|
|||||||
|
|
||||||
**Configuration**
|
**Configuration**
|
||||||
|
|
||||||
The following is a very basic configuration.json. It won't do anything but should get Ocelot starting.
|
The following is a very basic ocelot.json. It won't do anything but should get Ocelot starting.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ AddOcelot() (adds ocelot services), UseOcelot().Wait() (sets up all the Ocelot m
|
|||||||
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
|
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
|
||||||
.AddJsonFile("appsettings.json", true, true)
|
.AddJsonFile("appsettings.json", true, true)
|
||||||
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
|
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
|
||||||
.AddJsonFile("configuration.json")
|
.AddJsonFile("ocelot.json")
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s => {
|
.ConfigureServices(s => {
|
||||||
@ -87,7 +87,7 @@ All versions can be found `here <https://www.nuget.org/packages/Ocelot/>`_.
|
|||||||
|
|
||||||
**Configuration**
|
**Configuration**
|
||||||
|
|
||||||
The following is a very basic configuration.json. It won't do anything but should get Ocelot starting.
|
The following is a very basic ocelot.json. It won't do anything but should get Ocelot starting.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ An example startup using a json file for configuration can be seen below.
|
|||||||
.SetBasePath(env.ContentRootPath)
|
.SetBasePath(env.ContentRootPath)
|
||||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
|
||||||
.AddJsonFile("configuration.json")
|
.AddJsonFile("ocelot.json")
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
|
|
||||||
Configuration = builder.Build();
|
Configuration = builder.Build();
|
||||||
|
@ -7,7 +7,7 @@ Ocelot does not support...
|
|||||||
|
|
||||||
* Fowarding a host header - The host header that you send to Ocelot will not be forwarded to the downstream service. Obviously this would break everything :(
|
* Fowarding a host header - The host header that you send to Ocelot will not be forwarded to the downstream service. Obviously this would break everything :(
|
||||||
|
|
||||||
* Swagger - I have looked multiple times at building swagger.json out of the Ocelot configuration.json but it doesnt fit into the vision
|
* Swagger - I have looked multiple times at building swagger.json out of the Ocelot ocelot.json but it doesnt fit into the vision
|
||||||
I have for Ocelot. If you would like to have Swagger in Ocelot then you must roll your own swagger.json and do the following in your
|
I have for Ocelot. If you would like to have Swagger in Ocelot then you must roll your own swagger.json and do the following in your
|
||||||
Startup.cs or Program.cs. The code sample below registers a piece of middleware that loads your hand rolled swagger.json and returns
|
Startup.cs or Program.cs. The code sample below registers a piece of middleware that loads your hand rolled swagger.json and returns
|
||||||
it on /swagger/v1/swagger.json. It then registers the SwaggerUI middleware from Swashbuckle.AspNetCore
|
it on /swagger/v1/swagger.json. It then registers the SwaggerUI middleware from Swashbuckle.AspNetCore
|
||||||
@ -28,8 +28,8 @@ it on /swagger/v1/swagger.json. It then registers the SwaggerUI middleware from
|
|||||||
|
|
||||||
app.UseOcelot().Wait();
|
app.UseOcelot().Wait();
|
||||||
|
|
||||||
The main reasons why I don't think Swagger makes sense is we already hand roll our definition in configuration.json.
|
The main reasons why I don't think Swagger makes sense is we already hand roll our definition in ocelot.json.
|
||||||
If we want people developing against Ocelot to be able to see what routes are available then either share the configuration.json
|
If we want people developing against Ocelot to be able to see what routes are available then either share the ocelot.json
|
||||||
with them (This should be as easy as granting access to a repo etc) or use the Ocelot administration API so that they can query Ocelot for the configuration.
|
with them (This should be as easy as granting access to a repo etc) or use the Ocelot administration API so that they can query Ocelot for the configuration.
|
||||||
|
|
||||||
In addition to this many people will configure Ocelot to proxy all traffic like /products/{everything} to there product service
|
In addition to this many people will configure Ocelot to proxy all traffic like /products/{everything} to there product service
|
||||||
@ -40,4 +40,4 @@ package doesnt reload swagger.json if it changes during runtime. Ocelot's config
|
|||||||
information would not match. Unless I rolled my own Swagger implementation.
|
information would not match. Unless I rolled my own Swagger implementation.
|
||||||
|
|
||||||
If the user wants something to easily test against the Ocelot API then I suggest using Postman as a simple way to do this. It might
|
If the user wants something to easily test against the Ocelot API then I suggest using Postman as a simple way to do this. It might
|
||||||
even be possible to write something that maps configuration.json to the postman json spec. However I don't intend to do this.
|
even be possible to write something that maps ocelot.json to the postman json spec. However I don't intend to do this.
|
@ -3,7 +3,7 @@
|
|||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="configuration.json;appsettings.json">
|
<None Update="ocelot.json;appsettings.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -106,7 +106,7 @@ namespace OcelotGraphQL
|
|||||||
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
|
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
|
||||||
.AddJsonFile("appsettings.json", true, true)
|
.AddJsonFile("appsettings.json", true, true)
|
||||||
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
|
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
|
||||||
.AddJsonFile("configuration.json")
|
.AddJsonFile("ocelot.json")
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s => {
|
.ConfigureServices(s => {
|
||||||
|
@ -47,7 +47,7 @@ RESPONSE
|
|||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
Please note this project never goes out to another service, it just gets the data for GraphQL in memory. You would need to add the details of your GraphQL server in configuration.json e.g.
|
Please note this project never goes out to another service, it just gets the data for GraphQL in memory. You would need to add the details of your GraphQL server in ocelot.json e.g.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
2
samples/OcelotServiceFabric/.gitignore
vendored
2
samples/OcelotServiceFabric/.gitignore
vendored
@ -13,7 +13,7 @@
|
|||||||
# Service fabric
|
# Service fabric
|
||||||
OcelotApplicationApiGatewayPkg/Code
|
OcelotApplicationApiGatewayPkg/Code
|
||||||
OcelotApplication/OcelotApplicationApiGatewayPkg/Code/appsettings.json
|
OcelotApplication/OcelotApplicationApiGatewayPkg/Code/appsettings.json
|
||||||
OcelotApplication/OcelotApplicationApiGatewayPkg/Code/configuration.json
|
OcelotApplication/OcelotApplicationApiGatewayPkg/Code/ocelot.json
|
||||||
OcelotApplication/OcelotApplicationApiGatewayPkg/Code/runtimes/
|
OcelotApplication/OcelotApplicationApiGatewayPkg/Code/runtimes/
|
||||||
OcelotApplicationServicePkg/Code
|
OcelotApplicationServicePkg/Code
|
||||||
OcelotApplication/OcelotApplicationApiGatewayPkg/Code/web.config
|
OcelotApplication/OcelotApplicationApiGatewayPkg/Code/web.config
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<PackageId>OcelotApplicationApiGateway</PackageId>
|
<PackageId>OcelotApplicationApiGateway</PackageId>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="configuration.json;appsettings.json;">
|
<None Update="ocelot.json;appsettings.json;">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -67,7 +67,7 @@ namespace OcelotApplicationApiGateway
|
|||||||
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
|
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
|
||||||
.AddJsonFile("appsettings.json", true, true)
|
.AddJsonFile("appsettings.json", true, true)
|
||||||
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
|
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
|
||||||
.AddJsonFile("configuration.json")
|
.AddJsonFile("ocelot.json")
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureLogging((hostingContext, logging) =>
|
.ConfigureLogging((hostingContext, logging) =>
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Ocelot.Cache;
|
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
|
|
||||||
namespace Ocelot.Cache
|
namespace Ocelot.Cache
|
||||||
{
|
{
|
||||||
@ -11,7 +7,7 @@ namespace Ocelot.Cache
|
|||||||
[Route("outputcache")]
|
[Route("outputcache")]
|
||||||
public class OutputCacheController : Controller
|
public class OutputCacheController : Controller
|
||||||
{
|
{
|
||||||
private IOcelotCache<CachedResponse> _cache;
|
private readonly IOcelotCache<CachedResponse> _cache;
|
||||||
|
|
||||||
public OutputCacheController(IOcelotCache<CachedResponse> cache)
|
public OutputCacheController(IOcelotCache<CachedResponse> cache)
|
||||||
{
|
{
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Authentication
|
|
||||||
{
|
|
||||||
public class HashMatcher : IHashMatcher
|
|
||||||
{
|
|
||||||
public bool Match(string password, string salt, string hash)
|
|
||||||
{
|
|
||||||
byte[] s = Convert.FromBase64String(salt);
|
|
||||||
|
|
||||||
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
|
|
||||||
password: password,
|
|
||||||
salt: s,
|
|
||||||
prf: KeyDerivationPrf.HMACSHA256,
|
|
||||||
iterationCount: 10000,
|
|
||||||
numBytesRequested: 256 / 8));
|
|
||||||
|
|
||||||
return hashed == hash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
namespace Ocelot.Configuration.Authentication
|
|
||||||
{
|
|
||||||
public interface IHashMatcher
|
|
||||||
{
|
|
||||||
bool Match(string password, string salt, string hash);
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,9 +16,8 @@ namespace Ocelot.Configuration.Creator
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Register as singleton
|
/// Register as singleton
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class FileOcelotConfigurationCreator : IOcelotConfigurationCreator
|
public class FileInternalConfigurationCreator : IInternalConfigurationCreator
|
||||||
{
|
{
|
||||||
private readonly IOptions<FileConfiguration> _options;
|
|
||||||
private readonly IConfigurationValidator _configurationValidator;
|
private readonly IConfigurationValidator _configurationValidator;
|
||||||
private readonly IOcelotLogger _logger;
|
private readonly IOcelotLogger _logger;
|
||||||
private readonly IClaimsToThingCreator _claimsToThingCreator;
|
private readonly IClaimsToThingCreator _claimsToThingCreator;
|
||||||
@ -35,8 +34,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
private readonly IHeaderFindAndReplaceCreator _headerFAndRCreator;
|
private readonly IHeaderFindAndReplaceCreator _headerFAndRCreator;
|
||||||
private readonly IDownstreamAddressesCreator _downstreamAddressesCreator;
|
private readonly IDownstreamAddressesCreator _downstreamAddressesCreator;
|
||||||
|
|
||||||
public FileOcelotConfigurationCreator(
|
public FileInternalConfigurationCreator(
|
||||||
IOptions<FileConfiguration> options,
|
|
||||||
IConfigurationValidator configurationValidator,
|
IConfigurationValidator configurationValidator,
|
||||||
IOcelotLoggerFactory loggerFactory,
|
IOcelotLoggerFactory loggerFactory,
|
||||||
IClaimsToThingCreator claimsToThingCreator,
|
IClaimsToThingCreator claimsToThingCreator,
|
||||||
@ -62,9 +60,8 @@ namespace Ocelot.Configuration.Creator
|
|||||||
_requestIdKeyCreator = requestIdKeyCreator;
|
_requestIdKeyCreator = requestIdKeyCreator;
|
||||||
_upstreamTemplatePatternCreator = upstreamTemplatePatternCreator;
|
_upstreamTemplatePatternCreator = upstreamTemplatePatternCreator;
|
||||||
_authOptionsCreator = authOptionsCreator;
|
_authOptionsCreator = authOptionsCreator;
|
||||||
_options = options;
|
|
||||||
_configurationValidator = configurationValidator;
|
_configurationValidator = configurationValidator;
|
||||||
_logger = loggerFactory.CreateLogger<FileOcelotConfigurationCreator>();
|
_logger = loggerFactory.CreateLogger<FileInternalConfigurationCreator>();
|
||||||
_claimsToThingCreator = claimsToThingCreator;
|
_claimsToThingCreator = claimsToThingCreator;
|
||||||
_serviceProviderConfigCreator = serviceProviderConfigCreator;
|
_serviceProviderConfigCreator = serviceProviderConfigCreator;
|
||||||
_qosOptionsCreator = qosOptionsCreator;
|
_qosOptionsCreator = qosOptionsCreator;
|
||||||
@ -72,19 +69,19 @@ namespace Ocelot.Configuration.Creator
|
|||||||
_httpHandlerOptionsCreator = httpHandlerOptionsCreator;
|
_httpHandlerOptionsCreator = httpHandlerOptionsCreator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Response<IOcelotConfiguration>> Create(FileConfiguration fileConfiguration)
|
public async Task<Response<IInternalConfiguration>> Create(FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
var config = await SetUpConfiguration(fileConfiguration);
|
var config = await SetUpConfiguration(fileConfiguration);
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Response<IOcelotConfiguration>> SetUpConfiguration(FileConfiguration fileConfiguration)
|
private async Task<Response<IInternalConfiguration>> SetUpConfiguration(FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
var response = await _configurationValidator.IsValid(fileConfiguration);
|
var response = await _configurationValidator.IsValid(fileConfiguration);
|
||||||
|
|
||||||
if (response.Data.IsError)
|
if (response.Data.IsError)
|
||||||
{
|
{
|
||||||
return new ErrorResponse<IOcelotConfiguration>(response.Data.Errors);
|
return new ErrorResponse<IInternalConfiguration>(response.Data.Errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
var reRoutes = new List<ReRoute>();
|
var reRoutes = new List<ReRoute>();
|
||||||
@ -106,9 +103,9 @@ namespace Ocelot.Configuration.Creator
|
|||||||
|
|
||||||
var serviceProviderConfiguration = _serviceProviderConfigCreator.Create(fileConfiguration.GlobalConfiguration);
|
var serviceProviderConfiguration = _serviceProviderConfigCreator.Create(fileConfiguration.GlobalConfiguration);
|
||||||
|
|
||||||
var config = new OcelotConfiguration(reRoutes, _adminPath.Path, serviceProviderConfiguration, fileConfiguration.GlobalConfiguration.RequestIdKey);
|
var config = new InternalConfiguration(reRoutes, _adminPath.Path, serviceProviderConfiguration, fileConfiguration.GlobalConfiguration.RequestIdKey);
|
||||||
|
|
||||||
return new OkResponse<IOcelotConfiguration>(config);
|
return new OkResponse<IInternalConfiguration>(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReRoute SetUpAggregateReRoute(List<ReRoute> reRoutes, FileAggregateReRoute aggregateReRoute, FileGlobalConfiguration globalConfiguration)
|
public ReRoute SetUpAggregateReRoute(List<ReRoute> reRoutes, FileAggregateReRoute aggregateReRoute, FileGlobalConfiguration globalConfiguration)
|
@ -0,0 +1,11 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
|
||||||
|
namespace Ocelot.Configuration.Creator
|
||||||
|
{
|
||||||
|
public interface IInternalConfigurationCreator
|
||||||
|
{
|
||||||
|
Task<Response<IInternalConfiguration>> Create(FileConfiguration fileConfiguration);
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Creator
|
|
||||||
{
|
|
||||||
public interface IOcelotConfigurationCreator
|
|
||||||
{
|
|
||||||
Task<Response<IOcelotConfiguration>> Create(FileConfiguration fileConfiguration);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using IdentityServer4.AccessTokenValidation;
|
|
||||||
using IdentityServer4.Models;
|
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Creator
|
namespace Ocelot.Configuration.Creator
|
||||||
{
|
{
|
||||||
|
@ -2,34 +2,34 @@ using System;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
using Ocelot.Configuration.Setter;
|
using Ocelot.Configuration.Setter;
|
||||||
using Ocelot.Raft;
|
using Ocelot.Raft;
|
||||||
using Rafty.Concensus;
|
using Rafty.Concensus;
|
||||||
|
|
||||||
namespace Ocelot.Configuration
|
namespace Ocelot.Configuration
|
||||||
{
|
{
|
||||||
|
using Repository;
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("configuration")]
|
[Route("configuration")]
|
||||||
public class FileConfigurationController : Controller
|
public class FileConfigurationController : Controller
|
||||||
{
|
{
|
||||||
private readonly IFileConfigurationProvider _configGetter;
|
private readonly IFileConfigurationRepository _repo;
|
||||||
private readonly IFileConfigurationSetter _configSetter;
|
private readonly IFileConfigurationSetter _setter;
|
||||||
private readonly IServiceProvider _serviceProvider;
|
private readonly IServiceProvider _provider;
|
||||||
|
|
||||||
public FileConfigurationController(IFileConfigurationProvider getFileConfig, IFileConfigurationSetter configSetter, IServiceProvider serviceProvider)
|
public FileConfigurationController(IFileConfigurationRepository repo, IFileConfigurationSetter setter, IServiceProvider provider)
|
||||||
{
|
{
|
||||||
_configGetter = getFileConfig;
|
_repo = repo;
|
||||||
_configSetter = configSetter;
|
_setter = setter;
|
||||||
_serviceProvider = serviceProvider;
|
_provider = provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IActionResult> Get()
|
public async Task<IActionResult> Get()
|
||||||
{
|
{
|
||||||
var response = await _configGetter.Get();
|
var response = await _repo.Get();
|
||||||
|
|
||||||
if(response.IsError)
|
if(response.IsError)
|
||||||
{
|
{
|
||||||
@ -43,7 +43,7 @@ namespace Ocelot.Configuration
|
|||||||
public async Task<IActionResult> Post([FromBody]FileConfiguration fileConfiguration)
|
public async Task<IActionResult> Post([FromBody]FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
//todo - this code is a bit shit sort it out..
|
//todo - this code is a bit shit sort it out..
|
||||||
var test = _serviceProvider.GetService(typeof(INode));
|
var test = _provider.GetService(typeof(INode));
|
||||||
if (test != null)
|
if (test != null)
|
||||||
{
|
{
|
||||||
var node = (INode)test;
|
var node = (INode)test;
|
||||||
@ -56,7 +56,7 @@ namespace Ocelot.Configuration
|
|||||||
return new OkObjectResult(result.Command.Configuration);
|
return new OkObjectResult(result.Command.Configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
var response = await _configSetter.Set(fileConfiguration);
|
var response = await _setter.Set(fileConfiguration);
|
||||||
|
|
||||||
if (response.IsError)
|
if (response.IsError)
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
namespace Ocelot.Configuration
|
||||||
using IdentityServer4.AccessTokenValidation;
|
|
||||||
using IdentityServer4.Models;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Provider
|
|
||||||
{
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public interface IIdentityServerConfiguration
|
public interface IIdentityServerConfiguration
|
||||||
{
|
{
|
||||||
string ApiName { get; }
|
string ApiName { get; }
|
@ -2,7 +2,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Ocelot.Configuration
|
namespace Ocelot.Configuration
|
||||||
{
|
{
|
||||||
public interface IOcelotConfiguration
|
public interface IInternalConfiguration
|
||||||
{
|
{
|
||||||
List<ReRoute> ReRoutes { get; }
|
List<ReRoute> ReRoutes { get; }
|
||||||
string AdministrationPath {get;}
|
string AdministrationPath {get;}
|
@ -1,9 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
namespace Ocelot.Configuration
|
||||||
using IdentityServer4.AccessTokenValidation;
|
|
||||||
using IdentityServer4.Models;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Provider
|
|
||||||
{
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public class IdentityServerConfiguration : IIdentityServerConfiguration
|
public class IdentityServerConfiguration : IIdentityServerConfiguration
|
||||||
{
|
{
|
||||||
public IdentityServerConfiguration(
|
public IdentityServerConfiguration(
|
||||||
@ -22,11 +20,11 @@ namespace Ocelot.Configuration.Provider
|
|||||||
CredentialsSigningCertificatePassword = credentialsSigningCertificatePassword;
|
CredentialsSigningCertificatePassword = credentialsSigningCertificatePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ApiName { get; private set; }
|
public string ApiName { get; }
|
||||||
public bool RequireHttps { get; private set; }
|
public bool RequireHttps { get; }
|
||||||
public List<string> AllowedScopes { get; private set; }
|
public List<string> AllowedScopes { get; }
|
||||||
public string ApiSecret { get; private set; }
|
public string ApiSecret { get; }
|
||||||
public string CredentialsSigningCertificateLocation { get; private set; }
|
public string CredentialsSigningCertificateLocation { get; }
|
||||||
public string CredentialsSigningCertificatePassword { get; private set; }
|
public string CredentialsSigningCertificatePassword { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,9 +2,9 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Ocelot.Configuration
|
namespace Ocelot.Configuration
|
||||||
{
|
{
|
||||||
public class OcelotConfiguration : IOcelotConfiguration
|
public class InternalConfiguration : IInternalConfiguration
|
||||||
{
|
{
|
||||||
public OcelotConfiguration(List<ReRoute> reRoutes, string administrationPath, ServiceProviderConfiguration serviceProviderConfiguration, string requestId)
|
public InternalConfiguration(List<ReRoute> reRoutes, string administrationPath, ServiceProviderConfiguration serviceProviderConfiguration, string requestId)
|
||||||
{
|
{
|
||||||
ReRoutes = reRoutes;
|
ReRoutes = reRoutes;
|
||||||
AdministrationPath = administrationPath;
|
AdministrationPath = administrationPath;
|
@ -1,26 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using Ocelot.Configuration.Repository;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Provider
|
|
||||||
{
|
|
||||||
public class FileConfigurationProvider : IFileConfigurationProvider
|
|
||||||
{
|
|
||||||
private IFileConfigurationRepository _repo;
|
|
||||||
|
|
||||||
public FileConfigurationProvider(IFileConfigurationRepository repo)
|
|
||||||
{
|
|
||||||
_repo = repo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Response<FileConfiguration>> Get()
|
|
||||||
{
|
|
||||||
var fileConfig = await _repo.Get();
|
|
||||||
return new OkResponse<FileConfiguration>(fileConfig.Data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Provider
|
|
||||||
{
|
|
||||||
public interface IFileConfigurationProvider
|
|
||||||
{
|
|
||||||
Task<Response<FileConfiguration>> Get();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Provider
|
|
||||||
{
|
|
||||||
public interface IOcelotConfigurationProvider
|
|
||||||
{
|
|
||||||
Task<Response<IOcelotConfiguration>> Get();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using Ocelot.Configuration.Repository;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Provider
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Register as singleton
|
|
||||||
/// </summary>
|
|
||||||
public class OcelotConfigurationProvider : IOcelotConfigurationProvider
|
|
||||||
{
|
|
||||||
private readonly IOcelotConfigurationRepository _config;
|
|
||||||
|
|
||||||
public OcelotConfigurationProvider(IOcelotConfigurationRepository repo)
|
|
||||||
{
|
|
||||||
_config = repo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Response<IOcelotConfiguration>> Get()
|
|
||||||
{
|
|
||||||
var repoConfig = await _config.Get();
|
|
||||||
|
|
||||||
if (repoConfig.IsError)
|
|
||||||
{
|
|
||||||
return new ErrorResponse<IOcelotConfiguration>(repoConfig.Errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new OkResponse<IOcelotConfiguration>(repoConfig.Data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +1,47 @@
|
|||||||
using System;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Consul;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using Ocelot.Infrastructure.Consul;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
using Ocelot.ServiceDiscovery.Configuration;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Repository
|
namespace Ocelot.Configuration.Repository
|
||||||
{
|
{
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Consul;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Ocelot.Infrastructure.Consul;
|
||||||
|
using Ocelot.Logging;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
using Ocelot.ServiceDiscovery.Configuration;
|
||||||
|
|
||||||
public class ConsulFileConfigurationRepository : IFileConfigurationRepository
|
public class ConsulFileConfigurationRepository : IFileConfigurationRepository
|
||||||
{
|
{
|
||||||
private readonly ConsulClient _consul;
|
private readonly ConsulClient _consul;
|
||||||
private const string OcelotConfiguration = "OcelotConfiguration";
|
private const string OcelotConfiguration = "InternalConfiguration";
|
||||||
private readonly Cache.IOcelotCache<FileConfiguration> _cache;
|
private readonly Cache.IOcelotCache<FileConfiguration> _cache;
|
||||||
|
private readonly IOcelotLogger _logger;
|
||||||
|
|
||||||
public ConsulFileConfigurationRepository(
|
public ConsulFileConfigurationRepository(
|
||||||
Cache.IOcelotCache<FileConfiguration> cache,
|
Cache.IOcelotCache<FileConfiguration> cache,
|
||||||
ServiceProviderConfiguration serviceProviderConfig,
|
IInternalConfigurationRepository repo,
|
||||||
IConsulClientFactory factory)
|
IConsulClientFactory factory,
|
||||||
|
IOcelotLoggerFactory loggerFactory)
|
||||||
{
|
{
|
||||||
var consulHost = string.IsNullOrEmpty(serviceProviderConfig?.Host) ? "localhost" : serviceProviderConfig?.Host;
|
_logger = loggerFactory.CreateLogger<ConsulFileConfigurationRepository>();
|
||||||
var consulPort = serviceProviderConfig?.Port ?? 8500;
|
|
||||||
var config = new ConsulRegistryConfiguration(consulHost, consulPort, OcelotConfiguration, serviceProviderConfig?.Token);
|
|
||||||
_cache = cache;
|
_cache = cache;
|
||||||
|
|
||||||
|
var internalConfig = repo.Get();
|
||||||
|
|
||||||
|
var consulHost = "localhost";
|
||||||
|
var consulPort = 8500;
|
||||||
|
string token = null;
|
||||||
|
|
||||||
|
if (!internalConfig.IsError)
|
||||||
|
{
|
||||||
|
consulHost = string.IsNullOrEmpty(internalConfig.Data.ServiceProviderConfiguration?.Host) ? consulHost : internalConfig.Data.ServiceProviderConfiguration?.Host;
|
||||||
|
consulPort = internalConfig.Data.ServiceProviderConfiguration?.Port ?? consulPort;
|
||||||
|
token = internalConfig.Data.ServiceProviderConfiguration?.Token;
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = new ConsulRegistryConfiguration(consulHost, consulPort, OcelotConfiguration, token);
|
||||||
|
|
||||||
_consul = factory.Get(config);
|
_consul = factory.Get(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,15 +7,17 @@ using Ocelot.Responses;
|
|||||||
|
|
||||||
namespace Ocelot.Configuration.Repository
|
namespace Ocelot.Configuration.Repository
|
||||||
{
|
{
|
||||||
public class FileConfigurationRepository : IFileConfigurationRepository
|
public class DiskFileConfigurationRepository : IFileConfigurationRepository
|
||||||
{
|
{
|
||||||
private readonly string _configFilePath;
|
private readonly string _configFilePath;
|
||||||
|
|
||||||
private static readonly object _lock = new object();
|
private static readonly object _lock = new object();
|
||||||
|
|
||||||
public FileConfigurationRepository(IHostingEnvironment hostingEnvironment)
|
private const string ConfigurationFileName = "ocelot";
|
||||||
|
|
||||||
|
public DiskFileConfigurationRepository(IHostingEnvironment hostingEnvironment)
|
||||||
{
|
{
|
||||||
_configFilePath = $"{AppContext.BaseDirectory}/configuration{(string.IsNullOrEmpty(hostingEnvironment.EnvironmentName) ? string.Empty : ".")}{hostingEnvironment.EnvironmentName}.json";
|
_configFilePath = $"{AppContext.BaseDirectory}/{ConfigurationFileName}{(string.IsNullOrEmpty(hostingEnvironment.EnvironmentName) ? string.Empty : ".")}{hostingEnvironment.EnvironmentName}.json";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Response<FileConfiguration>> Get()
|
public Task<Response<FileConfiguration>> Get()
|
@ -0,0 +1,10 @@
|
|||||||
|
using Ocelot.Responses;
|
||||||
|
|
||||||
|
namespace Ocelot.Configuration.Repository
|
||||||
|
{
|
||||||
|
public interface IInternalConfigurationRepository
|
||||||
|
{
|
||||||
|
Response<IInternalConfiguration> Get();
|
||||||
|
Response AddOrReplace(IInternalConfiguration internalConfiguration);
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Repository
|
|
||||||
{
|
|
||||||
public interface IOcelotConfigurationRepository
|
|
||||||
{
|
|
||||||
Task<Response<IOcelotConfiguration>> Get();
|
|
||||||
Task<Response> AddOrReplace(IOcelotConfiguration ocelotConfiguration);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,29 @@
|
|||||||
|
using Ocelot.Responses;
|
||||||
|
|
||||||
|
namespace Ocelot.Configuration.Repository
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Register as singleton
|
||||||
|
/// </summary>
|
||||||
|
public class InMemoryInternalConfigurationRepository : IInternalConfigurationRepository
|
||||||
|
{
|
||||||
|
private static readonly object LockObject = new object();
|
||||||
|
|
||||||
|
private IInternalConfiguration _internalConfiguration;
|
||||||
|
|
||||||
|
public Response<IInternalConfiguration> Get()
|
||||||
|
{
|
||||||
|
return new OkResponse<IInternalConfiguration>(_internalConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response AddOrReplace(IInternalConfiguration internalConfiguration)
|
||||||
|
{
|
||||||
|
lock (LockObject)
|
||||||
|
{
|
||||||
|
_internalConfiguration = internalConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OkResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Repository
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Register as singleton
|
|
||||||
/// </summary>
|
|
||||||
public class InMemoryOcelotConfigurationRepository : IOcelotConfigurationRepository
|
|
||||||
{
|
|
||||||
private static readonly object LockObject = new object();
|
|
||||||
|
|
||||||
private IOcelotConfiguration _ocelotConfiguration;
|
|
||||||
|
|
||||||
public Task<Response<IOcelotConfiguration>> Get()
|
|
||||||
{
|
|
||||||
return Task.FromResult<Response<IOcelotConfiguration>>(new OkResponse<IOcelotConfiguration>(_ocelotConfiguration));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<Response> AddOrReplace(IOcelotConfiguration ocelotConfiguration)
|
|
||||||
{
|
|
||||||
lock (LockObject)
|
|
||||||
{
|
|
||||||
_ocelotConfiguration = ocelotConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.FromResult<Response>(new OkResponse());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,14 +6,16 @@ using Ocelot.Responses;
|
|||||||
|
|
||||||
namespace Ocelot.Configuration.Setter
|
namespace Ocelot.Configuration.Setter
|
||||||
{
|
{
|
||||||
public class FileConfigurationSetter : IFileConfigurationSetter
|
public class FileAndInternalConfigurationSetter : IFileConfigurationSetter
|
||||||
{
|
{
|
||||||
private readonly IOcelotConfigurationRepository _configRepo;
|
private readonly IInternalConfigurationRepository _configRepo;
|
||||||
private readonly IOcelotConfigurationCreator _configCreator;
|
private readonly IInternalConfigurationCreator _configCreator;
|
||||||
private readonly IFileConfigurationRepository _repo;
|
private readonly IFileConfigurationRepository _repo;
|
||||||
|
|
||||||
public FileConfigurationSetter(IOcelotConfigurationRepository configRepo,
|
public FileAndInternalConfigurationSetter(
|
||||||
IOcelotConfigurationCreator configCreator, IFileConfigurationRepository repo)
|
IInternalConfigurationRepository configRepo,
|
||||||
|
IInternalConfigurationCreator configCreator,
|
||||||
|
IFileConfigurationRepository repo)
|
||||||
{
|
{
|
||||||
_configRepo = configRepo;
|
_configRepo = configRepo;
|
||||||
_configCreator = configCreator;
|
_configCreator = configCreator;
|
||||||
@ -33,7 +35,7 @@ namespace Ocelot.Configuration.Setter
|
|||||||
|
|
||||||
if(!config.IsError)
|
if(!config.IsError)
|
||||||
{
|
{
|
||||||
await _configRepo.AddOrReplace(config.Data);
|
_configRepo.AddOrReplace(config.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ErrorResponse(config.Errors);
|
return new ErrorResponse(config.Errors);
|
@ -1,21 +1,73 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.Configuration.Memory;
|
|
||||||
|
|
||||||
namespace Ocelot.DependencyInjection
|
namespace Ocelot.DependencyInjection
|
||||||
{
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Configuration.Memory;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Configuration.File;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
public static class ConfigurationBuilderExtensions
|
public static class ConfigurationBuilderExtensions
|
||||||
{
|
{
|
||||||
[Obsolete("Please set BaseUrl in configuration.json GlobalConfiguration.BaseUrl")]
|
[Obsolete("Please set BaseUrl in ocelot.json GlobalConfiguration.BaseUrl")]
|
||||||
public static IConfigurationBuilder AddOcelotBaseUrl(this IConfigurationBuilder builder, string baseUrl)
|
public static IConfigurationBuilder AddOcelotBaseUrl(this IConfigurationBuilder builder, string baseUrl)
|
||||||
{
|
{
|
||||||
var memorySource = new MemoryConfigurationSource();
|
var memorySource = new MemoryConfigurationSource
|
||||||
memorySource.InitialData = new List<KeyValuePair<string, string>>
|
|
||||||
{
|
{
|
||||||
new KeyValuePair<string, string>("BaseUrl", baseUrl)
|
InitialData = new List<KeyValuePair<string, string>>
|
||||||
|
{
|
||||||
|
new KeyValuePair<string, string>("BaseUrl", baseUrl)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
builder.Add(memorySource);
|
builder.Add(memorySource);
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder)
|
||||||
|
{
|
||||||
|
const string pattern = "(?i)ocelot(.*).json$";
|
||||||
|
|
||||||
|
var reg = new Regex(pattern);
|
||||||
|
|
||||||
|
var files = Directory.GetFiles(".")
|
||||||
|
.Where(path => reg.IsMatch(path)).Where(x => x.Count(s => s == '.') == 3)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var fileConfiguration = new FileConfiguration();
|
||||||
|
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
// windows and unix sigh...
|
||||||
|
if(files.Count > 1 && (file == "./ocelot.json" || file == ".\\ocelot.json"))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lines = File.ReadAllText(file);
|
||||||
|
|
||||||
|
var config = JsonConvert.DeserializeObject<FileConfiguration>(lines);
|
||||||
|
|
||||||
|
// windows and unix sigh...
|
||||||
|
if (file == "./ocelot.global.json" || file == ".\\ocelot.global.json")
|
||||||
|
{
|
||||||
|
fileConfiguration.GlobalConfiguration = config.GlobalConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileConfiguration.Aggregates.AddRange(config.Aggregates);
|
||||||
|
fileConfiguration.ReRoutes.AddRange(config.ReRoutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
var json = JsonConvert.SerializeObject(fileConfiguration);
|
||||||
|
|
||||||
|
File.WriteAllText("ocelot.json", json);
|
||||||
|
|
||||||
|
builder.AddJsonFile("ocelot.json");
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
using Butterfly.Client.Tracing;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Ocelot.Middleware.Multiplexer;
|
|
||||||
|
|
||||||
namespace Ocelot.DependencyInjection
|
namespace Ocelot.DependencyInjection
|
||||||
{
|
{
|
||||||
using CacheManager.Core;
|
using CacheManager.Core;
|
||||||
@ -12,17 +8,14 @@ namespace Ocelot.DependencyInjection
|
|||||||
using Ocelot.Authorisation;
|
using Ocelot.Authorisation;
|
||||||
using Ocelot.Cache;
|
using Ocelot.Cache;
|
||||||
using Ocelot.Claims;
|
using Ocelot.Claims;
|
||||||
using Ocelot.Configuration.Authentication;
|
|
||||||
using Ocelot.Configuration.Creator;
|
using Ocelot.Configuration.Creator;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Configuration.Parser;
|
using Ocelot.Configuration.Parser;
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
using Ocelot.Configuration.Repository;
|
using Ocelot.Configuration.Repository;
|
||||||
using Ocelot.Configuration.Setter;
|
using Ocelot.Configuration.Setter;
|
||||||
using Ocelot.Configuration.Validator;
|
using Ocelot.Configuration.Validator;
|
||||||
using Ocelot.DownstreamRouteFinder.Finder;
|
using Ocelot.DownstreamRouteFinder.Finder;
|
||||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||||
using Ocelot.DownstreamUrlCreator;
|
|
||||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
|
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
|
||||||
using Ocelot.Headers;
|
using Ocelot.Headers;
|
||||||
using Ocelot.Infrastructure.Claims.Parser;
|
using Ocelot.Infrastructure.Claims.Parser;
|
||||||
@ -44,16 +37,14 @@ namespace Ocelot.DependencyInjection
|
|||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using IdentityServer4.AccessTokenValidation;
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.Builder;
|
|
||||||
using FileConfigurationProvider = Ocelot.Configuration.Provider.FileConfigurationProvider;
|
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using Butterfly.Client.AspNetCore;
|
using Butterfly.Client.AspNetCore;
|
||||||
using Ocelot.Infrastructure;
|
using Ocelot.Infrastructure;
|
||||||
using Ocelot.Infrastructure.Consul;
|
using Ocelot.Infrastructure.Consul;
|
||||||
|
using Butterfly.Client.Tracing;
|
||||||
|
using Ocelot.Middleware.Multiplexer;
|
||||||
|
|
||||||
public class OcelotBuilder : IOcelotBuilder
|
public class OcelotBuilder : IOcelotBuilder
|
||||||
{
|
{
|
||||||
@ -78,8 +69,8 @@ namespace Ocelot.DependencyInjection
|
|||||||
_services.TryAddSingleton<IHttpResponseHeaderReplacer, HttpResponseHeaderReplacer>();
|
_services.TryAddSingleton<IHttpResponseHeaderReplacer, HttpResponseHeaderReplacer>();
|
||||||
_services.TryAddSingleton<IHttpContextRequestHeaderReplacer, HttpContextRequestHeaderReplacer>();
|
_services.TryAddSingleton<IHttpContextRequestHeaderReplacer, HttpContextRequestHeaderReplacer>();
|
||||||
_services.TryAddSingleton<IHeaderFindAndReplaceCreator, HeaderFindAndReplaceCreator>();
|
_services.TryAddSingleton<IHeaderFindAndReplaceCreator, HeaderFindAndReplaceCreator>();
|
||||||
_services.TryAddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>();
|
_services.TryAddSingleton<IInternalConfigurationCreator, FileInternalConfigurationCreator>();
|
||||||
_services.TryAddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
|
_services.TryAddSingleton<IInternalConfigurationRepository, InMemoryInternalConfigurationRepository>();
|
||||||
_services.TryAddSingleton<IConfigurationValidator, FileConfigurationFluentValidator>();
|
_services.TryAddSingleton<IConfigurationValidator, FileConfigurationFluentValidator>();
|
||||||
_services.TryAddSingleton<IClaimsToThingCreator, ClaimsToThingCreator>();
|
_services.TryAddSingleton<IClaimsToThingCreator, ClaimsToThingCreator>();
|
||||||
_services.TryAddSingleton<IAuthenticationOptionsCreator, AuthenticationOptionsCreator>();
|
_services.TryAddSingleton<IAuthenticationOptionsCreator, AuthenticationOptionsCreator>();
|
||||||
@ -91,9 +82,8 @@ namespace Ocelot.DependencyInjection
|
|||||||
_services.TryAddSingleton<IRateLimitOptionsCreator, RateLimitOptionsCreator>();
|
_services.TryAddSingleton<IRateLimitOptionsCreator, RateLimitOptionsCreator>();
|
||||||
_services.TryAddSingleton<IBaseUrlFinder, BaseUrlFinder>();
|
_services.TryAddSingleton<IBaseUrlFinder, BaseUrlFinder>();
|
||||||
_services.TryAddSingleton<IRegionCreator, RegionCreator>();
|
_services.TryAddSingleton<IRegionCreator, RegionCreator>();
|
||||||
_services.TryAddSingleton<IFileConfigurationRepository, FileConfigurationRepository>();
|
_services.TryAddSingleton<IFileConfigurationRepository, DiskFileConfigurationRepository>();
|
||||||
_services.TryAddSingleton<IFileConfigurationSetter, FileConfigurationSetter>();
|
_services.TryAddSingleton<IFileConfigurationSetter, FileAndInternalConfigurationSetter>();
|
||||||
_services.TryAddSingleton<IFileConfigurationProvider, FileConfigurationProvider>();
|
|
||||||
_services.TryAddSingleton<IQosProviderHouse, QosProviderHouse>();
|
_services.TryAddSingleton<IQosProviderHouse, QosProviderHouse>();
|
||||||
_services.TryAddSingleton<IQoSProviderFactory, QoSProviderFactory>();
|
_services.TryAddSingleton<IQoSProviderFactory, QoSProviderFactory>();
|
||||||
_services.TryAddSingleton<IServiceDiscoveryProviderFactory, ServiceDiscoveryProviderFactory>();
|
_services.TryAddSingleton<IServiceDiscoveryProviderFactory, ServiceDiscoveryProviderFactory>();
|
||||||
@ -101,7 +91,6 @@ namespace Ocelot.DependencyInjection
|
|||||||
_services.TryAddSingleton<ILoadBalancerHouse, LoadBalancerHouse>();
|
_services.TryAddSingleton<ILoadBalancerHouse, LoadBalancerHouse>();
|
||||||
_services.TryAddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
_services.TryAddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||||
_services.TryAddSingleton<IRemoveOutputHeaders, RemoveOutputHeaders>();
|
_services.TryAddSingleton<IRemoveOutputHeaders, RemoveOutputHeaders>();
|
||||||
_services.TryAddSingleton<IOcelotConfigurationProvider, OcelotConfigurationProvider>();
|
|
||||||
_services.TryAddSingleton<IClaimToThingConfigurationParser, ClaimToThingConfigurationParser>();
|
_services.TryAddSingleton<IClaimToThingConfigurationParser, ClaimToThingConfigurationParser>();
|
||||||
_services.TryAddSingleton<IClaimsAuthoriser, ClaimsAuthoriser>();
|
_services.TryAddSingleton<IClaimsAuthoriser, ClaimsAuthoriser>();
|
||||||
_services.TryAddSingleton<IScopesAuthoriser, ScopesAuthoriser>();
|
_services.TryAddSingleton<IScopesAuthoriser, ScopesAuthoriser>();
|
||||||
@ -252,17 +241,6 @@ namespace Ocelot.DependencyInjection
|
|||||||
|
|
||||||
public IOcelotBuilder AddStoreOcelotConfigurationInConsul()
|
public IOcelotBuilder AddStoreOcelotConfigurationInConsul()
|
||||||
{
|
{
|
||||||
var serviceDiscoveryPort = _configurationRoot.GetValue("GlobalConfiguration:ServiceDiscoveryProvider:Port", 0);
|
|
||||||
var serviceDiscoveryHost = _configurationRoot.GetValue("GlobalConfiguration:ServiceDiscoveryProvider:Host", string.Empty);
|
|
||||||
var serviceDiscoveryToken = _configurationRoot.GetValue("GlobalConfiguration:ServiceDiscoveryProvider:Token", string.Empty);
|
|
||||||
|
|
||||||
var config = new ServiceProviderConfigurationBuilder()
|
|
||||||
.WithPort(serviceDiscoveryPort)
|
|
||||||
.WithHost(serviceDiscoveryHost)
|
|
||||||
.WithToken(serviceDiscoveryToken)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_services.AddSingleton<ServiceProviderConfiguration>(config);
|
|
||||||
_services.AddSingleton<ConsulFileConfigurationPoller>();
|
_services.AddSingleton<ConsulFileConfigurationPoller>();
|
||||||
_services.AddSingleton<IFileConfigurationRepository, ConsulFileConfigurationRepository>();
|
_services.AddSingleton<IFileConfigurationRepository, ConsulFileConfigurationRepository>();
|
||||||
return this;
|
return this;
|
||||||
@ -278,12 +256,12 @@ namespace Ocelot.DependencyInjection
|
|||||||
_services.AddSingleton<ICacheManager<CachedResponse>>(cacheManagerOutputCache);
|
_services.AddSingleton<ICacheManager<CachedResponse>>(cacheManagerOutputCache);
|
||||||
_services.AddSingleton<IOcelotCache<CachedResponse>>(ocelotOutputCacheManager);
|
_services.AddSingleton<IOcelotCache<CachedResponse>>(ocelotOutputCacheManager);
|
||||||
|
|
||||||
var ocelotConfigCacheManagerOutputCache = CacheFactory.Build<IOcelotConfiguration>("OcelotConfigurationCache", settings);
|
var ocelotConfigCacheManagerOutputCache = CacheFactory.Build<IInternalConfiguration>("OcelotConfigurationCache", settings);
|
||||||
var ocelotConfigCacheManager = new OcelotCacheManagerCache<IOcelotConfiguration>(ocelotConfigCacheManagerOutputCache);
|
var ocelotConfigCacheManager = new OcelotCacheManagerCache<IInternalConfiguration>(ocelotConfigCacheManagerOutputCache);
|
||||||
_services.RemoveAll(typeof(ICacheManager<IOcelotConfiguration>));
|
_services.RemoveAll(typeof(ICacheManager<IInternalConfiguration>));
|
||||||
_services.RemoveAll(typeof(IOcelotCache<IOcelotConfiguration>));
|
_services.RemoveAll(typeof(IOcelotCache<IInternalConfiguration>));
|
||||||
_services.AddSingleton<ICacheManager<IOcelotConfiguration>>(ocelotConfigCacheManagerOutputCache);
|
_services.AddSingleton<ICacheManager<IInternalConfiguration>>(ocelotConfigCacheManagerOutputCache);
|
||||||
_services.AddSingleton<IOcelotCache<IOcelotConfiguration>>(ocelotConfigCacheManager);
|
_services.AddSingleton<IOcelotCache<IInternalConfiguration>>(ocelotConfigCacheManager);
|
||||||
|
|
||||||
var fileConfigCacheManagerOutputCache = CacheFactory.Build<FileConfiguration>("FileConfigurationCache", settings);
|
var fileConfigCacheManagerOutputCache = CacheFactory.Build<FileConfiguration>("FileConfigurationCache", settings);
|
||||||
var fileConfigCacheManager = new OcelotCacheManagerCache<FileConfiguration>(fileConfigCacheManagerOutputCache);
|
var fileConfigCacheManager = new OcelotCacheManagerCache<FileConfiguration>(fileConfigCacheManagerOutputCache);
|
||||||
@ -304,7 +282,6 @@ namespace Ocelot.DependencyInjection
|
|||||||
private void AddIdentityServer(IIdentityServerConfiguration identityServerConfiguration, IAdministrationPath adminPath)
|
private void AddIdentityServer(IIdentityServerConfiguration identityServerConfiguration, IAdministrationPath adminPath)
|
||||||
{
|
{
|
||||||
_services.TryAddSingleton<IIdentityServerConfiguration>(identityServerConfiguration);
|
_services.TryAddSingleton<IIdentityServerConfiguration>(identityServerConfiguration);
|
||||||
_services.TryAddSingleton<IHashMatcher, HashMatcher>();
|
|
||||||
var identityServerBuilder = _services
|
var identityServerBuilder = _services
|
||||||
.AddIdentityServer(o => {
|
.AddIdentityServer(o => {
|
||||||
o.IssuerUri = "Ocelot";
|
o.IssuerUri = "Ocelot";
|
||||||
|
@ -18,7 +18,7 @@ namespace Ocelot.DownstreamRouteFinder.Finder
|
|||||||
_placeholderNameAndValueFinder = urlPathPlaceholderNameAndValueFinder;
|
_placeholderNameAndValueFinder = urlPathPlaceholderNameAndValueFinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response<DownstreamRoute> FindDownstreamRoute(string path, string httpMethod, IOcelotConfiguration configuration, string upstreamHost)
|
public Response<DownstreamRoute> FindDownstreamRoute(string path, string httpMethod, IInternalConfiguration configuration, string upstreamHost)
|
||||||
{
|
{
|
||||||
var downstreamRoutes = new List<DownstreamRoute>();
|
var downstreamRoutes = new List<DownstreamRoute>();
|
||||||
|
|
||||||
|
@ -6,6 +6,6 @@ namespace Ocelot.DownstreamRouteFinder.Finder
|
|||||||
{
|
{
|
||||||
public interface IDownstreamRouteFinder
|
public interface IDownstreamRouteFinder
|
||||||
{
|
{
|
||||||
Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod, IOcelotConfiguration configuration, string upstreamHost);
|
Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod, IInternalConfiguration configuration, string upstreamHost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration.Repository;
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
using Ocelot.DownstreamRouteFinder.Finder;
|
using Ocelot.DownstreamRouteFinder.Finder;
|
||||||
using Ocelot.Infrastructure.Extensions;
|
using Ocelot.Infrastructure.Extensions;
|
||||||
using Ocelot.Logging;
|
using Ocelot.Logging;
|
||||||
@ -14,17 +13,17 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
|
|||||||
{
|
{
|
||||||
private readonly OcelotRequestDelegate _next;
|
private readonly OcelotRequestDelegate _next;
|
||||||
private readonly IDownstreamRouteFinder _downstreamRouteFinder;
|
private readonly IDownstreamRouteFinder _downstreamRouteFinder;
|
||||||
private readonly IOcelotConfigurationProvider _configProvider;
|
private readonly IInternalConfigurationRepository _repo;
|
||||||
private readonly IMultiplexer _multiplexer;
|
private readonly IMultiplexer _multiplexer;
|
||||||
|
|
||||||
public DownstreamRouteFinderMiddleware(OcelotRequestDelegate next,
|
public DownstreamRouteFinderMiddleware(OcelotRequestDelegate next,
|
||||||
IOcelotLoggerFactory loggerFactory,
|
IOcelotLoggerFactory loggerFactory,
|
||||||
IDownstreamRouteFinder downstreamRouteFinder,
|
IDownstreamRouteFinder downstreamRouteFinder,
|
||||||
IOcelotConfigurationProvider configProvider,
|
IInternalConfigurationRepository repo,
|
||||||
IMultiplexer multiplexer)
|
IMultiplexer multiplexer)
|
||||||
:base(loggerFactory.CreateLogger<DownstreamRouteFinderMiddleware>())
|
:base(loggerFactory.CreateLogger<DownstreamRouteFinderMiddleware>())
|
||||||
{
|
{
|
||||||
_configProvider = configProvider;
|
_repo = repo;
|
||||||
_multiplexer = multiplexer;
|
_multiplexer = multiplexer;
|
||||||
_next = next;
|
_next = next;
|
||||||
_downstreamRouteFinder = downstreamRouteFinder;
|
_downstreamRouteFinder = downstreamRouteFinder;
|
||||||
@ -36,7 +35,7 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
|
|||||||
|
|
||||||
var upstreamHost = context.HttpContext.Request.Headers["Host"];
|
var upstreamHost = context.HttpContext.Request.Headers["Host"];
|
||||||
|
|
||||||
var configuration = await _configProvider.Get();
|
var configuration = _repo.Get();
|
||||||
|
|
||||||
if (configuration.IsError)
|
if (configuration.IsError)
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Ocelot.Configuration.Repository;
|
||||||
using Microsoft.Extensions.Primitives;
|
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
|
||||||
using Ocelot.Infrastructure.Extensions;
|
using Ocelot.Infrastructure.Extensions;
|
||||||
using Ocelot.Infrastructure.RequestData;
|
using Ocelot.Infrastructure.RequestData;
|
||||||
using Ocelot.Logging;
|
using Ocelot.Logging;
|
||||||
@ -18,16 +15,16 @@ namespace Ocelot.Errors.Middleware
|
|||||||
public class ExceptionHandlerMiddleware : OcelotMiddleware
|
public class ExceptionHandlerMiddleware : OcelotMiddleware
|
||||||
{
|
{
|
||||||
private readonly OcelotRequestDelegate _next;
|
private readonly OcelotRequestDelegate _next;
|
||||||
private readonly IOcelotConfigurationProvider _provider;
|
private readonly IInternalConfigurationRepository _configRepo;
|
||||||
private readonly IRequestScopedDataRepository _repo;
|
private readonly IRequestScopedDataRepository _repo;
|
||||||
|
|
||||||
public ExceptionHandlerMiddleware(OcelotRequestDelegate next,
|
public ExceptionHandlerMiddleware(OcelotRequestDelegate next,
|
||||||
IOcelotLoggerFactory loggerFactory,
|
IOcelotLoggerFactory loggerFactory,
|
||||||
IOcelotConfigurationProvider provider,
|
IInternalConfigurationRepository configRepo,
|
||||||
IRequestScopedDataRepository repo)
|
IRequestScopedDataRepository repo)
|
||||||
: base(loggerFactory.CreateLogger<ExceptionHandlerMiddleware>())
|
: base(loggerFactory.CreateLogger<ExceptionHandlerMiddleware>())
|
||||||
{
|
{
|
||||||
_provider = provider;
|
_configRepo = configRepo;
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
_next = next;
|
_next = next;
|
||||||
}
|
}
|
||||||
@ -36,7 +33,7 @@ namespace Ocelot.Errors.Middleware
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await TrySetGlobalRequestId(context);
|
TrySetGlobalRequestId(context);
|
||||||
|
|
||||||
Logger.LogDebug("ocelot pipeline started");
|
Logger.LogDebug("ocelot pipeline started");
|
||||||
|
|
||||||
@ -56,12 +53,12 @@ namespace Ocelot.Errors.Middleware
|
|||||||
Logger.LogDebug("ocelot pipeline finished");
|
Logger.LogDebug("ocelot pipeline finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task TrySetGlobalRequestId(DownstreamContext context)
|
private void TrySetGlobalRequestId(DownstreamContext context)
|
||||||
{
|
{
|
||||||
//try and get the global request id and set it for logs...
|
//try and get the global request id and set it for logs...
|
||||||
//should this basically be immutable per request...i guess it should!
|
//should this basically be immutable per request...i guess it should!
|
||||||
//first thing is get config
|
//first thing is get config
|
||||||
var configuration = await _provider.Get();
|
var configuration = _configRepo.Get();
|
||||||
|
|
||||||
if(configuration.IsError)
|
if(configuration.IsError)
|
||||||
{
|
{
|
||||||
|
@ -4,14 +4,12 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.Creator;
|
using Ocelot.Configuration.Creator;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
using Ocelot.Configuration.Repository;
|
using Ocelot.Configuration.Repository;
|
||||||
using Ocelot.Configuration.Setter;
|
using Ocelot.Configuration.Setter;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
@ -85,63 +83,108 @@
|
|||||||
node.Start(nodeId.Id);
|
node.Start(nodeId.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<IOcelotConfiguration> CreateConfiguration(IApplicationBuilder builder)
|
private static async Task<IInternalConfiguration> CreateConfiguration(IApplicationBuilder builder)
|
||||||
{
|
{
|
||||||
var deps = GetDependencies(builder);
|
// make configuration from file system?
|
||||||
|
// earlier user needed to add ocelot files in startup configuration stuff, asp.net will map it to this
|
||||||
|
var fileConfig = (IOptions<FileConfiguration>)builder.ApplicationServices.GetService(typeof(IOptions<FileConfiguration>));
|
||||||
|
|
||||||
var ocelotConfiguration = await deps.provider.Get();
|
// now create the config
|
||||||
|
var internalConfigCreator = (IInternalConfigurationCreator)builder.ApplicationServices.GetService(typeof(IInternalConfigurationCreator));
|
||||||
|
var internalConfig = await internalConfigCreator.Create(fileConfig.Value);
|
||||||
|
|
||||||
if (ConfigurationNotSetUp(ocelotConfiguration))
|
// now save it in memory
|
||||||
|
var internalConfigRepo = (IInternalConfigurationRepository)builder.ApplicationServices.GetService(typeof(IInternalConfigurationRepository));
|
||||||
|
internalConfigRepo.AddOrReplace(internalConfig.Data);
|
||||||
|
|
||||||
|
var fileConfigSetter = (IFileConfigurationSetter)builder.ApplicationServices.GetService(typeof(IFileConfigurationSetter));
|
||||||
|
|
||||||
|
var fileConfigRepo = (IFileConfigurationRepository)builder.ApplicationServices.GetService(typeof(IFileConfigurationRepository));
|
||||||
|
|
||||||
|
if (UsingConsul(fileConfigRepo))
|
||||||
{
|
{
|
||||||
var response = await SetConfig(builder, deps.fileConfiguration, deps.setter, deps.provider, deps.repo);
|
await SetFileConfigInConsul(builder, fileConfigRepo, fileConfig, internalConfigCreator, internalConfigRepo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await SetFileConfig(fileConfigSetter, fileConfig);
|
||||||
|
}
|
||||||
|
|
||||||
if (UnableToSetConfig(response))
|
return GetOcelotConfigAndReturn(internalConfigRepo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task SetFileConfigInConsul(IApplicationBuilder builder,
|
||||||
|
IFileConfigurationRepository fileConfigRepo, IOptions<FileConfiguration> fileConfig,
|
||||||
|
IInternalConfigurationCreator internalConfigCreator, IInternalConfigurationRepository internalConfigRepo)
|
||||||
|
{
|
||||||
|
// get the config from consul.
|
||||||
|
var fileConfigFromConsul = await fileConfigRepo.Get();
|
||||||
|
|
||||||
|
if (IsError(fileConfigFromConsul))
|
||||||
|
{
|
||||||
|
ThrowToStopOcelotStarting(fileConfigFromConsul);
|
||||||
|
}
|
||||||
|
else if (ConfigNotStoredInConsul(fileConfigFromConsul))
|
||||||
|
{
|
||||||
|
//there was no config in consul set the file in config in consul
|
||||||
|
await fileConfigRepo.Set(fileConfig.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// create the internal config from consul data
|
||||||
|
var internalConfig = await internalConfigCreator.Create(fileConfigFromConsul.Data);
|
||||||
|
|
||||||
|
if (IsError(internalConfig))
|
||||||
{
|
{
|
||||||
ThrowToStopOcelotStarting(response);
|
ThrowToStopOcelotStarting(internalConfig);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// add the internal config to the internal repo
|
||||||
|
var response = internalConfigRepo.AddOrReplace(internalConfig.Data);
|
||||||
|
|
||||||
|
if (IsError(response))
|
||||||
|
{
|
||||||
|
ThrowToStopOcelotStarting(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsError(internalConfig))
|
||||||
|
{
|
||||||
|
ThrowToStopOcelotStarting(internalConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return await GetOcelotConfigAndReturn(deps.provider);
|
//todo - this starts the poller if it has been registered...please this is so bad.
|
||||||
|
var hack = builder.ApplicationServices.GetService(typeof(ConsulFileConfigurationPoller));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<Response> SetConfig(IApplicationBuilder builder, IOptions<FileConfiguration> fileConfiguration, IFileConfigurationSetter setter, IOcelotConfigurationProvider provider, IFileConfigurationRepository repo)
|
private static async Task SetFileConfig(IFileConfigurationSetter fileConfigSetter, IOptions<FileConfiguration> fileConfig)
|
||||||
{
|
{
|
||||||
if (UsingConsul(repo))
|
Response response;
|
||||||
{
|
response = await fileConfigSetter.Set(fileConfig.Value);
|
||||||
return await SetUpConfigFromConsul(builder, repo, setter, fileConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await setter.Set(fileConfiguration.Value);
|
if (IsError(response))
|
||||||
|
{
|
||||||
|
ThrowToStopOcelotStarting(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool UnableToSetConfig(Response response)
|
private static bool ConfigNotStoredInConsul(Responses.Response<FileConfiguration> fileConfigFromConsul)
|
||||||
|
{
|
||||||
|
return fileConfigFromConsul.Data == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsError(Response response)
|
||||||
{
|
{
|
||||||
return response == null || response.IsError;
|
return response == null || response.IsError;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ConfigurationNotSetUp(Ocelot.Responses.Response<IOcelotConfiguration> ocelotConfiguration)
|
private static IInternalConfiguration GetOcelotConfigAndReturn(IInternalConfigurationRepository provider)
|
||||||
{
|
{
|
||||||
return ocelotConfiguration == null || ocelotConfiguration.Data == null || ocelotConfiguration.IsError;
|
var ocelotConfiguration = provider.Get();
|
||||||
}
|
|
||||||
|
|
||||||
private static (IOptions<FileConfiguration> fileConfiguration, IFileConfigurationSetter setter, IOcelotConfigurationProvider provider, IFileConfigurationRepository repo) GetDependencies(IApplicationBuilder builder)
|
if(ocelotConfiguration?.Data == null || ocelotConfiguration.IsError)
|
||||||
{
|
|
||||||
var fileConfiguration = (IOptions<FileConfiguration>)builder.ApplicationServices.GetService(typeof(IOptions<FileConfiguration>));
|
|
||||||
|
|
||||||
var setter = (IFileConfigurationSetter)builder.ApplicationServices.GetService(typeof(IFileConfigurationSetter));
|
|
||||||
|
|
||||||
var provider = (IOcelotConfigurationProvider)builder.ApplicationServices.GetService(typeof(IOcelotConfigurationProvider));
|
|
||||||
|
|
||||||
var repo = (IFileConfigurationRepository)builder.ApplicationServices.GetService(typeof(IFileConfigurationRepository));
|
|
||||||
|
|
||||||
return (fileConfiguration, setter, provider, repo);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task<IOcelotConfiguration> GetOcelotConfigAndReturn(IOcelotConfigurationProvider provider)
|
|
||||||
{
|
|
||||||
var ocelotConfiguration = await provider.Get();
|
|
||||||
|
|
||||||
if(ocelotConfiguration == null || ocelotConfiguration.Data == null || ocelotConfiguration.IsError)
|
|
||||||
{
|
{
|
||||||
ThrowToStopOcelotStarting(ocelotConfiguration);
|
ThrowToStopOcelotStarting(ocelotConfiguration);
|
||||||
}
|
}
|
||||||
@ -159,49 +202,7 @@
|
|||||||
return fileConfigRepo.GetType() == typeof(ConsulFileConfigurationRepository);
|
return fileConfigRepo.GetType() == typeof(ConsulFileConfigurationRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<Response> SetUpConfigFromConsul(IApplicationBuilder builder, IFileConfigurationRepository consulFileConfigRepo, IFileConfigurationSetter setter, IOptions<FileConfiguration> fileConfig)
|
private static void CreateAdministrationArea(IApplicationBuilder builder, IInternalConfiguration configuration)
|
||||||
{
|
|
||||||
Response config = null;
|
|
||||||
|
|
||||||
var ocelotConfigurationRepository =
|
|
||||||
(IOcelotConfigurationRepository) builder.ApplicationServices.GetService(
|
|
||||||
typeof(IOcelotConfigurationRepository));
|
|
||||||
|
|
||||||
var ocelotConfigurationCreator =
|
|
||||||
(IOcelotConfigurationCreator) builder.ApplicationServices.GetService(
|
|
||||||
typeof(IOcelotConfigurationCreator));
|
|
||||||
|
|
||||||
var fileConfigFromConsul = await consulFileConfigRepo.Get();
|
|
||||||
|
|
||||||
if (fileConfigFromConsul.Data == null)
|
|
||||||
{
|
|
||||||
config = await setter.Set(fileConfig.Value);
|
|
||||||
var hack = builder.ApplicationServices.GetService(typeof(ConsulFileConfigurationPoller));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var ocelotConfig = await ocelotConfigurationCreator.Create(fileConfigFromConsul.Data);
|
|
||||||
|
|
||||||
if(ocelotConfig.IsError)
|
|
||||||
{
|
|
||||||
return new ErrorResponse(ocelotConfig.Errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
config = await ocelotConfigurationRepository.AddOrReplace(ocelotConfig.Data);
|
|
||||||
|
|
||||||
if (config.IsError)
|
|
||||||
{
|
|
||||||
return new ErrorResponse(config.Errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
//todo - this starts the poller if it has been registered...please this is so bad.
|
|
||||||
var hack = builder.ApplicationServices.GetService(typeof(ConsulFileConfigurationPoller));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new OkResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CreateAdministrationArea(IApplicationBuilder builder, IOcelotConfiguration configuration)
|
|
||||||
{
|
{
|
||||||
if(!string.IsNullOrEmpty(configuration.AdministrationPath))
|
if(!string.IsNullOrEmpty(configuration.AdministrationPath))
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.Provider;
|
using Ocelot.Configuration.Repository;
|
||||||
using Ocelot.Middleware;
|
using Ocelot.Middleware;
|
||||||
using Rafty.Concensus;
|
using Rafty.Concensus;
|
||||||
using Rafty.Infrastructure;
|
using Rafty.Infrastructure;
|
||||||
@ -15,21 +13,20 @@ namespace Ocelot.Raft
|
|||||||
public class FilePeersProvider : IPeersProvider
|
public class FilePeersProvider : IPeersProvider
|
||||||
{
|
{
|
||||||
private readonly IOptions<FilePeers> _options;
|
private readonly IOptions<FilePeers> _options;
|
||||||
private List<IPeer> _peers;
|
private readonly List<IPeer> _peers;
|
||||||
private IBaseUrlFinder _finder;
|
private IBaseUrlFinder _finder;
|
||||||
private IOcelotConfigurationProvider _provider;
|
private IInternalConfigurationRepository _repo;
|
||||||
private IIdentityServerConfiguration _identityServerConfig;
|
private IIdentityServerConfiguration _identityServerConfig;
|
||||||
|
|
||||||
public FilePeersProvider(IOptions<FilePeers> options, IBaseUrlFinder finder, IOcelotConfigurationProvider provider, IIdentityServerConfiguration identityServerConfig)
|
public FilePeersProvider(IOptions<FilePeers> options, IBaseUrlFinder finder, IInternalConfigurationRepository repo, IIdentityServerConfiguration identityServerConfig)
|
||||||
{
|
{
|
||||||
_identityServerConfig = identityServerConfig;
|
_identityServerConfig = identityServerConfig;
|
||||||
_provider = provider;
|
_repo = repo;
|
||||||
_finder = finder;
|
_finder = finder;
|
||||||
_options = options;
|
_options = options;
|
||||||
_peers = new List<IPeer>();
|
_peers = new List<IPeer>();
|
||||||
|
|
||||||
//todo - sort out async nonsense..
|
var config = _repo.Get();
|
||||||
var config = _provider.Get().GetAwaiter().GetResult();
|
|
||||||
foreach (var item in _options.Value.Peers)
|
foreach (var item in _options.Value.Peers)
|
||||||
{
|
{
|
||||||
var httpClient = new HttpClient();
|
var httpClient = new HttpClient();
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ocelot.Authentication;
|
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
using Ocelot.Middleware;
|
using Ocelot.Middleware;
|
||||||
using Rafty.Concensus;
|
using Rafty.Concensus;
|
||||||
using Rafty.FiniteStateMachine;
|
using Rafty.FiniteStateMachine;
|
||||||
@ -16,15 +12,15 @@ namespace Ocelot.Raft
|
|||||||
[ExcludeFromCoverage]
|
[ExcludeFromCoverage]
|
||||||
public class HttpPeer : IPeer
|
public class HttpPeer : IPeer
|
||||||
{
|
{
|
||||||
private string _hostAndPort;
|
private readonly string _hostAndPort;
|
||||||
private HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private JsonSerializerSettings _jsonSerializerSettings;
|
private readonly JsonSerializerSettings _jsonSerializerSettings;
|
||||||
private string _baseSchemeUrlAndPort;
|
private readonly string _baseSchemeUrlAndPort;
|
||||||
private BearerToken _token;
|
private BearerToken _token;
|
||||||
private IOcelotConfiguration _config;
|
private readonly IInternalConfiguration _config;
|
||||||
private IIdentityServerConfiguration _identityServerConfiguration;
|
private readonly IIdentityServerConfiguration _identityServerConfiguration;
|
||||||
|
|
||||||
public HttpPeer(string hostAndPort, HttpClient httpClient, IBaseUrlFinder finder, IOcelotConfiguration config, IIdentityServerConfiguration identityServerConfiguration)
|
public HttpPeer(string hostAndPort, HttpClient httpClient, IBaseUrlFinder finder, IInternalConfiguration config, IIdentityServerConfiguration identityServerConfiguration)
|
||||||
{
|
{
|
||||||
_identityServerConfiguration = identityServerConfiguration;
|
_identityServerConfiguration = identityServerConfiguration;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
@ -303,7 +303,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
{
|
{
|
||||||
if (context.Request.Method.ToLower() == "get" && context.Request.Path.Value == "/v1/kv/OcelotConfiguration")
|
if (context.Request.Method.ToLower() == "get" && context.Request.Path.Value == "/v1/kv/InternalConfiguration")
|
||||||
{
|
{
|
||||||
var json = JsonConvert.SerializeObject(_config);
|
var json = JsonConvert.SerializeObject(_config);
|
||||||
|
|
||||||
@ -315,7 +315,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
await context.Response.WriteJsonAsync(new FakeConsulGetResponse[] { kvp });
|
await context.Response.WriteJsonAsync(new FakeConsulGetResponse[] { kvp });
|
||||||
}
|
}
|
||||||
else if (context.Request.Method.ToLower() == "put" && context.Request.Path.Value == "/v1/kv/OcelotConfiguration")
|
else if (context.Request.Method.ToLower() == "put" && context.Request.Path.Value == "/v1/kv/InternalConfiguration")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -352,7 +352,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
public int CreateIndex => 100;
|
public int CreateIndex => 100;
|
||||||
public int ModifyIndex => 200;
|
public int ModifyIndex => 200;
|
||||||
public int LockIndex => 200;
|
public int LockIndex => 200;
|
||||||
public string Key => "OcelotConfiguration";
|
public string Key => "InternalConfiguration";
|
||||||
public int Flags => 0;
|
public int Flags => 0;
|
||||||
public string Value { get; private set; }
|
public string Value { get; private set; }
|
||||||
public string Session => "adf4238a-882b-9ddc-4a9d-5b6758e4159e";
|
public string Session => "adf4238a-882b-9ddc-4a9d-5b6758e4159e";
|
||||||
|
@ -26,7 +26,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
_counter = 0;
|
_counter = 0;
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
_configurationPath = "configuration.json";
|
_configurationPath = "ocelot.json";
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="configuration.json;appsettings.json">
|
<None Update="appsettings.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -66,7 +66,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureLogging((hostingContext, logging) =>
|
.ConfigureLogging((hostingContext, logging) =>
|
||||||
@ -124,7 +124,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -152,7 +152,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -190,7 +190,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -221,7 +221,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -254,7 +254,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -287,7 +287,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -319,7 +319,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -358,7 +358,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -400,7 +400,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -437,7 +437,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -465,7 +465,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -525,7 +525,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var builder = new ConfigurationBuilder()
|
var builder = new ConfigurationBuilder()
|
||||||
.SetBasePath(Directory.GetCurrentDirectory())
|
.SetBasePath(Directory.GetCurrentDirectory())
|
||||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile("configuration.json")
|
.AddJsonFile("ocelot.json")
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
|
|
||||||
var configuration = builder.Build();
|
var configuration = builder.Build();
|
||||||
|
@ -5,6 +5,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
public static class TestConfiguration
|
public static class TestConfiguration
|
||||||
{
|
{
|
||||||
public static string ConfigurationPath => Path.Combine(AppContext.BaseDirectory, "configuration.json");
|
public static string ConfigurationPath => Path.Combine(AppContext.BaseDirectory, "ocelot.json");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
{
|
|
||||||
"ReRoutes": [
|
|
||||||
{
|
|
||||||
"DownstreamPathTemplate": "41879/",
|
|
||||||
"UpstreamPathTemplate": "/",
|
|
||||||
"UpstreamHttpMethod": "Get",
|
|
||||||
"AuthenticationOptions": {
|
|
||||||
"Provider": null,
|
|
||||||
"ProviderRootUrl": null,
|
|
||||||
"ApiName": null,
|
|
||||||
"RequireHttps": false,
|
|
||||||
"AllowedScopes": [],
|
|
||||||
"ApiSecret": null
|
|
||||||
},
|
|
||||||
"AddHeadersToRequest": {},
|
|
||||||
"AddClaimsToRequest": {},
|
|
||||||
"RouteClaimsRequirement": {},
|
|
||||||
"AddQueriesToRequest": {},
|
|
||||||
"RequestIdKey": null,
|
|
||||||
"FileCacheOptions": {
|
|
||||||
"TtlSeconds": 0
|
|
||||||
},
|
|
||||||
"ReRouteIsCaseSensitive": false,
|
|
||||||
"ServiceName": null,
|
|
||||||
"DownstreamScheme": "http",
|
|
||||||
"DownstreamHost": "localhost",
|
|
||||||
"DownstreamPort": 41879,
|
|
||||||
"QoSOptions": {
|
|
||||||
"ExceptionsAllowedBeforeBreaking": 0,
|
|
||||||
"DurationOfBreak": 0,
|
|
||||||
"TimeoutValue": 0
|
|
||||||
},
|
|
||||||
"LoadBalancer": null,
|
|
||||||
"RateLimitOptions": {
|
|
||||||
"ClientWhitelist": [],
|
|
||||||
"EnableRateLimiting": false,
|
|
||||||
"Period": null,
|
|
||||||
"PeriodTimespan": 0,
|
|
||||||
"Limit": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"GlobalConfiguration": {
|
|
||||||
"RequestIdKey": null,
|
|
||||||
"ServiceDiscoveryProvider": {
|
|
||||||
"Provider": null,
|
|
||||||
"Host": null,
|
|
||||||
"Port": 0
|
|
||||||
},
|
|
||||||
"AdministrationPath": null,
|
|
||||||
"RateLimitOptions": {
|
|
||||||
"ClientIdHeader": "ClientId",
|
|
||||||
"QuotaExceededMessage": null,
|
|
||||||
"RateLimitCounterPrefix": "ocelot",
|
|
||||||
"DisableRateLimitHeaders": false,
|
|
||||||
"HttpStatusCode": 429
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -461,7 +461,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x =>
|
.ConfigureServices(x =>
|
||||||
@ -579,7 +579,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x => {
|
.ConfigureServices(x => {
|
||||||
@ -612,7 +612,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x =>
|
.ConfigureServices(x =>
|
||||||
@ -652,7 +652,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x => {
|
.ConfigureServices(x => {
|
||||||
@ -675,7 +675,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
|
|
||||||
private void GivenThereIsAConfiguration(FileConfiguration fileConfiguration)
|
private void GivenThereIsAConfiguration(FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
var configurationPath = $"{Directory.GetCurrentDirectory()}/configuration.json";
|
var configurationPath = $"{Directory.GetCurrentDirectory()}/ocelot.json";
|
||||||
|
|
||||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
||||||
|
|
||||||
@ -688,7 +688,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
|
|
||||||
var text = File.ReadAllText(configurationPath);
|
var text = File.ReadAllText(configurationPath);
|
||||||
|
|
||||||
configurationPath = $"{AppContext.BaseDirectory}/configuration.json";
|
configurationPath = $"{AppContext.BaseDirectory}/ocelot.json";
|
||||||
|
|
||||||
if (File.Exists(configurationPath))
|
if (File.Exists(configurationPath))
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<CodeAnalysisRuleSet>..\..\codeanalysis.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>..\..\codeanalysis.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="peers.json;configuration.json;appsettings.json;idsrv3test.pfx">
|
<None Update="peers.json;appsettings.json;idsrv3test.pfx">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -301,7 +301,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
|
|
||||||
private void GivenThereIsAConfiguration(FileConfiguration fileConfiguration)
|
private void GivenThereIsAConfiguration(FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
var configurationPath = $"{Directory.GetCurrentDirectory()}/configuration.json";
|
var configurationPath = $"{Directory.GetCurrentDirectory()}/ocelot.json";
|
||||||
|
|
||||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
||||||
|
|
||||||
@ -314,7 +314,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
|
|
||||||
var text = File.ReadAllText(configurationPath);
|
var text = File.ReadAllText(configurationPath);
|
||||||
|
|
||||||
configurationPath = $"{AppContext.BaseDirectory}/configuration.json";
|
configurationPath = $"{AppContext.BaseDirectory}/ocelot.json";
|
||||||
|
|
||||||
if (File.Exists(configurationPath))
|
if (File.Exists(configurationPath))
|
||||||
{
|
{
|
||||||
@ -340,7 +340,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddJsonFile("peers.json", optional: true, reloadOnChange: true);
|
config.AddJsonFile("peers.json", optional: true, reloadOnChange: true);
|
||||||
#pragma warning disable CS0618
|
#pragma warning disable CS0618
|
||||||
config.AddOcelotBaseUrl(url);
|
config.AddOcelotBaseUrl(url);
|
||||||
|
@ -108,7 +108,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
config.AddJsonFile("configuration.json");
|
config.AddJsonFile("ocelot.json");
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x =>
|
.ConfigureServices(x =>
|
||||||
@ -138,7 +138,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
|
|
||||||
private void GivenThereIsAConfiguration(FileConfiguration fileConfiguration)
|
private void GivenThereIsAConfiguration(FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
var configurationPath = $"{Directory.GetCurrentDirectory()}/configuration.json";
|
var configurationPath = $"{Directory.GetCurrentDirectory()}/ocelot.json";
|
||||||
|
|
||||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
|
|
||||||
var text = File.ReadAllText(configurationPath);
|
var text = File.ReadAllText(configurationPath);
|
||||||
|
|
||||||
configurationPath = $"{AppContext.BaseDirectory}/configuration.json";
|
configurationPath = $"{AppContext.BaseDirectory}/ocelot.json";
|
||||||
|
|
||||||
if (File.Exists(configurationPath))
|
if (File.Exists(configurationPath))
|
||||||
{
|
{
|
||||||
|
0
test/Ocelot.IntegrationTests/configuration.json → test/Ocelot.IntegrationTests/ocelot.json
Executable file → Normal file
0
test/Ocelot.IntegrationTests/configuration.json → test/Ocelot.IntegrationTests/ocelot.json
Executable file → Normal file
@ -16,7 +16,7 @@
|
|||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="configuration.json;appsettings.json;idsrv3test.pfx">
|
<None Update="ocelot.json;appsettings.json;idsrv3test.pfx">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -21,7 +21,7 @@ namespace Ocelot.ManualTest
|
|||||||
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
|
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
|
||||||
.AddJsonFile("appsettings.json", true, true)
|
.AddJsonFile("appsettings.json", true, true)
|
||||||
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
|
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
|
||||||
.AddJsonFile("configuration.json")
|
.AddJsonFile("ocelot.json")
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s => {
|
.ConfigureServices(s => {
|
||||||
|
@ -1,22 +1,18 @@
|
|||||||
using System.Collections.Generic;
|
namespace Ocelot.UnitTests.Configuration
|
||||||
using Castle.Components.DictionaryAdapter;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Moq;
|
|
||||||
using Ocelot.Cache;
|
|
||||||
using Ocelot.Configuration;
|
|
||||||
using Ocelot.Configuration.Builder;
|
|
||||||
using Ocelot.Configuration.Creator;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using Ocelot.Configuration.Validator;
|
|
||||||
using Ocelot.Logging;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Configuration
|
|
||||||
{
|
{
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
|
using Moq;
|
||||||
|
using Ocelot.Cache;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.Configuration.Builder;
|
||||||
|
using Ocelot.Configuration.Creator;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Ocelot.Configuration.Validator;
|
||||||
|
using Ocelot.Logging;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
using Shouldly;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
using Ocelot.DependencyInjection;
|
using Ocelot.DependencyInjection;
|
||||||
using Ocelot.Errors;
|
using Ocelot.Errors;
|
||||||
using Ocelot.UnitTests.TestData;
|
using Ocelot.UnitTests.TestData;
|
||||||
@ -24,23 +20,22 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
public class FileConfigurationCreatorTests
|
public class FileConfigurationCreatorTests
|
||||||
{
|
{
|
||||||
private readonly Mock<IOptions<FileConfiguration>> _fileConfig;
|
|
||||||
private readonly Mock<IConfigurationValidator> _validator;
|
private readonly Mock<IConfigurationValidator> _validator;
|
||||||
private Response<IOcelotConfiguration> _config;
|
private Response<IInternalConfiguration> _config;
|
||||||
private FileConfiguration _fileConfiguration;
|
private FileConfiguration _fileConfiguration;
|
||||||
private readonly Mock<IOcelotLoggerFactory> _logger;
|
private readonly Mock<IOcelotLoggerFactory> _logger;
|
||||||
private readonly FileOcelotConfigurationCreator _ocelotConfigurationCreator;
|
private readonly FileInternalConfigurationCreator _internalConfigurationCreator;
|
||||||
private Mock<IClaimsToThingCreator> _claimsToThingCreator;
|
private readonly Mock<IClaimsToThingCreator> _claimsToThingCreator;
|
||||||
private Mock<IAuthenticationOptionsCreator> _authOptionsCreator;
|
private readonly Mock<IAuthenticationOptionsCreator> _authOptionsCreator;
|
||||||
private Mock<IUpstreamTemplatePatternCreator> _upstreamTemplatePatternCreator;
|
private readonly Mock<IUpstreamTemplatePatternCreator> _upstreamTemplatePatternCreator;
|
||||||
private Mock<IRequestIdKeyCreator> _requestIdKeyCreator;
|
private readonly Mock<IRequestIdKeyCreator> _requestIdKeyCreator;
|
||||||
private Mock<IServiceProviderConfigurationCreator> _serviceProviderConfigCreator;
|
private readonly Mock<IServiceProviderConfigurationCreator> _serviceProviderConfigCreator;
|
||||||
private Mock<IQoSOptionsCreator> _qosOptionsCreator;
|
private readonly Mock<IQoSOptionsCreator> _qosOptionsCreator;
|
||||||
private Mock<IReRouteOptionsCreator> _fileReRouteOptionsCreator;
|
private readonly Mock<IReRouteOptionsCreator> _fileReRouteOptionsCreator;
|
||||||
private Mock<IRateLimitOptionsCreator> _rateLimitOptions;
|
private readonly Mock<IRateLimitOptionsCreator> _rateLimitOptions;
|
||||||
private Mock<IRegionCreator> _regionCreator;
|
private readonly Mock<IRegionCreator> _regionCreator;
|
||||||
private Mock<IHttpHandlerOptionsCreator> _httpHandlerOptionsCreator;
|
private readonly Mock<IHttpHandlerOptionsCreator> _httpHandlerOptionsCreator;
|
||||||
private Mock<IAdministrationPath> _adminPath;
|
private readonly Mock<IAdministrationPath> _adminPath;
|
||||||
private readonly Mock<IHeaderFindAndReplaceCreator> _headerFindAndReplaceCreator;
|
private readonly Mock<IHeaderFindAndReplaceCreator> _headerFindAndReplaceCreator;
|
||||||
private readonly Mock<IDownstreamAddressesCreator> _downstreamAddressesCreator;
|
private readonly Mock<IDownstreamAddressesCreator> _downstreamAddressesCreator;
|
||||||
|
|
||||||
@ -48,7 +43,6 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
_logger = new Mock<IOcelotLoggerFactory>();
|
_logger = new Mock<IOcelotLoggerFactory>();
|
||||||
_validator = new Mock<IConfigurationValidator>();
|
_validator = new Mock<IConfigurationValidator>();
|
||||||
_fileConfig = new Mock<IOptions<FileConfiguration>>();
|
|
||||||
_claimsToThingCreator = new Mock<IClaimsToThingCreator>();
|
_claimsToThingCreator = new Mock<IClaimsToThingCreator>();
|
||||||
_authOptionsCreator = new Mock<IAuthenticationOptionsCreator>();
|
_authOptionsCreator = new Mock<IAuthenticationOptionsCreator>();
|
||||||
_upstreamTemplatePatternCreator = new Mock<IUpstreamTemplatePatternCreator>();
|
_upstreamTemplatePatternCreator = new Mock<IUpstreamTemplatePatternCreator>();
|
||||||
@ -63,8 +57,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
_headerFindAndReplaceCreator = new Mock<IHeaderFindAndReplaceCreator>();
|
_headerFindAndReplaceCreator = new Mock<IHeaderFindAndReplaceCreator>();
|
||||||
_downstreamAddressesCreator = new Mock<IDownstreamAddressesCreator>();
|
_downstreamAddressesCreator = new Mock<IDownstreamAddressesCreator>();
|
||||||
|
|
||||||
_ocelotConfigurationCreator = new FileOcelotConfigurationCreator(
|
_internalConfigurationCreator = new FileInternalConfigurationCreator(
|
||||||
_fileConfig.Object,
|
|
||||||
_validator.Object,
|
_validator.Object,
|
||||||
_logger.Object,
|
_logger.Object,
|
||||||
_claimsToThingCreator.Object,
|
_claimsToThingCreator.Object,
|
||||||
@ -262,7 +255,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.And(x => x.GivenTheConfigIsValid())
|
.And(x => x.GivenTheConfigIsValid())
|
||||||
.And(x => x.GivenTheFollowingRegionIsReturned("region"))
|
.And(x => x.GivenTheFollowingRegionIsReturned("region"))
|
||||||
.When(x => x.WhenICreateTheConfig())
|
.When(x => x.WhenICreateTheConfig())
|
||||||
.Then(x => x.ThenTheRegionCreatorIsCalledCorrectly("region"))
|
.Then(x => x.ThenTheRegionCreatorIsCalledCorrectly())
|
||||||
.And(x => x.ThenTheHeaderFindAndReplaceCreatorIsCalledCorrectly())
|
.And(x => x.ThenTheHeaderFindAndReplaceCreatorIsCalledCorrectly())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
@ -800,14 +793,11 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
private void GivenTheConfigIs(FileConfiguration fileConfiguration)
|
private void GivenTheConfigIs(FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
_fileConfiguration = fileConfiguration;
|
_fileConfiguration = fileConfiguration;
|
||||||
_fileConfig
|
|
||||||
.Setup(x => x.Value)
|
|
||||||
.Returns(_fileConfiguration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WhenICreateTheConfig()
|
private void WhenICreateTheConfig()
|
||||||
{
|
{
|
||||||
_config = _ocelotConfigurationCreator.Create(_fileConfiguration).Result;
|
_config = _internalConfigurationCreator.Create(_fileConfiguration).Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheReRoutesAre(List<ReRoute> expectedReRoutes)
|
private void ThenTheReRoutesAre(List<ReRoute> expectedReRoutes)
|
||||||
@ -928,7 +918,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.Returns(region);
|
.Returns(region);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheRegionCreatorIsCalledCorrectly(string expected)
|
private void ThenTheRegionCreatorIsCalledCorrectly()
|
||||||
{
|
{
|
||||||
_regionCreator
|
_regionCreator
|
||||||
.Verify(x => x.Create(_fileConfiguration.ReRoutes[0]), Times.Once);
|
.Verify(x => x.Create(_fileConfiguration.ReRoutes[0]), Times.Once);
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Moq;
|
|
||||||
using Ocelot.Configuration;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
|
||||||
using Xunit;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System.IO;
|
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
using Ocelot.Configuration.Repository;
|
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Configuration
|
|
||||||
{
|
|
||||||
public class FileConfigurationProviderTests
|
|
||||||
{
|
|
||||||
private readonly IFileConfigurationProvider _provider;
|
|
||||||
private Mock<IFileConfigurationRepository> _repo;
|
|
||||||
private FileConfiguration _result;
|
|
||||||
private FileConfiguration _fileConfiguration;
|
|
||||||
|
|
||||||
public FileConfigurationProviderTests()
|
|
||||||
{
|
|
||||||
_repo = new Mock<IFileConfigurationRepository>();
|
|
||||||
_provider = new FileConfigurationProvider(_repo.Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_return_file_configuration()
|
|
||||||
{
|
|
||||||
var config = new FileConfiguration();
|
|
||||||
|
|
||||||
this.Given(x => x.GivenTheConfigurationIs(config))
|
|
||||||
.When(x => x.WhenIGetTheReRoutes())
|
|
||||||
.Then(x => x.ThenTheRepoIsCalledCorrectly())
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
|
||||||
{
|
|
||||||
_fileConfiguration = fileConfiguration;
|
|
||||||
_repo
|
|
||||||
.Setup(x => x.Get())
|
|
||||||
.ReturnsAsync(new OkResponse<FileConfiguration>(fileConfiguration));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenIGetTheReRoutes()
|
|
||||||
{
|
|
||||||
_result = _provider.Get().Result.Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenTheRepoIsCalledCorrectly()
|
|
||||||
{
|
|
||||||
_repo
|
|
||||||
.Verify(x => x.Get(), Times.Once);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,12 +18,16 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
private IFileConfigurationRepository _repo;
|
private IFileConfigurationRepository _repo;
|
||||||
private FileConfiguration _result;
|
private FileConfiguration _result;
|
||||||
private FileConfiguration _fileConfiguration;
|
private FileConfiguration _fileConfiguration;
|
||||||
private string _environmentName = "DEV";
|
|
||||||
|
// This is a bit dirty and it is dev.dev so that the ConfigurationBuilderExtensionsTests
|
||||||
|
// cant pick it up if they run in parralel..sigh these are not really unit
|
||||||
|
// tests but whatever...
|
||||||
|
private string _environmentName = "DEV.DEV";
|
||||||
|
|
||||||
public FileConfigurationRepositoryTests()
|
public FileConfigurationRepositoryTests()
|
||||||
{
|
{
|
||||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||||
_repo = new FileConfigurationRepository(_hostingEnvironment.Object);
|
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -75,7 +79,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
_environmentName = null;
|
_environmentName = null;
|
||||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||||
_repo = new FileConfigurationRepository(_hostingEnvironment.Object);
|
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenIHaveAConfiguration(FileConfiguration fileConfiguration)
|
private void GivenIHaveAConfiguration(FileConfiguration fileConfiguration)
|
||||||
@ -113,7 +117,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
var configurationPath = $"{AppContext.BaseDirectory}/configuration{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
var configurationPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
||||||
|
|
||||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
||||||
|
|
||||||
|
@ -18,19 +18,19 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
public class FileConfigurationSetterTests
|
public class FileConfigurationSetterTests
|
||||||
{
|
{
|
||||||
private FileConfiguration _fileConfiguration;
|
private FileConfiguration _fileConfiguration;
|
||||||
private FileConfigurationSetter _configSetter;
|
private FileAndInternalConfigurationSetter _configSetter;
|
||||||
private Mock<IOcelotConfigurationRepository> _configRepo;
|
private Mock<IInternalConfigurationRepository> _configRepo;
|
||||||
private Mock<IOcelotConfigurationCreator> _configCreator;
|
private Mock<IInternalConfigurationCreator> _configCreator;
|
||||||
private Response<IOcelotConfiguration> _configuration;
|
private Response<IInternalConfiguration> _configuration;
|
||||||
private object _result;
|
private object _result;
|
||||||
private Mock<IFileConfigurationRepository> _repo;
|
private Mock<IFileConfigurationRepository> _repo;
|
||||||
|
|
||||||
public FileConfigurationSetterTests()
|
public FileConfigurationSetterTests()
|
||||||
{
|
{
|
||||||
_repo = new Mock<IFileConfigurationRepository>();
|
_repo = new Mock<IFileConfigurationRepository>();
|
||||||
_configRepo = new Mock<IOcelotConfigurationRepository>();
|
_configRepo = new Mock<IInternalConfigurationRepository>();
|
||||||
_configCreator = new Mock<IOcelotConfigurationCreator>();
|
_configCreator = new Mock<IInternalConfigurationCreator>();
|
||||||
_configSetter = new FileConfigurationSetter(_configRepo.Object, _configCreator.Object, _repo.Object);
|
_configSetter = new FileAndInternalConfigurationSetter(_configRepo.Object, _configCreator.Object, _repo.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -38,11 +38,11 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
var fileConfig = new FileConfiguration();
|
var fileConfig = new FileConfiguration();
|
||||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||||
var config = new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf");
|
var config = new InternalConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf");
|
||||||
|
|
||||||
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
|
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
|
||||||
.And(x => GivenTheRepoReturns(new OkResponse()))
|
.And(x => GivenTheRepoReturns(new OkResponse()))
|
||||||
.And(x => GivenTheCreatorReturns(new OkResponse<IOcelotConfiguration>(config)))
|
.And(x => GivenTheCreatorReturns(new OkResponse<IInternalConfiguration>(config)))
|
||||||
.When(x => WhenISetTheConfiguration())
|
.When(x => WhenISetTheConfiguration())
|
||||||
.Then(x => ThenTheConfigurationRepositoryIsCalledCorrectly())
|
.Then(x => ThenTheConfigurationRepositoryIsCalledCorrectly())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -67,7 +67,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
|
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
|
||||||
.And(x => GivenTheRepoReturns(new OkResponse()))
|
.And(x => GivenTheRepoReturns(new OkResponse()))
|
||||||
.And(x => GivenTheCreatorReturns(new ErrorResponse<IOcelotConfiguration>(It.IsAny<Error>())))
|
.And(x => GivenTheCreatorReturns(new ErrorResponse<IInternalConfiguration>(It.IsAny<Error>())))
|
||||||
.When(x => WhenISetTheConfiguration())
|
.When(x => WhenISetTheConfiguration())
|
||||||
.And(x => ThenAnErrorResponseIsReturned())
|
.And(x => ThenAnErrorResponseIsReturned())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -85,7 +85,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
_result.ShouldBeOfType<ErrorResponse>();
|
_result.ShouldBeOfType<ErrorResponse>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenTheCreatorReturns(Response<IOcelotConfiguration> configuration)
|
private void GivenTheCreatorReturns(Response<IInternalConfiguration> configuration)
|
||||||
{
|
{
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_configCreator
|
_configCreator
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
using Ocelot.Configuration.Authentication;
|
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Configuration
|
|
||||||
{
|
|
||||||
public class HashMatcherTests
|
|
||||||
{
|
|
||||||
private string _password;
|
|
||||||
private string _hash;
|
|
||||||
private string _salt;
|
|
||||||
private bool _result;
|
|
||||||
private HashMatcher _hashMatcher;
|
|
||||||
|
|
||||||
public HashMatcherTests()
|
|
||||||
{
|
|
||||||
_hashMatcher = new HashMatcher();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_match_hash()
|
|
||||||
{
|
|
||||||
var hash = "kE/mxd1hO9h9Sl2VhGhwJUd9xZEv4NP6qXoN39nIqM4=";
|
|
||||||
var salt = "zzWITpnDximUNKYLiUam/w==";
|
|
||||||
var password = "secret";
|
|
||||||
|
|
||||||
this.Given(x => GivenThePassword(password))
|
|
||||||
.And(x => GivenTheHash(hash))
|
|
||||||
.And(x => GivenTheSalt(salt))
|
|
||||||
.When(x => WhenIMatch())
|
|
||||||
.Then(x => ThenTheResultIs(true))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_not_match_hash()
|
|
||||||
{
|
|
||||||
var hash = "kE/mxd1hO9h9Sl2VhGhwJUd9xZEv4NP6qXoN39nIqM4=";
|
|
||||||
var salt = "zzWITpnDximUNKYLiUam/w==";
|
|
||||||
var password = "secret1";
|
|
||||||
|
|
||||||
this.Given(x => GivenThePassword(password))
|
|
||||||
.And(x => GivenTheHash(hash))
|
|
||||||
.And(x => GivenTheSalt(salt))
|
|
||||||
.When(x => WhenIMatch())
|
|
||||||
.Then(x => ThenTheResultIs(false))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenThePassword(string password)
|
|
||||||
{
|
|
||||||
_password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheHash(string hash)
|
|
||||||
{
|
|
||||||
_hash = hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheSalt(string salt)
|
|
||||||
{
|
|
||||||
_salt = salt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenIMatch()
|
|
||||||
{
|
|
||||||
_result = _hashMatcher.Match(_password, _salt, _hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenTheResultIs(bool expected)
|
|
||||||
{
|
|
||||||
_result.ShouldBe(expected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -149,6 +149,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
|
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_add_trace_id_header()
|
public void should_add_trace_id_header()
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.Builder;
|
using Ocelot.Configuration.Builder;
|
||||||
using Ocelot.Configuration.Repository;
|
using Ocelot.Configuration.Repository;
|
||||||
@ -14,14 +12,14 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
public class InMemoryConfigurationRepositoryTests
|
public class InMemoryConfigurationRepositoryTests
|
||||||
{
|
{
|
||||||
private readonly InMemoryOcelotConfigurationRepository _repo;
|
private readonly InMemoryInternalConfigurationRepository _repo;
|
||||||
private IOcelotConfiguration _config;
|
private IInternalConfiguration _config;
|
||||||
private Response _result;
|
private Response _result;
|
||||||
private Response<IOcelotConfiguration> _getResult;
|
private Response<IInternalConfiguration> _getResult;
|
||||||
|
|
||||||
public InMemoryConfigurationRepositoryTests()
|
public InMemoryConfigurationRepositoryTests()
|
||||||
{
|
{
|
||||||
_repo = new InMemoryOcelotConfigurationRepository();
|
_repo = new InMemoryInternalConfigurationRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -49,7 +47,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
private void WhenIGetTheConfiguration()
|
private void WhenIGetTheConfiguration()
|
||||||
{
|
{
|
||||||
_getResult = _repo.Get().Result;
|
_getResult = _repo.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsASavedConfiguration()
|
private void GivenThereIsASavedConfiguration()
|
||||||
@ -58,14 +56,14 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
WhenIAddOrReplaceTheConfig();
|
WhenIAddOrReplaceTheConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenTheConfigurationIs(IOcelotConfiguration config)
|
private void GivenTheConfigurationIs(IInternalConfiguration config)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WhenIAddOrReplaceTheConfig()
|
private void WhenIAddOrReplaceTheConfig()
|
||||||
{
|
{
|
||||||
_result = _repo.AddOrReplace(_config).Result;
|
_result = _repo.AddOrReplace(_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenNoErrorsAreReturned()
|
private void ThenNoErrorsAreReturned()
|
||||||
@ -73,7 +71,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
_result.IsError.ShouldBeFalse();
|
_result.IsError.ShouldBeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeConfig : IOcelotConfiguration
|
class FakeConfig : IInternalConfiguration
|
||||||
{
|
{
|
||||||
private readonly string _downstreamTemplatePath;
|
private readonly string _downstreamTemplatePath;
|
||||||
|
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Moq;
|
|
||||||
using Ocelot.Configuration;
|
|
||||||
using Ocelot.Configuration.Builder;
|
|
||||||
using Ocelot.Configuration.Creator;
|
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
using Ocelot.Configuration.Repository;
|
|
||||||
using Ocelot.Errors;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Configuration
|
|
||||||
{
|
|
||||||
public class OcelotConfigurationProviderTests
|
|
||||||
{
|
|
||||||
private readonly IOcelotConfigurationProvider _ocelotConfigurationProvider;
|
|
||||||
private readonly Mock<IOcelotConfigurationRepository> _configurationRepository;
|
|
||||||
private Response<IOcelotConfiguration> _result;
|
|
||||||
|
|
||||||
public OcelotConfigurationProviderTests()
|
|
||||||
{
|
|
||||||
_configurationRepository = new Mock<IOcelotConfigurationRepository>();
|
|
||||||
_ocelotConfigurationProvider = new OcelotConfigurationProvider(_configurationRepository.Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_get_config()
|
|
||||||
{
|
|
||||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
|
||||||
|
|
||||||
this.Given(x => x.GivenTheRepoReturns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, ""))))
|
|
||||||
.When(x => x.WhenIGetTheConfig())
|
|
||||||
.Then(x => x.TheFollowingIsReturned(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, ""))))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_return_error()
|
|
||||||
{
|
|
||||||
this.Given(x => x.GivenTheRepoReturns(new ErrorResponse<IOcelotConfiguration>(new List<Error>
|
|
||||||
{
|
|
||||||
new AnyError()
|
|
||||||
})))
|
|
||||||
.When(x => x.WhenIGetTheConfig())
|
|
||||||
.Then(x => x.TheFollowingIsReturned(
|
|
||||||
new ErrorResponse<IOcelotConfiguration>(new List<Error>
|
|
||||||
{
|
|
||||||
new AnyError()
|
|
||||||
})))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheRepoReturns(Response<IOcelotConfiguration> config)
|
|
||||||
{
|
|
||||||
_configurationRepository
|
|
||||||
.Setup(x => x.Get())
|
|
||||||
.ReturnsAsync(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenIGetTheConfig()
|
|
||||||
{
|
|
||||||
_result = _ocelotConfigurationProvider.Get().Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TheFollowingIsReturned(Response<IOcelotConfiguration> expected)
|
|
||||||
{
|
|
||||||
_result.IsError.ShouldBe(expected.IsError);
|
|
||||||
}
|
|
||||||
|
|
||||||
class AnyError : Error
|
|
||||||
{
|
|
||||||
public AnyError()
|
|
||||||
: base("blamo", OcelotErrorCode.UnknownError)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,32 +8,30 @@ using Ocelot.Responses;
|
|||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Ocelot.Raft;
|
using Ocelot.Raft;
|
||||||
using Rafty.Concensus;
|
using Rafty.Concensus;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Rafty.FiniteStateMachine;
|
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Controllers
|
namespace Ocelot.UnitTests.Controllers
|
||||||
{
|
{
|
||||||
|
using Ocelot.Configuration.Repository;
|
||||||
|
|
||||||
public class FileConfigurationControllerTests
|
public class FileConfigurationControllerTests
|
||||||
{
|
{
|
||||||
private FileConfigurationController _controller;
|
private readonly FileConfigurationController _controller;
|
||||||
private Mock<IFileConfigurationProvider> _configGetter;
|
private readonly Mock<IFileConfigurationRepository> _repo;
|
||||||
private Mock<IFileConfigurationSetter> _configSetter;
|
private readonly Mock<IFileConfigurationSetter> _setter;
|
||||||
private IActionResult _result;
|
private IActionResult _result;
|
||||||
private FileConfiguration _fileConfiguration;
|
private FileConfiguration _fileConfiguration;
|
||||||
private Mock<IServiceProvider> _provider;
|
private readonly Mock<IServiceProvider> _provider;
|
||||||
private Mock<INode> _node;
|
private Mock<INode> _node;
|
||||||
|
|
||||||
public FileConfigurationControllerTests()
|
public FileConfigurationControllerTests()
|
||||||
{
|
{
|
||||||
_provider = new Mock<IServiceProvider>();
|
_provider = new Mock<IServiceProvider>();
|
||||||
_configGetter = new Mock<IFileConfigurationProvider>();
|
_repo = new Mock<IFileConfigurationRepository>();
|
||||||
_configSetter = new Mock<IFileConfigurationSetter>();
|
_setter = new Mock<IFileConfigurationSetter>();
|
||||||
_controller = new FileConfigurationController(_configGetter.Object, _configSetter.Object, _provider.Object);
|
_controller = new FileConfigurationController(_repo.Object, _setter.Object, _provider.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -140,14 +138,14 @@ namespace Ocelot.UnitTests.Controllers
|
|||||||
|
|
||||||
private void GivenTheConfigSetterReturns(Response response)
|
private void GivenTheConfigSetterReturns(Response response)
|
||||||
{
|
{
|
||||||
_configSetter
|
_setter
|
||||||
.Setup(x => x.Set(It.IsAny<FileConfiguration>()))
|
.Setup(x => x.Set(It.IsAny<FileConfiguration>()))
|
||||||
.ReturnsAsync(response);
|
.ReturnsAsync(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheConfigrationSetterIsCalledCorrectly()
|
private void ThenTheConfigrationSetterIsCalledCorrectly()
|
||||||
{
|
{
|
||||||
_configSetter
|
_setter
|
||||||
.Verify(x => x.Set(_fileConfiguration), Times.Once);
|
.Verify(x => x.Set(_fileConfiguration), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +166,7 @@ namespace Ocelot.UnitTests.Controllers
|
|||||||
|
|
||||||
private void GivenTheGetConfigurationReturns(Ocelot.Responses.Response<FileConfiguration> fileConfiguration)
|
private void GivenTheGetConfigurationReturns(Ocelot.Responses.Response<FileConfiguration> fileConfiguration)
|
||||||
{
|
{
|
||||||
_configGetter
|
_repo
|
||||||
.Setup(x => x.Get())
|
.Setup(x => x.Get())
|
||||||
.ReturnsAsync(fileConfiguration);
|
.ReturnsAsync(fileConfiguration);
|
||||||
}
|
}
|
||||||
@ -180,7 +178,7 @@ namespace Ocelot.UnitTests.Controllers
|
|||||||
|
|
||||||
private void TheTheGetFileConfigurationIsCalledCorrectly()
|
private void TheTheGetFileConfigurationIsCalledCorrectly()
|
||||||
{
|
{
|
||||||
_configGetter
|
_repo
|
||||||
.Verify(x => x.Get(), Times.Once);
|
.Verify(x => x.Get(), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,25 +1,213 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
namespace Ocelot.UnitTests.DependencyInjection
|
||||||
using Ocelot.DependencyInjection;
|
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.DependencyInjection
|
|
||||||
{
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Ocelot.DependencyInjection;
|
||||||
|
using Shouldly;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
public class ConfigurationBuilderExtensionsTests
|
public class ConfigurationBuilderExtensionsTests
|
||||||
{
|
{
|
||||||
private IConfigurationRoot _configuration;
|
private IConfigurationRoot _configuration;
|
||||||
private string _result;
|
private string _result;
|
||||||
|
private IConfigurationRoot _configRoot;
|
||||||
|
private FileConfiguration _globalConfig;
|
||||||
|
private FileConfiguration _reRouteA;
|
||||||
|
private FileConfiguration _reRouteB;
|
||||||
|
private FileConfiguration _aggregate;
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_add_base_url_to_config()
|
public void should_add_base_url_to_config()
|
||||||
{
|
{
|
||||||
this.Given(x => GivenTheBaseUrl("test"))
|
this.Given(_ => GivenTheBaseUrl("test"))
|
||||||
.When(x => WhenIGet("BaseUrl"))
|
.When(_ => WhenIGet("BaseUrl"))
|
||||||
.Then(x => ThenTheResultIs("test"))
|
.Then(_ => ThenTheResultIs("test"))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_merge_files()
|
||||||
|
{
|
||||||
|
this.Given(_ => GivenMultipleConfigurationFiles())
|
||||||
|
.When(_ => WhenIAddOcelotConfiguration())
|
||||||
|
.Then(_ => ThenTheConfigsAreMerged())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenMultipleConfigurationFiles()
|
||||||
|
{
|
||||||
|
_globalConfig = new FileConfiguration
|
||||||
|
{
|
||||||
|
GlobalConfiguration = new FileGlobalConfiguration
|
||||||
|
{
|
||||||
|
BaseUrl = "BaseUrl",
|
||||||
|
RateLimitOptions = new FileRateLimitOptions
|
||||||
|
{
|
||||||
|
HttpStatusCode = 500,
|
||||||
|
ClientIdHeader = "ClientIdHeader",
|
||||||
|
DisableRateLimitHeaders = true,
|
||||||
|
QuotaExceededMessage = "QuotaExceededMessage",
|
||||||
|
RateLimitCounterPrefix = "RateLimitCounterPrefix"
|
||||||
|
},
|
||||||
|
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||||
|
{
|
||||||
|
Host = "Host",
|
||||||
|
Port = 80,
|
||||||
|
Type = "Type"
|
||||||
|
},
|
||||||
|
RequestIdKey = "RequestIdKey"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_reRouteA = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamScheme = "DownstreamScheme",
|
||||||
|
DownstreamPathTemplate = "DownstreamPathTemplate",
|
||||||
|
Key = "Key",
|
||||||
|
UpstreamHost = "UpstreamHost",
|
||||||
|
UpstreamHttpMethod = new List<string>
|
||||||
|
{
|
||||||
|
"UpstreamHttpMethod"
|
||||||
|
},
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "Host",
|
||||||
|
Port = 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_reRouteB = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamScheme = "DownstreamSchemeB",
|
||||||
|
DownstreamPathTemplate = "DownstreamPathTemplateB",
|
||||||
|
Key = "KeyB",
|
||||||
|
UpstreamHost = "UpstreamHostB",
|
||||||
|
UpstreamHttpMethod = new List<string>
|
||||||
|
{
|
||||||
|
"UpstreamHttpMethodB"
|
||||||
|
},
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "HostB",
|
||||||
|
Port = 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamScheme = "DownstreamSchemeBB",
|
||||||
|
DownstreamPathTemplate = "DownstreamPathTemplateBB",
|
||||||
|
Key = "KeyBB",
|
||||||
|
UpstreamHost = "UpstreamHostBB",
|
||||||
|
UpstreamHttpMethod = new List<string>
|
||||||
|
{
|
||||||
|
"UpstreamHttpMethodBB"
|
||||||
|
},
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "HostBB",
|
||||||
|
Port = 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_aggregate = new FileConfiguration
|
||||||
|
{
|
||||||
|
Aggregates = new List<FileAggregateReRoute>
|
||||||
|
{
|
||||||
|
new FileAggregateReRoute
|
||||||
|
{
|
||||||
|
ReRouteKeys = new List<string>
|
||||||
|
{
|
||||||
|
"KeyB",
|
||||||
|
"KeyBB"
|
||||||
|
},
|
||||||
|
UpstreamPathTemplate = "UpstreamPathTemplate",
|
||||||
|
},
|
||||||
|
new FileAggregateReRoute
|
||||||
|
{
|
||||||
|
ReRouteKeys = new List<string>
|
||||||
|
{
|
||||||
|
"KeyB",
|
||||||
|
"KeyBB"
|
||||||
|
},
|
||||||
|
UpstreamPathTemplate = "UpstreamPathTemplate",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
File.WriteAllText("ocelot.global.json", JsonConvert.SerializeObject(_globalConfig));
|
||||||
|
File.WriteAllText("ocelot.reRoutesA.json", JsonConvert.SerializeObject(_reRouteA));
|
||||||
|
File.WriteAllText("ocelot.reRoutesB.json", JsonConvert.SerializeObject(_reRouteB));
|
||||||
|
File.WriteAllText("ocelot.aggregates.json", JsonConvert.SerializeObject(_aggregate));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenIAddOcelotConfiguration()
|
||||||
|
{
|
||||||
|
IConfigurationBuilder builder = new ConfigurationBuilder();
|
||||||
|
builder.AddOcelot();
|
||||||
|
_configRoot = builder.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheConfigsAreMerged()
|
||||||
|
{
|
||||||
|
var fc = (FileConfiguration)_configRoot.Get(typeof(FileConfiguration));
|
||||||
|
|
||||||
|
fc.GlobalConfiguration.BaseUrl.ShouldBe(_globalConfig.GlobalConfiguration.BaseUrl);
|
||||||
|
fc.GlobalConfiguration.RateLimitOptions.ClientIdHeader.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.ClientIdHeader);
|
||||||
|
fc.GlobalConfiguration.RateLimitOptions.DisableRateLimitHeaders.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.DisableRateLimitHeaders);
|
||||||
|
fc.GlobalConfiguration.RateLimitOptions.HttpStatusCode.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.HttpStatusCode);
|
||||||
|
fc.GlobalConfiguration.RateLimitOptions.QuotaExceededMessage.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.QuotaExceededMessage);
|
||||||
|
fc.GlobalConfiguration.RateLimitOptions.RateLimitCounterPrefix.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.RateLimitCounterPrefix);
|
||||||
|
fc.GlobalConfiguration.RequestIdKey.ShouldBe(_globalConfig.GlobalConfiguration.RequestIdKey);
|
||||||
|
fc.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
||||||
|
fc.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
||||||
|
fc.GlobalConfiguration.ServiceDiscoveryProvider.Type.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Type);
|
||||||
|
|
||||||
|
fc.ReRoutes.Count.ShouldBe(_reRouteA.ReRoutes.Count + _reRouteB.ReRoutes.Count);
|
||||||
|
|
||||||
|
fc.ReRoutes.ShouldContain(x => x.DownstreamPathTemplate == _reRouteA.ReRoutes[0].DownstreamPathTemplate);
|
||||||
|
fc.ReRoutes.ShouldContain(x => x.DownstreamPathTemplate == _reRouteB.ReRoutes[0].DownstreamPathTemplate);
|
||||||
|
fc.ReRoutes.ShouldContain(x => x.DownstreamPathTemplate == _reRouteB.ReRoutes[1].DownstreamPathTemplate);
|
||||||
|
|
||||||
|
fc.ReRoutes.ShouldContain(x => x.DownstreamScheme == _reRouteA.ReRoutes[0].DownstreamScheme);
|
||||||
|
fc.ReRoutes.ShouldContain(x => x.DownstreamScheme == _reRouteB.ReRoutes[0].DownstreamScheme);
|
||||||
|
fc.ReRoutes.ShouldContain(x => x.DownstreamScheme == _reRouteB.ReRoutes[1].DownstreamScheme);
|
||||||
|
|
||||||
|
fc.ReRoutes.ShouldContain(x => x.Key == _reRouteA.ReRoutes[0].Key);
|
||||||
|
fc.ReRoutes.ShouldContain(x => x.Key == _reRouteB.ReRoutes[0].Key);
|
||||||
|
fc.ReRoutes.ShouldContain(x => x.Key == _reRouteB.ReRoutes[1].Key);
|
||||||
|
|
||||||
|
fc.ReRoutes.ShouldContain(x => x.UpstreamHost == _reRouteA.ReRoutes[0].UpstreamHost);
|
||||||
|
fc.ReRoutes.ShouldContain(x => x.UpstreamHost == _reRouteB.ReRoutes[0].UpstreamHost);
|
||||||
|
fc.ReRoutes.ShouldContain(x => x.UpstreamHost == _reRouteB.ReRoutes[1].UpstreamHost);
|
||||||
|
|
||||||
|
fc.Aggregates.Count.ShouldBe(_aggregate.Aggregates.Count);
|
||||||
|
}
|
||||||
|
|
||||||
private void GivenTheBaseUrl(string baseUrl)
|
private void GivenTheBaseUrl(string baseUrl)
|
||||||
{
|
{
|
||||||
#pragma warning disable CS0618
|
#pragma warning disable CS0618
|
||||||
|
@ -325,8 +325,8 @@ namespace Ocelot.UnitTests.DependencyInjection
|
|||||||
var outputCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<CachedResponse>));
|
var outputCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<CachedResponse>));
|
||||||
var outputCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<CachedResponse>));
|
var outputCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<CachedResponse>));
|
||||||
var instance = (ICacheManager<CachedResponse>)outputCacheManager.ImplementationInstance;
|
var instance = (ICacheManager<CachedResponse>)outputCacheManager.ImplementationInstance;
|
||||||
var ocelotConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<IOcelotConfiguration>));
|
var ocelotConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<IInternalConfiguration>));
|
||||||
var ocelotConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<IOcelotConfiguration>));
|
var ocelotConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<IInternalConfiguration>));
|
||||||
var fileConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<FileConfiguration>));
|
var fileConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<FileConfiguration>));
|
||||||
var fileConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<FileConfiguration>));
|
var fileConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<FileConfiguration>));
|
||||||
|
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
using Ocelot.Middleware;
|
namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||||
using Ocelot.Middleware.Multiplexer;
|
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|
||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -9,7 +6,6 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
using Moq;
|
using Moq;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.Builder;
|
using Ocelot.Configuration.Builder;
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
using Ocelot.DownstreamRouteFinder;
|
using Ocelot.DownstreamRouteFinder;
|
||||||
using Ocelot.DownstreamRouteFinder.Finder;
|
using Ocelot.DownstreamRouteFinder.Finder;
|
||||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||||
@ -19,23 +15,26 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
using Ocelot.Configuration.Repository;
|
||||||
|
using Ocelot.Middleware;
|
||||||
|
using Ocelot.Middleware.Multiplexer;
|
||||||
|
|
||||||
public class DownstreamRouteFinderMiddlewareTests
|
public class DownstreamRouteFinderMiddlewareTests
|
||||||
{
|
{
|
||||||
private readonly Mock<IDownstreamRouteFinder> _finder;
|
private readonly Mock<IDownstreamRouteFinder> _finder;
|
||||||
private readonly Mock<IOcelotConfigurationProvider> _provider;
|
private readonly Mock<IInternalConfigurationRepository> _repo;
|
||||||
private Response<DownstreamRoute> _downstreamRoute;
|
private Response<DownstreamRoute> _downstreamRoute;
|
||||||
private IOcelotConfiguration _config;
|
private IInternalConfiguration _config;
|
||||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||||
private Mock<IOcelotLogger> _logger;
|
private Mock<IOcelotLogger> _logger;
|
||||||
private DownstreamRouteFinderMiddleware _middleware;
|
private readonly DownstreamRouteFinderMiddleware _middleware;
|
||||||
private DownstreamContext _downstreamContext;
|
private readonly DownstreamContext _downstreamContext;
|
||||||
private OcelotRequestDelegate _next;
|
private OcelotRequestDelegate _next;
|
||||||
private readonly Mock<IMultiplexer> _multiplexer;
|
private readonly Mock<IMultiplexer> _multiplexer;
|
||||||
|
|
||||||
public DownstreamRouteFinderMiddlewareTests()
|
public DownstreamRouteFinderMiddlewareTests()
|
||||||
{
|
{
|
||||||
_provider = new Mock<IOcelotConfigurationProvider>();
|
_repo = new Mock<IInternalConfigurationRepository>();
|
||||||
_finder = new Mock<IDownstreamRouteFinder>();
|
_finder = new Mock<IDownstreamRouteFinder>();
|
||||||
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
|
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
|
||||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||||
@ -43,13 +42,13 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
_loggerFactory.Setup(x => x.CreateLogger<DownstreamRouteFinderMiddleware>()).Returns(_logger.Object);
|
_loggerFactory.Setup(x => x.CreateLogger<DownstreamRouteFinderMiddleware>()).Returns(_logger.Object);
|
||||||
_next = context => Task.CompletedTask;
|
_next = context => Task.CompletedTask;
|
||||||
_multiplexer = new Mock<IMultiplexer>();
|
_multiplexer = new Mock<IMultiplexer>();
|
||||||
_middleware = new DownstreamRouteFinderMiddleware(_next, _loggerFactory.Object, _finder.Object, _provider.Object, _multiplexer.Object);
|
_middleware = new DownstreamRouteFinderMiddleware(_next, _loggerFactory.Object, _finder.Object, _repo.Object, _multiplexer.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_call_scoped_data_repository_correctly()
|
public void should_call_scoped_data_repository_correctly()
|
||||||
{
|
{
|
||||||
var config = new OcelotConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "");
|
var config = new InternalConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "");
|
||||||
|
|
||||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||||
.WithDownstreamPathTemplate("any old string")
|
.WithDownstreamPathTemplate("any old string")
|
||||||
@ -74,19 +73,19 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
_middleware.Invoke(_downstreamContext).GetAwaiter().GetType();
|
_middleware.Invoke(_downstreamContext).GetAwaiter().GetType();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenTheFollowingConfig(IOcelotConfiguration config)
|
private void GivenTheFollowingConfig(IInternalConfiguration config)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
_provider
|
_repo
|
||||||
.Setup(x => x.Get())
|
.Setup(x => x.Get())
|
||||||
.ReturnsAsync(new OkResponse<IOcelotConfiguration>(_config));
|
.Returns(new OkResponse<IInternalConfiguration>(_config));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenTheDownStreamRouteFinderReturns(DownstreamRoute downstreamRoute)
|
private void GivenTheDownStreamRouteFinderReturns(DownstreamRoute downstreamRoute)
|
||||||
{
|
{
|
||||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||||
_finder
|
_finder
|
||||||
.Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IOcelotConfiguration>(), It.IsAny<string>()))
|
.Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IInternalConfiguration>(), It.IsAny<string>()))
|
||||||
.Returns(_downstreamRoute);
|
.Returns(_downstreamRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
using Moq;
|
using Moq;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.Builder;
|
using Ocelot.Configuration.Builder;
|
||||||
using Ocelot.Configuration.Creator;
|
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
using Ocelot.DownstreamRouteFinder;
|
using Ocelot.DownstreamRouteFinder;
|
||||||
using Ocelot.DownstreamRouteFinder.Finder;
|
using Ocelot.DownstreamRouteFinder.Finder;
|
||||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||||
@ -23,7 +21,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
private string _upstreamUrlPath;
|
private string _upstreamUrlPath;
|
||||||
private Response<DownstreamRoute> _result;
|
private Response<DownstreamRoute> _result;
|
||||||
private List<ReRoute> _reRoutesConfig;
|
private List<ReRoute> _reRoutesConfig;
|
||||||
private OcelotConfiguration _config;
|
private InternalConfiguration _config;
|
||||||
private Response<UrlMatch> _match;
|
private Response<UrlMatch> _match;
|
||||||
private string _upstreamHttpMethod;
|
private string _upstreamHttpMethod;
|
||||||
private string _upstreamHost;
|
private string _upstreamHost;
|
||||||
@ -711,7 +709,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
private void GivenTheConfigurationIs(List<ReRoute> reRoutesConfig, string adminPath, ServiceProviderConfiguration serviceProviderConfig)
|
private void GivenTheConfigurationIs(List<ReRoute> reRoutesConfig, string adminPath, ServiceProviderConfiguration serviceProviderConfig)
|
||||||
{
|
{
|
||||||
_reRoutesConfig = reRoutesConfig;
|
_reRoutesConfig = reRoutesConfig;
|
||||||
_config = new OcelotConfiguration(_reRoutesConfig, adminPath, serviceProviderConfig, "");
|
_config = new InternalConfiguration(_reRoutesConfig, adminPath, serviceProviderConfig, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)
|
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)
|
||||||
|
@ -9,17 +9,17 @@ namespace Ocelot.UnitTests.Errors
|
|||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.Provider;
|
|
||||||
using Moq;
|
using Moq;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Errors;
|
using Ocelot.Errors;
|
||||||
using Ocelot.Infrastructure.RequestData;
|
using Ocelot.Infrastructure.RequestData;
|
||||||
using Ocelot.Middleware;
|
using Ocelot.Middleware;
|
||||||
|
using Ocelot.Configuration.Repository;
|
||||||
|
|
||||||
public class ExceptionHandlerMiddlewareTests
|
public class ExceptionHandlerMiddlewareTests
|
||||||
{
|
{
|
||||||
bool _shouldThrowAnException;
|
bool _shouldThrowAnException;
|
||||||
private readonly Mock<IOcelotConfigurationProvider> _provider;
|
private readonly Mock<IInternalConfigurationRepository> _configRepo;
|
||||||
private readonly Mock<IRequestScopedDataRepository> _repo;
|
private readonly Mock<IRequestScopedDataRepository> _repo;
|
||||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||||
private Mock<IOcelotLogger> _logger;
|
private Mock<IOcelotLogger> _logger;
|
||||||
@ -29,7 +29,7 @@ namespace Ocelot.UnitTests.Errors
|
|||||||
|
|
||||||
public ExceptionHandlerMiddlewareTests()
|
public ExceptionHandlerMiddlewareTests()
|
||||||
{
|
{
|
||||||
_provider = new Mock<IOcelotConfigurationProvider>();
|
_configRepo = new Mock<IInternalConfigurationRepository>();
|
||||||
_repo = new Mock<IRequestScopedDataRepository>();
|
_repo = new Mock<IRequestScopedDataRepository>();
|
||||||
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
|
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
|
||||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||||
@ -45,13 +45,13 @@ namespace Ocelot.UnitTests.Errors
|
|||||||
|
|
||||||
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
|
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
|
||||||
};
|
};
|
||||||
_middleware = new ExceptionHandlerMiddleware(_next, _loggerFactory.Object, _provider.Object, _repo.Object);
|
_middleware = new ExceptionHandlerMiddleware(_next, _loggerFactory.Object, _configRepo.Object, _repo.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void NoDownstreamException()
|
public void NoDownstreamException()
|
||||||
{
|
{
|
||||||
var config = new OcelotConfiguration(null, null, null, null);
|
var config = new InternalConfiguration(null, null, null, null);
|
||||||
|
|
||||||
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
|
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
|
||||||
.And(_ => GivenTheConfigurationIs(config))
|
.And(_ => GivenTheConfigurationIs(config))
|
||||||
@ -64,7 +64,7 @@ namespace Ocelot.UnitTests.Errors
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void DownstreamException()
|
public void DownstreamException()
|
||||||
{
|
{
|
||||||
var config = new OcelotConfiguration(null, null, null, null);
|
var config = new InternalConfiguration(null, null, null, null);
|
||||||
|
|
||||||
this.Given(_ => GivenAnExceptionWillBeThrownDownstream())
|
this.Given(_ => GivenAnExceptionWillBeThrownDownstream())
|
||||||
.And(_ => GivenTheConfigurationIs(config))
|
.And(_ => GivenTheConfigurationIs(config))
|
||||||
@ -76,7 +76,7 @@ namespace Ocelot.UnitTests.Errors
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void ShouldSetRequestId()
|
public void ShouldSetRequestId()
|
||||||
{
|
{
|
||||||
var config = new OcelotConfiguration(null, null, null, "requestidkey");
|
var config = new InternalConfiguration(null, null, null, "requestidkey");
|
||||||
|
|
||||||
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
|
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
|
||||||
.And(_ => GivenTheConfigurationIs(config))
|
.And(_ => GivenTheConfigurationIs(config))
|
||||||
@ -89,7 +89,7 @@ namespace Ocelot.UnitTests.Errors
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void ShouldSetAspDotNetRequestId()
|
public void ShouldSetAspDotNetRequestId()
|
||||||
{
|
{
|
||||||
var config = new OcelotConfiguration(null, null, null, null);
|
var config = new InternalConfiguration(null, null, null, null);
|
||||||
|
|
||||||
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
|
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
|
||||||
.And(_ => GivenTheConfigurationIs(config))
|
.And(_ => GivenTheConfigurationIs(config))
|
||||||
@ -133,8 +133,8 @@ namespace Ocelot.UnitTests.Errors
|
|||||||
private void GivenTheConfigThrows()
|
private void GivenTheConfigThrows()
|
||||||
{
|
{
|
||||||
var ex = new Exception("outer", new Exception("inner"));
|
var ex = new Exception("outer", new Exception("inner"));
|
||||||
_provider
|
_configRepo
|
||||||
.Setup(x => x.Get()).ThrowsAsync(ex);
|
.Setup(x => x.Get()).Throws(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenAnExceptionIsThrown()
|
private void ThenAnExceptionIsThrown()
|
||||||
@ -144,9 +144,9 @@ namespace Ocelot.UnitTests.Errors
|
|||||||
|
|
||||||
private void GivenTheConfigReturnsError()
|
private void GivenTheConfigReturnsError()
|
||||||
{
|
{
|
||||||
var response = new Responses.ErrorResponse<IOcelotConfiguration>(new FakeError());
|
var response = new Responses.ErrorResponse<IInternalConfiguration>(new FakeError());
|
||||||
_provider
|
_configRepo
|
||||||
.Setup(x => x.Get()).ReturnsAsync(response);
|
.Setup(x => x.Get()).Returns(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TheRequestIdIsSet(string key, string value)
|
private void TheRequestIdIsSet(string key, string value)
|
||||||
@ -154,11 +154,11 @@ namespace Ocelot.UnitTests.Errors
|
|||||||
_repo.Verify(x => x.Add(key, value), Times.Once);
|
_repo.Verify(x => x.Add(key, value), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenTheConfigurationIs(IOcelotConfiguration config)
|
private void GivenTheConfigurationIs(IInternalConfiguration config)
|
||||||
{
|
{
|
||||||
var response = new Responses.OkResponse<IOcelotConfiguration>(config);
|
var response = new Responses.OkResponse<IInternalConfiguration>(config);
|
||||||
_provider
|
_configRepo
|
||||||
.Setup(x => x.Get()).ReturnsAsync(response);
|
.Setup(x => x.Get()).Returns(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenAnExceptionWillNotBeThrownDownstream()
|
private void GivenAnExceptionWillNotBeThrownDownstream()
|
||||||
|
@ -28,12 +28,6 @@
|
|||||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Update="idsrv3test.pfx">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.2" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.2" />
|
||||||
|
@ -1 +0,0 @@
|
|||||||
{"ReRoutes":[{"DownstreamPathTemplate":"/test/test/{test}","UpstreamPathTemplate":null,"UpstreamHttpMethod":null,"AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ApiName":null,"RequireHttps":false,"AllowedScopes":[],"ApiSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"https","DownstreamHost":"localhost","DownstreamPort":80,"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":"consul","Host":"blah","Port":198},"AdministrationPath":"testy"}}
|
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user